How to create a REST API in Python using the Flask Microframework

Published Dec 27, 2017Last updated Apr 24, 2018


IMAGE CREDIT: Edmond Atto

An API (Application Programming Interface) can be defined as a set of clearly defined methods of communication between various software components.
Wikipedia

Flask on the other hand is a Python micro-framework that is used to develop web applications.

I built an API around an application called BucketList. The application enables a user to Create, Read, Update and Delete(CRUD) a bucket and the items within. In this article, I will describe the process I went through while developing the API and I will share a few code snippets strictly for example purposes. The code lives on Github and you can find it here.

The initial folder structure

api/ 
  |- app 
    |- auth 
    |- bucket 
    |- bucketitems 
    |- __init__.py 
    |- config.py 
    |- models.py 
    |- views.py 
 |- .gitignore 
 |- manage.py 
 |- run.py 
 |- requirements.txt 
 |- README.md

Above is my initial folder structure with api as the name of the application folder. The application logic resides in the app folder. Within the app folder there are three flask Blueprints, auth, bucket and bucketitems.

  • The auth blueprint contains the logic for application authentication and authorization
  • The bucket blueprint contains the logic for carrying Bucket CRUD operations.
  • The bucketitems blueprint contains the Bucket Items CRUD operations.

Exploring the file structure

  1. The __init__.py file contains the code for setting up the Flask application and registering the different Blueprints onto the application instance.
  2. The config.py file contains the different application configuration options which are testing, development and production. A different configuration is used depending on the environment in which the application is being run.
  3. The models.py file contains the different database models, users , buckets , bucketitems and the other models.
  4. The views.py contains the application wide routes.
  5. The .gitignore file contains the files that should not be added and tracked by the Version Control System(VCS) in this case Git.
  6. The manage.py file contains the application commands defined by you and made available by the Flask-Script extension.
  7. The requirements.txt file contains a reference to the application extensions and their versions. It is generated by running pip freeze > requirements.txt in the terminal.
  8. The README.md markdown file contains any description or information the developer makes available to the application users.

Test Driven Development

Test Driven Development(TDD) is a good practice when writing code. From my experience, it enables you think about the different aspects of the code functionality you are going to write and then come up with tests upfront before writing the feature functionality. Later on, you write the code and make sure that your previously failing tests pass. In case you change something in your code later, just run your tests and make sure nothing is broken. If they fail, then you know you have a bug to fix.

During the development of the API, I practiced TDD in some parts of the implementation. I later on continued and wrote tests covering at least 97% of all the code I wrote.

I used a Flask extension called Flask-Testing for writing all my application tests and I run the tests using a Python package called nose.


Token Based Authentication

The entire API authentication is built using a Json Web Token(JWT) based authentication system. JWT tokens provide a way of representing claims securely between two parties.

I used a python package called Pyjwt to encode and decode JWTs. When a user signs up or logs in, a token is assigned to them. This token expires after a given period of time or when the user logs out. When the user logs out, the token is invalidated, blacklisted and added to the blacklisted table in the database.

Since most of the API resources should only be accessed by authenticated users. I created a view decorator to be used on all routes that require an authenticated user.


Version Control

Version control as the name suggests, is all about controlling the different versions of the application during its development. Git is probably the most common and easiest version control tool to use when developing an application.

For the most part of development, I used(simulated) the Gitflow-Workflow. This workflow suggests that you create a develop branch off of the master branch and then create feature branches off the develop branch. The most important take way from this workflow is that the master branch should only contain ‘working’ code (code ready for release).

I also used Github Pull Requests(PR) so that my colleagues could review and comment on my code before I could merge it into the develop branch.


Data Persistence

As you know, most applications have to store user data in one way or the other. My API uses a postgresql database to persist the users’ data, specifically the user sign-in credentials, buckets and their items.

I used the Flask-Sqlalchemy extension to interact with the database. This basically enabled me to create the user, bucket and bucket-items model classes.

I also used the Flask-Migrate extension to create migrations for the database. Database migrations are like ‘version control’ for the database schema.

I used another extension Forgerypy to create dummy data for the application so that I could test out some features such as api-pagination that somewhat require much data.


Configuration

The API runs within three environments development , testing and production . In order to switch configurations between these different environments, I created a config.py file to handle all the different variables for every environment.

The active configuration is managed by the APP_SETTING configuration variable which is set to one of the three configurations depending on the environment.


Continuous Integration

I am new to the whole concept of continuous integration (CI) so I am going to only point out one tool (Travis CI) which I used during development.

I used Travis to run my builds whenever I pushed a commit, branch or made a PR. Travis also enabled me through the .travis.yml file to set up a postgres database so that when it ran the tests no error would be encountered for the tests that required a database. After successfully running the tests, the coverage details were sent to coveralls for further analysis.


Adding Badges to your repository

Repository badges guided and also motivated me during development. I added the Travis, coverage(coveralls), BetterCode and Codacybadges.

  • The Travis badge showed whether the build had passed or failed
  • The coverage badge showed the test percentage coverage
  • Bettercode showed the quality of the code based on ten attributes
  • The codacy badge showed the general quality of the code.

API Documentation

Most of the API’s I have used before have some sort of guide on how to use them and this made it easy and simple for me to test them out. I felt the need to return the favor by writing documentation for my API using a tool called Apiary and hosted it with the API as the homepage you can try it out it’s live.


Final folder structure

A lot changed during development and so did the application folder structure. At the end of development my folder structured has changed to this below.

api/ 
  |- app 
    	|- auth 
        |- bucket 
        |- bucketitems 
        |- docs 
        	|- static 
            	|- js 
                	|- apairy.js 
                |- favicon 
            |- templates 
            	|- docs 
                	|- index.html 
        |- __init__.py 
        |- config.py 
        |- models.py 
        |- views.py 
  	|- migrations 
    |- tests 
    |- .coveralls.yml 
    |- .travis.yml 
    |- run.py 
    |- Procfile 
    |- .gitignore 
    |- manage.py 
    |- requirements.txt 
    |- README.md

I added a docs blueprint to handle everything concerned with the API documentation including the apiary.js file that contained the embed code for the Apiary API documentation, site favicon and the index.html file.

The tests folder contained the application tests, migrations folder contained the model migration files and the Procfile contained the Heroku configurations.

Hosting

Finally, after development I had to deploy my API. I chose to host my application with Heroku which is a platform that enables one to host applications written in a variety of programming languages.

The Procfile in the above folder structure contained the configurations that enabled Heroku run the application. These configurations included the gunicorn server config and config to create the database tables.

You can find my Post about Hosting this API on Heroku here .

The API is available here you can test it out.

All the code is hosted here.

Discover and read more posts from John Kagga
get started