Build API using Azure Function with Python and Azure Cosmos DB

Evan Wong
12 min readNov 4, 2020

--

Introduction

Serverless technologies is a valuable approach for rapid development and cost optimization.

A serverless computing doesn’t mean no server. The code still runs on a server, but you don’t need to care as much about the underlying infrastructure because a third-party service like a Cloud provider will handle it for you. This leads to less time in operations and more time for developing software.

Serverless typically follows a pay-per-execution model, which means you have to pay only when your code runs. This can result in huge cost savings. Serverless also typically provide automatic scaling in real-time based on the computing resources need.

In this tutorial, we’re going to build a Serverless API using HTTP Triggers in Azure Functions that uses a Azure Cosmos DB as database. We’re going to build an API for a hypothetical e-commerce that stores information about products.

We’re going to build this API using Python. I’m not going to go dive into huge detail about Azure Functions and the complexities behind Azure Cosmos DB, I’ll just be keeping it simple enough to demonstrate how they can all work together to make a simplistic API.

What is Azure Function?

Azure Functions are small pieces of code that we can run in Azure without worrying too much about application infrastructure. One of the great advantage using Azure Function is to save cost, the charges on happen when the functions are executed. Comparing with traditional server based or container based technology, whether or not the functions are executed, the charges is based on the duration that the application servers run.

We can use specific events to trigger actions in our Functions. For this tutorial, we’ll be triggering events based off HTTP requests.

What is Azure Cosmos DB?

Azure Cosmos DB is a fully managed globally distributed NoSQL database. It provides schema agnostic capabilities for developers to develop modern applications. Azure Cosmos DB elastically scale the provisioned throughput and storage for your Cosmos databases based on your need and pay only for the throughput and storage you need. This leads to significant cost savings.

For those who are familiar with MongoDB, Azure Cosmos DB implements the wire protocol for MongoDB. This implementation allows transparent compatibility with native MongoDB client SDKs, drivers, and tools. Azure Cosmos DB does host the MongoDB database engine.

Outline

In this tutorial, we would be doing the following steps:

  1. Create a new Cosmos DB account and container.
  2. Create a new Azure Function using Visual Studio Code and test.
  3. Develop the two APIs — CreateUser and GetUsers
  4. Deploy the two functions to the Azure Function

Prerequisites:

  1. Azure account and a valid subscription — https://portal.azure.com
  2. Visual Studio Code with the following extensions — Azure Functions, Azure Account and Python. Download VS Studio Code here
  3. Python 3.8
  4. Azure CLI version 2.4 or later
  5. Azure Functions Core Tools
  6. Source codes — https://github.com/echoesian/azure-function

Create new Azure Cosmos DB account

Create a Azure Cosmos DB Account on the Azure portal. Enter an account name for the Cosmos DB and leave other options as default. Click Review + Create.

After the validation is successful, we can click on the Create button.

Cosmos DB account deployment in progress

After the Cosmos DB account deployment is successful, you can click on the Go to resource button

On the Overview page, click ‘Add Container’ button to create new container.

Key in the Database id (serverless-db), Container id(user) and the Partition key (can use the /id as partition key). Remember the Database id and Container Id because we would be using on the later part of the tutorial. Click OK.

After the successful creation of the container and database, it should appear on the Data Explorer view.

Create new Azure Function

To create a Function in Azure, there are few ways to do it. One of the simplest way is to create functions on the Azure portal. In this tutorial, we will be using Visual Studio Code as the integrated development environment (IDE) for Azure Function codes development.

Let’s start coding! Open up the Visual Studio Code. Make sure all the required extensions on the prerequisites section have been installed.

Sign in to Azure

Once the Functions extension is installed, sign into your Azure account by navigating to the Azure: Functions explorer, select Sign in to Azure, and follow the prompts.

After signing in, verify that you see the email account of your Azure subscription in the Status Bar.

On the left pane, click on the Azure logo icon, navigate to the FUNCTIONS section and expand the subscription that you would need to deploy the Azure functions to.

To create a new project, click on the Create New Project… icon. Browse to the directory that you wish the project to be saved to.

Local directory for the project
Programming language
Project template
Function name

Then, choose Python as the programming language and HTTP trigger as the template for the first function. Provide a function name such as CreateUser for the HTTP trigger function or leave the default name.

Choose Anonymous for the authorization level. This is for testing purpose only and it is not recommended for Production usage. For Production, it is recommended to at least use Function as the authorization level.

Go back to the Explorer tab, the project files should be created.

Test Locally

Let’s do a simple test to make sure the default function is working properly. The Azure Function Core Tools lets you run your functions on your local computer. You can start the Function app either through VS Code or through the command line interface.

To run the Function app through VS Code:

On the top menu, navigate to the Run->Start Debugging.

If everything is running successful, you should see a URL generated for the HTTP trigger. Hold Ctrl+click (Cmd+click on macOS) on the URL. A browser page would be automatically loaded and you should see the response as below.

Try to pass in a name query string to the URL by pasting the below. Replace the [YourName] with your name.

?name=[YourName]

For the full link example: http://localhost:7071/api/HttpTrigger?name=Evan

This time, the response would be accepting your GET query string and it will output “Hello, …”. You can also test by using curl command or any other REST client software such as Postman.

At this stage, your sample hello world function is working correctly locally on your computer.

Code APIs

In this step, we will develop two APIs for the hypothetical e-commerce — one for creating a new user and another to list all available users in the system. Let’s code the first API

Create User API

We will be using Cosmos DB as the NoSQL database to store users data.

First, if the container has not been created initially, create the user container under the existing serverless-db database. On the Cosmos DB service page, click on the Data Explorer, on the serverless-db, click on the triple-dot button (…), click on “New Container” on the pop-up menu.

Cosmos DB — Create Container

Use existing database, and enter user as the Container id. Key in “/id” as the Partition key.

Back to the Visual Studio Code, download and import the source codes from my github repo.

Once the import is successful, you should see the directory structure like above.

Cosmos DB Connection String

First step is to change the Cosmos DB connection string to refer to your actual Azure Cosmos DB primary connection string. To find the connection string, go to the Azure portal, navigate to the Cosmos DB service. Click on the keys on the left menu.

Cosmos DB — Primary Connection String

Look for the PRIMARY CONNECTION STRING, copy the entire string. Go back to Visual Studio Code, open the local.settings.json file located at the root of the project folder.

local.settings.json

Locate the parameter “AzureCosmosDBConnectionString”, update the value to the Cosmos DB primary connection string that you have copied earlier.

Let me explain on the codes, since we are implementing a HTTP trigger, the input of the function would be a GET or POST request.

def main(req: func.HttpRequest, doc: func.Out[func.Document]) -> func.HttpResponse:

The Python code accept the request via HttpRequest and output as Cosmos DB binding and respond as HttpResponse.

name = req.params.get(‘name’)

Next, it would get the value of the name query string from the request.

newdocs = func.DocumentList()

Next, initialize a new DocumentList. After that, initialize a new dictionary and populate new ID and the user name. Id is randomly generated using the built-in uuid function. The dictionary will then append into the DocumentList. It then persist into the database using the set function.

doc.set(newdocs)

return func.HttpResponse(f”User {name} created successfully.”)

Finally, send the HTTP response as a customized message like above.

You will also need to verify if the settings on the Cosmos DB binding is correctly set. Open the function.json inside the CreateUser function project folder.

CreateUser API — function.json

Locate the “databaseName”, this parameter should point to the actual database name that you have created in the earlier part of the tutorial.

Test Create User Function

Now, to test the function, click on the Run->Start Debugging.

Local CreateUser API URL

Use a REST client to exaecute the request using the link provided.

By default, if there is no name specified as the query string, the response would be look like the above. Let’s put in the name query and try again.

This time, the message should indicate that the new user is created. Let’s verify if the user has been created in the Cosmos DB. Switch to the Azure portal and navigate to the Cosmos DB service page.

On the Data Explorer page, select the serverless-db and click on the user container and choose Items. On the right page, click on the last row of the items, you sould see the new user data. It works!

List Users API

Now, let’s create another API to retrieve all the users data.

GetUsers API — function.json

Let’s inspect the function.json file, notice the direction is “in” because we are using the input binding for Cosmos DB. There is also a new parameter — sqlQuery, this is the select query to get all the users.

GetUsers code __init__.

Open up the __init__.py file, the main function remains the same where it accepts incoming request as HTTP request and output as HTTP response. For this API, the input binding would get all the user data. The first step is to initialize an array to store all the users data. Secondly, loop through the DocumentList, create user object by assigning the value to the id and name respectively. Lastly, it will append to the array.

return func.HttpResponse(
json.dumps(users_json),
status_code=200,
mimetype=”application/json”)

The return would be the JSON array of the users data.

Test List Users Function

Switch back to the Visual Studio Code, while the debugging session is still open now, we can Ctrl+Click (cmd+Click on Mac) to execute the function within the browser.

The response would looks something like the above.

Deploy the Functions to Azure

Go to Azure and click on “up arrow” button to deploy the functions. Choose the subscription that you want the functions to deploy to.

Click “Create new Function App in Azure…”

Enter a function app name such as serverless-python (You should use any other name as the name has to be a globally unique name).

Choose Python 3.8

Choose the region.

Wait for a couple of minutes…From my experience, the functions should be deployed to Azure within 3 minutes.

Once it is deployed, on the Azure pane, we should see two functions displayed.

By default, the Azure Functions extension does not deploy the Cosmos DB connection string from the local.settings.json. So, we would need to manually add the connection strings on the Azure Function configuration page. On the configuration page, click on the “+ New connection string” button.

Enter the name “AzureCosmosDBConnectionString” and the value if the primary connection string that we can get from the local.settings.json file or the keys from the Cosmos DB service page. Click OK.

Click on the Save button.

Click Continue. The function app is now successfully deploy to the Azure.

Test Functions on Azure

There are several ways to test the functions including using a browser, REST client or Azure portal. In this step, we will be testing the two functions on Azure portal.

Navigate to the Functions page. Click on the CreateUser function.

On the Code + Test page, Click on the Test/Run button.

On the input section, add the name parameter with a value. Click Run.

If it is successful, we should be getting 200 OK response and the response message. To verify the function, go back to the function page and click on the GetUsers function. Similarly, click on the Test/Run button and click Run.

The newly created user should appear on the last record of the collection.

On the next topic, I’ll be expanding the scope of the project to use API Management capabilities to secure and govern the APIs. Subsequently, I’ll be covering the concept of DevOps to streamline the process of continuous integration and continuous deployment using the same project. Stay tuned and enjoy!

--

--

Evan Wong
Evan Wong

Written by Evan Wong

Passionate Cloud and Middleware Technologist

Responses (2)