I'm looking at the WSGI specification and I'm trying to figure out how servers like uWSGI fit into the picture. I understand the point of the WSGI spec is to separate web servers like nginx from web applications like something you'd write using Flask. What I don't understand is what uWSGI is for. Why can't nginx directly call my Flask application? Can't flask speak WSGI directly to it? Why does uWSGI need to get in between them?
There are two sides in the WSGI spec: the server and the web app. Which side is uWSGI on?
Okay, I think I get this now.
Because
nginx
doesn't support the WSGI spec. Technically nginx could implement theWSGI
spec if they wanted, they just haven't.That being the case, we need a web server that does implement the spec, which is what the
uWSGI
server is for.Note that
uWSGI
is a full fledged http server that can and does work well on its own. I've used it in this capacity several times and it works great. If you need super high throughput for static content, then you have the option of stickingnginx
in front of youruWSGI
server. When you do, they will communicate over a low level protocol known asuwsgi
."What the what?! Another thing called uwsgi?!" you ask. Yeah, it's confusing. When you reference
uWSGI
you are talking about an http server. When you talk aboutuwsgi
(all lowercase) you are talking about a binary protocol that theuWSGI
server uses to talk to other servers likenginx
. They picked a bad name on this one.For anyone who is interested, I wrote a blog article about it with more specifics, a bit of history, and some examples.
A traditional web server does not understand or have any way to run Python applications. That's why WSGI server come in. On the other hand Nginx supports reverse proxy to handle requests and pass back responses for Python WSGI servers.
This link might help you: https://www.fullstackpython.com/wsgi-servers.html
NGINX in this case only works as a reverse proxy, it receives the requests and proxies them to the application server, that would be UWSGI.
The UWSGI server is responsible for loading your Flask application using the WSGI interface. You can actually make UWSGI listen directly to requests from the internet and remove NGINX if you like, although it's mostly used behind a reverse proxy.
From the docs:
WSGI is just an interface specification, in simple terms, it tells you what methods you should be implemented for passing requets and responses between the server and the application. When using frameworks such as Flask or Django, this is handle by the framework itself.
In other words, WSGI is basically a contract between python applications (Flask, Django, etc) and web servers (UWSGI, Gunicorn, etc). The benefit is that you can change web servers with little effort because you know they comply with the WSGI specification, which is actually one of the goals, as stated in PEP-333.