wsgiref
— Utilidades WSGI e implementación de referencia¶
La Interfaz de Pasarela del Servidor Web, o Web Server Gateway Interface en inglés (WSGI), es una interfaz estándar entre el servidor web y aplicaciones web escritas en Python. Con una interfaz estándar es más sencillo usar una aplicación que soporte WSGI con diferentes servidores web.
Sólo los autores de servidores y frameworks web necesitan conocer cada detalle y caso límite del diseño WSGI. No es necesario conocer cada detalle de WSGI sólo para instalar o escribir una aplicación web usando un framework existente.
wsgiref
es una implementación de referencia de la especificación WSGI que se puede usar para añadir soporte WSGI a un servidor o framework web. Este módulo provee utilidades para manipular las variables de entorno WSGI y las cabeceras de respuesta, clases base para implementar servidores WSGI, un servidor HTTP de demostración que sirve aplicaciones WSGI, y una herramienta de validación que comprueba la compatibilidad de servidores y aplicaciones WSGI en base a la especificación PEP 3333.
Vea wsgi.readthedocs.io para más información sobre WSGI, así como enlaces a tutoriales y otros recursos.
wsgiref.util
– Utilidades de entorno WSGI¶
Este módulo ofrece una variedad de funciones útiles para trabajar con entornos WSGI. Un entorno WSGI es un diccionario que contiene variables de la petición HTTP, descrito en PEP 3333. Todas las funciones que aceptan un parámetro environ esperan un diccionario compatible con WSGI. Por favor, consulte la especificación detallada en PEP 3333.
-
wsgiref.util.
guess_scheme
(environ)¶ Retorna una deducción del valor para
wsgi.url_scheme
que debería ser «http» o «https», buscando la variable de entornoHTTPS
en el diccionario environ. El valor de retorno es una cadena.Esta función es útil al crear un gateway que envuelve CGI o un protocolo similar como FastCGI. Habitualmente, los servidores que ofrecen estos protocolos incluyen una variable
HTTPS
con el valor «1», «yes», o «on» cuando reciben una petición vía SSL. Así, esta función retorna «https» si encuentra ese valor, o «http», en caso contrario.
-
wsgiref.util.
request_uri
(environ, include_query=True)¶ Retorna la URI completa de la petición, opcionalmente la cadena de consulta, usando el algoritmo encontrado en la sección «URL Reconstruction» de PEP 3333. Si include_query es falso, la cadena de consulta no se incluye en la URI resultante.
-
wsgiref.util.
application_uri
(environ)¶ Similar a
request_uri()
excepto que se ignoran las variablesPATH_INFO
yQUERY_STRING
. El resultado es la URI base del objeto de aplicación indicado en la petición.
-
wsgiref.util.
shift_path_info
(environ)¶ Desplaza un solo nombre de
PATH_INFO
aSCRIPT_NAME
y retorna el nombre. Se modifica el diccionario environ, por lo que se deberá usar una copia si se quiere mantenerPATH_INFO
oSCRIPT_NAME
intactos.Si no quedan segmentos en
PATH_INFO
, retornaráNone
.Habitualmente, esta rutina se usa para procesar cada porción de la ruta del URI de la petición, por ejemplo, para usar la ruta como una serie de claves en un diccionario. Esta rutina modifica el entorno pasado para permitir invocar otra aplicación WSGI que esté localizada en la URI objetivo. Por ejemplo, si hay una aplicación WSGI en
/foo
, y la ruta es/foo/bar/baz
, y la aplicación WSGI en/foo
llama ashift_path_info()
, recibirá la cadena «bar», y se actualizará el entorno para pasarlo a una aplicación WSGI en/foo/bar
. Es decir,SCRIPT_NAME
cambiará de/foo
a/foo/bar
yPATH_INFO
cambiará de/bar/baz
a/baz
.Cuando
PATH_INFO
es únicamente «/», esta rutina retornará una cadena vacía y añadirá una barra final aSCRIPT_NAME
, incluso cuando normalmente los segmentos de ruta vacíos se ignoran ySCRIPT_NAME
no acaba con una barra. Este comportamiento es intencional, para asegurar que una aplicación puede diferenciar entre URIs que acaban en/x
de las que acaban en/x/
cuando usan esta rutina para atravesar objetos.
-
wsgiref.util.
setup_testing_defaults
(environ)¶ Actualiza environ con valores por defecto triviales con propósito de prueba.
Esta rutina añade varios parámetros requeridos por WSGI, incluyendo
HTTP_POST
,SERVER_NAME
,SERVER_PORT
,REQUEST_METHOD
,SCRIPT_NAME
,PATH_INFO
, y todas las variableswsgi.*
definidas en PEP 3333. Sólo ofrece valores por defecto y no reemplaza ningún valor existente en esas variables.Esta rutina pretende facilitar la preparación de entornos ficticios para pruebas unitarias de servidores y aplicaciones WSGI. NO debería usarse en servidores y aplicaciones WSGI reales, ya que los valores son ficticios!
Ejemplo de uso:
from wsgiref.util import setup_testing_defaults from wsgiref.simple_server import make_server # A relatively simple WSGI application. It's going to print out the # environment dictionary after being updated by setup_testing_defaults def simple_app(environ, start_response): setup_testing_defaults(environ) status = '200 OK' headers = [('Content-type', 'text/plain; charset=utf-8')] start_response(status, headers) ret = [("%s: %s\n" % (key, value)).encode("utf-8") for key, value in environ.items()] return ret with make_server('', 8000, simple_app) as httpd: print("Serving on port 8000...") httpd.serve_forever()
Además de las funciones de entorno previas, el módulo wsgiref.util
también ofrece las siguientes utilidades varias:
-
wsgiref.util.
is_hop_by_hop
(header_name)¶ Retorna
True
si “header_name” es una cabecera «Hop-by-Hop» HTTP/1.1, como se define en RFC 2616.
-
class
wsgiref.util.
FileWrapper
(filelike, blksize=8192)¶ Un wrapper para convertir un objeto archivo en un iterator. Los objetos resultantes soportan los estilos de iteración
__getitem__()
y__iter__()
, por compatibilidad con Python 2.1 y Jython. A medida que se itera sobre el objeto, el parámetro opcional blksize se pasará repetidamente al métodoread()
del objeto archivo para obtener cadenas de bytes para entregar. Cuandoread()
retorna una cadena de bytes vacía, la iteración finalizará y no se podrá reiniciar.Si filelike tiene un método
close()
, el objeto retornado también tendrá un métodoclose()
que llamará al métodoclose()
del objeto archivo subyacente.Ejemplo de uso:
from io import StringIO from wsgiref.util import FileWrapper # We're using a StringIO-buffer for as the file-like object filelike = StringIO("This is an example file-like object"*10) wrapper = FileWrapper(filelike, blksize=5) for chunk in wrapper: print(chunk)
Obsoleto desde la versión 3.8: El soporte de
sequence protocol
es obsoleto.
wsgiref.headers
– Herramientas para cabeceras de respuesta WSGI¶
Este módulo ofrece una sola clase, Headers
, para la manipulación de cabeceras de respuesta WSGI usando un interfaz de mapa.
-
class
wsgiref.headers.
Headers
([headers])¶ Crea un objeto con interfaz de mapa envolviendo headers, que debe ser una lista de tuplas nombre/valor de las cabeceras, como se describe en PEP 3333. El valor por defecto de headers es una lista vacía.
Los objetos
Headers
soportan las operaciones de mapa habituales incluyendo__getitem__()
,get()
,__setitem__()
,setdefault()
,__delitem__()
y__contains__()
. Para cada uno de esos métodos, la clave es el nombre de la cabecera, sin distinción entre mayúsculas y minúsculas, y el valor es el primer valor asociado con el nombre de la cabecera. Establecer una cabecera borra cualquier valor previamente existente y añade un nuevo valor al final de la lista de cabeceras. En general, el orden de las cabeceras existentes se mantiene, con las nuevas cabeceras añadidas al final de la lista de cabeceras.A diferencia de un diccionario, los objetos
Headers
no lanzan un error cuando se intenta obtener o eliminar una clave que no está en la lista de cabeceras subyacente. Al intentar obtener una clave inexistente simplemente se retornaráNone
, mientras que el intento de eliminación de una cabecera inexistente simplemente no tendrá ningún efecto.Los objetos
Headers
también soportan los métodoskeys()
,values()
, yitems()
. Las listas retornadas porkeys()
yitems()
pueden incluir la misma clave más de una vez si se trata de una cabecera de valor múltiple. Lalen()
de un objetoHeaders
es la misma que la longitud de susitems()
, que es la misma que la longitud de la lista de cabeceras envuelta. De hecho, el métodoitems()
simplemente retorna una copia de la lista de cabeceras.La llamada
bytes()
sobre un objetoHeaders
retorna una cadena de bytes formateada y lista para su transmisión como cabeceras de respuesta HTTP. Cada cabecera se ubica en una línea con su valor separado por dos puntos y un espacio. Cada línea finaliza con un retorno de carro y un salto de línea, y la cadena de bytes finaliza con una línea en blanco.Además de la interfaz de mapa y las funcionalidades de formateado, los objetos
Headers
también ofrecen los siguientes métodos para consultar y añadir cabeceras con múltiples valores, y para añadir cabeceras con parámetros MIME:-
get_all
(name)¶ Retorna una lista de todos los valores para la cabecera indicada.
La lista retornada tendrá los valores ordenados según la lista de cabeceras original o según se hayan añadido a esta instancia, y podrá contener duplicados. Cualquier campo eliminado y añadido de nuevo estará al final de la lista. Si no existen campos con el nombre indicado, retornará una lista vacía.
-
add_header
(name, value, **_params)¶ Añade una cabecera, posiblemente de valor múltiple, con los parámetros MIME opcionales especificados vía argumentos por palabra clave.
name es el nombre de la cabecera a añadir. Se pueden usar argumentos por palabra clave para establecer parámetros MIME para la cabecera. Cada parámetro debe ser una cadena o
None
. Todos los guiones bajos en los nombres de parámetros se convierten en guiones, dado que los guiones son inválidos en identificadores Python y muchos parámetros MIME incluyen guiones. Si el valor del parámetro es una cadena, se añade a los parámetros del valor de la cabecera con la formanombre=valor
. Si esNone
, sólo se añade el nombre del parámetro, para reflejar parámetros MIME sin valor. Ejemplo de uso:h.add_header('content-disposition', 'attachment', filename='bud.gif')
El código anterior añadirá una cabecera como la siguiente:
Content-Disposition: attachment; filename="bud.gif"
Distinto en la versión 3.5: El parámetro headers es opcional.
-
wsgiref.simple_server
– Un servidor HTTP WSGI simple¶
Este módulo implementa un servidor HTTP simple, basado en http.server
, que sirve aplicaciones WSGI. Cada instancia del servidor sirve una aplicación WSGI simple en una máquina y puerto dados. Si se quiere servir múltiples aplicaciones en una misma máquina y puerto, se deberá crear una aplicación WSGI que analiza PATH_INFO
para seleccionar qué aplicación invocar para cada petición. Por ejemplo, usando la función shift_path_info()
de wsgiref.util
.
-
wsgiref.simple_server.
make_server
(host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler)¶ Crea un nuevo servidor WSGI que sirve en host y port, aceptando conexiones para app. El valor de retorno es una instancia de server_class y procesará peticiones usando handler_class. app debe ser un objeto aplicación WSGI, como se define en PEP 3333.
Ejemplo de uso:
from wsgiref.simple_server import make_server, demo_app with make_server('', 8000, demo_app) as httpd: print("Serving HTTP on port 8000...") # Respond to requests until process is killed httpd.serve_forever() # Alternative: serve one request, then exit httpd.handle_request()
-
wsgiref.simple_server.
demo_app
(environ, start_response)¶ Esta función es una pequeña pero completa aplicación WSGI que retorna una página de texto con el mensaje «Hello world!» y una lista de pares clave/valor obtenida del parámetro environ. Es útil para verificar que un servidor WSGI, como
wsgiref.simple_server
, es capaz de ejecutar una aplicación WSGI simple correctamente.
-
class
wsgiref.simple_server.
WSGIServer
(server_address, RequestHandlerClass)¶ Crea una instancia de
WSGIServer
. server_address debe ser una tupla(máquina,puerto)
y RequestHandlerClass debe ser la subclase dehttp.server.BaseHTTPRequestHandler
que se usará para procesar peticiones.Normalmente, no es necesario invocar este constructor, ya que la función
make_server()
puede gestionar todos los detalles.WSGIServer
es una subclase dehttp.server.HTTPServer
, por lo que todos sus métodos, comoserve_forever()
yhandle_request()
, están disponibles.WSGIServer
también ofrece los siguientes métodos específicos de WSGI:-
set_app
(application)¶ Establece el invocable application como la aplicación WSGI que recibirá las peticiones.
-
get_app
()¶ Retorna la aplicación invocable actual.
Habitualmente, sin embargo, no es necesario usar estos métodos adicionales, ya que
set_app()
se llama desdemake_server()
yget_app()
existe sobretodo para el beneficio de instancias del gestor de peticiones.-
-
class
wsgiref.simple_server.
WSGIRequestHandler
(request, client_address, server)¶ Crea un gestor HTTP para la request indicada (es decir un socket), client_address (una tupla ``(máquina,puerto)``), y *server (una instancia
WSGIServer
).No es necesario crear instancias de esta clase directamente. Se crean automáticamente bajo demanda por objetos
WSGIServer
. Sin embargo, se pueden crear subclases de esta clase y proveerlas como handler_class a la funciónmake_server()
. Algunos métodos posiblemente relevantes para sobreescribir en estas subclases:-
get_environ
()¶ Retorna un diccionario con el entorno WSGI para una petición. La implementación por defecto copia el contenido del diccionario atributo
base_environ
del objetoWSGIserver
y añade varias cabeceras derivadas de la petición HTTP. Cada llamada a este método debe retornar un nuevo diccionario con todas las variables de entorno CGI relevante especificadas en PEP 3333.
-
get_stderr
()¶ Retorna el objeto que debe usarse como el flujo de
wsgi.errors
. La implementación por defecto retorna simplementesys.stderr
.
-
handle
()¶ Procesa la petición HTTP. La implementación por defecto crea una instancia gestora usando una clase
wsgiref.handlers
para implementar la interfaz de aplicación WSGI real.
-
wsgiref.validate
— Verificador de compatibilidad WSGI¶
Al crear nuevos objetos aplicación WSGI, frameworks, servidores, o middleware, puede ser útil validar la compatibilidad del nuevo código usando wsgiref.validate
. Este módulo ofrece una función que crea objetos de aplicación WSGI que validan las comunicaciones entre un servidor o gateway WSGI y un objeto de aplicación WSGI, para comprobar la compatibilidad del protocolo en ambos lados.
Hay que observar que esta utilidad no garantiza compatibilidad completa con PEP 3333. La ausencia de errores usando este módulo no implica que no existan errores. Sin embargo, si este módulo produce errores, implica que o el servidor o la aplicación no son 100% compatibles.
Este módulo se basa en el módulo paste.lint
de la librería Python Paste de Ian Bicking.
-
wsgiref.validate.
validator
(application)¶ Envuelve application y retorna un nuevo objeto de aplicación WSGI. La aplicación retornada reenviará todas las peticiones a la application original y comprobará que tanto la application como el servidor que la llama son compatibles con la especificación WSGI y con RFC 2616.
Cualquier incompatibilidad detectada provocará el lanzamiento de un
AssertionError
. Nótese que, sin embargo, cómo se gestionan estos errores depende del servidor. Por ejemplo,wsgiref.simple_server
y otros servidores basados enwsgiref.handlers
, que no sobreescriben los métodos de gestión de errores para hacer otras cosas, simplemente escribirán un mensaje de que el error ha ocurrido y volcarán la traza de error ensys.stderr
o algún otro flujo de errores.Este wrapper puede también generar salidas usando el módulo
warnings
para señalar comportamientos que son cuestionables pero que no están realmente prohibidos por PEP 3333. A no ser que se suprima esta salida usando opciones de línea de comandos de Python o la API dewarnings
, cualquier aviso se escribirá ensys.stderr
, en lugar de enwsgi.errors
, aunque sean el mismo objeto.Ejemplo de uso:
from wsgiref.validate import validator from wsgiref.simple_server import make_server # Our callable object which is intentionally not compliant to the # standard, so the validator is going to break def simple_app(environ, start_response): status = '200 OK' # HTTP Status headers = [('Content-type', 'text/plain')] # HTTP Headers start_response(status, headers) # This is going to break because we need to return a list, and # the validator is going to inform us return b"Hello World" # This is the application wrapped in a validator validator_app = validator(simple_app) with make_server('', 8000, validator_app) as httpd: print("Listening on port 8000....") httpd.serve_forever()
wsgiref.handlers
– Clases base servidor/gateway¶
Este módulo ofrece clases gestoras base para implementar servidores y gateways WSGI. Estas clases base gestionan la mayoría del trabajo de comunicarse con una aplicación WSGI, siempre que se les dé un entorno CGI, junto con una entrada, una salida, y un flujo de errores.
-
class
wsgiref.handlers.
CGIHandler
¶ Invocación basada en CGI vía
sys.stdin
,sys.stdout
,sys.stderr
yos.environ
. Esto es útil cuando se quiere ejecutar una aplicación WSGI como un script CGI. Simplemente es necesario invocarCGIHandler().run(app)
, dondeapp
es el objeto de aplicación WSGI que se quiere invocar.Esta clase es una subclase de
BaseCGIHandler
que establecewsgi.run_once
a cierto,wsgi.multithread
a falso, ywsgi.multiprocess
a cierto, y siempre usasys
yos
para obtener los flujos y entorno CGI necesarios.
-
class
wsgiref.handlers.
IISCGIHandler
¶ Una alternativa especializada a
CGIHandler
, para usar al desplegar en servidores web Microsoft IIS, sin establecer la opción de configuraciónallowPathInfo
(IIS>=7) o la meta-baseallowPathInfoForScriptMappings
(IIS<7).Por defecto, IIS entrega
PATH_INFO
que duplicaSCRIPT_NAME
al principio, causando problemas con aplicaciones WSGI que implementan enrutamiento. Este gestor elimina las partes duplicadas de la ruta.IIS se puede configurar para pasar el
PATH_INFO
correcto, pero esto causa otro error dondePATH_TRANSLATED
es incorrecto. Afortunadamente, esta variable rara vez se usa y no está garantizada por WSGI. Sin embargo, en IIS<7, la configuración solo se puede realizar en un nivel de vhost, lo que afecta a todas las demás asignaciones de scripts, muchas de las cuales se rompen cuando se exponen al errorPATH_TRANSLATED
. Por esta razón, IIS<7 casi nunca se implementa con la solución (incluso IIS7 rara vez lo usa porque todavía no tiene una interfaz de usuario).No hay forma de que el código CGI detecte cuándo la opción está activada, por lo que se ofrece una clase gestora separada. Se usa de la misma forma que
CGIHandler
, p.e. llamando aIISCGIHandler().run(app)
, dondeapp
es el objeto aplicación WSGI que se desea invocar.Nuevo en la versión 3.2.
-
class
wsgiref.handlers.
BaseCGIHandler
(stdin, stdout, stderr, environ, multithread=True, multiprocess=False)¶ Similar a
CGIHandler
, pero en lugar de usar los módulossys
yos
, el entorno CGI y los flujos de E/S se especifican explícitamente. Los valores multithread y multiprocess se pasan a las aplicaciones ejecutadas por la instancia de gestión comowsgi.multithread
ywsgi.multiprocess
.Esta clase es una subclase de
SimpleHandler
para usarse con servidores HTTP que no reciben peticiones directas de Internet, HTTP origin servers. Al escribir una implementación de un protocolo de pasarela, como CGI, FastCGI, SCGI, etcétera, que use una cabeceraStatus:
para enviar un estado HTTP, probablemente sea adecuado heredar de esta clase, en lugar deSimpleHandler
.
-
class
wsgiref.handlers.
SimpleHandler
(stdin, stdout, stderr, environ, multithread=True, multiprocess=False)¶ Similar a
BaseCGIHandler
pero diseñada para usarse con servidores que reciban peticiones directamente de Internet, o HTTP origin servers. Al escribir una implementación de un servidor HTTP, probablemente prefiera heredar de esta clase en lugar deBaseCGIHandler
.Esta clase es una subclase de
BaseHandler
. Sobreescribe los métodos__init__()
,get_stdin()
,get_stderr()
,add_cgi_vars()
,_write()
y_flush()
para soportar el uso explícito del entorno y los flujos a partir del constructor. El entorno y los flujos especificados se almacenan en los atributosstdin
,stdout
,stderr
yenviron
.El método
write()
de stdout podría escribir cada fragmento de información completamente, comoio.BufferedIOBase
.
-
class
wsgiref.handlers.
BaseHandler
¶ Esta es una clase base abstracta para ejecutar aplicaciones WSGI. Cada instancia gestionará una sola petición HTTP, aunque en principio se podría crear una subclase reutilizable para múltiples peticiones.
Las instancias de
BaseHandler
tiene un sólo método para uso externo:-
run
(app)¶ Ejecuta la aplicación WSGI app indicada.
Todos los otros métodos de
BaseHandler
se invocan por este método en el proceso de ejecutar la aplicación, es decir, existen principalmente para permitir personalizar el proceso.Los métodos siguientes DEBEN sobrescribirse en una subclase:
-
_write
(data)¶ Enviar los bytes data para la transmisión al cliente. Es correcto que este método realmente transmita la información. La clase
BaseHandler
simplemente separa las operaciones de escritura y liberación para una mayor eficiencia cuando el sistema subyacente realmente hace esa distinción.
-
_flush
()¶ Forzar la transmisión de los datos en el búfer al cliente. Es correcto si este método no es operativo, p.e., si
_write()
realmente envía los datos.
-
get_stdin
()¶ Retorna un objeto de flujo de entrada disponible para usar como
wsgi.input
de la petición en proceso actualmente.
-
get_stderr
()¶ Retorna un objeto de flujo de salida disponible para usar como
wsgi.errors
de la petición en proceso actualmente.
-
add_cgi_vars
()¶ Inserta las variables CGI para la petición actual en el atributo
environ
.
A continuación se describen algunos métodos y atributos más que podría ser interesante sobrescribir. Esta lista es sólo un sumario, sin embargo, y no incluye cada método que puede ser sobrescrito. Conviene consultar las docstrings y el código fuente para obtener información adicional antes de intentar crear una subclase de
BaseHandler
personalizada.Atributos y métodos para personalizar el entorno WSGI:
-
wsgi_multithread
¶ El valor a usar en la variable de entorno
wsgi.multithread
. Por defecto es cierto enBaseHandler
, pero puede tener un valor por defecto distinto (o establecerse en el constructor) en otras subclases.
-
wsgi_multiprocess
¶ El valor a usar en la variable de entorno
wsgi.multiprocess
. Por defecto es cierto enBaseHandler
, pero puede tener un valor por defecto distinto (o establecerse en el constructor) en otras subclases.
-
wsgi_run_once
¶ El valor a usar en la variable de entorno
wsgi.run_once
. Por defecto es falso enBaseHandler
, pero enCGIHandler
es cierto por defecto.
-
os_environ
¶ Las variables de entorno por defecto que se incluirán en el entorno WSGI de cada petición. Por defecto, es una copia de
os.environ
cuando se importawsgiref.handlers
, pero otras subclases pueden crear las suyas propias a nivel de clase o de instancia. Se debe tener en cuenta que el diccionario se debe considerar como de sólo lectura, ya que el valor por defecto se comparte entre múltiples clases e instancias.
-
server_software
¶ Si el atributo
origin_server
tiene valor, éste se usa para establecer el valor por defecto de la variable de entorno WSGISERVER_SOFTWARE
y un cabeceraServer:
por defecto en las respuestas HTTP. Las clases gestoras que no son HTTP origin servers, comoBaseCGIHandler
yCGIHandler
, ignoran este atributo.Distinto en la versión 3.3: El término «Python» se reemplaza con el término específico correspondiente a la implementación del intérprete, como «CPython», «Jython», etc.
-
get_scheme
()¶ Retorna el esquema usado en la URL para la petición actual. La implementación por defecto utiliza la función
guess_scheme()
dewsgiref.util
para adivinar si el esquema debería ser «http» o «https», basándose en las variables deenviron
de la petición actual.
-
setup_environ
()¶ Establece el atributo
environ
a un entorno WSGI completo. La implementación por defecto utiliza todos los métodos y atributos anteriormente mencionados, más los métodosget_stdin()
,get_stderr()
yadd_cgi_vars()
, y el atributowsgi_file_wrapper
. También incluye una claveSERVER_SOFTWARE
si no existe, siempre y cuando el atributoorigin_server
tiene un valor válido y el atributoserver_software
está establecido.
Métodos y atributos para personalizar el manejo de excepciones:
-
log_exception
(exc_info)¶ Envía la tupla exc_info al registro del servidor. exc_info es un tupla
(type, value, traceback)
. La implementación por defecto simplemente escribe el seguimiento de la pila en el flujowsgi.errors
de la petición y lo vacía. Las subclases pueden sobrescribir éste método para cambiar el formato o redirigir la salida, enviar mensajes de correo con el seguimiento de pila a un administrador o cualquier otra acción que se considere adecuada.
-
traceback_limit
¶ El máximo número de marcos a incluir en la salida de seguimientos de pilas por el método por defecto
log_exception()
. Si valeNone
, se incluyen todos los marcos.
-
error_output
(environ, start_response)¶ Este método es una aplicación WSGI para generar una página de error para el usuario. Sólo se invoca si un error ocurre antes de enviar las cabeceras al cliente.
Este método puede acceder a la información de error actual usando
sys.exc_info()
y debería pasar esa información a start_response cuando es llamada, tal y como se describe en la sección «Error Handling» de PEP 3333.La implementación por defecto sólo utiliza los atributos
error_status
,error_headers
yerror_body
para generar una página de salida. Las subclases pueden sobrescribir éste para producir una salida de error dinámica mejor.Hay que tener en cuenta, sin embargo, que no se recomienda, desde una perspectiva de seguridad, mostrar información de diagnóstico a cualquier usuario antiguo. Idealmente, se debería hacer algo especial para activar la salida de información de diagnóstico, motivo por el que la implementación por defecto no incluye ninguna.
-
error_status
¶ El estado HTTP utilizado para las respuestas de error. Se debería utilizar una de las cadenas de estado definidas en PEP 3333. Por defecto es un código 500 y un mensaje.
-
error_headers
¶ Las cabeceras HTTP utilizadas por las respuestas de error. Debería tratarse de una lista de cabeceras de respuesta WSGI (tuplas
(name, value)
), tal y como se describe en PEP 3333. La lista por defecto simplemente establece el tipo de contenido atext/plain
.
-
error_body
¶ El cuerpo de la respuesta de error. Debería ser una cadena de bytes con el cuerpo de la respuesta HTTP. Por defecto contiene el texto plano A server error occurred. Please contact the administrator.
Métodos y atributos para la funcionalidad «Optional Platform-Specific File Handling» de PEP 3333:
-
wsgi_file_wrapper
¶ Una factoría
wsgi.file_wrapper
, oNone
. El valor por defecto de este atributo es la clasewsgiref.util.FileWrapper
.
-
sendfile
()¶ Sobrescribir para implementar la transmisión de ficheros específica para la plataforma. Este método se llama sólo si el valor de retorno de la aplicación es una instancia de la clase especificada por el atributo
wsgi_file_wrapper
. Debería retornar un valor cierto si fue capaz de transmitir correctamente el fichero, de modo que el código por defecto de transmisión no será ejecutado. La implementación por defecto de este método simplemente retorna un valor falso.
Métodos y atributos varios:
-
origin_server
¶ Este atributo debería establecerse a cierto si los métodos
_write()
y_flush()
están siendo usados para comunicar directamente al cliente, en lugar de usar un protocolo de pasarela CGI que requiere el estado HTTP en una cabeceraStatus:
especial.El valor por defecto de este atributo es cierto en
BaseHandler
, pero enBaseCGIHandler
yCGIHandler
es falso.
-
http_version
¶ Si
origin_server
es cierto, este atributo de tipo cadena se usa para establecer la versión HTTP de la respuesta enviada al cliente. Por defecto es"1.0"
.
-
-
wsgiref.handlers.
read_environ
()¶ Transcodifica las variables CGI de
os.environ
a cadenas «bytes in unicode» definidas en PEP 3333, retornando un nuevo diccionario. Esta función se usa enCGIHandler
yIISCGIHandler
en lugar de usar directamenteos.environ
, lo que no es necesariamente compatible con EWGI en todas las plataformas y servidores web usando Python 3 – específicamente, aquellas en las que el entorno actual del sistema operativo es Unicode, p.e. Windows, o en las que el entorno está en bytes, pero la codificación del sistema usada por Python para descodificar lo es cualquier otro que ISO-8859-1, por ejemplo, sistemas UNIX que usen UTF-8.Cuando se está implementando un gestor basado en CGI propio, probablemente se requiera usar esta rutina en lugar de sólo copiar directamente los valores de
os.environ
.Nuevo en la versión 3.2.
Ejemplos¶
Ésta es una aplicación WSGI «Hello World» que funciona:
from wsgiref.simple_server import make_server
# Every WSGI application must have an application object - a callable
# object that accepts two arguments. For that purpose, we're going to
# use a function (note that you're not limited to a function, you can
# use a class for example). The first argument passed to the function
# is a dictionary containing CGI-style environment variables and the
# second variable is the callable object.
def hello_world_app(environ, start_response):
status = '200 OK' # HTTP Status
headers = [('Content-type', 'text/plain; charset=utf-8')] # HTTP Headers
start_response(status, headers)
# The returned object is going to be printed
return [b"Hello World"]
with make_server('', 8000, hello_world_app) as httpd:
print("Serving on port 8000...")
# Serve until process is killed
httpd.serve_forever()
Ejemplo de una aplicación WSGI que sirve el directorio actual, acepta un directorio opcional y un número de puerto (default: 8000) en la línea de comandos:
#!/usr/bin/env python3
'''
Small wsgiref based web server. Takes a path to serve from and an
optional port number (defaults to 8000), then tries to serve files.
Mime types are guessed from the file names, 404 errors are raised
if the file is not found. Used for the make serve target in Doc.
'''
import sys
import os
import mimetypes
from wsgiref import simple_server, util
def app(environ, respond):
fn = os.path.join(path, environ['PATH_INFO'][1:])
if '.' not in fn.split(os.path.sep)[-1]:
fn = os.path.join(fn, 'index.html')
type = mimetypes.guess_type(fn)[0]
if os.path.exists(fn):
respond('200 OK', [('Content-Type', type)])
return util.FileWrapper(open(fn, "rb"))
else:
respond('404 Not Found', [('Content-Type', 'text/plain')])
return [b'not found']
if __name__ == '__main__':
path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
port = int(sys.argv[2]) if len(sys.argv) > 2 else 8000
httpd = simple_server.make_server('', port, app)
print("Serving {} on port {}, control-C to stop".format(path, port))
try:
httpd.serve_forever()
except KeyboardInterrupt:
print("Shutting down.")
httpd.server_close()