Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Gunicorn forward request to flask

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.

like image 529
neel Avatar asked Mar 07 '16 14:03

neel


People also ask

How do you integrate Gunicorn with a Flask?

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.

Does Flask need Gunicorn?

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.

How does Gunicorn handle multiple requests?

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.


1 Answers

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.

like image 194
wong2 Avatar answered Sep 20 '22 01:09

wong2