Expose your ML model via a simple API in Python

As data scientists, it is important that we have a method of sharing the insight from our models. In this post, I am going to show you how to create a super simple API, whereby the customer can pass URL parameters to extract data, generated by a Python function. Before we get started, make sure you have Flask installed (pip install Flask).

The first example I am going to look at is as below. Here, we are simply allowing the user to hit our API via a URL. When they do so, they will get the response provided by the Python function (in this case, the string ‘yo’). So, when the user goes to 127.0.0.1:5000/welcome, that is the response they will get.

NOTE: run the file with FLASK_APP=app.py flask run and kill the process with sudo fuser -k 5000/tcp (where 5000 is the port being used).

#import the flask class
from flask import Flask

#create a new instance of the class
app = Flask(__name__)

#route() decorator tells flask which URL should trigger the function
@app.route('/welcome/')


def welcome():
    return 'yo'

app.run()
    

Here is the reponse:

Now, let’s increase the usefulness a little bit. Now we are going to allow the user to pass their own name into the URL. So, when the customer visits 127.0.0.1:5000/theirname, they will get a response ‘yo theirname’.

from flask import Flask
app = Flask(__name__)

@app.route('/<string:name>/')
def hello(name):
    return "yo " + name

app.run()

Finally, let’s do something really useful. Now I am going to return customer information from a database (Pandas Dataframe in this case – for simplicity).

As you can see, I have defined a dataframe (df), which contains the details of two users. Now, if the URL 127.0.0.1:5000/firstname/lastname is visited, it will return the first name, last name, town and age for that customer.

This is super useful. Imagine that you create a customer happiness score every day. You could produce that score and load it into a database. When a customer makes contact, the customer service team can quickly request the customers happiness score, simply by providing the customer ID. This makes the data much more accessible & can be integrated into many systems and use-cases.

import pandas as pd
from flask import Flask

app = Flask(__name__)

users = [['bob', 'smith', 'london', 22], ['carl', 'liners', 'manchester', 44]]
df = pd.DataFrame(users)
df.columns = ['name', 'last', 'town', 'age']


@app.route('/<string:name>/<string:last>')
def hello(name, last):
    output = df.loc[(df['name'] == name) & (df['last'] == last)]
    return str(output.values.tolist())

app.run()

When we deploy a new ML model, we can pickle the model definition:

import pickle
pickle.dump(clf, open('/home/pickled_model.pickle', 'wb'))

We can use this pickled file to make predictions via an API call, given passed input features. We can define our API as below.

from flask import *
import numpy as np
import pickle as p
import json

app = Flask(__name__)


@app.route('/api/', methods=['POST'])

def makecalc():
    #load the pickled model
    happinessModel = '/home/pickled_model.pickle'
    model = p.load(open(happinessModel, 'rb'))
    data = request.get_json()

    #make and return prediction
    prediction = np.array2string(model.predict(data))
    return prediction
    
app.run()

To call the API to make predictions we use the below. This will call the /api URL we’ve defined above & pass in a number of input features. These will be evaluated by the model & a prediction will be returned.

import requests
import json

#the API url
url = 'http://127.0.0.1:5000/api'

#the input features to the model
features = [[12.6, 8.1, 0.03, 42]]
json_features = json.dumps(features)

#make the HTTP post & print the response
headers = {'content-type': 'application/json', 'Accept-Charset': 'UTF-8'}
r = requests.post(url, data=json_features, headers=headers)

print(r, r.text)

We will talk about scaling the API deployment and performance considerations (including serialization approach) in a future article.

Kodey

One thought on “Expose your ML model via a simple API in Python

Comments are closed.