Deploying a Machine Learning Model Using a Flask Application + API

IV
Finastra Fintechs & Devs
5 min readApr 14, 2020
An infographic about API’s and how they are useful and versatile for businesses.

If you’re here, you’ve probably already read the NLP post that we published earlier. In this post I’m going to show you the next steps after creating a trained machine learning model: deployment using a flask application. We’re going to go one step further and show you how to connect and make a request to an API and push the model’s predictions.

What is a flask application and why do we need one?

In simple terms, a flask application is the bridge between having a machine learning model and using it — what good is a trained model if we can’t implement what we trained it for, right?

Using this thing called a flask application, we can load our trained model (in our case, our .pkl file) and use it to make predictions. The flask app, a file named app.py, hosts our model and has 2 routes: predict and payment.

The predict route will communicate with the gmail client and receive a POST request containing the email text. The email string will hit our model, which will return the model’s prediction. The payment route will communicate through a gmail browser extension that will push the payment data to an API. The API we will be using today is FusionFabric.cloud Payment Initiation API. For future reference, we will abbreviate to FFDC Payment API.

We start the file app.py with our imports:

# imports
from flask import Flask, request, jsonify
import traceback
import requests
from flask_cors import CORS
from NER import CRF_NER
import authenticate
import payments_api

Then we instantiate the application:

# API definition
app = Flask(__name__)
CORS(app)

Define our first route:

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

Create our prediction functions:

def predict():
if request.method == 'POST':
if crf:
try:
json_ = request.json
sentence = json_["email"]
result = c.query(sentence)
response = jsonify(result)
response.headers.add('Access-Control-Allow-Origin', '*')
response.headers.add('Access-Control-Allow-Headers', 'origin')

return response
except:
return jsonify({'trace': traceback.format_exc()})
else:
return jsonify({'error':'no model found'})
else:
return jsonify({'error': 'no get request handler'})

Now we define our second route and function:

@app.route('/payment', methods=['POST'])
def payment():
try:
json_ = request.json
a = authenticate.authenticate('config.csv')
response,token = a.get_token()
p = payments_api.payments_api(token,'POST')payload = p.sample_post
payload['debtorAccountId']['name'] = json_['accountB']
payload['creditor']['name'] = json_['accountA']
payload['instructedAmount']['amount'] = json_['amount']
response = p.connect_endpoint(payload)returnResponse = jsonify(response.text)return returnResponse
except:
return jsonify({'error': 'there was an error'})

Now at the end of app.py, we add in some last details:

if __name__ == '__main__':
port = 5000
model_filepath = 'crf_model_with_currency.pkl'
c = CRF_NER(model_filepath)
crf = c.load_model()
app.run(port=port, debug=True, ssl_context='adhoc')

When app.py executes, we can see that it loads our model, so we can use it to make predictions.

One of the ways we decided to use the predictions was to create a browser extension, and we created one for Gmail (click here for a tutorial we used!). The browser extension uses the predictions from the model to pre-fill a web form by parsing through the text in the email draft and it returns the tagged entities (amount, currency, accountA, accountB).

The model parses through the text and tags the entities. The sidebar shows the browser extension — if the model tags the wrong labels, we can simply edit them before we hit submit.

We didn’t fully automate this process — the user has the ability to edit the form after it has been pre-filled. This is because the model might not always make the correct prediction, there could have been a typo in the email, etc. So after reviewing that the information is correct, once the submit button is pressed, the Gmail client browser extension makes an HTTP request to the FFDC Payment Initiation API. This is what we defined in the second route and function.

In our second function, we have a line of code:

p = payments_api.payments_api(token,'POST')

And in our imports, you may have noticed:

import payments_api

This is a class that we created to help us process a request to the API credit transfer endpoint. Here, we take in an authentication token and have a function called connect_endpoint() which takes in the payload, our data, that we want to push to the endpoint.

class payments_api:    def __init__(self,token,method,additional_headers={},params = None):
self.token = token
self.endpoint_type = method
self.base_url = 'https://api.fusionfabric.cloud/payment/payment-initiation/v1/credit-transfer/international/initiate'
self.additional_headers = additional_headers
self.params = params
self.sample_post = {}

The last dictionary we left empty for brevity, but you can find sample contents of that dictionary here at the bottom of the page where it says Request Samples. Now back to the code..

We have another function inside the this class:

def connect_endpoint(self, payload):
self.url = self.base_url
headers = {
'Authorization': 'Bearer ' + self.token,
'Content-Type' : 'application/json'
}
for key in self.additional_headers.keys():
headers[key] = self.additional_headers[key]
stringified_payload = json.dumps(payload)
response = requests.request(self.endpoint_type, self.url, params=self.params, data=stringified_payload,headers=headers)
return response

This function returns an HTTP response along with its status code, such as 200 OK.

This Payments API is one of 11 APIs that Finastra has available for payments (see the full list here!). In addition to payments, we also offer APIs for the other areas of finance: Retail Banking, Corporate Banking, Lending, and Treasury and Capital Markets.

FusionFabric.cloud (abbreviated FFDC) is Finastra’s open developer platform for financial solutions. Using this platform, developers can build apps, collaborate, leverage resources, and monetize applications. In just a few weeks, my teammates and I were able to leverage this platform to fully demonstrate a proof-of-concept that assists financial services — just imagine how useful this could be to for production level business solutions! The word out on the street is that the new wave of open banking and decentralization is going to revolutionize the finance industry — I guess we’ll have to just wait and see.

Here’s an infographic that highlights some key features of Open Banking solutions.

I’d like to end this off introducing you to my teammates! The three of us took a proposed idea into proof-of concept and gradually worked our way up — we even have versions where we host on Microsoft Azure instead of using a flask application.

Adam Lieberman has a degree in mathematics and a masters in machine learning both from Georgia Tech. He leads the data science team at Finastra and is passionate about taking proof of concept projects and turning them into real-world, production solutions.

Josh Abelman is a software engineer in Finastra’s Innovation Lab. He works with the data science team to help bring models to life. His main interests are full-stack development and deep learning.

Thanks for reading, bye for now!

--

--

IV
Finastra Fintechs & Devs

Advancing the #FinTech industry using the latest AI/ML techniques.