- deploy/: scripts de PowerShell para instalar el servicio (cuenta de servicio con acceso a la ruta de red, reinicio automático, parada con Ctrl+C, rotación de la salida, PYTHONUTF8), actualizar a una versión etiquetada o volver a una anterior, y desinstalar. - docs/despliegue_windows.md: requisitos, instalación, operación, rollback y problemas frecuentes. - tools/verificar_conexiones.py: comprueba .env, Graph, SAP, HANA y la ruta de red sin modificar nada. - CHANGELOG.md, README e inventario; pyproject.toml pasa a 1.2.0. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
5.7 KiB
Despliegue en Windows (servicio con NSSM)
El demonio (main.py) corre como servicio de Windows gestionado con NSSM: arranca con el servidor, se reinicia solo si se cae y se detiene de forma ordenada. La carpeta deploy/ trae los scripts.
Los scripts de
deploy/se revisaron con el analizador de PowerShell (sintaxis correcta) pero no se ejecutaron en un Windows real. Pruébelos primero en un servidor de pruebas.
Requisitos del servidor
| Requisito | Detalle |
|---|---|
| Windows | Server 2016 o superior, o Windows 10/11 |
| Python | 3.11 o superior, 64 bits (el cliente de SAP HANA, hdbcli, lo requiere) |
| Git y NSSM | git en el PATH y nssm.exe en el PATH (https://nssm.cc) |
| Red hacia fuera | login.microsoftonline.com y graph.microsoft.com (443) |
| Red hacia SAP | Service Layer (SAP_B1_URL, puerto 50000 por defecto) y HANA (HANA_SERVER, puerto 30015) |
| Ruta de red | Acceso de lectura y escritura a RUTA_RED_FACTURACION (recurso UNC) |
| Cuenta de servicio | Una cuenta de dominio, por ejemplo ABERIO\svc_facturas, con acceso a esa ruta de red |
| Zona horaria | El código asume hora de Lima (UTC-5) para la fecha y hora de recepción que ve el proveedor |
La cuenta de servicio es importante. Por defecto un servicio corre como LocalSystem, que no ve recursos de red: la copia a la ruta de facturación electrónica fallaría. Use una cuenta con permiso sobre ese recurso.
Instalación
En PowerShell como administrador:
cd C:\apps
git clone https://unasgeorge.vaquita-hadar.ts.net/george/descarga_factura_transporte.git
cd descarga_factura_transporte
git checkout v1.2.0 # siempre una versión etiquetada, no main
py -3 -m venv venv
venv\Scripts\python -m pip install -r requirements.txt
copy .env.example .env # y completar los valores
Complete el .env (cómo obtener las credenciales de Microsoft: configurar_msal.md). Empiece con NOTIFICACION_MODO=prueba: las respuestas van al equipo y no a los proveedores. Defina NOTIFICACION_EQUIPO y LOGO_URL.
Verificar antes de instalar el servicio
venv\Scripts\python tools\verificar_conexiones.py
Revisa, sin modificar nada ni imprimir secretos: el .env, el token y la lectura del buzón de Microsoft Graph, SAP Service Layer, SAP HANA y la ruta de red de facturación (que debe ser accesible y escribible con la cuenta del servicio). Termina con código 1 si algo falla. Opcionalmente, las pruebas (no tocan SAP ni Outlook):
venv\Scripts\python -m pip install pytest==9.1.1
venv\Scripts\python -m pytest -q
Instalar y arrancar el servicio
.\deploy\instalar_servicio.ps1 -Cuenta "ABERIO\svc_facturas" # pide la contraseña
nssm start descarga_factura_transporte
El script configura: arranque automático, directorio de trabajo del proyecto, reinicio automático a los 30 s si el proceso muere, parada con Ctrl+C (20 s de gracia), rotación de la salida del servicio a 10 MB y las variables PYTHONUTF8=1 y PYTHONIOENCODING=utf-8 (sin ellas los emojis del log dan error en la consola de Windows).
Comprobar que funciona
Get-Service descarga_factura_transporte
Get-Content logs\descarga_factura_transporte.log -Wait -Tail 30
En el log, al arrancar, debe verse 🚀 Demonio iniciado … (versión 1.2.0), y config_validator anuncia el modo de notificación (PRUEBA o REAL).
Operación
| Tema | Detalle |
|---|---|
| Logs de la aplicación | logs\descarga_factura_transporte.log, rotación diaria, 30 días |
| Salida del servicio | logs\servicio.out.log y servicio.err.log (10 MB, rotan). Mire servicio.err.log si el servicio arranca y se detiene |
Cambiar el .env |
nssm restart descarga_factura_transporte |
| Horarios | HORARIOS en main.py (24 h cubiertas, ver main.md) |
| Copia de seguridad | emails.db guarda los correos procesados y los códigos de seguimiento. Cópielo con el servicio detenido, o con sqlite3 emails.db ".backup respaldo.db" |
| Espacio en disco | adjuntos\ y resultado\ no se limpian solos: planifique una limpieza periódica |
| Pasar a modo real | Cuando el equipo haya validado las respuestas: NOTIFICACION_MODO=real y reiniciar |
Actualizar y volver atrás (rollback)
Siempre a una versión etiquetada (ver CHANGELOG):
.\deploy\actualizar.ps1 -Version v1.2.0
.\deploy\actualizar.ps1 -Version v1.1.0 # volver a la anterior
El script detiene el servicio, hace git checkout de la etiqueta, instala las dependencias y arranca de nuevo (aunque algo falle, vuelve a levantar lo que había). No toca el .env ni emails.db. Se niega a actuar si hay cambios locales sin guardar.
Desinstalar
.\deploy\desinstalar_servicio.ps1 # no borra el proyecto, el .env ni emails.db
Problemas frecuentes
| Síntoma | Causa probable |
|---|---|
| El servicio arranca y se detiene enseguida | Falta el .env, o config_validator rechazó una variable: ver logs\servicio.err.log |
Access is denied al copiar a la ruta de red |
El servicio corre como LocalSystem. Reinstale con -Cuenta o cambie la cuenta en services.msc |
UnicodeEncodeError en la salida del servicio |
Falta PYTHONUTF8=1: reinstale con instalar_servicio.ps1 |
AADSTS7000222 / AADSTS700016 |
Secret vencido / CLIENT_ID y TENANT_ID de aplicaciones distintas: ver configurar_msal.md |
ConnectTimeout hacia SAP o HANA |
VPN o firewall: abra el puerto 50000 (Service Layer) y 30015 (HANA) desde el servidor |
| Los correos llegan sin logo | LOGO_URL vacío o no accesible públicamente |