applications - framework python web
Cómo encajan los frameworks web de Python, WSGI y CGI (5)
Tengo una cuenta de Bluehost donde puedo ejecutar scripts de Python como CGI. Supongo que es el CGI más simple, porque para ejecutarlo tengo que definir lo siguiente en .htaccess
:
Options +ExecCGI
AddType text/html py
AddHandler cgi-script .py
Ahora, cada vez que busco programación web con Python, escucho mucho sobre WSGI y cómo la usan la mayoría de los frameworks. Pero simplemente no entiendo cómo encaja todo, especialmente cuando se da mi servidor web (Apache ejecutándose en la máquina de un host) y no como algo con lo que realmente pueda jugar (excepto la definición de los comandos .htaccess
).
¿Cómo se conectan WSGI , CGI y los marcos? ¿Qué necesito saber, instalar y hacer si quiero ejecutar un marco web (digamos web.py o CherryPy ) en mi configuración básica de CGI? ¿Cómo instalar WSGI?
Creo que la respuesta de Florian responde a la parte de su pregunta sobre "qué es WSGI", especialmente si lee el PEP .
En cuanto a las preguntas que plantea hacia el final:
WSGI, CGI, FastCGI, etc. son todos los protocolos para que un servidor web ejecute código y entregue el contenido dinámico que se produce. Compare esto con servicio web estático, donde un archivo HTML simple se entrega básicamente al cliente.
CGI, FastCGI y SCGI son independientes del idioma. Puede escribir scripts CGI en Perl, Python, C, bash, lo que sea. CGI define a qué ejecutable se llamará, en función de la URL, y cómo se llamará: los argumentos y el entorno. También define cómo debe devolverse el valor de retorno al servidor web una vez que finalice su ejecutable. Las variaciones son básicamente optimizaciones para poder manejar más solicitudes, reducir la latencia, etc. el concepto básico es el mismo.
WSGI es solo Python. En lugar de un protocolo independiente del idioma, se define una firma de función estándar:
def simple_app(environ, start_response):
"""Simplest possible application object"""
status = ''200 OK''
response_headers = [(''Content-type'',''text/plain'')]
start_response(status, response_headers)
return [''Hello world!/n'']
Esa es una aplicación WSGI completa (si es limitada). Un servidor web con soporte WSGI (como Apache con mod_wsgi) puede invocar esta función cada vez que llega una solicitud.
La razón por la que esto es tan bueno es que podemos evitar el paso complicado de convertir HTTP GET / POST a CGI a Python, y viceversa en el camino de salida. Es un vínculo mucho más directo, limpio y eficiente.
También hace que sea mucho más fácil tener frameworks de larga ejecución corriendo detrás de servidores web, si todo lo que se necesita hacer para una solicitud es una llamada a función. Con CGI simple, tendrías que iniciar todo tu framework para cada solicitud individual.
Para tener soporte WSGI, necesitará tener instalado un módulo WSGI (como mod_wsgi ), o usar un servidor web con WSGI integrado (como CherryPy ). Si ninguno de estos es posible, puede usar el puente CGI-WSGI que se proporciona en el PEP.
Es una capa de abstracción simple para Python, similar a las especificaciones de Servlet para Java. Mientras que CGI es realmente de bajo nivel y simplemente descarga cosas al entorno de proceso y al estándar de entrada / salida, las dos especificaciones anteriores modelan la solicitud y la respuesta http como construcciones en el lenguaje. Sin embargo, mi impresión es que en Python las personas no se han conformado con las implementaciones de facto, por lo que tiene una combinación de implementaciones de referencia y otras bibliotecas de tipo utilidad que proporcionan otras cosas junto con el soporte de WSGI (por ejemplo, Pegar). Por supuesto que podría estar equivocado, soy un recién llegado a Python. La comunidad de "scripting web" está abordando el problema desde una dirección diferente (alojamiento compartido, herencia CGI, preocupaciones de separación de privilegios) que la gente de Java tenía el lujo de comenzar (ejecutando un solo contenedor empresarial en un entorno dedicado contra compilado e implementado estáticamente código).
Puede ejecutar WSGI a través de CGI, ya que Pep333 lo demuestra como ejemplo. Sin embargo, cada vez que hay una solicitud, se inicia un nuevo intérprete de Python y todo el contexto (conexiones de bases de datos, etc.) debe ser compilado, lo que lleva tiempo.
Lo mejor si desea ejecutar WSGI sería si su host instalara mod_wsgi y realizara una configuración adecuada para diferir el control a una aplicación suya.
Flup es otra forma de ejecutar WSGI para cualquier servidor web que pueda hablar FCGI , SCGI o AJP. Desde mi experiencia, solo FCGI realmente funciona, y puede usarse en Apache ya sea a través de mod_fastcgi o si puede ejecutar un demonio de Python separado con mod_proxy_fcgi .
WSGI es un protocolo muy parecido al CGI, que define un conjunto de reglas sobre cómo el servidor web y el código de Python pueden interactuar, se define como Pep333 . Hace posible que muchos servidores web diferentes puedan usar muchos frameworks y aplicaciones diferentes usando el mismo protocolo de aplicación. Esto es muy beneficioso y lo hace tan útil.
Si no tiene claro todos los términos en este espacio, y admitámoslo, es un acrónimo cargado de confusión, también hay un buen lector de fondo en la forma de un HOWTO oficial de python que analiza CGI vs. FastCGI vs. WSGI y así en: http://docs.python.org/howto/webservers.html
¿Cómo WSGI, CGI y los marcos están todos conectados?
Apache escucha en el puerto 80. Obtiene una solicitud HTTP. Analiza la solicitud para encontrar una manera de responder. Apache tiene MUCHAS opciones para responder. Una forma de responder es usar CGI para ejecutar un script. Otra forma de responder es simplemente servir un archivo.
En el caso de CGI, Apache prepara un entorno e invoca el script a través del protocolo CGI. Esta es una situación estándar de fork / exec de Unix: el subproceso CGI hereda un entorno de sistema operativo que incluye socket y stdout. El subproceso CGI escribe una respuesta, que se remonta a Apache; Apache envía esta respuesta al navegador.
CGI es primitivo y molesto. Principalmente porque divide un subproceso para cada solicitud, y el subproceso debe salir o cerrar stdout y stderr para indicar el final de la respuesta.
WSGI es una interfaz que se basa en el patrón de diseño CGI. No es necesariamente CGI: no tiene que bifurcar un subproceso para cada solicitud. Puede ser CGI, pero no tiene que serlo.
WSGI se agrega al patrón de diseño CGI de varias maneras importantes. Analiza los encabezados de solicitud HTTP por usted y los agrega al entorno. Suministra cualquier entrada orientada a POST como un objeto similar a un archivo en el entorno. También le proporciona una función que formulará la respuesta, lo que le evitará muchos detalles de formato.
¿Qué necesito saber / instalar / hacer si quiero ejecutar un marco web (digamos web.py o cherrypy) en mi configuración básica de CGI?
Recuerde que bifurcar un subproceso es costoso. Hay dos formas de evitar esto.
Embedded
mod_wsgi
omod_python
incrusta Python dentro de Apache; ningún proceso es bifurcado Apache ejecuta la aplicación Django directamente.Daemon
mod_wsgi
omod_fastcgi
permite que Apache interactúe con un daemon independiente (o "proceso de larga ejecución"), utilizando el protocolo WSGI. Usted inicia su proceso Django de larga duración, luego configura el mod_fastcgi de Apache para comunicarse con este proceso.
Tenga en cuenta que mod_wsgi
puede funcionar en cualquier modo: embedded o daemon.
Cuando leas en mod_fastcgi, verás que Django utiliza flup para crear una interfaz compatible con WSGI a partir de la información proporcionada por mod_fastcgi. La tubería funciona así.
Apache -> mod_fastcgi -> FLUP (via FastCGI protocol) -> Django (via WSGI protocol)
Django tiene varios "django.core.handlers" para las diversas interfaces.
Para mod_fastcgi, Django proporciona un manage.py runfcgi
que integra FLUP y el manejador.
Para mod_wsgi, hay un controlador de núcleo para esto.
¿Cómo instalar WSGI?
Siga estas instrucciones.
https://code.google.com/archive/p/modwsgi/wikis/IntegrationWithDjango.wiki
Para fondo, mira esto
http://docs.djangoproject.com/en/dev/howto/deployment/#howto-deployment-index