# Assistants to Responses in Flask and FastAPI
## Kill the polling loop
Old shape in a view: create a run, then `while run.status not in ("completed",
"failed"): sleep(1); run = retrieve(run.id)`. New shape: one
`client.responses.create(...)` call that returns when the model is done, with
`response.output` holding message and tool-call items. Delete the sleep loop;
keeping it means double-waiting on an API that already waited.
For long tasks, use background mode (`background=True`) and poll
`client.responses.retrieve(response.id)` on `status`, or register a webhook.
Do not hold a Flask request open for a 10-minute run.
## Replace thread_id in your store
If you stored `thread_id` per user in your database or session, that column now
holds a conversation id or the latest `response.id` used as `previous_response_id`
on the next call. Migrate the column semantics explicitly:
- Option A (server-side state): create a Conversation once per user, pass
`conversation=conversation_id` on every call.
- Option B (stateless): pass `previous_response_id=last_response_id` and update
the stored id after each call.
Do not store both and mix them; pick one per user row.
## Header and namespace cleanup
- Remove the `OpenAI-Beta: assistants=v2` header from your client setup.
- Replace `client.beta.threads.runs.*` with `client.responses.*`.
- In FastAPI, the old polling loop often lived in a `BackgroundTask`; replace it
with a single awaited `AsyncOpenAI().responses.create`.
## Check before you ship
- Search for `threads`, `runs.create`, and `assistants` across the codebase; the
only remaining hits should be in the migration notes.
- Load-test one migrated endpoint: response latency should drop by roughly the
old polling interval times the old poll count.