Lab 2 - Create the Function

Deploy your ONNX model in an Azure Function

1. Create the Azure Function

Run the func init command back in the terminal window you have open, as follows, to create a functions project in a folder named SimpsonsFunctions with the Python runtime and navigate into the project folder.

func init SimpsonsFunctions --python
cd SimpsonsFunctions 

This folder contains various files for the project, including configurations files named local.settings.json and host.json. Because local.settings.json can contain secrets downloaded from Azure, the file is excluded from source control by default in the .gitignore file.

Add a function to your project by using the following command, where the --name argument is the unique name of your function (Classify) and the --template argument specifies the function's trigger (HTTP).

func new --name Classify --template "HTTP trigger" --authlevel "anonymous"

func new creates a subfolder matching the function name that contains a code file appropriate to the project's chosen language and a configuration file named function.json.

Open the file that contains the code for your function.

code Classify/__init__.py    

Replace the code in the function (Classify/__init__.py) with:

import logging
import onnxruntime as nxrun
import numpy as np
import PIL
from PIL import Image
import requests
from io import BytesIO
import azure.functions as func

def main(req: func.HttpRequest) -> func.HttpResponse:

    ## Get the image and resize it to 244x244 pixels
    url = req.params.get('url')
    response = requests.get(url)
    image = PIL.Image.open(BytesIO(response.content)).resize([224,224])

    ## Load the model and score the image
    model_path = "model/model.onnx"
    sess = nxrun.InferenceSession(model_path)
    input_array = np.array(image, dtype=np.float32)[np.newaxis, :, :, :]
    input_array = input_array.transpose((0, 3, 1, 2))[:, (2, 1, 0), :, :]
    input_name = sess.get_inputs()[0].name
    outputs = sess.run(None, {input_name: input_array.astype(np.float32)})

    ## Find the label with the highest score
    label = outputs[0][0][0]
    score = (outputs[1][0][outputs[0][0][0]]*100)
    
    ## Return and log the response
    response = f"I'm {score:.2f}% sure I see: {label}"
    logging.info(response)
    return func.HttpResponse(response)

Copy the model to the function.

cp ../model/ ./model -r

Open the requirements.txt. This files contains a list of packages that need to be installed in the Azure Function.

code requirements.txt

Add the following packages to the requirements.txt

onnxruntime
pillow!=8.3.0
requests

2. Deploy the Azure Functions

Create the Azure Resources

Create a resource group for the Azure Function

az group create --name SimpsonsFunc_RG --location WestEurope

Create a Storage Account. Replace <UNIQUE_NAME> with a unique name like simpsonfunc112

In the previous example, replace <STORAGE_NAME> with a name that is appropriate to you and unique in Azure Storage. Names must contain three to 24 characters numbers and lowercase letters only. Standard_LRS specifies a general-purpose account, which is supported by Functions.

az storage account create --name <UNIQUE_NAME> --resource-group SimpsonsFunc_RG  --sku Standard_LRS

Create the function app in Azure:

az functionapp create --name <APP_NAME> --storage-account <STORAGE_NAME> --resource-group SimpsonsFunc_RG --consumption-plan-location westeurope --runtime python --runtime-version 3.8 --functions-version 3 --os-type linux  

In the previous example, replace <APP_NAME> with a globally unique name appropriate to you. The <APP_NAME> is also the default DNS domain for the function app.

This command creates a function app running in your specified language runtime under the Azure Functions Consumption Plan, which is free for the amount of usage you incur here. The command also provisions an associated Azure Application Insights instance in the same resource group, with which you can monitor your function app and view logs. For more information, see Monitor Azure Functions. The instance incurs no costs until you activate it.

After you've successfully created your function app in Azure, you're now ready to deploy your local functions project by using the func azure functionapp publish command.

Publish the Azure Function

In the following example, replace <APP_NAME> with the name of your app.

func azure functionapp publish <APP_NAME>

Test the published function

Copy the Invoke URL, paste it in your browser and add the query string below to the URL.

?url=https://github.com/hnky/dataset-lego-figures/raw/master/_test/Bart.jpg

As a result, you should see:

Done! Well done, you have now successfully deployed a classification model, that you have created using the Azure Custom Vision Service, running in a Python Azure Function.

Last updated