Skip to main content

Lib/wsgiref/handlers.py

Source:

cpython 3.14 @ ab2d84fe1023/Lib/wsgiref/handlers.py

wsgiref.handlers implements the WSGI gateway (PEP 3333). BaseHandler.run(app) calls the WSGI application and sends the response headers and body to the transport.

Map

LinesSymbolRole
1-80BaseHandlerAbstract base: run, start_response, write, finish_response
81-200SimpleHandlerConcrete handler with stdin, stdout, stderr streams
201-350BaseCGIHandlerCGI: write response to sys.stdout
351-450WSGIRequestHandlerSubclass for http.server.BaseHTTPRequestHandler
451-500make_serverCreate a WSGIServer bound to an address

Reading

BaseHandler.run

# CPython: Lib/wsgiref/handlers.py:98 BaseHandler.run
def run(self, application):
"""Invoke the WSGI application and send the response."""
try:
self.setup_environ()
self.result = application(self.environ, self.start_response)
self.finish_response()
except:
try:
self.handle_error()
except:
self.close()
raise

start_response

# CPython: Lib/wsgiref/handlers.py:140 BaseHandler.start_response
def start_response(self, status, headers, exc_info=None):
"""WSGI start_response callable: record status and headers."""
if exc_info:
try:
if self.headers_sent:
reraise(*exc_info)
finally:
exc_info = None
elif self.headers is not None:
raise AssertionError("Headers already set!")
self.status = status
self.headers = self.headers_class(headers)
return self.write

start_response is called once by the WSGI application before any body is written. It returns the write callable for legacy apps.

write

# CPython: Lib/wsgiref/handlers.py:175 BaseHandler.write
def write(self, data):
"""Write data to the response. Called by legacy WSGI apps."""
assert isinstance(data, bytes), "write() argument must be a bytes instance"
if not self.status:
raise AssertionError("write() before start_response()")
elif not self.headers_sent:
self.send_headers()
self._write(data) # delegates to transport
self._flush()

finish_response

# CPython: Lib/wsgiref/handlers.py:200 BaseHandler.finish_response
def finish_response(self):
"""Send the response body from the WSGI result iterable."""
try:
for data in self.result:
self.write(data)
self.finish_content()
except:
self.close()
raise
else:
self.close()

WSGI result must be an iterable of bytes objects.

make_server

# CPython: Lib/wsgiref/simple_server.py:120 make_server
def make_server(host, port, app, server_class=WSGIServer,
handler_class=WSGIRequestHandler):
"""Create a WSGI server for testing purposes."""
server = server_class((host, port), handler_class)
server.set_app(app)
return server

gopy notes

wsgiref is pure Python and works with gopy's http.server and socket modules. BaseHandler.run calls the WSGI application callable which is any Python callable. self._write calls sys.stdout.buffer.write() in BaseCGIHandler, using gopy's file object.