Creating an API with Flask

This is the second post in a series of three for the Chicago Python (ChiPy) Mentorship Program, if you’re in Chicago you should check it out:

Our objective

Deploy a TensorFlow model so people can send the model data and get predictions back.

Where we are

In the last blog post, I showed you how to take a TensorFlow model, Dockerize it, and deploy it to the cloud. We met our objective — but it isn’t practical because the TensorFlow API isn’t user friendly. In this blog post, I’ll show you how to create an Application Programming Interface (API) for the model, build a simple website using Flask, and let a user interact with the API via the website.

Here’s what our setup will look like in the end:

Why build our own API?

Take a quick glance at what a request looks like if we want to send data straight into the TensorFlow API.

There are almost 50 features in both x1 and x2! To make it more complicated, some features correspond to a rehabilitation outcome measures, and others correspond to a special mask that is applied to the data. It would be a nightmare for a person to try and create these requests in this format. How about something a little easier for someone to understand?

This may still be difficult to interpret if you aren’t familiar with the data, but trust me it’s much more readable than before. The score_t1 and score_t2 fields are a patient’s scores measured at time point #1 and time point #2, respectively. In this example, we have measurements for the Berg Balance Scale (BBS), the Functional Independence Measure for Walking, and the Functional Independence Measure for Stairs. All the user needs to do is list the outcome measure and the score. I’ll take care of the data cleaning with my API.

Why not just put the logic directly in the website instead of making the API standalone? Either way will work. But creating a standalone API will make it easier to test, update, and document what we are doing. We can also let users interact directly with the API, or plug the API into other applications.

Building the API

We’re building the API in Flask because it’s lightweight and simple to get started. This was my first time using Flask so I had to start with the basics. Here are a few of the tutorials I found helpful:

Here is the Flask application for our custom API. The SiameseAPI.classes module has our methods to clean the data.

We have a few different requests we can make with this API. The simplest is ping, which simply replies “Success” for a GET request, or echos back the data in a POST request. The outcomes request returns a list of all the possible outcome measures the user can enter along with some validation parameters. The predict request cleans and sends data to the TensorFlow API.

I’m using the flask_restplus package because it offers built in validation and integrates Swagger to create nice looking documentation.

Swagger automatically generates pretty API documentation.

The next step is to put our custom API on our server so we can access it from the web. Flask comes with a local development server, but this isn’t meant for production. To deploy our API we need an HTTP server to handle requests. I used Apache2 for this project and followed a great tutorial from DigitalOcean.

Let’s try asking our API what outcomes it supports:

Outcomes that our API accepts.

It works! We’ll see some examples with it making predictions when we make our website.

Creating a Flask website

People can use our custom API now, but most clinicians won’t know what to do with an API. Instead, we’ll make a web form that lets users input their data, sends the data to our custom API, and returns the results to the web page. Now that I have a bit of experience in Flask, I made a simple website:

Flask app for our website. Templates/static files not shown.

Add a little bit of CSS with Bootstrap and we have a website!

Our form to input data, and the model’s output.

Now we can enter a patients outcome measurements, and the model will return an improvement score. So much better than working directly with the TensorFlow API!

What’s next?

We have our bare-bones pipelines built, but there is a lot we can add to make our API and website more robust. It depends what we find most exciting in the next month, but here are some of the options:

  1. Launching our website
  2. Improved documentation (Swagger) and logging tools
  3. Accepting additional input types (e.g. CSV for batch processing)
  4. Unit testing and integration testing
  5. Automating deployment
  6. Improved error handling and validation
  7. Improved authorization and security settings

This is further than I ever thought I would make it in this program. Huge shout out to my mentor Will for all of his help, I would be nowhere close to where I am now without his help! Thanks for reading, part three coming soon.