Skip to content

Latest commit

 

History

History
 
 

VS Code and TypeScript

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

Azure Functions

Overview

In this lab, you will create an Azure Function to perform automated moderation of customer reviews using Microsoft Cognitive Services. The function monitors a storage queue where the website puts alerts for my function to know that there's a new review; and binds to blob storage where the review picture is, and to a CosmosDB document where the review text and other metadata are. It performs then an automated analysis of the image using the Microsoft Cognitive Services Computer Vision API and the text using Content Moderator API.

Objectives

In this hands-on lab, you will learn how to:

  • Create an Azure Function App from Azure Functions CLI and Visual Studio Code
  • Write an Azure Function that uses a queue trigger, a blob storage input and a Cosmos DB document input.
  • Add application settings to an Azure Function App
  • Use Microsoft Cognitive Services to analyze a text and an image and store the results in a Cosmos DB document

Prerequisites

In order to complete this hands-on-lab, it is required to have:

For local debugging:

  • .NET Core 2.x SDK

  • Azure Core Function Tools 2.x

     npm install -g azure-functions-core-tools@core
    

Exercises

This hands-on lab includes the following exercises:

Estimated time to complete this lab: 60 minutes.

Exercise 1: Setup the environment

In this exercise, you will create an Azure Function App using Azure Functions CLI and Visual Studio Code.

  1. Create a new folder and initialize an Azure Function by doing the following from a command prompt:

    mkdir RedShirtTour
    cd RedShirtTour
    func init
    

Choose node as worker runtime and then typescript as language. host.json, local.settings.json, package.json and tsconfig.json will be created.

  1. Let's create a simple queue triggered function:

    func new
    

    Choose Azure Queue Storage trigger as template and enter the name ReviewTextAndImage for the function name.

    Creating a function from Powershell

    A TypeScript template has now been created.

  2. We are now ready to work in Visual Studio Code. Let's open up VS Code:

    code .
    

The next step is to write our function.

Exercise 2: Write the Azure Function

In this exercise, you will write TypeScript code that uses the Computer Vision API to analyze images added to the "input-images" container and the Content Moderator API to analyse the review text of the Cosmos DB document.

  1. First of all, install the Azure Functions extension and reload VS Code.

    Install Azure Functions extension

  2. From the terminal in VS Code, execute the following commands to install the packages used by the function:

    cd ReviewTextAndImage
    npm install --save-dev @types/node
    npm install axios
    
  3. Let's define the trigger and the bindings of the function:

    A trigger defines how a function is invoked. A function must have exactly one trigger. Triggers have associated data, which is usually the payload that triggered the function.

    Input and output bindings provide a declarative way to connect to data from within your code. Bindings are optional and a function can have multiple input and output bindings.

    Source: https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings

    Open function.json and replace the JSON shown in the code editor with the following JSON:

    {
      "disabled": false,
      "bindings": [
    	{
    	  "name": "queueInput",
    	  "type": "queueTrigger",
    	  "direction": "in",
    	  "queueName": "review-queue",
    	  "connection": "AzureWebJobsStorage"
    	},
    	{
    	  "name": "image",
    	  "type": "blob",
    	  "dataType": "binary",
    	  "direction": "in",
    	  "path": "input-images/{BlobName}",
    	  "connection": "AzureWebJobsStorage"
    	},
    	{
    	  "type": "cosmosDB",
    	  "name": "inputDocumentIn",
    	  "direction": "in",
    	  "databaseName": "customerReviewData",
    	  "collectionName": "reviews",
    	  "id": "{DocumentId}",
    	  "partitionKey": "Reviews",
    	  "connectionStringSetting": "customerReviewDataDocDB"
    	},
    	{
    	  "type": "cosmosDB",
    	  "name": "inputDocumentOut",
    	  "direction": "out",
    	  "databaseName": "customerReviewData",
    	  "collectionName": "reviews",
    	  "createIfNotExists": false,
    	  "partitionKey": "Reviews",
    	  "connectionStringSetting": "customerReviewDataDocDB"
    	}
      ],
      "scriptFile": "../dist/ReviewTextAndImage/index.js"
    }

    As you can see, the function has a queue trigger, a Blob storage input, a Cosmos DB input binding and a Cosmos DB ouput binding.

  4. Change the function definition in your index.ts:

    import { AzureFunction, Context } from "@azure/functions"
    import axios from 'axios';
    
    const CONTENT_MODERATOR_API_URL: string = "https://westeurope.api.cognitive.microsoft.com/contentmoderator/moderate/v1.0/ProcessText/Screen?language=eng";
    const COMPUTER_VISION_API_URL: string = "https://westeurope.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Description,Tags&language=en";
    
    const queueTrigger: AzureFunction = async function (context: Context, myQueueItem: string, image: any, inputDocumentIn: any): Promise<void> {
    }
    
    export default queueTrigger;
  5. Let's write a function to review the text of the review:

    async function passesTextModeratorAsync(document: any): Promise<boolean> {
    	if (document.ReviewText == null) {
    		return true;
    	}
    
    	let config: any = {
    		headers: {
    			"Ocp-Apim-Subscription-Key": process.env["ContentModerationApiKey"],
    			"Content-Type": "text/plain"
    		}
    	};
    
    	let content: string = document.ReviewText;
    	let result = await axios.post(
    		CONTENT_MODERATOR_API_URL,
    		content,
    		config);
    
    	// If we have Terms in result it failed the moderation (Terms will have the bad terms)
    	return result.data.Terms == null;
    }
  6. Now, call the previous function from the run function:

    let passesText = await passesTextModeratorAsync(inputDocumentIn);
  7. Text has been reviewed. Time to analyze the image now. Add the following function to your code editor:

    async function analyzeImage(image: any): Promise<[string, boolean]> {
    	let config: any = {
    		processData: false,
    		headers: {
    			"Ocp-Apim-Subscription-Key": process.env["MicrosoftVisionApiKey"],
    			"Content-Type": "application/octet-stream"
    		}
    	};
    
    	let result = await axios.post(
    		COMPUTER_VISION_API_URL,
    		image,
    		config);
    
    	let caption = result.data.description.captions[0].text;
    	let containsCat = (<Array<Tag>>result.data.tags).some(item => {
    		return item.name.indexOf("cat") !== -1;
    	});
    
    	return [caption, containsCat];
    }
    
    interface Tag {
    	confidence: number,
    	name: string
    }
  8. Call it from the run function. It will be slightly different as the Cosmos DB document needs to be updated:

    context.bindings.inputDocumentOut = inputDocumentIn;
    
    let imageInformation = await analyzeImage(image);
    
    context.bindings.inputDocumentOut.IsApproved = imageInformation[1] && passesText;
    context.bindings.inputDocumentOut.Caption = imageInformation[0];

    First, a copy of the input document is created, then the function to analyze the image is called and finally certain properties of our document are updated.

You are done with the coding part of this lab!

Exercise 3: Deploy the Function app

  1. First of all, run npm install to install dev dependencies.

  2. To build your function app, run npm run build. To prepare it for deployment, use npm run build:production.

  3. From VS Code, in the Azure: functions section, press the following button to deploy the function app:

    Deploy to Function App

    Choose a folder on your local system, then choose an Azure subscription and select a function app (or create a new one).

  4. Add the following settings in the Application Settings of your function app:

  • AzureWebJobsStorage: Connection string to the storage account
  • ContentModerationApiKey: Content Moderation Api Key
  • MicrosoftVisionApiKey: Computer Vision Api Key
  • customerReviewDataDocDB: Cosmos DB connection string

Application settings

The Azure Function has now been published and configured. Let's test it out!

In your browser, open a new tab and go to the Azure Portal. Go to the function app you have created and open your function to see the logs.

Open another tab and navigate to the website you have deployed at the beginning of this hands-on-lab. Select Reviews in the menu, then press the button add picture. Submit a new picture by pressing + Image and then the button Create.

Have a look at the logs of your function, you should see Function started and also Function completed. Depending on the photo you submitted, you should now see it either in Approved or Rejected in the website.