WSGI (Web Server Gateway Interface) standardizes how Python web servers forward requests to web frameworks such as Flask or Django. It separates application code from the server that runs it, avoiding framework-specific server interfaces. WSGI became the de facto Python web-application deployment standard after PEP 333 was accepted in 2004. section 9.2 section 9.2.1
A minimal WSGI application follows a simple request-and-response shape:
- Defines a Python function receiving an environment and a start_response callable. section 9.2.1
- Starts the response with a status and headers, then returns the response body as bytes. section 9.2.1
- Runs behind a production WSGI server such as Gunicorn rather than Flask’s development server. section 9.1.4
Serving a Flask endpoint
A Flask application can expose a database-backed /brands endpoint and run under Gunicorn with eight workers. The workers create eight database connections and can serve eight requests concurrently. A benchmark example returned about 551 requests per second, providing a practical basis for comparing Flask’s WSGI deployment with an asynchronous server. section 9.1.4
Listing 9.6 A WSGI application
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"WSGI hello!"]
Inspect the minimal WSGI application: it accepts the environment and response starter, sends a 200 response, and returns a byte-string body. section 9.2.1
WSGI’s simplicity is also its boundary. Its specification predates asyncio, provides no await point, and supports only request/response lifecycles. It therefore cannot handle asynchronous workloads or long-lived protocols such as WebSockets; ASGI redesigns the interface around coroutines for those needs. section 9.2 section 9.2.1

