Skip to content

Commit 97d73cf

Browse files
stainless-app[bot]RobertCraigie
authored andcommitted
feat: add Realtime API support (#1958)
More information on the Realtime API can be found here: https://platform.openai.com/docs/guides/realtime
1 parent ec22ffb commit 97d73cf

File tree

70 files changed

+3313
-4
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+3313
-4
lines changed

.stats.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
configured_endpoints: 69
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai-779ea2754025daf5e18eb8ceb203ec321692636bc3a999338556a479178efa6c.yml
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai-0d64ca9e45f51b4279f87b205eeb3a3576df98407698ce053f2e2302c1c08df1.yml

api.md

+51
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,57 @@ Methods:
239239

240240
## Realtime
241241

242+
Types:
243+
244+
```python
245+
from openai.types.beta.realtime import (
246+
ConversationCreatedEvent,
247+
ConversationItem,
248+
ConversationItemContent,
249+
ConversationItemCreateEvent,
250+
ConversationItemCreatedEvent,
251+
ConversationItemDeleteEvent,
252+
ConversationItemDeletedEvent,
253+
ConversationItemInputAudioTranscriptionCompletedEvent,
254+
ConversationItemInputAudioTranscriptionFailedEvent,
255+
ConversationItemTruncateEvent,
256+
ConversationItemTruncatedEvent,
257+
ErrorEvent,
258+
InputAudioBufferAppendEvent,
259+
InputAudioBufferClearEvent,
260+
InputAudioBufferClearedEvent,
261+
InputAudioBufferCommitEvent,
262+
InputAudioBufferCommittedEvent,
263+
InputAudioBufferSpeechStartedEvent,
264+
InputAudioBufferSpeechStoppedEvent,
265+
RateLimitsUpdatedEvent,
266+
RealtimeClientEvent,
267+
RealtimeResponse,
268+
RealtimeResponseStatus,
269+
RealtimeResponseUsage,
270+
RealtimeServerEvent,
271+
ResponseAudioDeltaEvent,
272+
ResponseAudioDoneEvent,
273+
ResponseAudioTranscriptDeltaEvent,
274+
ResponseAudioTranscriptDoneEvent,
275+
ResponseCancelEvent,
276+
ResponseContentPartAddedEvent,
277+
ResponseContentPartDoneEvent,
278+
ResponseCreateEvent,
279+
ResponseCreatedEvent,
280+
ResponseDoneEvent,
281+
ResponseFunctionCallArgumentsDeltaEvent,
282+
ResponseFunctionCallArgumentsDoneEvent,
283+
ResponseOutputItemAddedEvent,
284+
ResponseOutputItemDoneEvent,
285+
ResponseTextDeltaEvent,
286+
ResponseTextDoneEvent,
287+
SessionCreatedEvent,
288+
SessionUpdateEvent,
289+
SessionUpdatedEvent,
290+
)
291+
```
292+
242293
### Sessions
243294

244295
Types:

pyproject.toml

+4-3
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,17 @@ classifiers = [
3535
"License :: OSI Approved :: Apache Software License"
3636
]
3737

38-
[project.optional-dependencies]
39-
datalib = ["numpy >= 1", "pandas >= 1.2.3", "pandas-stubs >= 1.1.0.11"]
40-
4138
[project.urls]
4239
Homepage = "https://github.com/openai/openai-python"
4340
Repository = "https://github.com/openai/openai-python"
4441

4542
[project.scripts]
4643
openai = "openai.cli:main"
4744

45+
[project.optional-dependencies]
46+
realtime = ["websockets >= 13, < 15"]
47+
datalib = ["numpy >= 1", "pandas >= 1.2.3", "pandas-stubs >= 1.1.0.11"]
48+
4849
[tool.rye]
4950
managed = true
5051
# version pins are in requirements-dev.lock

requirements-dev.lock

+2
Original file line numberDiff line numberDiff line change
@@ -185,5 +185,7 @@ urllib3==2.2.1
185185
# via requests
186186
virtualenv==20.24.5
187187
# via nox
188+
websockets==14.1
189+
# via openai
188190
zipp==3.17.0
189191
# via importlib-metadata

requirements.lock

+2
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,5 @@ typing-extensions==4.12.2
6464
# via pydantic-core
6565
tzdata==2024.1
6666
# via pandas
67+
websockets==14.1
68+
# via openai

src/openai/_client.py

+26
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,22 @@ class OpenAI(SyncAPIClient):
6363
organization: str | None
6464
project: str | None
6565

66+
websocket_base_url: str | httpx.URL | None
67+
"""Base URL for WebSocket connections.
68+
69+
If not specified, the default base URL will be used, with 'wss://' replacing the
70+
'http://' or 'https://' scheme. For example: 'http://example.com' becomes
71+
'wss://example.com'
72+
"""
73+
6674
def __init__(
6775
self,
6876
*,
6977
api_key: str | None = None,
7078
organization: str | None = None,
7179
project: str | None = None,
7280
base_url: str | httpx.URL | None = None,
81+
websocket_base_url: str | httpx.URL | None = None,
7382
timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
7483
max_retries: int = DEFAULT_MAX_RETRIES,
7584
default_headers: Mapping[str, str] | None = None,
@@ -111,6 +120,8 @@ def __init__(
111120
project = os.environ.get("OPENAI_PROJECT_ID")
112121
self.project = project
113122

123+
self.websocket_base_url = websocket_base_url
124+
114125
if base_url is None:
115126
base_url = os.environ.get("OPENAI_BASE_URL")
116127
if base_url is None:
@@ -172,6 +183,7 @@ def copy(
172183
api_key: str | None = None,
173184
organization: str | None = None,
174185
project: str | None = None,
186+
websocket_base_url: str | httpx.URL | None = None,
175187
base_url: str | httpx.URL | None = None,
176188
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
177189
http_client: httpx.Client | None = None,
@@ -208,6 +220,7 @@ def copy(
208220
api_key=api_key or self.api_key,
209221
organization=organization or self.organization,
210222
project=project or self.project,
223+
websocket_base_url=websocket_base_url or self.websocket_base_url,
211224
base_url=base_url or self.base_url,
212225
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
213226
http_client=http_client,
@@ -277,13 +290,22 @@ class AsyncOpenAI(AsyncAPIClient):
277290
organization: str | None
278291
project: str | None
279292

293+
websocket_base_url: str | httpx.URL | None
294+
"""Base URL for WebSocket connections.
295+
296+
If not specified, the default base URL will be used, with 'wss://' replacing the
297+
'http://' or 'https://' scheme. For example: 'http://example.com' becomes
298+
'wss://example.com'
299+
"""
300+
280301
def __init__(
281302
self,
282303
*,
283304
api_key: str | None = None,
284305
organization: str | None = None,
285306
project: str | None = None,
286307
base_url: str | httpx.URL | None = None,
308+
websocket_base_url: str | httpx.URL | None = None,
287309
timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
288310
max_retries: int = DEFAULT_MAX_RETRIES,
289311
default_headers: Mapping[str, str] | None = None,
@@ -325,6 +347,8 @@ def __init__(
325347
project = os.environ.get("OPENAI_PROJECT_ID")
326348
self.project = project
327349

350+
self.websocket_base_url = websocket_base_url
351+
328352
if base_url is None:
329353
base_url = os.environ.get("OPENAI_BASE_URL")
330354
if base_url is None:
@@ -386,6 +410,7 @@ def copy(
386410
api_key: str | None = None,
387411
organization: str | None = None,
388412
project: str | None = None,
413+
websocket_base_url: str | httpx.URL | None = None,
389414
base_url: str | httpx.URL | None = None,
390415
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
391416
http_client: httpx.AsyncClient | None = None,
@@ -422,6 +447,7 @@ def copy(
422447
api_key=api_key or self.api_key,
423448
organization=organization or self.organization,
424449
project=project or self.project,
450+
websocket_base_url=websocket_base_url or self.websocket_base_url,
425451
base_url=base_url or self.base_url,
426452
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
427453
http_client=http_client,

src/openai/lib/azure.py

+14
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ def __init__(
7676
azure_ad_token: str | None = None,
7777
azure_ad_token_provider: AzureADTokenProvider | None = None,
7878
organization: str | None = None,
79+
websocket_base_url: str | httpx.URL | None = None,
7980
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
8081
max_retries: int = DEFAULT_MAX_RETRIES,
8182
default_headers: Mapping[str, str] | None = None,
@@ -94,6 +95,7 @@ def __init__(
9495
azure_ad_token: str | None = None,
9596
azure_ad_token_provider: AzureADTokenProvider | None = None,
9697
organization: str | None = None,
98+
websocket_base_url: str | httpx.URL | None = None,
9799
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
98100
max_retries: int = DEFAULT_MAX_RETRIES,
99101
default_headers: Mapping[str, str] | None = None,
@@ -112,6 +114,7 @@ def __init__(
112114
azure_ad_token: str | None = None,
113115
azure_ad_token_provider: AzureADTokenProvider | None = None,
114116
organization: str | None = None,
117+
websocket_base_url: str | httpx.URL | None = None,
115118
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
116119
max_retries: int = DEFAULT_MAX_RETRIES,
117120
default_headers: Mapping[str, str] | None = None,
@@ -131,6 +134,7 @@ def __init__(
131134
azure_ad_token_provider: AzureADTokenProvider | None = None,
132135
organization: str | None = None,
133136
project: str | None = None,
137+
websocket_base_url: str | httpx.URL | None = None,
134138
base_url: str | None = None,
135139
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
136140
max_retries: int = DEFAULT_MAX_RETRIES,
@@ -214,6 +218,7 @@ def __init__(
214218
default_headers=default_headers,
215219
default_query=default_query,
216220
http_client=http_client,
221+
websocket_base_url=websocket_base_url,
217222
_strict_response_validation=_strict_response_validation,
218223
)
219224
self._api_version = api_version
@@ -227,6 +232,7 @@ def copy(
227232
api_key: str | None = None,
228233
organization: str | None = None,
229234
project: str | None = None,
235+
websocket_base_url: str | httpx.URL | None = None,
230236
api_version: str | None = None,
231237
azure_ad_token: str | None = None,
232238
azure_ad_token_provider: AzureADTokenProvider | None = None,
@@ -247,6 +253,7 @@ def copy(
247253
api_key=api_key,
248254
organization=organization,
249255
project=project,
256+
websocket_base_url=websocket_base_url,
250257
base_url=base_url,
251258
timeout=timeout,
252259
http_client=http_client,
@@ -314,6 +321,7 @@ def __init__(
314321
azure_ad_token_provider: AsyncAzureADTokenProvider | None = None,
315322
organization: str | None = None,
316323
project: str | None = None,
324+
websocket_base_url: str | httpx.URL | None = None,
317325
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
318326
max_retries: int = DEFAULT_MAX_RETRIES,
319327
default_headers: Mapping[str, str] | None = None,
@@ -333,6 +341,7 @@ def __init__(
333341
azure_ad_token_provider: AsyncAzureADTokenProvider | None = None,
334342
organization: str | None = None,
335343
project: str | None = None,
344+
websocket_base_url: str | httpx.URL | None = None,
336345
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
337346
max_retries: int = DEFAULT_MAX_RETRIES,
338347
default_headers: Mapping[str, str] | None = None,
@@ -352,6 +361,7 @@ def __init__(
352361
azure_ad_token_provider: AsyncAzureADTokenProvider | None = None,
353362
organization: str | None = None,
354363
project: str | None = None,
364+
websocket_base_url: str | httpx.URL | None = None,
355365
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
356366
max_retries: int = DEFAULT_MAX_RETRIES,
357367
default_headers: Mapping[str, str] | None = None,
@@ -372,6 +382,7 @@ def __init__(
372382
organization: str | None = None,
373383
project: str | None = None,
374384
base_url: str | None = None,
385+
websocket_base_url: str | httpx.URL | None = None,
375386
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
376387
max_retries: int = DEFAULT_MAX_RETRIES,
377388
default_headers: Mapping[str, str] | None = None,
@@ -454,6 +465,7 @@ def __init__(
454465
default_headers=default_headers,
455466
default_query=default_query,
456467
http_client=http_client,
468+
websocket_base_url=websocket_base_url,
457469
_strict_response_validation=_strict_response_validation,
458470
)
459471
self._api_version = api_version
@@ -467,6 +479,7 @@ def copy(
467479
api_key: str | None = None,
468480
organization: str | None = None,
469481
project: str | None = None,
482+
websocket_base_url: str | httpx.URL | None = None,
470483
api_version: str | None = None,
471484
azure_ad_token: str | None = None,
472485
azure_ad_token_provider: AsyncAzureADTokenProvider | None = None,
@@ -487,6 +500,7 @@ def copy(
487500
api_key=api_key,
488501
organization=organization,
489502
project=project,
503+
websocket_base_url=websocket_base_url,
490504
base_url=base_url,
491505
timeout=timeout,
492506
http_client=http_client,

0 commit comments

Comments
 (0)