Python is one of the most popular languages for building web applications. At the core of any production-ready Python web app is a robust web server that can efficiently handle requests at scale.
In this comprehensive guide, we will explore 9 battle-tested Python web servers and dig deep into their features, use cases, and best practices around deployment. Whether you are building the next viral web app or running complex analytics, there is a Python web server here that will fit your needs!
Understanding Python Web Servers
A Python web server provides the critical infrastructure to run Python web apps in production environments. It is responsible for:
- Listening for HTTP/HTTPS requests from clients like web browsers
- Routing requests to the appropriate Python web application based on URL rules
- Running the Python web app code to generate dynamic responses
- Returning responses like HTML/JSON to fulfill requests
- Handling parallel requests efficiently to ensure good throughput
Python web servers act as the gateway between the outside world and your Python web apps. They speak HTTP on one end and Python on the other end.
Python web server architecture (Image source: Geekflare)
WSGI vs ASGI – A Quick Comparison
When running Python web apps, servers will communicate with them using either the WSGI (Web Server Gateway Interface) or the newer ASGI (Asynchronous Server Gateway Interface). Understanding the difference is key to choosing the right server:
- WSGI processes requests sequentially. This can cause slow clients to block servers from working on other requests.
- ASGI supports asynchronous, non-blocking request handling. This improves concurrency and is better suited for modern web development needs.
So newer Python web frameworks like FastAPI tend to use ASGI, while traditional apps using Django or Flask run on WSGI servers.
Top Python Web Servers to Try
Without further ado, here is the list of 9 versatile, production-grade Python web servers:
1. Uvicorn – A Lightning-Fast ASGI Server
Uvicorn is an ultra-fast ASGI server optimized for lightening-fast response times. It is built on uvloop and httptools to handle thousands of concurrent requests efficiently.
Key Features
- Implements the ASGI specification for Python async web apps
- Supports HTTP/1.1 and WebSockets protocol
- High-performance architecture using asyncio and uvloop
- Tuned for very low latency responses
- Command-line interface for configuring deployments
- Framework-agnostic – works with FastAPI, Starlette etc.
To install Uvicorn:
pip install uvicorn
A basic usage example with FastAPI:
import uvicorn
if __name__ == "__main__":
uvicorn.run("myapp:app", host="127.0.0.1", port=8000)
Uvicorn best suits applications needing raw throughput for API responses or real-time communication. Its only downside is a lack of process management capabilities compared to servers like Gunicorn.
2. Gunicorn – A WSGI Workhorse for Python Web Apps
Gunicorn (Green Unicorn) lives up to its mythical name as a reliable WSGI server for taking Python web apps into production. It is a mature, battle-tested server used by many large apps running Django, Flask, and Pyramid apps.
Key Features
- Implements the WSGI interface for communicating with Python apps
- High-performance architecture for serving concurrent requests
- Advanced process management with auto-restart, zero-downtime deploys etc.
- Support for TLS, HTTP/2, proxies, and UNIX socket files out of the box
- Easy to integrate with Nginx for added flexibility
- Used extensively with Django
To install Gunicorn:
pip install gunicorn
Running a Flask app with Gunicorn:
gunicorn --bind 0.0.0.0:5000 wsgi:app
Gunicorn can effortlessly handle heavy traffic loads with support for worker processes/threads. It is the prime choice for taking WSGI-based Python frameworks like Django into production.
3. CherryPy – A Simple Yet Powerful Python Web Framework + Server
CherryPy allows building web apps with Python in a straightforward, object-oriented way. It is both a web framework and a self-contained web server unlike Django and Flask.
Key Features
- Full-stack Python web framework with integrated web server
- Does not need WSGI connectors or external web servers
- Multi-threaded for handling concurrent requests out of the box
- Built-in support for fast HTTP/1.1 compliant web server
- Straightforward API allowing developers to focus on their app
- Escaping chained callbacks lets developers write cleaner code
To install CherryPy:
pip install cherrypy
A CherryPy "Hello World" app:
import cherrypy
class HelloWorld(object):
@cherrypy.expose
def index(self):
return "Hello World!"
cherrypy.quickstart(HelloWorld())
CherryPy is great for smaller apps where you want to get up and running quickly without nitty-gritty server configuration. Its integrated architecture avoids complex WSGI/ASGI distinctions as well.
4. Daphne – ASGI Support for Django Apps
Daphne brings ASGI support to traditional Django applications with synchronous Python code. It allows them to benefit from the non-blocking concurrency model of ASGI under the hood.
Key Features
- Designed for use with Django asynchronous support
- Fully compliant with the ASGI 2.0 specification
- Supports HTTP/1.1, HTTP/2, and WebSockets protocols
- Automatic generation of HTTP error pages for client-side issues
- Easy to deploy behind application servers like Nginx
Installing Daphne:
pip install daphne
Typical usage with Django:
daphne my_project.asgi:application
Daphne unlocks additional performance for Django-based apps which can be invaluable for highly dynamic sites with traffic bursting at the seams.
5. Trio – An Async Framework Bouquet
Trio provides an entire ecosystem of libraries for handling async IO and concurrency in Python using async/await syntax. This includes several web toolkits as well:
Web Frameworks
- Hypercorn – An ASGI server along the lines of Uvicorn
- Muffin – An ASGI web framework for building async web apps
- Starlette – A lightweight ASGI framework by FastAPI creator
Other Libraries
- Trio WebSocket – WebSocket server based on Trio
- Httpx – Fully async HTTP client
The Trio ecosystem offers a complete solution for modern asynchronous web development in Python.
To install Trio and Hypercorn:
pip install hypercorn
pip install trio
An example Hypercorn server:
from hypercorn import Config
from hypercorn.trio import serve
async def app(scope, receive, send):
...
config = Config()
serve(app, config)
The Trio libraries provide a very developer-friendly way to build async Python web apps from the ground up.
6. Twisted Web – A Non-Blocking Web Server + Framework
Twisted is an event-driven networking framework supporting non-blocking asynchronous I/O. Twisted Web, a sub-project specifically targets web apps.
Key Features
- Performs asynchronous operations for fast, concurrent apps
- Comes with a WSGI server along with HTTP clients/servers
- APIs for tasks like managing TLS, authentication, headers etc
- Substantial ecosystem of related Python libraries/tools
- Well-organized, clean codebase focused on being Pythonic
To install Twisted on Linux:
sudo apt install python3-twisted
A simple Twisted web server:
from twisted.web import server, resource
from twisted.internet import reactor
class Simple(resource.Resource):
isLeaf = True
def render_GET(self, request):
return b"Hello, world!"
site = server.Site(Simple())
reactor.listenTCP(8000, site)
reactor.run()
Twisted Web is a great fit for highly asynchronous web services and provides powerful building blocks for custom servers.
7. Aiohttp – Asynchronous HTTP Client & Server
Aiohttp provides a versatile HTTP toolkit for building asynchronous Python web apps using asyncio.
It contains client and server implementations supporting features like WebSockets, connection pooling etc.
Key Features
- Client & server APIs for HTTP and WebSocket transports
- Supports HTTP/1.1 and HTTP/2 on the server side
- Async context managers for acquiring and releasing connections
- Middlewares and signals to handle events in HTTP lifecycle
- Integrated unit testing framework and debug toolbar
Install Aiohttp:
pip install aiohttp
A basic Aiohttp web server:
from aiohttp import web
async def handle(request):
name = request.match_info.get(‘name‘, "Anonymous")
text = "Hello {}".format(name)
return web.Response(text=text)
app = web.Application()
app.add_routes([web.get(‘/‘, handle)])
web.run_app(app)
Aiohttp allows crafting robust HTTP clients/servers for new age Python web apps using async/await for maximum throughput.
8. Tornado Web – Optimized for Long Connections
Tornado is another widely used asynchronous framework supporting non-blocking I/O in Python. It is well suited for long connection scenarios like WebSockets.
Key Features
- High scalability using non-blocking HTTP requests
- Lightweight enough to handle >50k concurrent connections
- Integrated support for WebSocket handshaking and data transfer
- Templating and authentication modules for web UI development
- Ability to offload work to background threads/processes when needed
- Large ecosystem of middleware, libraries and tools
Installing Tornado:
pip install tornado
A sample Tornado server response:
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
def make_app():
return tornado.web.Application([
(r"/", MainHandler),
])
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
Tornado is optimized for use cases like real-time analytics, chat platforms etc where hanging HTTP/WebSocket connections are commonplace.
9. Meinheld – For High Throughput WSGI Apps
Meinheld is a WSGI-based web server designed for maximizing throughput for Python apps. Its pipelining allows protocol parsing decoupled from application logic.
Key Features
- Implements WSGI using the meinheld.wsgi module
- Uses non-blocking sockets with pipelining for high throughput
- Greenlets minimize lock contention for solid concurrency
- Low memory footprint – avoids extra copies of data
- Compatible with Python WSGI frameworks like Django
Install Meinheld using pip:
pip install meinheld
Basic usage with a Flask app:
from meinheld import server
server.listen(("localhost", 5000))
server.run(flask.Flask(__name__))
Meinheld aims to wring out the maximum possible performance for traditional WSGI Python web apps.
Choosing the Right Python Web Server
With the wide variety of servers available, here is a concise guide on which ones work best for common scenarios:
Purpose | Recommended Servers |
---|---|
Maximizing throughput | Uvicorn, Meinheld |
Running WSGI apps | Gunicorn, Meinheld |
Running ASGI apps | Uvicorn, Hypercorn |
Adding concurrency to Django | Daphne |
Real-time apps w/ WebSockets | Tornado, Twisted |
Simple apps needing quick start | CherryPy |
Complete async web toolkit | Trio, Aiohttp |
I hope this detailed guide on Python web servers helped you understand the landscape and pick the right choice for your application needs! Let me know if you have any other feedback or server suggestions in the comments.