fix(deps): declara fastapi e uvicorn no requirements — clone novo passa a subir - #57
Conversation
…sa a subir `laguna_server.py` importa `uvicorn`/`fastapi` no topo do módulo, mas nenhum dos dois estava em `requirements.txt` nem em `requirements.lock`. Quem seguia o Quick start do README ao pé da letra (e pulava o bloco rotulado "opcional") instalava um ambiente incapaz de subir o app: o atalho do `install_shortcuts.ps1` aponta para o `Laguna.vbs`, que roda `pythonw.exe` — o `ModuleNotFoundError` ia para um stdout invisível, falha 100% silenciosa. - `requirements.txt`: `fastapi>=0.129,<1` e `uvicorn>=0.40,<1`, no estilo dos vizinhos. - `requirements.lock`: versões exatas do ambiente canônico (`pip show` em C:\Python313). - README PT/EN: o bloco "(opcional)" passa a instalar só `pywebview`, que é o único de fato opcional (fallback explícito em `laguna_app.py`). - `tests_unit/conftest.py`: comentário desatualizado; o stub segue necessário e hermético (o job da CI instala só `pytest numpy`). Refs #56
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
O `uvicorn` puro traz só `click` e `h11` (confirmado por `pip show`). Sem
`websockets` nem `wsproto`, `uvicorn/protocols/websockets/auto.py` resolve
`AutoWebSocketsProtocol = None`, o upgrade do `/ws` nunca acontece e o
Starlette passa a rotear `GET /ws` como HTTP comum → 404.
Prova no app real (`uvicorn.Config(app, ws="none")`, que é exatamente o que
o auto-resolve faz sem lib de WS):
ws_protocol_class resolvido: None
HTTP/1.1 404 Not Found
Efeito para quem clona: a UI carrega (o mount de `static/` funciona) e nunca
atualiza — `static/app.js:710` cai em `scheduleReconnect()` num laço infinito,
sem erro acionável na tela. `laguna_server.py:305` (`@app.websocket("/ws")`) é
a espinha da UI live, então declarar fastapi+uvicorn sem uma lib de WS conserta
o "importa" e deixa o "funciona" quebrado.
Não é dependência nova de verdade: `websockets==15.0.1` já está no ambiente
canônico e já é exigida em runtime desde que o `/ws` existe — este commit
declara o que o app já usa, na mesma linha do resto desta PR.
Refs #56
Parecer do PR Doctor — quórum §7.2 concluído, 3× APROVA (merge)Balde B (área de quórum): toca 1ª rodada — 2 APROVA / 1 VETOLente Pipeline/Latência — APROVA. Zero linha executável no diff; Lente Produto/UX — APROVA. Paridade PT/EN exata ( Lente Privacidade/Robustez — VETO. Veto confirmado na fonte e no app realNão aceitei o veto no argumento: verifiquei. Uma correção ao veto: o sintoma é 404, não 400 — sem upgrade, o Starlette roteia Não acatei o 2º ponto do veto (starlette/pydantic sem pin no lock): Reparo (
|
Contexto
laguna_server.py:23-26importauvicornefastapino topo do módulo, mas nenhum dos dois estava declarado emrequirements.txtnem emrequirements.lock. Um clone novo seguindo o Quick start do README ao pé da letra — e pulando o bloco rotulado "(opcional)" — instalava um ambiente incapaz de subir o app.Pior:
install_shortcuts.ps1:8aponta o atalho para oLaguna.vbs, que rodapythonw.exe(sem console). OModuleNotFoundError: No module named 'fastapi'ia para um stdout que ninguém vê — falha 100% silenciosa, sem janela e sem erro. Quem já tem o ambiente montado (o dono, as worktrees da frota) nunca viu o problema.O que mudou
requirements.txt+fastapi>=0.129,<1,+uvicorn>=0.40,<1— bounds no mesmo estilo dos vizinhos, fora de qualquer bloco opcionalrequirements.lock+fastapi==0.129.0,+uvicorn==0.40.0na seção "diretas" — versões exatas do ambiente canônico, comprovadas viapip shownoC:\Python313README.md(PT:315-316/ EN:864-865)pywebview, e o comentário diz o que ele realmente entrega (janela nativa; sem ele,laguna_app.pycai no navegador padrão — fallback explícito emlaguna_app.py:10-11)tests_unit/conftest.py:29-35tests-unitdo CI instala sópytest numpyOs dois arquivos de requirements foram mexidos no mesmo PR — a #41 existe justamente para impedir que divirjam.
Sobre a doutrina (HANDBOOK §7.2/§8): não é dependência nova
fastapieuvicornjá são importados em produção desde sempre e já estão instalados no ambiente canônico. Este PR apenas declara o que o app já usa — não adiciona nada ao ambiente de ninguém, e não consome a cota de "≤1 dependência leve nova por semana". Ainda assim, por tocarrequirements.*:Solicito quórum (HANDBOOK §7)
Gate (resultado real)
python -m compileall -q .→COMPILE_OK;python -c "import fase0_poc, laguna_core, laguna_server"→IMPORTS_OK.pytest tests_unit/— verde.48 passed in 3.98s(com o conftest atualizado; stub hermético segue ativo mesmo com fastapi real instalado).python -c "import fastapi, uvicorn"→DEPS_OK 0.129.0 0.40.0. Auditoria dos imports de terceiro no topo dos módulos de produção, todos agora com linha correspondente norequirements.txt:laguna_server.py→sounddevice✅,uvicorn✅ (novo),fastapi✅ (novo)laguna_core.py→numpy✅,sounddevice✅laguna_pipeline.py→numpy✅laguna_devices.py→sounddevice✅fase0_poc.py→numpy✅,sounddevice✅laguna_core.py/fase0_poc.py/laguna_pipeline.py(zero linhas de código de produção no diff).static/.Riscos
Baixos. Nenhuma linha de código executável mudou (só requirements, README e um comentário). Não há impacto em latência nem na promessa 100% local. O único efeito colateral possível é
pip install -r requirements.txtpassar a puxar starlette/pydantic/h11/click em ambientes que não os tinham — que é exatamente o comportamento correto, já que o app não roda sem eles.Closes #56