Can anyone describe the process of how Gunicorn
forward the request to Flask
internally
?
It would be great if someone explains each and every step involved in the process from receiving the request by Gunicorn to forwarding it to Flask and the reverse way.
Please keep in mind while explaining that I am a newbee in this area.
When you run the server via Gunicorn, you need to specify the module name and the variable name of the app for Gunicorn to access it. Note that the variable should be a WSGI callable object for e.g a flask app object. This is as per the definition in Gunicorn Docs.
Although Flask has a built-in web server, as we all know, it's not suitable for production and needs to be put behind a real web server able to communicate with Flask through a WSGI protocol. A common choice for that is Gunicorn—a Python WSGI HTTP server.
If each request takes 10 milliseconds, a single worker dishes out 100 RPS. If some requests take 10 milliseconds, others take, say, up to 5 seconds, then you'll need more than one concurrent worker, so the one request that takes 5 seconds does not "hog" all of your serving capability.
Gunicorn and Flask talks through WSGI, which has two sides: server side and the application side.
on the application(framework) side, we need to provide a callable, the simplest example:
def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
return ['Hello World']
the server will call this application and providing environment information and a callback function which is used to indicate start of a response. when the server get the response, it will return it to browser.
so, for gunicorn and flask:
from flask import Flask
app = Flask(__name__)
when you do this, you've actually got an WSGI compatible application, app
is a callable:
class Flask(object):
...
def __call__(self, environ, start_response):
"""Shortcut for :attr:`wsgi_app`."""
return self.wsgi_app(environ, start_response)
[source](https://github.com/mitsuhiko/flask/blob/master/flask/app.py#L1976)
and when you run gunicorn app:app
, you're telling gunicorn where to load your application, source
when a request comes, gunicorn parses it, construct a dict environ
, which is defined here, contains information like REQUEST_METHOD
, QUERY_STRING
etc, then call the application(a Flask object!) with it: app(environ, start_repsonse)
source, start_repsonse
is a callback in Gunicorn to get the reponse status and headers, and the return value of the app
call will be send as response body.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With