Back to Blog
Python

Python OpenAI Responses API Usage: Practical Examples

python openai responses api usage: Learn how to use the OpenAI Responses API from Python: making requests, handling responses, streaming, error handling, and productio...

OpenAIResponses APIPythonLLMStreaming
Python code interacting with the OpenAI Responses API, showing a request and response flow.

Understanding python openai responses api usage starts with knowing how the Responses API differs from the older Chat Completions API. The Responses API, introduced by OpenAI, unifies chat, tool calls, and structured outputs into a single endpoint. For Python developers, this means a simpler client method and a more predictable response format. This article covers the practical patterns you need to call the API, handle its output, stream responses, and integrate it into production code.

What the Responses API Changes

The Responses API is OpenAI's newer interface for model interactions. It consolidates chat completions, tool use, and structured outputs into a single responses.create call. For Python developers, this means you no longer need to switch between different endpoints for text generation, function calling, or structured JSON output. The response object is uniform: it contains an output list where each item has a type, and convenience properties like output_text for plain text.

The main advantage is consistency. If you build an agent that sometimes calls tools and sometimes returns plain text, the Responses API gives you one code path to handle both. The older Chat Completions API still works, but the Responses API is the direction OpenAI is moving for new features.

Setting Up the OpenAI Client

Before making any request, install the OpenAI Python SDK and configure your API key. The SDK reads the key from an environment variable if you pass it to the client constructor.

import os from openai import OpenAI client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))

Storing the key in an environment variable keeps it out of source control. For local development, you can put it in a .env file and load it with python-dotenv. For production, use a secrets manager.

Making a Basic Request

The core method is client.responses.create. It accepts a model name and an input string. The response object has an output_text attribute that contains the model's text reply.

response = client.responses.create( model="gpt-4o", input="Explain the difference between lists and tuples in Python." ) print(response.output_text)

This is the simplest possible call. The input parameter can also be a list of message objects if you need to provide conversation history. For a single prompt, a plain string is sufficient.

Understanding the Response Object

The response object is more than just text. It has an output list that contains items such as message and function_call. Each item has a type field. For a plain text response, the output contains a message item with a content list. The output_text property is a shortcut that concatenates all text parts from the output.

for item in response.output: print(item.type) if item.type == "message": for content in item.content: print(content.type, content.text)

This structure becomes important when you use tools or structured outputs. Instead of parsing a raw string, you can inspect typed items.

Streaming Responses

For long responses or interactive applications, streaming reduces perceived latency. The SDK provides a stream method that yields events as they arrive.

with client.responses.stream( model="gpt-4o", input="Write a short story about a robot learning to paint." ) as stream: for event in stream: if event.type == "response.output_text.delta": print(event.delta, end="")

The event types follow the API's streaming protocol. The response.output_text.delta event carries incremental text. You can also handle other events like response.created or response.completed to manage state.

Streaming is useful for chat interfaces and any scenario where you want to show partial output. It also lets you cancel the request early if the user stops the interaction.

Error Handling and Retries

Network calls can fail for many reasons: rate limits, authentication problems, or temporary outages. The OpenAI SDK raises exceptions that inherit from openai.OpenAIError. The most common ones are AuthenticationError, RateLimitError, APIConnectionError, and APIStatusError.

from openai import OpenAIError, RateLimitError, APIConnectionError try: response = client.responses.create( model="gpt-4o", input="Hello" ) except RateLimitError: # Back off and retry after a delay print("Rate limit exceeded") except APIConnectionError: # Network issue print("Connection failed") except OpenAIError as e: print(f"OpenAI error: {e}")

For production, implement retries with exponential backoff. The SDK has built-in retry logic for transient errors, but you may want to control the policy yourself. Libraries like tenacity make this straightforward.

Using Tools and Function Calling

The Responses API supports tool use. You define a tool with a JSON schema, and the model can request a function call. The response output will contain a function_call item with the function name and arguments.

tools = [ { "type": "function", "name": "get_weather", "description": "Get the current weather for a city", "parameters": { "type": "object", "properties": { "city": {"type": "string"} }, "required": ["city"] } } ] response = client.responses.create( model="gpt-4o", input="What's the weather in Paris?", tools=tools )

After receiving a function_call, you execute the function locally and send the result back to the model using the input parameter with a conversation history. This loop is the core of building an agent.

Production Considerations

When moving from a script to a production service, several details matter.

Timeouts: A model call can take tens of seconds. Set a reasonable timeout on the client to avoid hanging requests.

client = OpenAI(timeout=60.0)

Concurrency: The SDK is synchronous by default. For high throughput, use asyncio with AsyncOpenAI or run calls in a thread pool. Each call is independent, so you can parallelize with asyncio.gather.

Cost: The Responses API bills based on input and output tokens. Streaming does not reduce cost, but it can help you stop generation early if the user cancels. Monitor token usage in the response object's usage field.

Observability: Log the model, input, output, and latency for each call. This helps with debugging and cost analysis. Avoid logging full prompts that may contain sensitive data.

The Responses API is a solid choice for new Python projects that need chat, tool use, or structured outputs. Its unified interface reduces boilerplate and keeps your codebase simpler as you add features.

python openai responses api usage: Practical Usage and Code | RYUSLOG DEV