Flask is a micro web framework written in Python. We first show how a simple service works, and then show how to load a model (e.g., based on pytorch) and serve it as well.
The key thing to see here are that the HTTP route /
is mapped directly to a function weather
. For instance, when someone hits localhost:5000
(5000 is the default unless specified in app.run()
below) the function weather
starts execution based on any received inputs.
# load Flask
import flask
from flask import jsonify
from geopy.geocoders import Nominatim
import requests
app = flask.Flask(__name__)
# define a predict function as an endpoint
@app.route("/", methods=["GET","POST"])
def weather():
data = {"success": False}
#https://pypi.org/project/geopy/
geolocator = Nominatim(user_agent="cloud_function_weather_app")
params = flask.request.json
if params is None:
params = flask.request.args
# params = request.get_json()
if "msg" in params:
location = geolocator.geocode(str(params['msg']))
# https://www.weather.gov/documentation/services-web-api
result1 = requests.get(f"https://api.weather.gov/points/{location.latitude},{location.longitude}")
result2 = requests.get(f"{result1.json()['properties']['forecast']}")
data["response"] = result2.json()
data["success"] = True
return jsonify(data)
# start the flask app, allow remote connections
if __name__ == '__main__':
app.run(host='0.0.0.0')
This service can be run by using the command python weather.py
(assuming that is the filename for the above script) locally. If the port 5000 is open, then this server will be accessible to the world if the server has an external IP address.
We can modify the above to serve the recommendation models we built earlier as follows:
from surprise import Dataset
from surprise.dump import load
from collections import defaultdict
import pandas as pd
import flask
def get_top_n(predictions, n=10):
# First map the predictions to each user.
top_n = defaultdict(list)
for uid, iid, true_r, est, _ in predictions:
top_n[uid].append((iid, est))
# Then sort the predictions for each user and retrieve the k highest ones.
for uid, user_ratings in top_n.items():
user_ratings.sort(key=lambda x: x[1], reverse=True)
top_n[uid] = user_ratings[:n]
return top_n
df = pd.read_csv('./movies.dat',sep="::",header=None,engine='python')
df.columns = ['iid','name','genre']
df.set_index('iid',inplace=True)
predictions, algo = load('./surprise_model')
top_n = get_top_n(predictions, n=5)
app = flask.Flask(__name__)
# define a predict function as an endpoint
@app.route("/", methods=["GET"])
def predict():
data = {"success": False}
# check for passed in parameters
params = flask.request.json
if params is None:
params = flask.request.args
if "uid" in params.keys():
data["response"] = str([df.loc[int(iid),'name'] for (iid, _) in top_n[params.get("uid")]])
data["success"] = True
# return a response in json format
return flask.jsonify(data)
# start the flask app, allow remote connections
app.run(host='0.0.0.0')
You can use the following request in the browser http://0.0.0.0:5000/?uid=196
or use the requests module.