6.1 KiB
Diseño: arranque automático e inteligente para no-técnicos (doctor.ps1)
Fecha: 2026-08-22 Estado: aprobado en conversación
Problema
Los .bat actuales son wrappers finos de dos .ps1 robustos, pero asumen un
entorno ya preparado. Para una persona no técnica:
- Si falta Python (o
pythones el stub falso de la Microsoft Store), el error parpadea y la ventana desaparece sin que se entienda nada. - Si faltan dependencias (
pip install -e ".[web]"nunca se corrió), uvicorn muere con un traceback ilegible. - Los errores terminan con la ventana cerrándose: imposible leer qué pasó.
Objetivo
Doble clic en start-server.bat = la aplicación abre en el navegador,
siempre. El script detecta y repara el entorno por sí mismo. Un solo icono
para el usuario; stop-server.bat queda como acompañante.
Enfoque elegido (B)
Separación de responsabilidades: entorno vs ciclo de vida.
start-server.bat ──> scripts/doctor.ps1 (NUEVO)
├─ ¿server ya vivo? ── sí --> abrir navegador, fin
├─ resolver Python (py -3 > python > python3)
│ └─ ninguno válido --> winget install
│ └─ sin winget --> abrir python.org + ERROR
├─ import-test de deps
│ └─ falla --> pip install -e ".[web]"
├─ ffmpeg presente? -- no --> aviso suave NO bloqueante
└─ ok --> scripts/start-server.ps1 -PythonExe $py
└─ puertos, healthz, browser (SIN CAMBIOS de lógica)
start-server.ps1 conserva toda su lógica verificada (sondas TCP rápidas,
limpieza de entradas obsoletas, barrido 8000-8100, apertura de navegador).
Único cambio permitido: parámetro opcional -PythonExe (default python)
usado en la línea de comando de uvicorn.
Por qué -PythonExe es necesario
Tras una instalación fresca vía winget, el PATH de la sesión actual no
incluye el Python nuevo. El doctor resuelve la ruta concreta
(%LocalAppData%\Programs\Python\Python312\python.exe) y se la pasa al
launcher; sin esto, el primer arranque post-instalación fallaría.
Flujo detallado del doctor
- Server vivo primero (antes de cualquier chequeo de entorno): sondea el
puerto registrado en
.run/server.info; si responde, abre el navegador y termina con exit 0. Evita instalar dependencias solo para decir "ya está corriendo". - Resolver Python, candidatos en orden:
py -3,python,python3. Cada candidato es válido solo si:- ejecuta
--versiony la salida matcheaPython 3.con versión ≥ 3.10; - su ruta no contiene
WindowsApps(stub de la Store que no ejecuta nada).
- ejecuta
- Instalar Python si falta:
winget install --id Python.Python.3.12 --silent --accept-package-agreements --accept-source-agreements. Después de instalar, sondear rutas conocidas (%LocalAppData%\Programs\Python\*,C:\Program Files\Python312\) antes de rendirse. Sin winget disponible: abrirhttps://www.python.org/downloads/en el navegador + instrucción en lenguaje simple + exit ≠ 0. - Import-test de dependencias:
& $py -c "import fastapi, uvicorn, jinja2, sse_starlette, yt_dlp". Nunca importayt_scraper.webapp.appaquí: ese import abre la DB real del proyecto víaconfig.yaml, corre migraciones yreconcile_markdown(gotcha documentado en CLAUDE.md). Si falla el test:-m pip install -e ".[web]"mostrando progreso ("instalando por primera vez, puede tardar un par de minutos"). Si falta pip:-m ensurepip. - ffmpeg:
Get-Command ffmpeg; ausente → aviso amarillo no bloqueante ("la descarga de audio no estará disponible; todo lo demás funciona"). - Delegar:
& start-server.ps1 -PythonExe $py+ passthrough de args. - Propagar exit code.
Reglas de ventana (.bat)
| Resultado | Ventana |
|---|---|
| Exit 0 | mensaje verde + cuenta regresiva ~5 s → cierra sola |
| Exit ≠ 0 | queda abierta (pause) con causa legible + últimas líneas de log |
Hoy los errores parpadean y desaparecen: es la regla más importante del
cambio. Aplica a ambos .bat.
Mensajes
Español plano, sin jerga dirigida al usuario final ("servidor", "conexión"; no "puerto", "PID", "uvicorn", "PATH"):
[ok] Servidor listo en http://localhost:8000 — abriendo tu navegador...[ok] El servidor ya estaba corriendo — abriendo...[info] Instalando Python automáticamente (~25 MB)…[info] Instalando las piezas que faltan por primera vez (1-2 min)…- Error:
Algo falló al iniciar el servidor. Esto fue lo último que hizo:
El pulido de copys aplica también a los mensajes visibles de
start-server.ps1 y stop-server.ps1 (solo texto; cero cambios de lógica).
Errores cubiertos
| Caso | Detección | Acción |
|---|---|---|
| Stub falso Microsoft Store | --version falla o ruta *WindowsApps* |
Siguiente candidato |
| Sin Python válido | 3 candidatos fallan | winget silencioso; sin winget → python.org + ERROR |
| PATH fresco post-instalación | winget OK | Sondeo de rutas conocidas |
| pip ausente | -m pip --version falla |
ensurepip |
| Deps rotas/faltantes | import-test falla | pip install -e ".[web]" |
| ffmpeg ausente | Get-Command vacío |
Aviso amarillo no bloqueante |
| Error de arranque | exit ≠ 0 del launcher | Ventana queda abierta con log |
Fuera de alcance
- No se toca lógica de puertos, healthz, browser ni cancelación del launcher.
- No hay
setup.batseparado (el doctor es el setup). - No se instalan
[dev]ni[analysis]: solo core +[web], lo necesario para correr la aplicación. - Sin tests automatizados nuevos de PowerShell (el repo no tiene infra para
eso); verificación manual guiada por
-CheckOnly.
Verificación
doctor.ps1 -CheckOnly: reporta qué haría sin cambiar nada (cada rama de decisión observable sin efectos).- Escenarios manuales: server ya vivo → solo navegador; server apagado → arranque completo; stop limpio tras arranque; ventana persistente ante error simulado (p. ej. PATH sin Python en un subproceso controlado).