Skip to content
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "1.102.0"
".": "1.103.0"
}
8 changes: 4 additions & 4 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 119
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-8517ffa1004e31ca2523d617629e64be6fe4f13403ddfd9db5b3be002656cbde.yml
openapi_spec_hash: b64dd8c8b23082a7aa2a3e5c5fffd8bd
config_hash: fe0ea26680ac2075a6cd66416aefe7db
configured_endpoints: 118
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-356b4364203ff36d7724074cd04f6e684253bfcc3c9d969122d730aa7bc51b46.yml
openapi_spec_hash: 4ab8e96f52699bc3d2b0c4432aa92af8
config_hash: b854932c0ea24b400bdd64e4376936bd
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
# Changelog

## 1.103.0 (2025-09-02)

Full Changelog: [v1.102.0...v1.103.0](https://github.com/openai/openai-python/compare/v1.102.0...v1.103.0)

### Features

* **api:** realtime API updates ([b7c2ddc](https://github.com/openai/openai-python/commit/b7c2ddc5e5dedda01015b3d0e14ea6eb68c282d3))


### Bug Fixes

* **responses:** add missing params to stream() method ([bfc0673](https://github.com/openai/openai-python/commit/bfc06732ffe3764cb95cef9f23b4b5c0d312826a))


### Chores

* bump `inline-snapshot` version to 0.28.0 ([#2590](https://github.com/openai/openai-python/issues/2590)) ([a6b0872](https://github.com/openai/openai-python/commit/a6b087226587d4cc4f59f1f09a595921b2823ef2))
* **client:** format imports ([7ae3020](https://github.com/openai/openai-python/commit/7ae3020b3ca7de21e6e9a0a1c40908e655f6cad5))
* **internal:** add Sequence related utils ([d3d72b9](https://github.com/openai/openai-python/commit/d3d72b9ce3c0885bf2b6934ac57d9e84f8653208))
* **internal:** fix formatting ([3ab273f](https://github.com/openai/openai-python/commit/3ab273f21e601f088be7502b7bb5d249fc386d6a))
* **internal:** minor formatting change ([478a348](https://github.com/openai/openai-python/commit/478a34881c968e9cab9d93ac2cf8da2fcb37c46c))
* **internal:** update pyright exclude list ([66e440f](https://github.com/openai/openai-python/commit/66e440fac3ca388400392c64211450dedc491c11))

## 1.102.0 (2025-08-26)

Full Changelog: [v1.101.0...v1.102.0](https://github.com/openai/openai-python/compare/v1.101.0...v1.102.0)
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ async def main():
asyncio.run(main())
```

## Realtime API beta
## Realtime API

The Realtime API enables you to build low-latency, multi-modal conversational experiences. It currently supports text and audio as both input and output, as well as [function calling](https://platform.openai.com/docs/guides/function-calling) through a WebSocket connection.

Expand All @@ -243,7 +243,7 @@ from openai import AsyncOpenAI
async def main():
client = AsyncOpenAI()

async with client.beta.realtime.connect(model="gpt-4o-realtime-preview") as connection:
async with client.realtime.connect(model="gpt-realtime") as connection:
await connection.session.update(session={'modalities': ['text']})

await connection.conversation.item.create(
Expand Down Expand Up @@ -277,7 +277,7 @@ Whenever an error occurs, the Realtime API will send an [`error` event](https://
```py
client = AsyncOpenAI()

async with client.beta.realtime.connect(model="gpt-4o-realtime-preview") as connection:
async with client.realtime.connect(model="gpt-realtime") as connection:
...
async for event in connection:
if event.type == 'error':
Expand Down
111 changes: 111 additions & 0 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ from openai.types.webhooks import (
FineTuningJobCancelledWebhookEvent,
FineTuningJobFailedWebhookEvent,
FineTuningJobSucceededWebhookEvent,
RealtimeCallIncomingWebhookEvent,
ResponseCancelledWebhookEvent,
ResponseCompletedWebhookEvent,
ResponseFailedWebhookEvent,
Expand Down Expand Up @@ -832,6 +833,7 @@ from openai.types.responses import (
ToolChoiceMcp,
ToolChoiceOptions,
ToolChoiceTypes,
WebSearchPreviewTool,
WebSearchTool,
)
```
Expand All @@ -855,6 +857,115 @@ Methods:

- <code title="get /responses/{response_id}/input_items">client.responses.input_items.<a href="./src/openai/resources/responses/input_items.py">list</a>(response_id, \*\*<a href="src/openai/types/responses/input_item_list_params.py">params</a>) -> <a href="./src/openai/types/responses/response_item.py">SyncCursorPage[ResponseItem]</a></code>

# Realtime

Types:

```python
from openai.types.realtime import (
ConversationCreatedEvent,
ConversationItem,
ConversationItemAdded,
ConversationItemCreateEvent,
ConversationItemCreatedEvent,
ConversationItemDeleteEvent,
ConversationItemDeletedEvent,
ConversationItemDone,
ConversationItemInputAudioTranscriptionCompletedEvent,
ConversationItemInputAudioTranscriptionDeltaEvent,
ConversationItemInputAudioTranscriptionFailedEvent,
ConversationItemInputAudioTranscriptionSegment,
ConversationItemRetrieveEvent,
ConversationItemTruncateEvent,
ConversationItemTruncatedEvent,
ConversationItemWithReference,
InputAudioBufferAppendEvent,
InputAudioBufferClearEvent,
InputAudioBufferClearedEvent,
InputAudioBufferCommitEvent,
InputAudioBufferCommittedEvent,
InputAudioBufferSpeechStartedEvent,
InputAudioBufferSpeechStoppedEvent,
InputAudioBufferTimeoutTriggered,
LogProbProperties,
McpListToolsCompleted,
McpListToolsFailed,
McpListToolsInProgress,
OutputAudioBufferClearEvent,
RateLimitsUpdatedEvent,
RealtimeAudioConfig,
RealtimeClientEvent,
RealtimeClientSecretConfig,
RealtimeConversationItemAssistantMessage,
RealtimeConversationItemFunctionCall,
RealtimeConversationItemFunctionCallOutput,
RealtimeConversationItemSystemMessage,
RealtimeConversationItemUserMessage,
RealtimeError,
RealtimeErrorEvent,
RealtimeMcpApprovalRequest,
RealtimeMcpApprovalResponse,
RealtimeMcpListTools,
RealtimeMcpProtocolError,
RealtimeMcpToolCall,
RealtimeMcpToolExecutionError,
RealtimeMcphttpError,
RealtimeResponse,
RealtimeResponseStatus,
RealtimeResponseUsage,
RealtimeResponseUsageInputTokenDetails,
RealtimeResponseUsageOutputTokenDetails,
RealtimeServerEvent,
RealtimeSession,
RealtimeSessionCreateRequest,
RealtimeToolChoiceConfig,
RealtimeToolsConfig,
RealtimeToolsConfigUnion,
RealtimeTracingConfig,
RealtimeTranscriptionSessionCreateRequest,
RealtimeTruncation,
ResponseAudioDeltaEvent,
ResponseAudioDoneEvent,
ResponseAudioTranscriptDeltaEvent,
ResponseAudioTranscriptDoneEvent,
ResponseCancelEvent,
ResponseContentPartAddedEvent,
ResponseContentPartDoneEvent,
ResponseCreateEvent,
ResponseCreatedEvent,
ResponseDoneEvent,
ResponseFunctionCallArgumentsDeltaEvent,
ResponseFunctionCallArgumentsDoneEvent,
ResponseMcpCallArgumentsDelta,
ResponseMcpCallArgumentsDone,
ResponseMcpCallCompleted,
ResponseMcpCallFailed,
ResponseMcpCallInProgress,
ResponseOutputItemAddedEvent,
ResponseOutputItemDoneEvent,
ResponseTextDeltaEvent,
ResponseTextDoneEvent,
SessionCreatedEvent,
SessionUpdateEvent,
SessionUpdatedEvent,
TranscriptionSessionCreated,
TranscriptionSessionUpdate,
TranscriptionSessionUpdatedEvent,
)
```

## ClientSecrets

Types:

```python
from openai.types.realtime import RealtimeSessionCreateResponse, ClientSecretCreateResponse
```

Methods:

- <code title="post /realtime/client_secrets">client.realtime.client_secrets.<a href="./src/openai/resources/realtime/client_secrets.py">create</a>(\*\*<a href="src/openai/types/realtime/client_secret_create_params.py">params</a>) -> <a href="./src/openai/types/realtime/client_secret_create_response.py">ClientSecretCreateResponse</a></code>

# Conversations

Types:
Expand Down
2 changes: 1 addition & 1 deletion examples/realtime/audio_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import sounddevice as sd
from pydub import AudioSegment

from openai.resources.beta.realtime.realtime import AsyncRealtimeConnection
from openai.resources.realtime.realtime import AsyncRealtimeConnection

CHUNK_LENGTH_S = 0.05 # 100ms
SAMPLE_RATE = 24000
Expand Down
16 changes: 11 additions & 5 deletions examples/realtime/azure_realtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,16 @@ async def main() -> None:
azure_ad_token_provider=get_bearer_token_provider(credential, "https://cognitiveservices.azure.com/.default"),
api_version="2024-10-01-preview",
)
async with client.beta.realtime.connect(
model="gpt-4o-realtime-preview", # deployment name for your model
async with client.realtime.connect(
model="gpt-realtime", # deployment name for your model
) as connection:
await connection.session.update(session={"modalities": ["text"]}) # type: ignore
await connection.session.update(
session={
"output_modalities": ["text"],
"model": "gpt-realtime",
"type": "realtime",
}
)
while True:
user_input = input("Enter a message: ")
if user_input == "q":
Expand All @@ -44,9 +50,9 @@ async def main() -> None:
)
await connection.response.create()
async for event in connection:
if event.type == "response.text.delta":
if event.type == "response.output_text.delta":
print(event.delta, flush=True, end="")
elif event.type == "response.text.done":
elif event.type == "response.output_text.done":
print()
elif event.type == "response.done":
break
Expand Down
20 changes: 14 additions & 6 deletions examples/realtime/push_to_talk_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
from textual.containers import Container

from openai import AsyncOpenAI
from openai.types.beta.realtime.session import Session
from openai.resources.beta.realtime.realtime import AsyncRealtimeConnection
from openai.types.realtime.session import Session
from openai.resources.realtime.realtime import AsyncRealtimeConnection


class SessionDisplay(Static):
Expand Down Expand Up @@ -154,13 +154,21 @@ async def on_mount(self) -> None:
self.run_worker(self.send_mic_audio())

async def handle_realtime_connection(self) -> None:
async with self.client.beta.realtime.connect(model="gpt-4o-realtime-preview") as conn:
async with self.client.realtime.connect(model="gpt-realtime") as conn:
self.connection = conn
self.connected.set()

# note: this is the default and can be omitted
# if you want to manually handle VAD yourself, then set `'turn_detection': None`
await conn.session.update(session={"turn_detection": {"type": "server_vad"}})
await conn.session.update(
session={
"audio": {
"input": {"turn_detection": {"type": "server_vad"}},
},
"model": "gpt-realtime",
"type": "realtime",
}
)

acc_items: dict[str, Any] = {}

Expand All @@ -176,7 +184,7 @@ async def handle_realtime_connection(self) -> None:
self.session = event.session
continue

if event.type == "response.audio.delta":
if event.type == "response.output_audio.delta":
if event.item_id != self.last_audio_item_id:
self.audio_player.reset_frame_count()
self.last_audio_item_id = event.item_id
Expand All @@ -185,7 +193,7 @@ async def handle_realtime_connection(self) -> None:
self.audio_player.add_data(bytes_data)
continue

if event.type == "response.audio_transcript.delta":
if event.type == "response.output_audio_transcript.delta":
try:
text = acc_items[event.item_id]
except KeyError:
Expand Down
54 changes: 54 additions & 0 deletions examples/realtime/realtime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env rye run python
import asyncio

from openai import AsyncOpenAI

# Azure OpenAI Realtime Docs

# How-to: https://learn.microsoft.com/azure/ai-services/openai/how-to/realtime-audio
# Supported models and API versions: https://learn.microsoft.com/azure/ai-services/openai/how-to/realtime-audio#supported-models
# Entra ID auth: https://learn.microsoft.com/azure/ai-services/openai/how-to/managed-identity


async def main() -> None:
"""The following example demonstrates how to configure OpenAI to use the Realtime API.
For an audio example, see push_to_talk_app.py and update the client and model parameter accordingly.

When prompted for user input, type a message and hit enter to send it to the model.
Enter "q" to quit the conversation.
"""

client = AsyncOpenAI()
async with client.realtime.connect(
model="gpt-realtime",
) as connection:
await connection.session.update(
session={
"output_modalities": ["text"],
"model": "gpt-realtime",
"type": "realtime",
}
)
while True:
user_input = input("Enter a message: ")
if user_input == "q":
break

await connection.conversation.item.create(
item={
"type": "message",
"role": "user",
"content": [{"type": "input_text", "text": user_input}],
}
)
await connection.response.create()
async for event in connection:
if event.type == "response.output_text.delta":
print(event.delta, flush=True, end="")
elif event.type == "response.output_text.done":
print()
elif event.type == "response.done":
break


asyncio.run(main())
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "openai"
version = "1.102.0"
version = "1.103.0"
description = "The official Python library for the openai API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down Expand Up @@ -64,7 +64,7 @@ dev-dependencies = [
"dirty-equals>=0.6.0",
"importlib-metadata>=6.7.0",
"rich>=13.7.1",
"inline-snapshot >=0.7.0",
"inline-snapshot>=0.28.0",
"azure-identity >=1.14.1",
"types-tqdm > 4",
"types-pyaudio > 0",
Expand Down Expand Up @@ -165,6 +165,7 @@ exclude = [
"_dev",
".venv",
".nox",
".git",

# uses inline `uv` script dependencies
# which means it can't be type checked
Expand Down
2 changes: 1 addition & 1 deletion requirements-dev.lock
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ idna==3.4
importlib-metadata==7.0.0
iniconfig==2.0.0
# via pytest
inline-snapshot==0.27.0
inline-snapshot==0.28.0
jiter==0.5.0
# via openai
markdown-it-py==3.0.0
Expand Down
1 change: 1 addition & 0 deletions src/openai/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ def _reset_client() -> None: # type: ignore[reportUnusedFunction]
models as models,
batches as batches,
uploads as uploads,
realtime as realtime,
webhooks as webhooks,
responses as responses,
containers as containers,
Expand Down
Loading
Loading