uWSGI

uWSGI es un conjunto de servidores rápidos y compilados con una amplia configuración y capacidades que van más allá de un servidor básico.

  • Puede ser muy eficiente debido a que es un programa compilado.

  • Es complejo de configurar más allá de la aplicación básica, y tiene tantas opciones que puede ser difícil de entender para los principiantes.

  • No es compatible con Windows (pero sí con WSL).

  • En algunos casos es necesario instalar un compilador.

Esta página describe los aspectos básicos de la ejecución de uWSGI. Asegúrese de leer su documentación para entender qué características están disponibles.

Instalación

uWSGI tiene múltiples formas de instalarse. La más sencilla es instalar el paquete pyuwsgi, que proporciona ruedas precompiladas para plataformas comunes. Sin embargo, no proporciona soporte SSL, que puede ser proporcionado con un proxy inverso en su lugar.

Crea un virtualenv, instala tu aplicación y luego instala pyuwsgi.

$ cd hello-app
$ python -m venv .venv
$ . .venv/bin/activate
$ pip install .  # install your application
$ pip install pyuwsgi

Si tienes un compilador disponible, puedes instalar el paquete uwsgi en su lugar. O instalar el paquete pyuwsgi desde sdist en lugar de wheel. Cualquiera de los dos métodos incluirá soporte para SSL.

$ pip install uwsgi

# or
$ pip install --no-binary pyuwsgi pyuwsgi

Ejecutando

La forma más básica de ejecutar uWSGI es decirle que inicie un servidor HTTP e importe su aplicación.

$ uwsgi --http 127.0.0.1:8000 --master -p 4 -w hello:app

*** Starting uWSGI 2.0.20 (64bit) on [x] ***
*** Operational MODE: preforking ***
mounting hello:app on /
spawned uWSGI master process (pid: x)
spawned uWSGI worker 1 (pid: x, cores: 1)
spawned uWSGI worker 2 (pid: x, cores: 1)
spawned uWSGI worker 3 (pid: x, cores: 1)
spawned uWSGI worker 4 (pid: x, cores: 1)
spawned uWSGI http 1 (pid: x)

Si utiliza el patrón de fábrica de aplicaciones, tendrá que crear un pequeño archivo de Python para crear la aplicación, y luego apuntar a uWSGI.

wsgi.py
from hello import create_app

app = create_app()
$ uwsgi --http 127.0.0.1:8000 --master -p 4 -w wsgi:app

La opción --http inicia un servidor HTTP en el puerto 8000 de 127.0.0.1. La opción --master especifica el gestor de trabajadores estándar. La opción -p inicia 4 procesos de trabajo; un valor inicial podría ser CPU * 2. La opción -w indica a uWSGI cómo importar su aplicación

Vinculación externa

uWSGI no debe ser ejecutado como root con la configuración mostrada en este documento porque causaría que el código de su aplicación se ejecute como root, lo cual no es seguro. Sin embargo, esto significa que no será posible enlazar con el puerto 80 o 443. En su lugar, debe utilizarse un proxy inverso como nginx o Apache httpd delante de uWSGI. Es posible ejecutar uWSGI como root de forma segura, pero eso está fuera del alcance de este documento.

uWSGI ha optimizado la integración con Nginx uWSGI y Apache mod_proxy_uwsgi, y posiblemente otros servidores, en lugar de utilizar un proxy HTTP estándar. Esa configuración está más allá del alcance de este documento, vea los enlaces para más información.

Puedes enlazar con todas las IPs externas en un puerto no privilegiado usando la opción --http 0.0.0.0:8000. No hagas esto cuando utilices una configuración de proxy inverso, de lo contrario será posible eludir el proxy.

$ uwsgi --http 0.0.0.0:8000 --master -p 4 -w wsgi:app

0.0.0.0 no es una dirección válida para navegar, sino que debes utilizar una dirección IP específica en tu navegador.

Async con gevent

El sync worker por defecto es apropiado para muchos casos de uso. Si necesitas soporte asíncrono, uWSGI proporciona un trabajador gevent. Esto no es lo mismo que el async/await de Python, o la especificación del servidor ASGI. Debes usar gevent en tu propio código para ver algún beneficio al usar el worker.

Cuando se utiliza gevent, se requiere greenlet>=1.0, de lo contrario los contextos locales como request no funcionarán como se espera. Cuando se utiliza PyPy, se requiere PyPy>=7.3.7.

$ uwsgi --http 127.0.0.1:8000 --master --gevent 100 -w wsgi:app

*** Starting uWSGI 2.0.20 (64bit) on [x] ***
*** Operational MODE: async ***
mounting hello:app on /
spawned uWSGI master process (pid: x)
spawned uWSGI worker 1 (pid: x, cores: 100)
spawned uWSGI http 1 (pid: x)
*** running gevent loop engine [addr:x] ***