What is WSGI ?
If you’ve ever worked with Flask or Django, you’ve already worked with WSGI whether you knew it or not. But what is WSGI? And how does it drive Python web frameworks?
In this article, I’ll explain WSGI, why it’s needed, and demonstrate how to create your own WSGI-driven web server entirely from scratch with just Python’s standard library.
WSGI App Interface
def application(environ, start_response): ... return [b'response body']
- environ: a dictionary with HTTP request info (method, path, headers, etc.)
- start_response(status, headers): tells the server what the response looks like
- Return value: an iterable (usually a list of bytes) containing the response body
Step-by-step flow:
- Client opens http://localhost:8000/hello
- Your browser sends a GET
/hello
HTTP request to port 8000. - WSGI Server Receives It
- Python’s WSGI server (like
wsgiref.simple_server
) accepts the TCP connection. - Server Calls
application(environ, start_response)
- It creates the environ dict and provides a
start_response
callback.
- environ includes:
{ 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/hello', 'QUERY_STRING': '', … }
- Your WSGI App Processes It.
- You inspect the path, method, etc and prepare a response.
- You call :
start_response('200 OK', [('Content-Type', 'application/json')]) return [b'{"message": "hello"}'] WSGI Server Converts It to an HTTP Response
- WSGI Server Converts It to an HTTP Response
- It sends the response to the client:
HTTP/1.1 200 OK Content-Type: application/json {"message": "hello"}
Your browser shows {“message”: “hello”} on screen.
Creating a WSGI Server from Scratch
Let’s build a basic server that responds to a request to /hello
## app.py def application(environ, start_response): method = environ['REQUEST_METHOD'] path = environ['PATH_INFO'] query = environ['QUERY_STRING'] print("Client requested:", method, path, query) print("Environment variables:", environ) print("start_response function:", start_response) if path == '/hello': response = [b'{"message": "hello"}'] else: response = [b'{"error": "Not Found"}'] status = '200 OK' if path == '/hello' else '404 Not Found' headers = [('Content-Type', 'application/json')] start_response(status, headers) return response
## run.py from wsgiref.simple_server import make_server from app import application port = 8000 httpd = make_server('', port, application) print(f"Serving on port {port}...") httpd.serve_forever()
In your terminal you can run python run.py
and you’ll get an output like Serving on port 8000...
By diving into WSGI, you’re not only learning how requests are handled,
you’re learning about Python web framework design and the beauty of interface-based architecture. The complete specification exists in PEP 3333, and I recommend reading through it after you’ve created a simple WSGI app yourself. It’s brief, readable, and full of insight into what keeps Python’s web world going.
Top comments (0)