Flask Primer

Flask is a REST engine written in Python. Pretty much like Django, however much simpler. It is very suitable for exposing microservices, with a small number of controllers etc. Here is a sample of how to do stuff with Flask.

Import: to use it, you have to install the package with pip, the packge name is flask;

The g object

The g object is accessed with flask.g and it is an object that is isolated in a request / response cycle. You add stuff in it, then get it wherever you need it and then read the previously set attributes. It is like a dictionary, so update it with whatever key / value pairs you want.

One very good example: the general configuration data is one thing, the db connection pool is another thing that can be set

Hello world sample with annotation

Here is an example of an application with a controller associated with that flask application instance

import flask


def start():
    app = flask.Flask(__name__)

    @app.route('/', methods=['GET'])
    def alfa():
        return "the response"

    app.run('0.0.0.0', 8080)


if __name__ == '__main__':
    start()

So you see the following:

  • application is defined
  • @app is related to the flask application stored in variable app, different variable, different annotation
  • @app.route registers route “/” for method GET for the function alfa

In the end all the requests on the server at port 8080 shall be processed by this function

Hello world sample without annotation

In the above example there is a small problem: you need to define the function alfa inside a context that has all defined, app, etc. This is an issue: a project with 100 controllers, each exposing different route etc cannot be practically devised in this way: at least each controller function should be defined in a different file, to look more elegant etc. OK. So how do you programmatically add a route to a flask application, well, in this way:

import flask


def alpha():
    return "the response"


def start():
    app = flask.Flask(__name__)

    app.add_url_rule('/', 'root', alpha, methods=['GET'])

    app.run('0.0.0.0', 8080)


if __name__ == '__main__':
    start()

Simple: function alpha is defined elsewhere; it is now in our file for simplicity but typically for bigger applications it is moved in a totally different file.

Setting response status code and headers

In the method alpha defined above, instead of merely returning a string, better create a response from flask and then modify the state of this response by adding headers and overriding the status code – which normally is 200, here:

def alpha():
    resp = flask.Response("the response")
    resp.headers.update({'Content-Type': 'text'})
    resp.status_code = 206

    return resp

Before request and after request

Many times you need to have something done before any request is being transferred to the route processors. A good example is either to get the actual start of the transaction for metrics, or to get the g object and put some stuff in it to be available for downstream processing.

This is how you define a function that is used before any request:

def call_before_request():
    print('before request')


def call_after_request(response):
    print('after request')
    return response


def start():
    app = flask.Flask(__name__)

    app.add_url_rule('/', 'root', alpha, methods=['GET'])
    app.before_request_funcs[None] = [call_before_request]
    app.after_request_funcs[None] = [call_after_request]

    app.run('0.0.0.0', 8080)

Please note:

  • you can use very well annotation before_request and after_reqeust but again, the functions that are implemented for this purpose must be defined in a context where app is easy to access
  • very important, the call after request gets the http response as a parameter and must return this response (after you did or you did not changes to it) or else you get http code 500
  • definitely the fact that we wrote some print statements inside those function is only for demo purposes; normally you use either logging or you just don’t print stuff from those functions.