Deploying a REST API using Anaconda Enterprise¶
With Anaconda Enterprise, you can create functions or models that can be easily deployed so other data scientists can use them without having to add a web stack.
Rather than giving other data scientists your model, you can give them an interface to the model, which you can then update, improve and redeploy.
You should know how to deploy a project and how to use deployment tokens to share the deployment.
This example is based on the Scotch whisky recommendation engine and can also be found at the ae_scotches_api folder within the Anaconda Enterprise distribution.
Before you start¶
Make a scotch-recommending API¶
The original scotch classification data is from the Classification of whiskies page.
The data have been made public as a Python pickled dataframe.
In a terminal window, enter these commands to add the data to download to the project:
anaconda-project add-download FEATURES https://ibm.box.com/shared/static/2vntdqbozf9lzmukkeoq1lfi2pcb00j1.dataframe anaconda-project add-download SIM https://ibm.box.com/shared/static/54kzs5zquv0vjycemjckjbh0n00e7m5t.dataframe
Or add the following to the file
anaconda-project.yml:downloads: FEATURES: url: 'https://ibm.box.com/shared/static/2vntdqbozf9lzmukkeoq1lfi2pcb00j1.dataframe' SIM: url: 'https://ibm.box.com/shared/static/54kzs5zquv0vjycemjckjbh0n00e7m5t.dataframe'
And in a terminal window run:
anaconda-project prepare
Add the packages that your REST API will depend on:
anaconda-project add-packages pandas anaconda-project add-packages -c anaconda-enterprise anaconda-enterprise-web-publisher
Open a Jupyter Notebook, rename it to
Scotchesand load the data.import os import pandas as pd import pickle features_pickle = os.getenv('FEATURES', '2vntdqbozf9lzmukkeoq1lfi2pcb00j1.dataframe') # These ENV VARS were defined on add-download sim_pickle = os.getenv('SIM', '54kzs5zquv0vjycemjckjbh0n00e7m5t.dataframe') with open(features_pickle, 'rb') as pkl: features_df = pickle.loads(pkl.read()) with open(sim_pickle, 'rb') as pkl: sim_df = pickle.loads(pkl.read())
Add this code to be able to handle HTTP requests.
Define a global REQUEST JSON string that will be replaced on each invocation of the API.
import json REQUEST = json.dumps({ 'path' : {}, 'args' : {}, 'body': {} })
Import the Anaconda Enterprise
publishfunction.from anaconda_enterprise import publish
Create a function that will be available from the
/scotchesURL when deployed.@publish() def scotches(): names = sim_df.columns.tolist() return json.dumps(dict(names=names), indent=4)
To be able to run, add this to the file
anaconda-project.yml:commands: api: rest_api: Scotches.ipynb supports_http_options: true default: true default: notebook: Scotches.ipynb description: Run the notebook for local development variables: KG_FORCE_KERNEL_NAME: python3
Then you can execute:
anaconda-project run api
Now if you visit
http://localhost:8888/scotchesfrom within the editing session you will see the list of scotches.From an editing session terminal, execute:
curl localhost:8888/scotches
To deploy the project as an API, go to the Project menu and select the Deploy project tab. From the command drop-down, select the
apicommand.This deploys the notebook as an API which you can then query.
To query externally, create a token and find the url to the running project. You can do both from the deployment view of your project.
Go to the deployments menu and click on your deployed project. On the Advanced tab, find the url for the running project. Click the Generate button. This generates a long JWT token. A JWT token is a JSON Web Token, and JSON is JavaScript Object Notation.
Example using
curl:export TOKEN="<generated-token-goes-here>" # save long string of text in variable curl -L -H "Authorization: Bearer $TOKEN" <url-of-project>
The
-Loption tells curl to follow redirects. The-Hadds a header. In this case-Hadds the token required to authorize the client to visit that URL.You can also use Postman. Remember to include the authorization header.
You can specify the HTTP verb you want use to access the data:
@publish(methods=['POST']) def scotch_details(name): features = features_df.loc[name] return '{"features":%s}' % features.to_json()
If you do
curl -X POST -d name=Talisker 127.0.0.1:8889/scotch_detailsor POST to the platform, you can use the REST API to access data about the scotch named Talisker.If you deploy the project as described above you can add the
-X POSToption tocurlto access that function.