Streaming makes apps feel fast because users see words immediately instead of waiting for the whole answer.
Without streaming your program waits for the complete answer. Streaming delivers it in small pieces as the model writes, the way ChatGPT shows words appearing.
Add stream=True to responses.create. Instead of a finished response you get an iterator of events, small typed messages sent over a long-lived HTTP connection (server-sent events). Each event has a type:
response.created: the response has started.response.output_text.delta: a new piece of text, inevent.delta.response.completed: done;event.responseholds the full response, including usage.error: something went wrong mid-stream.
There are many more event types for tool calls, reasoning summaries and so on. Handle the ones you need and ignore the rest, because new types are added over time.
Print deltas with end="" and flush=True so they appear immediately.
One trade-off: content moderation is harder with streaming. If you check outputs for harmful content, partial text reaches the user before the full answer can be checked, so decide whether some features should wait for the complete text.
Example
from openai import OpenAI
client = OpenAI()
stream = client.responses.create(
model="gpt-6-astra",
input="Write a short poem about rain.",
stream=True,
)
for event in stream:
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
elif event.type == "response.completed":
print("\n tokens:", event.response.usage.total_tokens)
elif event.type == "error":
print("\n stream error:", event)Remember
stream=Truereturns an iterator of typed events- Text arrives in
response.output_text.deltaevents response.completedcarries the final response and usage
Watch out for
- Crashing on unknown event types; ignore types you don't handle.