• © Goverland Inc. 2026
  • v1.0.8
  • Privacy Policy
  • Terms of Use
PaoPaoPaoPaoby0x6CEEa0FC41387fC6780aA78125ffdE3EcE0dc103ppyaa.eth

PEP 444 -- Python Web3 Interface

Voting ended about 4 years agoSucceeded

Abstract This document specifies a proposed second-generation standard interface between web servers and Python web applications or frameworks.

PEP Deferral Further exploration of the concepts covered in this PEP has been deferred for lack of a current champion interested in promoting the goals of the PEP and collecting and incorporating feedback, and with sufficient available time to do so effectively.

Note that since this PEP was first created, PEP 3333 was created as a more incremental update that permitted use of WSGI on Python 3.2+. However, an alternative specification that furthers the Python 3 goals of a cleaner separation of binary and text data may still be valuable.

Rationale and Goals This protocol and specification is influenced heavily by the Web Services Gateway Interface (WSGI) 1.0 standard described in PEP 333 [1]. The high-level rationale for having any standard that allows Python-based web servers and applications to interoperate is outlined in PEP 333. This document essentially uses PEP 333 as a template, and changes its wording in various places for the purpose of forming a different standard.

Python currently boasts a wide variety of web application frameworks which use the WSGI 1.0 protocol. However, due to changes in the language, the WSGI 1.0 protocol is not compatible with Python 3. This specification describes a standardized WSGI-like protocol that lets Python 2.6, 2.7 and 3.1+ applications communicate with web servers. Web3 is clearly a WSGI derivative; it only uses a different name than "WSGI" in order to indicate that it is not in any way backwards compatible.

Applications and servers which are written to this specification are meant to work properly under Python 2.6.X, Python 2.7.X and Python 3.1+. Neither an application nor a server that implements the Web3 specification can be easily written which will work under Python 2 versions earlier than 2.6 nor Python 3 versions earlier than 3.1.

Note

Whatever Python 3 version fixed http://bugs.python.org/issue4006 so os.environ['foo'] returns surrogates (ala PEP 383) when the value of 'foo' cannot be decoded using the current locale instead of failing with a KeyError is the true minimum Python 3 version. In particular, however, Python 3.0 is not supported.

Note

Python 2.6 is the first Python version that supported an alias for bytes and the b"foo" literal syntax. This is why it is the minimum version supported by Web3.

Explicability and documentability are the main technical drivers for the decisions made within the standard.

Differences from WSGI All protocol-specific environment names are prefixed with web3. rather than wsgi., eg. web3.input rather than wsgi.input. All values present as environment dictionary values are explicitly bytes instances instead of native strings. (Environment keys however are native strings, always str regardless of platform). All values returned by an application must be bytes instances, including status code, header names and values, and the body. Wherever WSGI 1.0 referred to an app_iter, this specification refers to a body. No start_response() callback (and therefore no write() callable nor exc_info data). The readline() function of web3.input must support a size hint parameter. The read() function of web3.input must be length delimited. A call without a size argument must not read more than the content length header specifies. In case a content length header is absent the stream must not return anything on read. It must never request more data than specified from the client. No requirement for middleware to yield an empty string if it needs more information from an application to produce output (e.g. no "Middleware Handling of Block Boundaries"). Filelike objects passed to a "file_wrapper" must have an iter which returns bytes (never text). wsgi.file_wrapper is not supported. QUERY_STRING, SCRIPT_NAME, PATH_INFO values required to be placed in environ by server (each as the empty bytes instance if no associated value is received in the HTTP request). web3.path_info and web3.script_name should be put into the Web3 environment, if possible, by the origin Web3 server. When available, each is the original, plain 7-bit ASCII, URL-encoded variant of its CGI equivalent derived directly from the request URI (with %2F segment markers and other meta-characters intact). If the server cannot provide one (or both) of these values, it must omit the value(s) it cannot provide from the environment. This requirement was removed: "middleware components must not block iteration waiting for multiple values from an application iterable. If the middleware needs to accumulate more data from the application before it can produce any output, it must yield an empty string." SERVER_PORT must be a bytes instance (not an integer). The server must not inject an additional Content-Length header by guessing the length from the response iterable. This must be set by the application itself in all situations. If the origin server advertises that it has the web3.async capability, a Web3 application callable used by the server is permitted to return a callable that accepts no arguments. When it does so, this callable is to be called periodically by the origin server until it returns a non-None response, which must be a normal Web3 response tuple. Specification Overview The Web3 interface has two sides: the "server" or "gateway" side, and the "application" or "framework" side. The server side invokes a callable object that is provided by the application side. The specifics of how that object is provided are up to the server or gateway. It is assumed that some servers or gateways will require an application's deployer to write a short script to create an instance of the server or gateway, and supply it with the application object. Other servers and gateways may use configuration files or other mechanisms to specify where an application object should be imported from, or otherwise obtained.

In addition to "pure" servers/gateways and applications/frameworks, it is also possible to create "middleware" components that implement both sides of this specification. Such components act as an application to their containing server, and as a server to a contained application, and can be used to provide extended APIs, content transformation, navigation, and other useful functions.

Throughout this specification, we will use the term "application callable" to mean "a function, a method, or an instance with a call method". It is up to the server, gateway, or application implementing the application callable to choose the appropriate implementation technique for their needs. Conversely, a server, gateway, or application that is invoking a callable must not have any dependency on what kind of callable was provided to it. Application callables are only to be called, not introspected upon.

The Application/Framework Side The application object is simply a callable object that accepts one argument. The term "object" should not be misconstrued as requiring an actual object instance: a function, method, or instance with a call method are all acceptable for use as an application object. Application objects must be able to be invoked more than once, as virtually all servers/gateways (other than CGI) will make such repeated requests. If this cannot be guaranteed by the implementation of the actual application, it has to be wrapped in a function that creates a new instance on each call.

Note

Although we refer to it as an "application" object, this should not be construed to mean that application developers will use Web3 as a web programming API. It is assumed that application developers will continue to use existing, high-level framework services to develop their applications. Web3 is a tool for framework and server developers, and is not intended to directly support application developers.)

An example of an application which is a function (simple_app):

def simple_app(environ): """Simplest possible application object""" status = b'200 OK' headers = [(b'Content-type', b'text/plain')] body = [b'Hello world!\n'] return body, status, headers An example of an application which is an instance (simple_app):

class AppClass(object):

"""Produce the same output, but using an instance.  An
instance of this class must be instantiated before it is
passed to the server.  """

def call(self, environ): status = b'200 OK' headers = [(b'Content-type', b'text/plain')] body = [b'Hello world!\n'] return body, status, headers

simple_app = AppClass() Alternately, an application callable may return a callable instead of the tuple if the server supports asynchronous execution. See information concerning web3.async for more information.

The Server/Gateway Side The server or gateway invokes the application callable once for each request it receives from an HTTP client, that is directed at the

Off-Chain Vote

YES
335 65%
NO
180 35%
Download mobile app to vote

Timeline

Dec 29, 2021Proposal created
Dec 29, 2021Proposal vote started
Dec 31, 2021Proposal vote ended
Oct 11, 2024Proposal updated