Deployment API

Prerequisites

You need to create a deployment from the deployment view. The deployment view will show you the information you need to use the Deployment API:

  • All the input and output names (and shapes) of your model

  • The URL and deployment token to use for your requests

  • The status of the deployment. Make sure it is enabled, or requests will be denied

Structure of a prediction request

To submit examples, you use a HTTP client to send a POST request to the URL indicated on the deployment page that you want to use.

You can send such requests by using cURL, Python (e.g., with the requests package), or our sidekick tool for Python. Other packages, languages, or tools may also be used if they follow the API specifications.

Header

Your request must always have a header, which is a JSON formatted string. The header must contain the deployment token, which is used to authenticate the request.

It must also contain the format of the request’s payload. The Deployment API only accepts JSON formatted payloads, so the header looks like this:

{
    'Authorization': 'Bearer <token>',
    'Content-Type': 'application/json'
}

where you replace <token> with the deployment token that you copy from the Deployment view.

Payload

To submit examples, you attach them in the payload of the request. The payload is also a JSON formatted string, which contains the features of one or more examples to be evaluated.

The structure of the JSON payload has a single key called rows, associated with a comma-separated array of examples.
Each example is a collection of key-value pairs, where the keys are the names of the input features of the model.

For instance, if your deployment parameters look like this in the Deployment view:

The parameter list of a deployment.

Then the JSON payload to submit 4 examples will look like this:

{
    "rows": [
        {"Type": "animal", "Sound": "miaow", "Size": 0.4},
        {"Type": "animal", "Sound": "woof", "Size": 1.2},
        {"Type": "vehicle", "Sound": "tchoo", "Size": 80},
        {"Type": "vehicle", "Sound": "vroom", "Size": 3.2}
    ]
}

Note that you don’t need to have line breaks inside your payload, and it could look like this:

{"rows": [{"Type": "animal", "Sound": "miaow", "Size": 0.3},{"Type": "animal", "Sound": "woof", "Size": 1.2},{"Type": "vehicle", "Sound": "tchoo", "Size": 80},{"Type": "vehicle", "Sound": "vroom", "Size": 3.2}]}

Response

Once you send the request with a valid header and payload, your model will process the examples submitted and return predictions for each of them.

The predictions are given as a JSON formatted text string and their structure is identical to that of the payload.
The predictions in the rows array contain a key-value pair using the Name of each Output feature listed in the Deployment view.

There can be more than one output feature if the model Target block uses a feature set, or if the model has one or more Output blocks.

The response to the example request above would look like this:

{
    "rows": [
        {"Weight": 1.2},
        {"Weight": 4.7},
        {"Weight": 900000},
        {"Weight": 3000}
    ]
}

Examples

Submitting tabular data

Tabular data is data whose features could be submitted inside a CSV file (i.e., single numeric value, categorical, or text).

Here are examples for submitting one example.

Sidekick

import sidekick

query = [{"Type": "animal", "Sound": "Miaow", "Size": 0.26}]

client = sidekick.Deployment(url=<URL>, token=<token>)
response = client.predict_many(query)
print(response)

Python

  • Submit a JSON formatted string as payload:

import requests

url = <URL>
token = <token>
header = {'Authorization': 'Bearer {}'.format(token), 'Content-Type': 'application/json'}

payload = '{"rows": [{"Type": "animal", "Sound": "Miaow", "Size": 0.43}]}'
response = requests.request("POST", url, headers=header, data=payload)
print(response.json())

Note that payload is a text string, but header can be passed directly as a Python dictionary object. You can also pass the payload as a Python dictionary object by using the json argument instead of data:

  • Submit a Python dictionary object as payload:

payload = {"rows": [{"Type": "animal", "Sound": "Miaow", "Size": 0.43}]}
response = requests.request("POST", url, headers=header, json=payload)

cURL

  • Submit a JSON formatted payload string:

curl -X POST \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json"  \
-d '{"rows": [{"Type": "animal", "Sound": "Miaow", "Size": 0.43}]}' \
<URL>
  • Submit an example with cURL options:

As with Python, you can use cURL to send data using native options, rather than sending a JSON formatted string. With cURL, however, you can only submit one example at a time this way.

curl -X POST \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-F "Type=animal" \
-F "Sound=woof" \
-F "Size=1.3" \
<URL>

Submitting images

How to submit images as features.

You can also submit examples that have images as some of their features. The submission is always done via a JSON formatted text string, so you need to transform the images into text. The following examples show how to create a payload that you can use as above when some features are examples.

Sidekick

import sidekick
from PIL import Image

query = [{'Feature Name': Image.open('images/Number_6.png')},
         {'Feature Name': Image.open('images/Number_7.png')}]

client = sidekick.Deployment(url='<URL>', token='<token>')
response = client.predict_many(query)

Python

import base64
import os

def encode_image(image_file, img_type):
    encoded_image = 'data:image/{};base64,'.format(img_type) + base64.b64encode(image_file.read()).decode('ascii')
    return encoded_image

# The path to the image file
img_path = "images/Number_6.png"
# The image extension, 'jpg' and 'png' are supported
img_type = os.path.splitext(img_path)[-1][1:]

with open(img_path, "rb") as image_file:      # read file as binary
    image_as_text = encode_image(image_file, img_type)

payload = {"rows": [{"Feature Name": image_as_text, "Sound": "Miaow", "Size": 0.43}]}

url = <URL>
token = <token>
header = {'Authorization': 'Bearer {}'.format(token), 'Content-Type': 'application/json'}

response = requests.request("POST", url, headers=header, json=payload)

curl

curl -X POST \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json"  \
-F "Feature Name=@Number_6.png" \
<URL>

Submitting arrays

How to submit arrays as features.

Models can work with features that are multi-dimensional arrays. To train such models, you can import NumPy files as parts of your datasets.

When working with a deployed model, multi-dimensional arrays are passed as two JSON key-value pairs:

  • The shape key provides a list representing the shape of the array

  • The data key provides a list of all the array values, in row major order

The following examples show how to provide data for a 10 by 10 by 3 array, which would look like this in the deployment view:

Multi-dimensional array as input feature.

Python

payload = {"rows": [{"Array feature": {"shape": [10, 10, 3]}, "data": [1, 2, 3, 4, <...>, 299, 300] }]}

If you have the data available as a NumPy array A, you can create the same payload like this:

payload = {"rows": [{"Array feature": {"shape": list(A.shape), "data": A.flatten().tolist()}}]}

header = {'Authorization': 'Bearer {}'.format(token), 'Content-Type': 'application/json'}

response = requests.request("POST", url, headers=header, json=payload)
print(response.json())

Sidekick

With sidekick, you can give the NumPy array directly in the query:

import sidekick

query = [{'Array feature': A}]

client = sidekick.Deployment(url='<URL>', token='<token>')
response = client.predict_many(query)
print(response)

Working with responses

When you submit a request, you will get a standard HTTP code telling you if the operation was successful or not. A value in the two hundreds usually indicate success, and four to five hundred indicates an error.

When successful, you will also receive a JSON formatted string as the payload of the response. This string contains the predictions for the list of submitted examples, or an error message if there was a problem (e.g., one of the examples submitted contained invalid data).

Python

After sending a prediction request, e.g.,

import requests

url = <URL>
token = <token>
header = {'Authorization': 'Bearer {}'.format(token), 'Content-Type': 'application/json'}

payload = '{"rows": [{"Type": "animal", "Sound": "Miaow", "Size": 0.43}]}'
response = requests.request("POST", url, headers=header, data=payload)

you can get the status code with status_code:

print(response.status_code)

and the JSON message with json():

print(response.json())

cURL

In cURL, the status code should be displayed when you submit a command. You may need to use the verbose -v option to get more feedback from cURL.


Understanding prediction results

The predictions for 2 submitted examples look like this:

{'rows': ['output name': value1, 'output name': value2]}

Depending on the type of the output, the JSON object value1 can have different forms.

Numeric predictions

For numeric predictions (single number), the value is returned directly. The message looks like this:

{'rows': ['output name': 0.3740423, 'output name': 6.784281]}

Categorical predictions

For categorical predictions, every possible category is returned as a key, and the associated value gives the probability of the example belonging to that class. For example:

{'rows': ['output name': {'cat': 0.98, 'dog': 0.005, 'train': 0.005, 'car':0.01 }, 'output name': {'cat': 0.001, 'dog': 0.001, 'train': 0.899, 'car':0.1 }]}

Image predictions

If the output of the model is an image, it is returned encoded as a text string.

Sidekick

Sidekick will automatically convert the response to a PIL image object:

url = '<URL>'
token = '<token>'

client = sidekick.Deployment(url=url, token=token)
response = client.predict_many(query)
response[0]['Image feature'].show()
Python

In Python, you can convert the JSON response to an image like this:

shape = response.json()['rows'][0]['Array feature']['shape']
data = response.json()['rows'][0]['Array feature']['data']
A = np.array(data)
A = np.reshape(A, shape)
print(A)

Array predictions

Sidekick

Sidekick will automatically convert multi-dimensional array features to NumPy arrays:

url = '<URL>'
token = '<token>'

client = sidekick.Deployment(url=url, token=token)
response = client.predict_many(query)
print(response[0]['Array feature'])
Python

You can convert the JSON response to an a NumPy array with Python code like this:

shape = response.json()['rows'][0]['Array feature']['shape']
data = response.json()['rows'][0]['Array feature']['data']
A = np.array(data)
A = np.reshape(A, shape)