# gevent

# `gevent.pywsgi` – A pure-Python, gevent-friendly WSGI server

The server is provided in `WSGIServer`, but most of the actual WSGI work is handled by `WSGIHandler` — a new instance is created for each request. The server can be customized to use different subclasses of `WSGIHandler`.

class `WSGIServer`(listener, application=None, backlog=None, spawn='default', log='default', error_log='default', handler_class=None, environ=None, **ssl_args)

  Bases: `gevent.server.StreamServer`

  A WSGI server based on `StreamServer` that supports HTTPS.

  Parameters:

  - log – If given, an object with a `write` method to which request (access) logs will be written. If not given, defaults to `sys.stderr`. You may pass `None` to disable request logging. You may use a wrapper, around e.g., `logging`, to support objects that don’t implement a `write` method. (If you pass a `Logger` instance, or in general something that provides a `log` method but not a `write` method, such a wrapper will automatically be created and it will be logged to at the `INFO` level.)
  - error_log – If given, a file-like object with `write`, `writelines` and `flush` methods to which error logs will be written. If not given, defaults to `sys.stderr`. You may pass `None` to disable error logging (not recommended). You may use a wrapper, around e.g., `logging`, to support objects that don’t implement the proper methods. This parameter will become the value for `wsgi.errors` in the WSGI environment (if not already set). (As with log, wrappers for `Logger` instances and the like will be created automatically and logged to at the `ERROR` level.)

  See also

  `LoggingLogAdapter`
    See important warnings before attempting to use `logging`.

  Changed in version 1.1a3: Added the `error_log` parameter, and set `wsgi.errors` in the WSGI environment to this value.

  Changed in version 1.1a3: Add support for passing `logging.Logger` objects to the `log` and `error_log` arguments.

  `environ_class`

    alias of `builtins.dict`

  `handler_class`

    A callable taking three arguments: (socket, address, server) and returning an object with a `handle()` method. The callable is called once for each incoming socket request, as is its handle method. The handle method should not return until all use of the socket is complete.

    This class uses the `WSGIHandler` object as the default value. You may subclass this class and set a different default value, or you may pass a value to use in the `handler_class` keyword constructor argument.

    alias of `WSGIHandler`

  `secure_environ_class`

    alias of `WSGISecureEnviron`

  `handle`(sock, address)

    Create an instance of `handler_class` to handle the request.

    This method blocks until the handler returns.

  `init_socket`()

    If the user initialized the server with an address rather than socket, then this function will create a socket, bind it and put it into listening mode.

    It is not supposed to be called by the user, it is called by `start()` before starting the accept loop.

  `update_environ`()

    Called before the first request is handled to fill in WSGI environment values.

    This includes getting the correct server name and port.

  `error_log` = None

    The object to which error logs will be written. It must never be None. Initialized from the `error_log` constructor parameter.

  `log` = None

    The object to which request logs will be written. It must never be None. Initialized from the `log` constructor parameter.

class `WSGIHandler`(sock, address, server, rfile=None)

  Bases: `object`

  Handles HTTP requests from a socket, creates the WSGI environment, and interacts with the WSGI application.

  This is the default value of `WSGIServer.handler_class`. This class may be subclassed carefully, and that class set on a `WSGIServer` instance through a keyword argument at construction time.

  Instances are constructed with the same arguments as passed to the server’s `WSGIServer.handle()` method followed by the server itself. The application and environment are obtained from the server.

  `get_environ`()

    Construct and return a new WSGI environment dictionary for a specific request.

    This should begin with asking the server for the base environment using `WSGIServer.get_environ()`, and then proceed to add the request specific values.

    By the time this method is invoked the request line and request shall have been parsed and `self.headers` shall be populated.

  `handle`()

    The main request handling method, called by the server.

    This method runs a request handling loop, calling `handle_one_request()` until all requests on the connection have been handled (that is, it implements keep-alive).

  `handle_one_request`()

    Handles one HTTP request using `self.socket` and `self.rfile`.

    Each invocation of this method will do several things, including (but not limited to):

    - Read the request line using `read_requestline()`;
    - Read the rest of the request, including headers, with `read_request()`;
    - Construct a new WSGI environment in `self.environ` using `get_environ()`;
    - Store the application in `self.application`, retrieving it from the server;
    - Handle the remainder of the request, including invoking the application, with `handle_one_response()`

    There are several possible return values to indicate the state of the client connection:

    - `None`
        The client connection is already closed or should be closed because the WSGI application or client set the `Connection: close` header. The request handling loop should terminate and perform cleanup steps.
    - (status, body)
        An HTTP status and body tuple. The request was in error, as detailed by the status and body. The request handling loop should terminate, close the connection, and perform cleanup steps. Note that the `body` is the complete contents to send to the client, including all headers and the initial status line.
    - `True`
        The literal `True` value. The request was successfully handled and the response sent to the client by `handle_one_response()`. The connection remains open to process more requests and the connection handling loop should call this method again. This is the typical return value.

    See also

    `handle()`

    Changed in version 1.1b6: Funnel exceptions having to do with invalid HTTP requests through `_handle_client_error()` to allow subclasses to customize. Note that this is experimental and may change in the future.

  `handle_one_response`()

    Invoke the application to produce one response.

    This is called by `handle_one_request()` after all the state for the request has been established. It is responsible for error handling.

  `read_request`(raw_requestline)

    Parse the incoming request.

    Parses various headers into `self.headers` using `MessageClass`. Other attributes that are set upon a successful return of this method include `self.content_length` and `self.close_connection`.

    Parameters: | raw_requestline (str) – A native `str` representing the request line. A processed version of this will be stored into `self.requestline`.
    Raises: | ValueError – If the request is invalid. This error will not be logged as a traceback (because it’s a client issue, not a server problem).
    Returns: | A boolean value indicating whether the request was successfully parsed. This method should either return a true value or have raised a ValueError with details about the parsing error.

    Changed in version 1.1b6: Raise the previously documented `ValueError` in more cases instead of returning a false value; this allows subclasses more opportunity to customize behaviour.

  `read_requestline`()

    Read and return the HTTP request line.

    Under both Python 2 and 3, this should return the native `str` type; under Python 3, this probably means the bytes read from the network need to be decoded (using the ISO-8859-1 charset, aka latin-1).

  `start_response`(status, headers, exc_info=None)

    Changed in version 1.2a1: Avoid HTTP header injection by raising a `ValueError` if status or any header name or value contains a carriage return or newline.

    Changed in version 1.1b5: Pro-actively handle checking the encoding of the status line and headers during this method. On Python 2, avoid some extra encodings.

  `ignored_socket_errors` = (32, 104)

    These errors are silently ignored by `handle_one_response()` to avoid producing excess log entries on normal operating conditions. They indicate a remote client has disconnected and there is little or nothing this process can be expected to do about it. You may change this value in a subclass.

    The default value includes `errno.EPIPE` and `errno.ECONNRESET`. On Windows this also includes `errno.WSAECONNABORTED`.

    This is a provisional API, subject to change. See pull request #377, pull request #999 and issue #136.

    New in version 1.3.

class `LoggingLogAdapter`(logger, level=20)

  Bases: `object`

  An adapter for `logging.Logger` instances to let them be used with `WSGIServer`.

  Warning

  Unless the entire process is monkey-patched at a very early part of the lifecycle (before logging is configured), loggers are likely to not be gevent-cooperative. For example, the socket and syslog handlers use the socket module in a way that can block, and most handlers acquire threading locks.

  Warning

  It may be possible for the logging functions to be called in the `gevent.Hub` greenlet. Code running in the hub greenlet cannot use any gevent blocking functions without triggering a `LoopExit`.

  New in version 1.1a3.

  Changed in version 1.1b6: Attributes not present on this object are proxied to the underlying logger instance. This permits using custom `Logger` subclasses (or indeed, even duck-typed objects).

  Changed in version 1.1: Strip trailing newline characters on the message passed to `write()` because log handlers will usually add one themselves.

  Write information to the logger at the given level (default to INFO).

  `flush`()

    No-op; required to be a file-like object

class `Environ`

  Bases: `dict`

  A base class that can be used for WSGI environment objects.

  Provisional API.

  New in version 1.2a1.

  `copy`() → a shallow copy of D

class `SecureEnviron`

  Bases: `gevent.pywsgi.Environ`

  An environment that does not print its keys and values by default.

  Provisional API.

  This is intended to keep potentially sensitive information like HTTP authorization and cookies from being inadvertently printed or logged.

  For debugging, each instance can have its secure_repr attribute set to `False`, which will cause it to print like a normal dict.

  When secure_repr is `True` (the default), then the value of the whitelist_keys attribute is consulted; if this value is true-ish, it should be a container (something that responds to `in`) of key names (typically a list or set). Keys and values in this dictionary that are in whitelist_keys will then be printed, while all other values will be masked. These values may be customized on the class by setting the default_secure_repr and default_whitelist_keys, respectively:

      >>> environ = SecureEnviron(key='value')
      >>> environ
      <pywsgi.SecureEnviron dict (keys: 1) at ...

  If we whitelist the key, it gets printed:

      >>> environ.whitelist_keys = {'key'}
      >>> environ
      {'key': 'value'}

  A non-whitelisted key (only, to avoid doctest issues) is masked:

      >>> environ['secure'] = 'secret'; del environ['key']
      >>> environ
      {'secure': '<MASKED>'}

  We can turn it off entirely for the instance:

      >>> environ.secure_repr = False
      >>> environ
      {'secure': 'secret'}

  We can also customize it at the class level (here we use a new class to be explicit and to avoid polluting the true default values; we would set this class to be the `environ_class` of the server):

      >>> class MyEnviron(SecureEnviron):
      ...    default_whitelist_keys = ('key',)
      ...
      >>> environ = MyEnviron({'key': 'value'})
      >>> environ
      {'key': 'value'}

  New in version 1.2a1.

class `WSGISecureEnviron`

  Bases: `gevent.pywsgi.SecureEnviron`

  Specializes the default list of whitelisted keys to a few common WSGI variables.

  Example:

      >>> environ = WSGISecureEnviron(REMOTE_ADDR='::1', HTTP_AUTHORIZATION='secret')
      >>> environ
      {'REMOTE_ADDR': '::1', (hidden keys: 1)}
      >>> import pprint
      >>> pprint.pprint(environ)
      {'REMOTE_ADDR': '::1', (hidden keys: 1)}
      >>> print(pprint.pformat(environ))
      {'REMOTE_ADDR': '::1', (hidden keys: 1)}

Next page: `gevent.server` – TCP/SSL server