Global AI Bootcamp 2023 Low Code Lab With Logic Apps and Azure AI Services

Overview
Welcome to the Global AI Bootcamp 2023. This is a lab designed by me to demonstrate how easy it is to create a speed infraction ticketing system using Azure Logic Apps, Azure AI with writing minimal amount of code.
Lab Introduction
I have always been a fan of movies. When I think of fast cars, comedy, and swag, Rowan Atkinson's Johnny English driving a Rolls Royce or Aston Martin always comes to my mind. He always ends up speeding his vehicle and gets captured in the speed detecting camera and believe me his facial expressions are always hilarious. Have a look!
Though Johnny English destroys the camera with his awesome car fired missile, this gives us a real life example where we can use the power of serverless computing to process the captured images of the driving vehicles.
Lab Problem Statement
The people of Abracadabra country are speed aficionados and some times in their zeal of enjoying the thrill of fast speed, they cross the legal speed limit laid down by the local government. Hence the Minister of Transport has decided to install speed triggered cameras at major intersections in all the major cities pan Abracadabra. The cameras will capture the images of the vehicles and upload the images to the cloud. The process is
- The cameras upload captured images to the cloud storage as blobs along with all the details like the district where infraction occurred etc.
- The in cloud system detects the registration number and notifies the registered owner of the speeding infractions.
Lab Goals
This lab intents to help participants understand how easy it is to implement the AI infused Low Code No Code systems which are easy to maintain and scale.
Lab Steps
The lab will focus on following points
- Learn about reactive style of application programming
- Create Azure Computer Vision API instance
- Create a no code / low code logic apps workflow which processes images uploaded to the blob storage and sends a notification to culprit
Solution
Following is the architecture diagram for the solution and the steps involved
- The image captured by motion cameras is upload to a blob storage container
- The image upload event triggers the logic app workflow
- The workflow retrieves the contents of the uploaded image
- The workflow invokes the computer vision API to extract the number using OCR
- The workflow retrieves the driver registration information and sends notification
- The workflow creates a ticket in the ticket database
- Notify the reistered owner of the infraction
In case of failure, the workflow moves the image from the uploaded container to the container where some one manually process the image
Setting Up Prerequisites
Before following with this Lab, it is necessary to have below things set up
A Computer
Access to a computer and internet is required to do the development and follow along
Getting Azure Subscription
An acive azure subscription is required. A free trial account can be set up using Azure Trial Account Link
Creating Resource Group
You will need a resource group to club all the assets we build during the lab. Create a resource group called rg-ai-blobal-btcmp-2k23-01
. Following are the steps to create a resource group.
On the left hand side, click on the hamburger menu and select Resource groups
Click on Create
Fill out the form and click on Review + Create
Once the validation passes successfully, click on create.
Registering Event Grid Provider
Before we begin using reactive programming to access uploaded blobs, we need to enable Event Grid Provider for the subscription. Following are the steps to achieve this.
On Home page, select Subscription. You can also search for it at the top search bar
Select the subscription you are using for this lab
Under Setting section, select Resource Providers
Scroll down and locate
Microsoft.EventGrid
. Select it and click on Register at topOnce done, you will get notification and
Microsoft.EventGrid
will be registered as a resource provider.
Setting up Email Account To Send And Receive Email
You can use send grid to send emails. You can get free Send Grid Account using free plan from Get started for free with Send Grid
Follow the steps provided to verify sender and set up 2FA. Post that create a API key from settings and save it as it will be used at a later point in time to send the email.
Solution Implementation
Creating Azure Cosmos DB
We will use the Azure Cosmos DB to store the fictional vehicle registration data. We will also use the same database to store the created tickets. The registration data and ticket data will be stored in different containers in the database. We will use the district
as the partition key to partition the data properly.
Click on the hamburger menu icon on the left side and select Azure Cosmos DB.
Click on Create
Select Azure Cosmos DB for NoSQL
Fill out the basics form (Change the Account Name) and click on Review + Create
Click on Create
Once done you will get the notification
Navigate to the Cosmos DB and select Keys and make a not of the name of the cosmos DB and primary key. This will be required later.
Creating Azure Cosmos DB Collections
Registration Container
Navigate to the Cosmos DB and select Data Explorer on Left Hand Side and click on New Container
Fill out the form as shown below an click on OK
Expand the registration container and click on items.
Click on New Item at top and add following JSON (More details will be shared at the time of the live demo)
1{
2 "id": "<registration number>",
3 "ownerName": "<Name>",
4 "district": "Pune",
5 "contactEmail": "<Working Email Address>",
6}
- Click on Save to save the item
Tickets Container
- Click on New Container
- Fill out the form as shown below and click on OK
Creating Computer Vision API Instance
We will need Computer Vision API to use the OCR to extract the registration number. Follow below steps to create a free instance of the computer vision API
- Click on the hamburger icon and click on create a resource
Click on AI + Machine Learning and the locate computer vision and click on Create
Fill out the form as shown below. You may want to change the name under instance details. Click on Review + Create
Once the validation passes, click on Create to create the instance.
You will get a notification once done. Click on the Go to resource. You will be navigated to the instance
On the resource page, on the left pane, click on the Keys and Endpoints and the copy Key 1 and Endpoint. We will need it later on.
Creating The Blob Storage
- Click on the hamburger icon and click on create a resource
Click on Storage and select Storage Account and click on Create
Fill out the form as shown below. You will need to change the name. Click on Review. No need to change any other properties
Click on Create to create the storage account instance
Once the deployment is done, Click on Go to resource
On the left hand side, click on the Access Keys and copy the blob storage name and key(you will have to click on show and then copy the key)
Adding Container
On left hand side blade, select containers.
Click on Container to add a new container and fill out the form as shown and click on Create
Repeat step 2 to create another container called
manualops
With this we are set to start building the workflow.
Creating Logic Apps Workflow
We will use Logic Apps service to create an orchestration workflow which will read the contents of the uploaded blob and detect number and send an email notification for the infraction. Follow the steps given below
- Click on the hamburger icon and click on create a resource
Select Integration and Find Logic Apps and click on Create
Fill out the form as shown below and click on Review + Create
Once the validation passes, click on Create to start the deployment
Once Deployment is done, click on Go to resource
Programming the Logic Apps
We will now add the logic to the created logic apps. Follow the steps given below
- Once you go to the logic apps, the logic apps designer will be presented to you. Here you can select different templates that are available out of the box. We will select the
Blank logic app
template
Now we will add the trigger to the logic app. As the name suggest, the trigger is what starts the logic app. In our case, our trigger is
When a blob is created
event. When this event occurs for the blob uploaded to theuploads
container we created earlier, we want to start the processing. In Search box, search forEvent Grid
. Select theWhen a resource event occurs
You will now be asked to sign in. Use Defauly directory and click on sign in. Complete the sign in.
Now we will configure the Logic app to react to the blob created event when the blob is uploaded to the
uploads
container. Configure the Event Grid Trigger as shown below.
Click on Save to save the logic app.
Now we will add the logic to get the url of the uploaded blob from which we will get information about the container and the name of the uploaded blob. If we observe, the general schema for a blob created event as raised by Azure is of following form
1{
2 "topic": "/subscriptions/{subscription-id}/resourceGroups/Storage/providers/Microsoft.Storage/storageAccounts/my-storage-account",
3 "subject": "/blobServices/default/containers/test-container/blobs/new-file.txt",
4 "eventType": "Microsoft.Storage.BlobCreated",
5 "eventTime": "2017-06-26T18:41:00.9584103Z",
6 "id": "831e1650-001e-001b-66ab-eeb76e069631",
7 "data": {
8 "api": "PutBlockList",
9 "clientRequestId": "6d79dbfb-0e37-4fc4-981f-442c9ca65760",
10 "requestId": "831e1650-001e-001b-66ab-eeb76e000000",
11 "eTag": "\"0x8D4BCC2E4835CD0\"",
12 "contentType": "text/plain",
13 "contentLength": 524288,
14 "blobType": "BlockBlob",
15 "url": "https://my-storage-account.blob.core.windows.net/testcontainer/new-file.txt",
16 "sequencer": "00000000000004420000000000028963",
17 "storageDiagnostics": {
18 "batchId": "b68529f3-68cd-4744-baa4-3c0498ec19f0"
19 }
20 },
21 "dataVersion": "",
22 "metadataVersion": "1"
23}
- In the search bar search for variables and select
Initialize variable
action
- We will now read the url from the blob created event sampled above and then use logic apps functions to get the value of the path. We will read the
url
property in the data object in the trigger body using following formula
1triggerBody()?['data']?['url']
This will give us the url of the uploaded blob. From this we want to extractout /testcontainer/new-file.txt
. So we use another function called uriPath
. SO our final function will look like below.
1uriPath(triggerBody()?['data']?['url'])
this will give us the required path of the blob.
Click in the Value box on the variable form. A window will pop up on the right hand side, select expression
there and enter above formula there and click on ok. Save the logic app.
We will now read the content of the blob using the Blob Storage related action. In the search box, search for
Azure Blob Storage
and selectGet Blob Content using Path(V2)
We will now need to use the blob storage details that we captured earlier to configure the connection to the blob storage. Once you select action in previous Step, you will be presented following screen. Fill out with the necessary details as shown below. Click on Create to create the connection
Configure the action as shown below and save the logic app.
We will now pass the content of the uploaded blob to the OCR function of the Computer Vision API. In the seach box, search for 'Computer Vision' and select
Optical Character Recognition(OCR) to Text
action.
- Once you select the action, you will be asked to create a connection for the Computer Vision API. Here you will need the access details saved earlier while creating the Computer Vision API instance. Fill out the form as shown below and click on Create
Configure the action as shown below and save the logic app.
The OCR if it detects words in the image will give a response like shown in sample below.
1{
2 "text": "MHXXBD8877"
3}
while a failure to detect will produce following message
1{
2 "text": ""
3}
Lets code out the failure path. On this path we will create a new blob in the
manualops
container so that some other system can pick up the image for manual processing and we will delete the original blob inuploads
containerIn the search bar, search for
Condition
and select Control. Then selectCondition
We will check if the
text
property in the output ofOptical Character Recognition(OCR) to Text
is empty now. If it is empty, we will follow the path defined in Step 16 We will use the formula
1empty(body('Optical_Character_Recognition_(OCR)_to_Text')?['text'])
Configure the condition as shown in below steps and Save the logic app
On the true path, click on
Add an action
. In the search box, search forAzure Blob Storage
and selectCreate Blob V2
as shown belowWe will no need to extract the name of the blob to copy it to the destination container. We already have the path stored in variable
varBlobPath
earlier. We will now manipulate it to get the name of the blob. If you recall, the blob url is of format
1https://my-storage-account.blob.core.windows.net/<containerName>/new-file.txt
and the varBlobPath
variable contains value /<containerName>/new-file.txt
.
we will use following formula to read the blob name
1substring(variables('varBlobPath'),add(lastIndexOf(variables('varBlobPath'), '/'), 1))
and
1triggerBody()?['data']?['url']
to read the url of the uploaded blob.
Configure the properties of the action as shown below and Save the logic app
Finally it should look like below
Now we will delete the original blob in the uploads container. Click on Add an Action. In the Search bar,search for
Azure Blob Storage
and selectDelete Blob V2
as shown belowConfigure the action by filling the form as shown below and save the logic app
We will now code the postive path where the text is detected in image. We will do so on the false part of the condition.
On the False Part, Click on
Add an action
. In the search box, search forAzure Cosmos DB
and selectQuery Documents V5
- Once done, you will be presented the screen to create a connection to the Azure Cosmos DB. Here you will need the name of the Cosmos DB and access key saved earlier. Cofigure the connection as shown below and Click on Create
- Since the registrations will be held across various districts, it is possible that a vehicle registered in one district can commit speeding infraction in another district, hence we will use for now a cross partition query. The query to get the registration against the vehicle number, we will use following SQL query.
1SELECT TOP 1 * FROM registration WHERE registration.id = "registration Number"
Configure the action as shown below and save the logic app
- The response from the
Query Documents V5
will be an array and will be of following format
1[
2 {
3 "id": "<registration Number>",
4 "ownerName": "Mandar Dharmadhikari",
5 "district": "Pune",
6 "contactEmail": "codidharma@gmail.com",
7 "_rid": "rJwmAPuVCTYBAAAAAAAAAA==",
8 "_self": "dbs/rJwmAA==/colls/rJwmAPuVCTY=/docs/rJwmAPuVCTYBAAAAAAAAAA==/",
9 "_etag": "\"00009c3b-0000-2000-0000-6400f7f50000\"",
10 "_attachments": "attachments/",
11 "_ts": 1677785077
12 }
13]
We will implement another fail safe logic here, if, i.e. If there is no or multiple registration detected, we will move the blob to manualops contaier and delete the original blob.
Click on
Add an action
. In the search bar, search forControl
and selectCondition
.As mentioned in step 27, we will check if the
Query Document V5
returns no or multiple registrations. Configure the conditions as shown below
What we have done is check if the number of documents is received is 1 or not. If not, we implement the fail safe logic else we issue notification to vehicle owner.
To implement the fail safe logic in False path, follow steps from 19 to 22
Let us now implement the path to send email notification to the culprit.
We will first create a ticket record in the
tickets
container in cosmos db. For simplicity, we will generate a guid as the ticket number and store it using compose action
,in real world, this ticket number can be alpha numeric.
- In the search box, search for
Azure Cosmos DB
and SelectCreate or Update a Document V3
.
- Configure the properties as shown below
- We now need to create the document that we want to store in the cosmos db. Remember that we have used
district
as the partition id in ourtickets
container. In real world, you will have infraction happening in same or different districts and you can have multiple logical way of determining the place where infraction occure, for now,lets assume that the place of infraction and place of vehicle registration is same district.
Lets start by setting the Document Id, which will be the ticket number.
We will now set other properties like the Vehicle Registration Number and Owner Name. Since we know for sure that we will get to this step when only one registration is found, we will use following formula, to extract the vehicle registration number, owner name and district respectively.
1string(first(body('Query_documents_V5')?['value'])?['id'])
2string(first(body('Query_documents_V5')?['value'])?['ownerName'])
3string(first(body('Query_documents_V5')?['value'])?['district'])
Configure them as shown below.
Save the logic app once done
Lets us now code the final logic to send the email notification. In the true path of the condition created in step 28, click on
Add an action
. In the search box, search forSend Grid
and selectSend email V4
You will now be presented to configure the SendGrid connection by providing connection name and send grid key. Configure the connection as shown below and click on Create
- Now we configure the action. By default you will only see option to configure
To
email address only. We will need other parameters like Attachments etc to send a proper mail. To get these, click on theAdd new parameter
dropdown and select as shown below and then click outside the dropdown to get these parameters
- You will need to set up the email id of the sender which you registered as part of the pre requisites.
To get the To
email address, we have to get the email address from the output of the Query Documents V5
. Since we know for sure that we will get to sending email when only one registration is found, we will use following formula, to extract the email address
1string(first(body('Query_documents_V5')?['value'])?['contactEmail'])
configure the To
field as shown below
To configure the Subject, follow the step below
To Set Body of the email, follow below steps
To get the addressee name, we use the formula
1string(first(body('Query_documents_V5')?['value'])?['ownerName'])
We will now configure following text
A speeding infraction has been recorded against the vehicle <Registration> registered to you. A ticket <ticket number> has been issued against you with a fine of Rs 500. Please pay your dues by visting nearest office of department of transport
To get the registration numnber we will use following formula
1body('Optical_Character_Recognition_(OCR)_to_Text')?['text']
To get the ticket number, we will use the output of the compose action as used in step 35
The configured body should look like follows
Now lets set the attachment, the atachment is nothing but the blob that was uploaded to the uploads
folder which triggered the workflow.
Set the name of the name of the blob that was uploaded. We will use following formula to read the blob name
1substring(variables('varBlobPath'),add(lastIndexOf(variables('varBlobPath'), '/'), 1))
To set the contents of the attachment we will use following formula
1base64ToBinary(body('Get_blob_content_using_path_(V2)')?['$content'])
To set the content type of the attachment, we will use following formula
1body('Get_blob_content_using_path_(V2)')?['$content-type']
Save the logic app
Testing The Workflow
You will be testing three scenarios
- When no text/ registration number is detected by the computer vision
- When registration number is detected by that registration number is not available in the
registration
container in Azure Cosmos DB - When the registration number is detected and ticket is created and the infraction is notified over email.
Clean up
Once done, you can delete the resource group created earlier along with all the resources to clean up the lab assets
Summmary
In this lab, you learnt how easy it is to add AI and have quick working low code workflows.