Our Flask API Template Code


In the previous chapter, we created a Web App that's accessible via the web browser. Pretty cool! but what if we wanted to call this API from different Apps e.g. a Native Android or iOS App?


Let's turn it into RESTful API that returns simple JSON responses encapsulating the results.

NOTE: A RESTful API is an application program interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data.


Step 1: Firstly, install Postman to test our API

Step 2: Our Flask API Code

import os
from flask import Flask, flash, request, redirect, url_for, jsonify
from werkzeug.utils import secure_filename
import cv2
import numpy as np
import keras
from keras.models import load_model
from keras import backend as K

UPLOAD_FOLDER = './uploads/'
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg'])
DEBUG = True
app = Flask(__name__)
app.config.from_object(__name__)
app.config['SECRET_KEY'] = '7d441f27d441f27567d441f2b6176a'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

def allowed_file(filename):
	return '.' in filename and \
		   filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/', methods=['GET', 'POST'])
def upload_file():
	if request.method == 'POST':
		# check if the post request has the file part
		if 'file' not in request.files:
			flash('No file part')
			return redirect(request.url)
		file = request.files['file']
		# if user does not select file, browser also
		# submit an empty part without filename
		if file.filename == '':
			flash('No selected file')
			return redirect(request.url)
		if file and allowed_file(file.filename):
			filename = secure_filename(file.filename)
			file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
			image = cv2.imread(os.path.dirname(os.path.realpath(__file__))+"/uploads/"+filename)
			color_result = getDominantColor(image)
			dogOrCat = catOrDog(image)
			#return redirect(url_for('upload_file',filename=filename)), jsonify({"key":
			return jsonify({"MainColor": color_result, "catOrDog": dogOrCat} )
	return '''
	<!doctype html>
	<title>API</title>
	<h1>API Running Successfully</h1>'''

def catOrDog(image):
	'''Determines if the image contains a cat or dog'''
	classifier = load_model('./models/cats_vs_dogs_V1.h5')
	image = cv2.resize(image, (150,150), interpolation = cv2.INTER_AREA)
	image = image.reshape(1,150,150,3) 
	res = str(classifier.predict_classes(image, 1, verbose = 0)[0][0])
	print(res)
	print(type(res))
	if res == "0":
		res = "Cat"
	else:
		res = "Dog"
	K.clear_session()
	return res

def getDominantColor(image):
	'''returns the dominate color among Blue, Green and Reds in the image '''
	B, G, R = cv2.split(image)
	B, G, R = np.sum(B), np.sum(G), np.sum(R)
	color_sums = [B,G,R]
	color_values = {"0": "Blue", "1":"Green", "2": "Red"}
	return color_values[str(np.argmax(color_sums))]


if __name__ == "__main__":
	app.run()

Using Postman (see image above and the corresponding numbered steps below:

  1. Change the protocol to POST

  2. Enter the local host address: http://127.0.0.1:5000/

  3. Change Tab to Body

  4. Select the form-data radio button

  5. From the drop-down, select Key type to be file

  6. For Value, select one of our test images

  7. Click send to send our image to our API

  8. Our response will be shown in the window below.

The output is JSON file containing:

{
    "MainColor": "Red",
    "catOrDog": "Cat"
}

The cool thing about using Postman is that we can generate the code to call this API in several different languages:

See blue box to bring up the code box:

Code Generator

Now that you've got your Flask API and Web App working, let's look at deploying this on AWS using an EC2 Instance.