Flask, Docker & React: Microservices done right Pt. 1

Introduction

Just to be clear, this is my attempt at doing things right. Considering the nature of the beast that is containerisation and microservices, this is no more than my understanding of best practices around this space. This will also give me an opportunity to be criticised from the wider community (assuming anyone actually reads this) and hopefully learn from my mistakes.

I hope to treat this as a multi-series post whereby each week I attempt to improve on my knowledge of flask, docker etc… and use this medium to share my learnings and findings.

I would also like to preface this by saying I am by no means an expert in flask, docker, nor React. In fact, python is my go to hobby language – Java and it’s related tools is how earn my dough – but is something I’ve always a had a keen interest in learning along with React and Docker.

Getting Started

This part of the series uses the following tools and technologies:

Part 1.
  • Intellij (optional)
  • Python 3.6.1
  • Flask v0.12.2
  • Flask-Script v2.0.5

Objectives

  1. Develop a restful API with Flask
  2. Utilise Flask Script to start and stop the app.

To surmise, by the end of this post, we should have one endpoint
GET /matrix

which should return the following JSON response:
{"hello":"world"}

Setting up environment

Create a new folder for the app (it shall be named matrix), use virtualenv to create an isolated python environment, install flask and flask-script (a tool used to start and stop flask apps).

$ mkdir matrix && cd matrix
$ mkdir project
$ python3.6 -m venv env
$ source env/bin/activate
(env)$ pip install flask==0.12.2
(env)$ pip install flask-script==2.0.5

Intellij (my IDE of choice) will require the python plugin installed first:

To get started in intellij, open up the directory:
File -> New -> Project From Existing Sources -> Select the matrix directory -> choose all the defaults

Next we need to make Intellij aware of our isolated virtualenv environment:
From the projects context menu: Open Module Settings -> (Under Platform Settings) SDKs -> (plus sign) Add Python SDK -> Add Local -> Navigate to and select ..env/bin/python3.6

Add an __init__.py file to the "project" directory and configure the first endpoint:

# project/__init__.py

from flask import Flask, jsonify

# instantiate the app
app = Flask(__name__)


@app.route('/matrix', methods=['GET'])
def matrix():
    return jsonify({
        'hello': 'world'
    })

Next we’ll create a file to set up the manager instance – a script used to help manage our app.

# manage.py


from flask_script import Manager

from app import app

manager = Manager(app)

if __name__ == '__main__':
    manager.run()

We should now be able to start the server and navigate to http://localhost:5000/matrix to see a response. To start the server, run the following in the terminal:
(env)$ python manage.py runserver

And the response:

{
  "hello": "world"
}

The next set of steps is to enable hot reload of our app. Begin by killing the server and adding new file called config.py to the "project" directory:

# project/config.py

class BaseConfig:
    """Base configuration"""
    DEBUG = False
    TESTING = False


class DevelopmentConfig(BaseConfig):
    """Development configuration"""
    DEBUG = True


class TestingConfig(BaseConfig):
    """Testing configuration"""
    DEBUG = True
    TESTING = True


class ProductionConfig(BaseConfig):
    """Production configuration"""
    DEBUG = False

And update the __init__.py file to pull in the newly created dev config when the app starts up:

# project/__init__.py

from flask import Flask, jsonify

# instantiate the app
app = Flask(__name__)

# set config
app.config.from_object('project.config.DevelopmentConfig')


@app.route('/matrix', methods=['GET'])
def matrix():
    return jsonify({
        'hello': 'world'
    })

Re-running the app should trigger flasks debug mode allowing for automatic code re-deploys when any changes have been detected:

(env) ➜  matrix python manage.py runserver
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 903-022-126

Finally, we’ll create a requirements.txt file in the projects root in order to help manage the app’s dependencies. Firstly, kill the app once more and run the following command in the terminal:

(env) ➜  matrix pip freeze > requirements.txt

Init a git repo and commit your code.

Update 1: 17/07/2017

Example code for this post can be found here.

Leave a Reply

Your email address will not be published. Required fields are marked *