{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreiaodaprendnynncjeh6b7gbqxufqdgvcy3anl7qr6hluj64qnu7jy",
"uri": "at://did:plc:lk3jfj3zq4k4wxnk474axylu/app.bsky.feed.post/3mhuu6svao3t2"
},
"path": "/t/cancelling-stream-does-not-show-usage/1377768#post_1",
"publishedAt": "2026-03-25T09:42:28.000Z",
"site": "https://community.openai.com",
"textContent": "When we cancel a stream OpenAI does not tell us how much it was charged. See this example code:\n\n\n import asyncio\n import base64\n from pathlib import Path\n\n from openai import AsyncOpenAI\n\n from utils.storage_utils import get_mime_type\n\n MAX_CHUNKS = 20\n\n\n async def main():\n client = AsyncOpenAI()\n pdf_path = Path(__file__).parent / \"test.pdf\"\n pdf_bytes = pdf_path.read_bytes()\n filename = pdf_path.name\n\n file_content = [\n {\n \"type\": \"input_file\",\n \"filename\": filename,\n \"file_data\": f\"data:{get_mime_type(filename)};base64,{base64.b64encode(pdf_bytes).decode()}\",\n }\n ]\n\n stream = await client.responses.create(\n model=\"gpt-5-mini\",\n input=[{\"role\": \"user\", \"content\": file_content + [{\"type\": \"input_text\", \"text\": \"Can you summarise this file?\"}]}],\n stream=True,\n background=True,\n )\n\n response_id = None\n chunk_count = 0\n\n async for event in stream:\n if event.type == \"response.created\":\n response_id = event.response.id\n print(f\"Response ID: {response_id}\\n\")\n\n elif event.type == \"response.output_text.delta\":\n print(event.delta, end=\"\", flush=True)\n chunk_count += 1\n\n if chunk_count >= MAX_CHUNKS:\n print(f\"\\n\\n--- cancelling after {chunk_count} chunks ---\\n\")\n cancelled = await client.responses.cancel(response_id)\n print(f\"[cancel] status: {cancelled.status}\")\n print(f\"[cancel] usage: {cancelled.usage}\")\n break\n\n elif event.type == \"response.completed\":\n print(f\"\\n[stream] status: {event.response.status}\")\n print(f\"[stream] usage: {event.response.usage}\")\n\n await stream.close()\n\n if response_id:\n result = await client.responses.retrieve(response_id)\n print(f\"\\n[retrieve] status: {result.status}\")\n print(f\"[retrieve] usage: {result.usage}\")\n\n\n if __name__ == \"__main__\":\n asyncio.run(main())\n\n\nThe output is:\n\n\n Response ID: resp_*\n\n Here’s a concise summary of the acta (hearing minutes):\n\n - Court and process\n\n\n --- cancelling after 20 chunks ---\n\n [cancel] status: cancelled\n [cancel] usage: None\n\n [retrieve] status: cancelled\n [retrieve] usage: None\n",
"title": "Cancelling Stream Does Not Show Usage"
}