# Deploy Your Python Functions as a REST API

This tutorial demonstrates how to deploy an arbitrary python function as an api with Bluemix and Flask — complete with clean, intuitive Swagger API documentation. Our python function will be a simple implementation of the Sieve of Eratosthenes, which takes one integer parameter `n` and returns all primes `p` such that `p <= n`.

While completing this tutorial, you will:

• Create an algorithm (or some arbitrary function) using Notebooks in DSX
• Persist the function
• Develop a RESTful API with Swagger documentation using Flask
• Deploy your API to Bluemix

### Implementing the “Sieve of Eratosthenes”

First, we’ll need to create a folder which will contain all of the files needed for our application. I’ll name mine `sieve`.

``!mkdir sieve``

Change into that directory and we’ll get started.

``cd sieve``

The Sieve of Eratosthenes is an ancient prime number sieve which, roughly, finds all the primes up to a given upper bound by striking multiples from the list of candidate primes. The algorithm looks like this:

Let’s write the function in pure python. The exact implementation is not the focus of this article, but it is cool to think about.

`def Eratosthenes(upper_bound):    prime = [True] * upper_bound         for p in range(3, upper_bound, 2):        if p > (upper_bound**.5):            break        if prime[p]==True:            for i in range(p * p, upper_bound, 2 * p):                prime[i] = False        return [2] + [p for p in range(3, upper_bound, 2) if                prime[p]]`

Testing,

``Eratosthenes(22) # [2, 3, 5, 7, 11, 13, 17, 19]``

We can use some built-in Jupyter magic to write files. We’ll put our function in this file for use later in the application. You can define as many functions as you’d like in this file.

To write, simply prepend this line to the code cell that we want to write `%%writefile <file_name>`

We’ll name this `prime_sieve.py`.

``%%writefile prime_sieve.py`def Eratosthenes(upper_bound):    prime = [True] * upper_bound         for p in range(3, upper_bound, 2):        if p > (upper_bound**.5):            break        if prime[p]==True:            for i in range(p * p, upper_bound, 2 * p):                prime[i] = False        return [2] + [p for p in range(3, upper_bound, 2) if                prime[p]]`

We’ll save this function into a file, so we can make use of it later.

### Develop a RESTful API

We’ll use a few tools to develop the API, like Cloud Foundry and Flask. This part of the tutorial is an expansion of a previous guide. From within a Notebook, we can write files and execute shell commands, which means that we can develop the app entirely within DSX notebooks.

``%%writefile my_flask_app.py from flask import Flask, Response, jsonify from flask_restplus import Api, Resource, fields, reqparse from flask_cors import CORS, cross_origin import os ``
``# the app app = Flask(__name__) CORS(app) api = Api(app, version='1.0', title='APIs for Python Functions', validate=False) ns = api.namespace('primality', 'Returns a list of all primes below a given upper bound') ``
``# load the algo from prime_sieve import Eratosthenes as algo ``
``''' We import our function `Erasosthenes` from the file prime_sieve.py. You create all the classes and functions that you want in that file, and import them into the app. ''' ``
``# model the input data model_input = api.model('Enter the upper bound:', { "UPPER_BOUND": fields.Integer(maximum=10e16)}) ``
``# the input data type here is Integer. You can change this to whatever works for your app. ``
``# On Bluemix, get the port number from the environment variable PORT # When running this app on the local machine, default to 8080 ``
``port = int(os.getenv('PORT', 8080)) ``
``# The ENDPOINT @ns.route('/sieve') ``
``# the endpoint class SIEVE(Resource):     @api.response(200, "Success", model_input)       @api.expect(model_input)    def post(self):        parser = reqparse.RequestParser()        parser.add_argument('UPPER_BOUND', type=int)        args = parser.parse_args()        inp = int(args["UPPER_BOUND"])         result = algo(inp)         return jsonify({"primes": result}) ``
``# run if __name__ == '__main__': app.run(host='0.0.0.0', port=port, debug=False) # deploy with debug=False``

### Supporting Documents

We’ll need to include some other files in order for our api to behave properly when we try to deploy the app to Bluemix. These files are:

• `manifest.yml`, this includes basic information about your app, such as the name and memory
• `setup.py`
• `README.md`
• `requirements.txt`
• `Procfile`

We’ll run the following in different cells to create these files.

``%%writefile manifest.yml --- applications: - name: PRIMALITY_UNIQUE - random-route: true - memory: 256M``
``%%writefile Procfile web: python my_flask_app.py``
``%%writefile README.md "Getting Started with Python Algos on Bluemix"``
``%%writefile requirements.txt Flask==0.11.1 cloudant==2.4.0 flasgger==0.6.4 Flask-Cors==3.0.2 Flask-RESTful==0.3.6 flask-restplus==0.9.2 gevent==1.2.1``
``%%writefile setup.py """ Hello World app for deploying Python functions as APIs on Bluemix """ # Always prefer setuptools over distutils from setuptools import setup, find_packages from codecs import open from os import path here = path.abspath(path.dirname(__file__)) with open(path.join(here, 'README.md'), encoding='utf-8') as f:    long_description = f.read() ``
``setup( name='primality_test', version='1.0.0', description='Running Python apps on Bluemix', long_description=long_description, url='https://github.com/IBM-Bluemix/python-hello-world-flask', license='Apache-2.0' )``
``%%writefile LICENSE """Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION ..."""``

### Deploy to Bluemix

Now, we’ll deploy the application to IBM Bluemix. To accomplish this, you’ll need a Bluemix Account. For more information on this part of the tutorial, we have some helpful documentation on deploying an app after it’s been created.

At this point in the tutorial, we have written all of the files needed for our app to run. In order to deploy to Bluemix (and retain the most felixibility when it comes to debugging, etc), I suggest that you copy this notebook and run all the previous cells. If you naviagte to `Kernel` and select `Restart & Run all`, this will happen automatically. Then, in your local directory, you'll have all the necessary files to proceed to these next steps.

One alternative is to create the above files yourself with your favorite text editor. If this is the case, then remove the `%%writefile` magics from the top of the code cells.

Ok, let’s deploy this app. You’ll need basic familiarity with the command line for best results.

• Install Cloud Foundry command line. This open source service works with Bluemix to deploy apps.
• Open the terminal or command prompt.

Mac — Click on the finder icon in the top right, search for terminal and open that

Linux — Depends on the distro, but you probably know where it is. In the menu look for accessories.

Windows — Click the start button, search for cmd, open.

• Log in to Bluemix by running the following command

`cf login -a https://api.ng.bluemix.net`

• Push the app!

`cf push <my_app_name>`

Replacing your app name with the name of app in the `manifest.yml` file. Make sure your app name is unique.

You should run `cf apps` to check the status of your application.

That’s it!

### Testing the API

``import requests``

& read the docs!

More seriously, you’ve created the docs yourself.
Take a look by navigating to the url.

Shoutout to Snehal Gawas for her patience and insight regarding this material!

Originally published at datascience.ibm.com on June 20, 2017.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.