Flask dev server como backend de apps de escritorio: qué ajustar
El aviso de Flask sobre no usarlo en producción se puede ignorar si lo embebes como backend local, pero exige fijar 127.0.0.1, desactivar el recargador y activar threading.

Aunque el servidor de desarrollo de Flask muestra una advertencia de que no es apto para producción, existen casos legítimos para usarlo como backend de una aplicación de escritorio. La advertencia asume que el servidor atiende tráfico público desde Internet, con clientes impredecibles y problemas de escalado. En una app de escritorio el servidor queda limitado al bucle local: la única petición viene de una pestaña en el mismo sistema y la premisa cambia. Aun así, hay que tomar tres decisiones técnicas para no convertir esa relajación en un error.
La primera es fijar la interfaz de red a 127.0.0.1. Cualquier otra elección, como 0.0.0.0, expone el servidor a otros equipos de la misma red. Esto parece obvio, pero se puede pasar por alto en entornos de desarrollo que usan direcciones abiertas para acceder desde el móvil.
La segunda afecta a la recarga automática. El servidor de Flask arranca en realidad dos procesos cuando el auto-reloader está activo: uno vigila los cambios en el código y otro atiende las peticiones HTTP. En una aplicación empaquetada no necesitas esa recarga, y el doble proceso complica el control de la instancia única, la ocupación del puerto y la detección de dobles lanzamientos. Desactívalo con use_reloader=False.
La tercera decisión está en el manejo de peticiones concurrentes. Por defecto Flask procesa una petición a la vez. Con una interfaz en el navegador es habitual que lleguen varias simultáneamente: por ejemplo, una solicitud prolongada para iniciar una tarea de mantenimiento mientras un pequeño ping periódico verifica que la pestaña sigue viva. Si el servidor atiende en serie, el ping se queda en cola hasta que la tarea larga termine. Activa threaded=True para que cada petición se atienda en su propio hilo.
Ahora que hay varios hilos, la variable global compartida es un problema. Dos handlers pueden intentar la misma operación de “comprobar si algo está en curso y, si no, lanzarlo” al mismo tiempo. Un mutex con threading.Lock lo resuelve; no es lo mismo que el bloqueo por archivos con fcntl o msvcrt, que protege procesos distintos, mientras aquí es necesario entre hilos del mismo proceso.
Queda además la gestión de puertos. Una app de escritorio suele asignar una dirección fija, pero si el usuario lanza dos veces la aplicación, la segunda no podrá enlazar el puerto. Lo habitual es escanear el primer puerto libre y registrar la instancia en un marcador. Con estos ajustes —loopback, sin reloader, con threading y con el estado compartido protegido— el aviso de Flask deja de preocupar, aunque siempre quedan aspectos propios del proveedor: por ejemplo, la compresión estática o la autenticación del primer acceso.

