# 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.