setup: init-db e reset-db rispondono 500 (asyncio.run dentro il loop) #80

Closed
opened 2026-10-17 10:42:09 +00:00 by Adriano · 3 comments
Owner

FILE: src/backend/api/routers/setup.py:48 _stamp_head() -> command.stamp(Config(alembic.ini), 'head') -> src/backend/migrations/env.py:81 asyncio.run(run_async_migrations()).
COSA SI ROMPE: POST /api/setup/init-db (setup.py:308-315) e POST /api/setup/reset-db (setup.py:737-751) sono endpoint async: asyncio.run dentro un loop gia' attivo -> RuntimeError -> 500. Vale per Docker e per il pacchetto Windows (TieMeasureFlow#76).
TROVATO DA: agente piano C (#76), prova a mano sull'exe installato su daitarn il 17/10/2026. avvio.py non usa init-db (esegue upgrade head da se'), quindi il primo avvio del pacchetto non e' bloccato; reset-db dalla pagina di setup si'.
CORREZIONE PROBABILE: _stamp_head eseguito in un thread (await asyncio.to_thread / run_in_threadpool) oppure env.py che riusa il loop se gia' attivo. TEST: chiamata a init-db e reset-db con TestClient su SQLite file, 200 e riga in alembic_version.

FILE: src/backend/api/routers/setup.py:48 _stamp_head() -> command.stamp(Config(alembic.ini), 'head') -> src/backend/migrations/env.py:81 asyncio.run(run_async_migrations()). COSA SI ROMPE: POST /api/setup/init-db (setup.py:308-315) e POST /api/setup/reset-db (setup.py:737-751) sono endpoint async: asyncio.run dentro un loop gia' attivo -> RuntimeError -> 500. Vale per Docker e per il pacchetto Windows (TieMeasureFlow#76). TROVATO DA: agente piano C (#76), prova a mano sull'exe installato su daitarn il 17/10/2026. avvio.py non usa init-db (esegue upgrade head da se'), quindi il primo avvio del pacchetto non e' bloccato; reset-db dalla pagina di setup si'. CORREZIONE PROBABILE: _stamp_head eseguito in un thread (await asyncio.to_thread / run_in_threadpool) oppure env.py che riusa il loop se gia' attivo. TEST: chiamata a init-db e reset-db con TestClient su SQLite file, 200 e riga in alembic_version.
Adriano added the bug label 2026-10-17 10:42:09 +00:00
Adriano added the assegnata:daitarn label 2026-10-17 12:08:12 +00:00
Author
Owner

🔵 daitarn — preso in carico 2026-10-17T12:08:10Z
ramo: lavoro/daitarn · capacità: build-windows, gpu

🔵 daitarn — **preso in carico** 2026-10-17T12:08:10Z ramo: `lavoro/daitarn` · capacità: build-windows, gpu
Author
Owner

ANALISI (passo 1, Opus 5.5)
COSA: src/backend/api/routers/setup.py, endpoint async init_db (riga 308) e reset_db (riga 737) chiamano _stamp_head() (riga 39) in modo sincrono; command.stamp esegue src/backend/migrations/env.py, che in run_migrations_online (riga 80) fa asyncio.run() dentro il loop gia' attivo di FastAPI -> RuntimeError -> 500.
PERCHE' NON SI VEDEVA: src/backend/tests/test_setup.py:30 e test_station_seed.py:39 sostituiscono _stamp_head con lambda: None.
MODIFICHE:

  1. setup.py: nei due endpoint await asyncio.to_thread(_stamp_head) al posto di _stamp_head() (nel thread non c'e' un loop, asyncio.run di env.py funziona). Commento inline col perche'. Nessun'altra modifica a setup.py.
  2. Nessuna modifica a env.py (la usano anche avvio.py del pacchetto Windows e i deploy).
    TEST (nuovo file src/backend/tests/test_setup_stamp.py):
  • su un file SQLite temporaneo (DB_URL=sqlite+aiosqlite:////t.db, come src/backend/tests/test_sqlite_file.py) senza monkeypatch di _stamp_head: POST /api/setup/init-db con SETUP_PASSWORD -> 200 e tabella alembic_version con una riga uguale alla head di Alembic (ScriptDirectory.from_config(...).get_current_head()).
  • reset-db con confirm=true sullo stesso schema -> 200 e alembic_version ancora alla head.
  • I test esistenti test_setup.py e test_station_seed.py restano verdi senza modifiche.
  • Suite backend: uv run --python 3.13 ... pytest src/backend/tests -n 8 -> nessun rosso nuovo.
    NON TOCCARE: src/backend/migrations/, src/backend/config.py, src/backend/database.py, src/frontend/, packaging/**, test_setup.py, test_station_seed.py.
ANALISI (passo 1, Opus 5.5) COSA: src/backend/api/routers/setup.py, endpoint async init_db (riga 308) e reset_db (riga 737) chiamano _stamp_head() (riga 39) in modo sincrono; command.stamp esegue src/backend/migrations/env.py, che in run_migrations_online (riga 80) fa asyncio.run() dentro il loop gia' attivo di FastAPI -> RuntimeError -> 500. PERCHE' NON SI VEDEVA: src/backend/tests/test_setup.py:30 e test_station_seed.py:39 sostituiscono _stamp_head con lambda: None. MODIFICHE: 1. setup.py: nei due endpoint `await asyncio.to_thread(_stamp_head)` al posto di `_stamp_head()` (nel thread non c'e' un loop, asyncio.run di env.py funziona). Commento inline col perche'. Nessun'altra modifica a setup.py. 2. Nessuna modifica a env.py (la usano anche avvio.py del pacchetto Windows e i deploy). TEST (nuovo file src/backend/tests/test_setup_stamp.py): - su un file SQLite temporaneo (DB_URL=sqlite+aiosqlite:///<tmp>/t.db, come src/backend/tests/test_sqlite_file.py) senza monkeypatch di _stamp_head: POST /api/setup/init-db con SETUP_PASSWORD -> 200 e tabella alembic_version con una riga uguale alla head di Alembic (ScriptDirectory.from_config(...).get_current_head()). - reset-db con confirm=true sullo stesso schema -> 200 e alembic_version ancora alla head. - I test esistenti test_setup.py e test_station_seed.py restano verdi senza modifiche. - Suite backend: uv run --python 3.13 ... pytest src/backend/tests -n 8 -> nessun rosso nuovo. NON TOCCARE: src/backend/migrations/**, src/backend/config.py, src/backend/database.py, src/frontend/**, packaging/**, test_setup.py, test_station_seed.py.
Author
Owner

Soluzione

ESITO: fatto
FILE: src/backend/api/routers/setup.py — init_db e reset_db: await asyncio.to_thread(_stamp_head) (env.py fa asyncio.run, vietato nel loop di FastAPI). src/backend/tests/test_setup_stamp.py — 2 test nuovi con _stamp_head reale su file SQLite: alembic_version alla head dopo init-db e reset-db.
COMMIT: f8f5f24 (lavoro/daitarn-tmf-80), merge 0b22643 in V3.0.0.
PROVA: test_setup_stamp.py prima del fix -> 2 failed (RuntimeError asyncio.run in running loop), dopo -> 2 passed. PROVA: ramo integrato V3.0.0 d652891 su daitarn, Python 3.13: pytest -n 8 src/backend/tests src/frontend/flask_app/tests packaging/windows/tests -> 911 passed, 4 skipped, 0 failed. Tag v3.0.0-rc2.

**Soluzione** ESITO: fatto FILE: src/backend/api/routers/setup.py — init_db e reset_db: await asyncio.to_thread(_stamp_head) (env.py fa asyncio.run, vietato nel loop di FastAPI). src/backend/tests/test_setup_stamp.py — 2 test nuovi con _stamp_head reale su file SQLite: alembic_version alla head dopo init-db e reset-db. COMMIT: f8f5f24 (lavoro/daitarn-tmf-80), merge 0b22643 in V3.0.0. PROVA: test_setup_stamp.py prima del fix -> 2 failed (RuntimeError asyncio.run in running loop), dopo -> 2 passed. PROVA: ramo integrato V3.0.0 d652891 su daitarn, Python 3.13: pytest -n 8 src/backend/tests src/frontend/flask_app/tests packaging/windows/tests -> 911 passed, 4 skipped, 0 failed. Tag v3.0.0-rc2.
Adriano removed the assegnata:daitarn label 2026-10-17 12:38:15 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Adriano/TieMeasureFlow#80