DEV Community

Hasan Faraz Khan
Hasan Faraz Khan

Posted on

Understanding WSGI and building a simple web server in Python

What is WSGI ?

captionless image

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'] 
Enter fullscreen mode Exit fullscreen mode
  • 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:

  1. 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.
  1. environ includes:
{ 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/hello', 'QUERY_STRING': '', … } 
Enter fullscreen mode Exit fullscreen mode
  1. 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 
Enter fullscreen mode Exit fullscreen mode
  1. 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"} 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode
## 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() 
Enter fullscreen mode Exit fullscreen mode

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)