diff --git a/README.md b/README.md index 1fabef6a81..5f2c066cdb 100644 --- a/README.md +++ b/README.md @@ -396,7 +396,7 @@ Basic text based example: ```py import asyncio -from openai import AsyncOpenAI +from openai import AsyncOpenAI, OpenAIError async def main(): @@ -422,7 +422,13 @@ async def main(): print() elif event.type == "response.done": + if event.response.status != "completed": + raise OpenAIError("The Realtime response did not complete") break + elif event.type == "error": + raise OpenAIError("Realtime returned an error; inspect the event in your application") + else: + raise OpenAIError("Realtime disconnected before response.done") asyncio.run(main()) diff --git a/examples/live/audio_transcript.py b/examples/live/audio_transcript.py index ce952ee343..98045a0830 100644 --- a/examples/live/audio_transcript.py +++ b/examples/live/audio_transcript.py @@ -59,6 +59,7 @@ async def receive() -> None: await transcript.push(event) if event.type == "session.closed": return + raise OpenAIError("Live disconnected before session.closed") receiver = asyncio.create_task(receive()) try: diff --git a/examples/realtime/azure_realtime.py b/examples/realtime/azure_realtime.py index a8bcf4c536..b0b044559c 100644 --- a/examples/realtime/azure_realtime.py +++ b/examples/realtime/azure_realtime.py @@ -20,60 +20,64 @@ async def main() -> None: Enter "q" to quit the conversation. """ - credential = DefaultAzureCredential() - token_provider = get_bearer_token_provider(credential, "https://cognitiveservices.azure.com/.default") - token = await token_provider() - - # The endpoint of your Azure OpenAI resource is required. You can set it in the AZURE_OPENAI_ENDPOINT - # environment variable. - # You can find it in the Microsoft Foundry portal in the Overview page of your Azure OpenAI resource. - # Example: https://{your-resource}.openai.azure.com - endpoint = os.environ["AZURE_OPENAI_ENDPOINT"] - - # The deployment name of the model you want to use is required. You can set it in the AZURE_OPENAI_DEPLOYMENT_NAME - # environment variable. - # You can find it in the Foundry portal in the "Models + endpoints" page of your Azure OpenAI resource. - # Example: gpt-realtime - deployment_name = os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"] - - base_url = endpoint.replace("https://", "wss://").rstrip("/") + "/openai/v1" - - # The APIs are compatible with the OpenAI client library. - # You can use the OpenAI client library to access the Azure OpenAI APIs. - # Make sure to set the baseURL and apiKey to use the Azure OpenAI endpoint and token. - client = AsyncOpenAI(websocket_base_url=base_url, api_key=token) - async with client.realtime.connect( - model=deployment_name, - ) as connection: - await connection.session.update( - session={ - "output_modalities": ["text"], - "model": deployment_name, - "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}], - } + async with DefaultAzureCredential() as credential: + token_provider = get_bearer_token_provider(credential, "https://cognitiveservices.azure.com/.default") + token = await token_provider() + + # The endpoint of your Azure OpenAI resource is required. You can set it in the AZURE_OPENAI_ENDPOINT + # environment variable. + # You can find it in the Microsoft Foundry portal in the Overview page of your Azure OpenAI resource. + # Example: https://{your-resource}.openai.azure.com + endpoint = os.environ["AZURE_OPENAI_ENDPOINT"] + + # The deployment name of the model you want to use is required. You can set it in the AZURE_OPENAI_DEPLOYMENT_NAME + # environment variable. + # You can find it in the Foundry portal in the "Models + endpoints" page of your Azure OpenAI resource. + # Example: gpt-realtime + deployment_name = os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"] + + base_url = endpoint.replace("https://", "wss://").rstrip("/") + "/openai/v1" + + # The APIs are compatible with the OpenAI client library. + # You can use the OpenAI client library to access the Azure OpenAI APIs. + # Make sure to set the baseURL and apiKey to use the Azure OpenAI endpoint and token. + async with ( + AsyncOpenAI(websocket_base_url=base_url, api_key=token) as client, + client.realtime.connect(model=deployment_name) as connection, + ): + await connection.session.update( + session={ + "output_modalities": ["text"], + "model": deployment_name, + "type": "realtime", + }, ) - 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": + while True: + user_input = input("Enter a message: ") + if user_input == "q": break - await credential.close() + 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 == "error": + raise RuntimeError(f"Realtime error: {event.error.type} ({event.error.code})") + elif event.type == "response.done": + if event.response.status != "completed": + raise RuntimeError(f"Response did not complete successfully: {event.response.status}") + break + else: + raise RuntimeError("WebSocket closed before the response completed.") asyncio.run(main()) diff --git a/examples/responses/multi_agent_websocket.py b/examples/responses/multi_agent_websocket.py index a6390419de..1817be6cf9 100644 --- a/examples/responses/multi_agent_websocket.py +++ b/examples/responses/multi_agent_websocket.py @@ -1,6 +1,6 @@ from __future__ import annotations -from openai import OpenAI +from openai import OpenAI, OpenAIError from openai.types.beta import BetaResponseOutputItem PROMPT = """Compare these fictional proposals on speed, cost, reliability, and security. @@ -42,5 +42,9 @@ def agent_name(item: BetaResponseOutputItem) -> str: print(event.delta, end="", flush=True) if event.type == "response.completed": break + if event.type in {"response.failed", "response.incomplete", "error"}: + raise OpenAIError(f"Multi-agent request ended with {event.type}") + else: + raise OpenAIError("Connection closed before the multi-agent response completed") print()