Week 3 · Chapter 4 · Basic
stream = client.responses.create(
model="gpt-5.4-nano",
input=prompt,
stream=True,
)
for event in stream:
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
stream=True switches the return type to typed eventsresponse.output_text.deltaflush=True is non-negotiable; Python buffers stdout by defaultstream = client.models.generate_content_stream(
model="gemini-3.1-flash-lite",
contents=prompt,
)
for chunk in stream:
if chunk.text:
print(chunk.text, end="", flush=True)
generate_content_stream is the streaming twin.text delta or emptyEach one is its own docker-compose project under
code/showcase/<slug>/.
def run_stream(input: str) -> Iterator[str]:
stream = client.responses.create(..., stream=True)
for event in stream:
if event.type == "response.output_text.delta":
yield event.delta
def run(input: str) -> str:
return "".join(run_stream(input))
run_stream is the lessonrun is a one-liner accumulatorPOST /api/ai → final string (non-streaming)POST /api/ai/stream → SSE feed of {delta} eventsStreaming is one keyword argument away from a better-feeling app. The model never got faster. The experience of waiting did. Reach for it whenever the output is long enough that a reader would tab away.