# `wsgiref` — Utilidades WSGI e implementación de referencia

Source code: Lib/wsgiref

Advertencia

`wsgiref` is a reference implementation and is not recommended for production. The module only implements basic security checks.

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, tipos para validadores estáticos de tipos, 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, y los alias de tipos que pueden usarse en las anotaciones de tipo en `WSGIEnvironment`.

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 entorno `HTTPS` 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 variables `PATH_INFO` y `QUERY_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` a `SCRIPT_NAME` y retorna el nombre. Se modifica el diccionario environ, por lo que se deberá usar una copia si se quiere mantener `PATH_INFO` o `SCRIPT_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 a `shift_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` y `PATH_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 a `SCRIPT_NAME`, incluso cuando normalmente los segmentos de ruta vacíos se ignoran y `SCRIPT_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 variables `wsgi.*` 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)

  Una implementación concreta del protocolo `wsgiref.types.FileWrapper` usado para convertir objetos de tipo archivo en un iterator. Los objetos resultantes son iterables. A medida que se itera sobre el objeto, el parámetro opcional blksize se pasará repetidamente al método `read()` del objeto archivo para obtener cadenas de bytes para entregar. Cuando `read()` 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étodo `close()` que llamará al método `close()` 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)

  Distinto en la versión 3.11: Support for `__getitem__()` method has been removed.

## `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.

  `Headers` objects support typical mapping operations including `__getitem__()`, `get()`, `__setitem__()`, `setdefault()`, `__delitem__()` and `__contains__()`. For each of these methods, the key is the header name (treated case-insensitively), and the value is the first value associated with that header name. Setting a header deletes any existing values for that header, then adds a new value at the end of the wrapped header list. Headers” existing order is generally maintained, with new headers added to the end of the wrapped list.

  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étodos `keys()`, `values()`, y `items()`. Las listas retornadas por `keys()` y `items()` pueden incluir la misma clave más de una vez si se trata de una cabecera de valor múltiple. La `len()` de un objeto `Headers` es la misma que la longitud de sus `items()`, que es la misma que la longitud de la lista de cabeceras envuelta. De hecho, el método `items()` simplemente retorna una copia de la lista de cabeceras.

  La llamada `bytes()` sobre un objeto `Headers` 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 forma `nombre=valor`. Si es `None`, 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 de `http.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 de `http.server.HTTPServer`, por lo que todos sus métodos, como `serve_forever()` y `handle_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 actualmente establecida.

  Habitualmente, sin embargo, no es necesario usar estos métodos adicionales, ya que `set_app()` se llama desde `make_server()` y `get_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ón `make_server()`. Algunos métodos posiblemente relevantes para sobreescribir en estas subclases:

  get_environ()

    Retorna un diccionario `WSGIEnvironment` para una petición. La implementación por defecto copia el contenido del diccionario atributo `base_environ` del objeto `WSGIserver` 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 relevantes especificadas en PEP 3333.

  get_stderr()

    Retorna el objeto que debe usarse como el flujo de `wsgi.errors`. La implementación por defecto retorna simplemente `sys.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 en `wsgiref.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 en `sys.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 de `warnings`, cualquier aviso se escribirá en `sys.stderr`, en lugar de en `wsgi.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` y `os.environ`. Esto es útil cuando se quiere ejecutar una aplicación WSGI como un script CGI. Simplemente es necesario invocar `CGIHandler().run(app)`, donde `app` es el objeto de aplicación WSGI que se quiere invocar.

  Esta clase es una subclase de `BaseCGIHandler` que establece `wsgi.run_once` a cierto, `wsgi.multithread` a falso, y `wsgi.multiprocess` a cierto, y siempre usa `sys` y `os` 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ón `allowPathInfo` (IIS>=7) o la meta-base `allowPathInfoForScriptMappings` (IIS<7).

  Por defecto, IIS entrega `PATH_INFO` que duplica `SCRIPT_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 donde `PATH_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 error `PATH_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 a `IISCGIHandler().run(app)`, donde `app` 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ódulos `sys` y `os`, 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 como `wsgi.multithread` y `wsgi.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 cabecera `Status:` para enviar un estado HTTP, probablemente sea adecuado heredar de esta clase, en lugar de `SimpleHandler`.

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 de `BaseCGIHandler`.

  This class is a subclass of `BaseHandler`. It overrides the `__init__()`, `get_stdin()`, `get_stderr()`, `add_cgi_vars()`, `_write()`, and `_flush()` methods to support explicitly setting the environment and streams via the constructor. The supplied environment and streams are stored in the `stdin`, `stdout`, `stderr`, and `environ` attributes.

  El método `write()` de stdout podría escribir cada fragmento de información completamente, como `io.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 compatible con `InputStream`, apropiado para usar como `wsgi.input` de la petición en proceso actualmente.

  get_stderr()

    Retorna un objeto compatible con `ErrorStream`, apropiado 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 en `BaseHandler`, 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 en `BaseHandler`, 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 en `BaseHandler`, pero en `CGIHandler` 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 importa `wsgiref.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 WSGI `SERVER_SOFTWARE` y un cabecera `Server:` por defecto en las respuestas HTTP. Las clases gestoras que no son HTTP origin servers, como `BaseCGIHandler` y `CGIHandler`, 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()` de `wsgiref.util` para adivinar si el esquema debería ser «http» o «https», basándose en las variables de `environ` 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étodos `get_stdin()`, `get_stderr()` y `add_cgi_vars()`, y el atributo `wsgi_file_wrapper`. También incluye una clave `SERVER_SOFTWARE` si no existe, siempre y cuando el atributo `origin_server` tiene un valor válido y el atributo `server_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 flujo `wsgi.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 vale `None`, 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.

    This method can access the current error using `sys.exception()`, and should pass that information to start_response when calling it (as described in the «Error Handling» section of PEP 3333).

    La implementación por defecto sólo utiliza los atributos `error_status`, `error_headers` y `error_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 a `text/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 fábrica `wsgi.file_wrapper` compatible con `wsgiref.types.FileWrapper`, o `None`. El valor por defecto de este atributo es la clase `wsgiref.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 cabecera `Status:` especial.

    El valor por defecto de este atributo es cierto en `BaseHandler`, pero en `BaseCGIHandler` y `CGIHandler` 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 en `CGIHandler` y `IISCGIHandler` en lugar de usar directamente `os.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.

## `wsgiref.types` — Tipos de WSGI para validadores estáticos de tipos

Este módulo provee varios tipos para validadores estáticos de tipos, como se describe en PEP 3333.

Nuevo en la versión 3.11.

class wsgiref.types.StartResponse

  Un `typing.Protocol` que describe los invocables start_response() (PEP 3333).

wsgiref.types.WSGIEnvironment

  Un alias de tipo que describe un diccionario de entorno WSGI.

wsgiref.types.WSGIApplication

  Un alias de tipo que describe una aplicación WSGI invocable.

class wsgiref.types.InputStream

  Un `typing.Protocol` que describe un flujo de entrada WSGI.

class wsgiref.types.ErrorStream

  Un `typing.Protocol` que describe un flujo de error WSGI.

class wsgiref.types.FileWrapper

  Un `typing.Protocol` que describe un envoltorio de archivo. Vea `wsgiref.util.FileWrapper` para una implementación concreta de este protocolo.

## Ejemplos

Ésta es una aplicación WSGI «Hello World» que funciona:

    """
    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.
    """
    from wsgiref.simple_server import make_server

    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:

    """
    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.
    """
    import mimetypes
    import os
    import sys
    from wsgiref import simple_server, util

    def app(environ, respond):
        # Get the file name and MIME type
        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")
        mime_type = mimetypes.guess_type(fn)[0]

        # Return 200 OK if file exists, otherwise 404 Not Found
        if os.path.exists(fn):
            respond("200 OK", [("Content-Type", mime_type)])
            return util.FileWrapper(open(fn, "rb"))
        else:
            respond("404 Not Found", [("Content-Type", "text/plain")])
            return [b"not found"]

    if __name__ == "__main__":
        # Get the path and port from command-line arguments
        path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
        port = int(sys.argv[2]) if len(sys.argv) > 2 else 8000

        # Make and start the server until control-c
        httpd = simple_server.make_server("", port, app)
        print(f"Serving {path} on port {port}, control-C to stop")
        try:
            httpd.serve_forever()
        except KeyboardInterrupt:
            print("Shutting down.")
            httpd.server_close()