WSGI vs ASGI: cuándo usar cada protocolo

Resumen

La base de un backend Python moderno empieza por entender cómo se conecta con un servidor web. Aquí verás, de forma clara y práctica, cuándo usar WSGI o ASGI, cómo ejecutar una app con Unicorn, y qué implicaciones tiene el asincronismo con Uvicorn, Django, Fast API y Flask.

¿Qué diferencia a WSGI de ASGI en Python web?

Las aplicaciones Python no devuelven HTML por sí mismas: producen un output que el servidor traduce a un response. Para eso existen dos protocolos clave.

  • WSGI: estándar para apps tradicionales que procesan un solo request y devuelven un response. Ideal para lógica síncrona.
  • ASGI: evolución que habilita asincronismo con async/await, manejo eficiente de múltiples requests y soporte de WebSockets.

Elección práctica según tu contexto:

  • Si tu app es síncrona (por ejemplo, un Django sin compatibilidad asíncrona), usa WSGI con librerías como UWSGI o Unicorn.
  • Si usas Fast API moderno o necesitas WebSockets, el camino es ASGI con Uvicorn.
  • En operaciones de lectura/escritura de disco, ASGI puede ser más rápido al trabajar en varios hilos, mientras que en WSGI estas lecturas pueden ser más lentas.

¿Qué rol cumplen request, response y headers?

  • El servidor traduce el request HTTP para que Python lo entienda.
  • La app genera un response con un estado (por ejemplo, 200 OK) y headers como Content-Type.
  • El cuerpo de la respuesta debe ser bytes (ej.: b"Hello WSGI World").

¿Cómo encajan NGINX y los workers?

  • En producción, un bind expone la app en una IP y puerto, y NGINX suele conectarse a los procesos que sirven el tráfico.
  • Los workers permiten correr varios procesos de tu app para aprovechar el servidor.

¿Cómo crear y ejecutar una app WSGI con Unicorn?

Partimos de un entorno virtual en Visual Studio Code y un archivo wsgiapp.py. La app se llama App porque luego la referenciamos en el comando de ejecución.

¿Qué código mínimo necesita una app WSGI?

# wsgiapp.py def App(environ, start_response): status = '200 OK' headers = [('Content-Type', 'text/plain; charset=utf-8')] start_response(status, headers) return [b'Hello WSGI World']
  • environ: diccionario con datos del request.
  • start_response: función para iniciar el response con estado y headers.
  • Cuerpo en bytes: b'Hello WSGI World'.

¿Cómo ejecutar con workers y bind?

  • Activa el entorno virtual e instala la dependencia.
  • Ejecuta Unicorn indicando procesos, IP y puerto, y referencia módulo:App.
unicorn --workers 2 --bind 127.0.0.1:8000 wsgiapp:App
  • --workers 2: dos procesos de la app.
  • --bind 127.0.0.1:8000: expone en localhost y puerto 8000.
  • wsgiapp:App: módulo y nombre de la aplicación WSGI.

Al abrir la URL indicada, verás el mensaje "Hello WSGI World" servido por la app a través de Unicorn.

¿Qué considerar en producción y cómo avanzar con Uvicorn?

El flujo general se mantiene para asincronismo: cambia la librería a Uvicorn y el protocolo a ASGI.

¿Cuándo usar Uvicorn y qué aporta asyncio?

  • Uvicorn permite ejecutar en varios hilos e integra asyncio para manejar muchas tareas concurrentes.
  • Si necesitas WebSockets, debes usar Uvicorn con ASGI.

¿Qué combinaciones con frameworks son frecuentes?

  • Django: puede correr con WSGI (por ejemplo, UWSGI o Unicorn) y también con ASGI.
  • Fast API: se ejecuta con Uvicorn; no utiliza UWSGI.
  • Flask: tradicionalmente WSGI, aunque el enfoque depende de tu código y librerías.

Además:

  • Bind e IP: un bind típico local es 127.0.0.1 con un puerto como 8000.
  • Reto práctico: crea una app asíncrona con Fast API, ejecútala con Uvicorn en el puerto 9000 y deja ambas corriendo para comparar los mensajes.
  • Buenas prácticas: usa entorno virtual y exclúyelo del repositorio para evitar subir dependencias.

¿Tienes dudas sobre el uso de WSGI vs ASGI, o sobre la ejecución con Unicorn y Uvicorn? Cuéntame tu contexto y qué framework usas, y afinamos la configuración ideal para tu proyecto.