Skip to content

Commit

Permalink
feat: add Realtime API support (#1958)
Browse files Browse the repository at this point in the history
More information on the Realtime API can be found here:
https://platform.openai.com/docs/guides/realtime
  • Loading branch information
stainless-app[bot] authored and RobertCraigie committed Dec 17, 2024
1 parent ec22ffb commit 97d73cf
Show file tree
Hide file tree
Showing 70 changed files with 3,313 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .stats.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
configured_endpoints: 69
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai-779ea2754025daf5e18eb8ceb203ec321692636bc3a999338556a479178efa6c.yml
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai-0d64ca9e45f51b4279f87b205eeb3a3576df98407698ce053f2e2302c1c08df1.yml
51 changes: 51 additions & 0 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,57 @@ Methods:

## Realtime

Types:

```python
from openai.types.beta.realtime import (
ConversationCreatedEvent,
ConversationItem,
ConversationItemContent,
ConversationItemCreateEvent,
ConversationItemCreatedEvent,
ConversationItemDeleteEvent,
ConversationItemDeletedEvent,
ConversationItemInputAudioTranscriptionCompletedEvent,
ConversationItemInputAudioTranscriptionFailedEvent,
ConversationItemTruncateEvent,
ConversationItemTruncatedEvent,
ErrorEvent,
InputAudioBufferAppendEvent,
InputAudioBufferClearEvent,
InputAudioBufferClearedEvent,
InputAudioBufferCommitEvent,
InputAudioBufferCommittedEvent,
InputAudioBufferSpeechStartedEvent,
InputAudioBufferSpeechStoppedEvent,
RateLimitsUpdatedEvent,
RealtimeClientEvent,
RealtimeResponse,
RealtimeResponseStatus,
RealtimeResponseUsage,
RealtimeServerEvent,
ResponseAudioDeltaEvent,
ResponseAudioDoneEvent,
ResponseAudioTranscriptDeltaEvent,
ResponseAudioTranscriptDoneEvent,
ResponseCancelEvent,
ResponseContentPartAddedEvent,
ResponseContentPartDoneEvent,
ResponseCreateEvent,
ResponseCreatedEvent,
ResponseDoneEvent,
ResponseFunctionCallArgumentsDeltaEvent,
ResponseFunctionCallArgumentsDoneEvent,
ResponseOutputItemAddedEvent,
ResponseOutputItemDoneEvent,
ResponseTextDeltaEvent,
ResponseTextDoneEvent,
SessionCreatedEvent,
SessionUpdateEvent,
SessionUpdatedEvent,
)
```

### Sessions

Types:
Expand Down
7 changes: 4 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,17 @@ classifiers = [
"License :: OSI Approved :: Apache Software License"
]

[project.optional-dependencies]
datalib = ["numpy >= 1", "pandas >= 1.2.3", "pandas-stubs >= 1.1.0.11"]

[project.urls]
Homepage = "https://github.com/openai/openai-python"
Repository = "https://github.com/openai/openai-python"

[project.scripts]
openai = "openai.cli:main"

[project.optional-dependencies]
realtime = ["websockets >= 13, < 15"]
datalib = ["numpy >= 1", "pandas >= 1.2.3", "pandas-stubs >= 1.1.0.11"]

[tool.rye]
managed = true
# version pins are in requirements-dev.lock
Expand Down
2 changes: 2 additions & 0 deletions requirements-dev.lock
Original file line number Diff line number Diff line change
Expand Up @@ -185,5 +185,7 @@ urllib3==2.2.1
# via requests
virtualenv==20.24.5
# via nox
websockets==14.1
# via openai
zipp==3.17.0
# via importlib-metadata
2 changes: 2 additions & 0 deletions requirements.lock
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,5 @@ typing-extensions==4.12.2
# via pydantic-core
tzdata==2024.1
# via pandas
websockets==14.1
# via openai
26 changes: 26 additions & 0 deletions src/openai/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,22 @@ class OpenAI(SyncAPIClient):
organization: str | None
project: str | None

websocket_base_url: str | httpx.URL | None
"""Base URL for WebSocket connections.
If not specified, the default base URL will be used, with 'wss://' replacing the
'http://' or 'https://' scheme. For example: 'http://example.com' becomes
'wss://example.com'
"""

def __init__(
self,
*,
api_key: str | None = None,
organization: str | None = None,
project: str | None = None,
base_url: str | httpx.URL | None = None,
websocket_base_url: str | httpx.URL | None = None,
timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
default_headers: Mapping[str, str] | None = None,
Expand Down Expand Up @@ -111,6 +120,8 @@ def __init__(
project = os.environ.get("OPENAI_PROJECT_ID")
self.project = project

self.websocket_base_url = websocket_base_url

if base_url is None:
base_url = os.environ.get("OPENAI_BASE_URL")
if base_url is None:
Expand Down Expand Up @@ -172,6 +183,7 @@ def copy(
api_key: str | None = None,
organization: str | None = None,
project: str | None = None,
websocket_base_url: str | httpx.URL | None = None,
base_url: str | httpx.URL | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
http_client: httpx.Client | None = None,
Expand Down Expand Up @@ -208,6 +220,7 @@ def copy(
api_key=api_key or self.api_key,
organization=organization or self.organization,
project=project or self.project,
websocket_base_url=websocket_base_url or self.websocket_base_url,
base_url=base_url or self.base_url,
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
http_client=http_client,
Expand Down Expand Up @@ -277,13 +290,22 @@ class AsyncOpenAI(AsyncAPIClient):
organization: str | None
project: str | None

websocket_base_url: str | httpx.URL | None
"""Base URL for WebSocket connections.
If not specified, the default base URL will be used, with 'wss://' replacing the
'http://' or 'https://' scheme. For example: 'http://example.com' becomes
'wss://example.com'
"""

def __init__(
self,
*,
api_key: str | None = None,
organization: str | None = None,
project: str | None = None,
base_url: str | httpx.URL | None = None,
websocket_base_url: str | httpx.URL | None = None,
timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
default_headers: Mapping[str, str] | None = None,
Expand Down Expand Up @@ -325,6 +347,8 @@ def __init__(
project = os.environ.get("OPENAI_PROJECT_ID")
self.project = project

self.websocket_base_url = websocket_base_url

if base_url is None:
base_url = os.environ.get("OPENAI_BASE_URL")
if base_url is None:
Expand Down Expand Up @@ -386,6 +410,7 @@ def copy(
api_key: str | None = None,
organization: str | None = None,
project: str | None = None,
websocket_base_url: str | httpx.URL | None = None,
base_url: str | httpx.URL | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
http_client: httpx.AsyncClient | None = None,
Expand Down Expand Up @@ -422,6 +447,7 @@ def copy(
api_key=api_key or self.api_key,
organization=organization or self.organization,
project=project or self.project,
websocket_base_url=websocket_base_url or self.websocket_base_url,
base_url=base_url or self.base_url,
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
http_client=http_client,
Expand Down
14 changes: 14 additions & 0 deletions src/openai/lib/azure.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def __init__(
azure_ad_token: str | None = None,
azure_ad_token_provider: AzureADTokenProvider | None = None,
organization: str | None = None,
websocket_base_url: str | httpx.URL | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
default_headers: Mapping[str, str] | None = None,
Expand All @@ -94,6 +95,7 @@ def __init__(
azure_ad_token: str | None = None,
azure_ad_token_provider: AzureADTokenProvider | None = None,
organization: str | None = None,
websocket_base_url: str | httpx.URL | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
default_headers: Mapping[str, str] | None = None,
Expand All @@ -112,6 +114,7 @@ def __init__(
azure_ad_token: str | None = None,
azure_ad_token_provider: AzureADTokenProvider | None = None,
organization: str | None = None,
websocket_base_url: str | httpx.URL | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
default_headers: Mapping[str, str] | None = None,
Expand All @@ -131,6 +134,7 @@ def __init__(
azure_ad_token_provider: AzureADTokenProvider | None = None,
organization: str | None = None,
project: str | None = None,
websocket_base_url: str | httpx.URL | None = None,
base_url: str | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
Expand Down Expand Up @@ -214,6 +218,7 @@ def __init__(
default_headers=default_headers,
default_query=default_query,
http_client=http_client,
websocket_base_url=websocket_base_url,
_strict_response_validation=_strict_response_validation,
)
self._api_version = api_version
Expand All @@ -227,6 +232,7 @@ def copy(
api_key: str | None = None,
organization: str | None = None,
project: str | None = None,
websocket_base_url: str | httpx.URL | None = None,
api_version: str | None = None,
azure_ad_token: str | None = None,
azure_ad_token_provider: AzureADTokenProvider | None = None,
Expand All @@ -247,6 +253,7 @@ def copy(
api_key=api_key,
organization=organization,
project=project,
websocket_base_url=websocket_base_url,
base_url=base_url,
timeout=timeout,
http_client=http_client,
Expand Down Expand Up @@ -314,6 +321,7 @@ def __init__(
azure_ad_token_provider: AsyncAzureADTokenProvider | None = None,
organization: str | None = None,
project: str | None = None,
websocket_base_url: str | httpx.URL | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
default_headers: Mapping[str, str] | None = None,
Expand All @@ -333,6 +341,7 @@ def __init__(
azure_ad_token_provider: AsyncAzureADTokenProvider | None = None,
organization: str | None = None,
project: str | None = None,
websocket_base_url: str | httpx.URL | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
default_headers: Mapping[str, str] | None = None,
Expand All @@ -352,6 +361,7 @@ def __init__(
azure_ad_token_provider: AsyncAzureADTokenProvider | None = None,
organization: str | None = None,
project: str | None = None,
websocket_base_url: str | httpx.URL | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
default_headers: Mapping[str, str] | None = None,
Expand All @@ -372,6 +382,7 @@ def __init__(
organization: str | None = None,
project: str | None = None,
base_url: str | None = None,
websocket_base_url: str | httpx.URL | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
default_headers: Mapping[str, str] | None = None,
Expand Down Expand Up @@ -454,6 +465,7 @@ def __init__(
default_headers=default_headers,
default_query=default_query,
http_client=http_client,
websocket_base_url=websocket_base_url,
_strict_response_validation=_strict_response_validation,
)
self._api_version = api_version
Expand All @@ -467,6 +479,7 @@ def copy(
api_key: str | None = None,
organization: str | None = None,
project: str | None = None,
websocket_base_url: str | httpx.URL | None = None,
api_version: str | None = None,
azure_ad_token: str | None = None,
azure_ad_token_provider: AsyncAzureADTokenProvider | None = None,
Expand All @@ -487,6 +500,7 @@ def copy(
api_key=api_key,
organization=organization,
project=project,
websocket_base_url=websocket_base_url,
base_url=base_url,
timeout=timeout,
http_client=http_client,
Expand Down
Loading

0 comments on commit 97d73cf

Please sign in to comment.