WSGI Concepts
When you run a Flask app, there’s always a “server” involved.
But your Flask code is just Python functions. So how does an HTTP request become a Python function call?
That bridge is WSGI.
What is WSGI?
Section titled “What is WSGI?”WSGI stands for Web Server Gateway Interface.
It’s a Python standard that defines a simple contract between:
- a WSGI server (Gunicorn, uWSGI, Waitress)
- a WSGI app (Flask app)
The goal: any WSGI server can run any WSGI-compatible Python web app.
The simplest WSGI mental model
Section titled “The simplest WSGI mental model”A WSGI server:
- Accepts an HTTP request from the network
- Builds an
environdictionary (details about the request) - Calls your Flask app like a Python callable
- Receives the response body iterator
- Sends bytes back to the client
flowchart LR C[Client] -->|HTTP| WS[WSGI Server] WS -->|environ + start_response| F["Flask (WSGI App)"] F -->|status, headers, body| WS WS -->|HTTP Response| C
Dev server vs WSGI server
Section titled “Dev server vs WSGI server”When you run:
flask run
Flask uses a development server (Werkzeug).
It is:
- fine for local development
- not designed for heavy production workloads
- not tuned for security/hardening
In production, you typically run Flask behind:
- Gunicorn (WSGI server) and often
- Nginx (reverse proxy for TLS, caching, static files, etc.)
Where does “WSGI app” live in Flask?
Section titled “Where does “WSGI app” live in Flask?”If you have:
from flask import Flask
app = Flask(__name__)app is a WSGI application callable.
WSGI servers point to it like:
gunicorn "app:app"
Meaning: import the module app.py, then use the app variable.
Why you should care
Section titled “Why you should care”Understanding WSGI helps you debug:
- “It works locally but not in production.”
- incorrect host/port binding
- reverse proxy headers (X-Forwarded-For)
- timeouts and worker model issues
pch.coffeeTagline
pch.coffeeCtapch.feedbackHeading
pch.feedbackSubheading