Click here to Skip to main content
15,881,852 members
Articles / Hosted Services / Azure
Article

Modernizing Python Apps and Data on Azure - Part 6: Becoming Cloud Native

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
4 May 2022CPOL8 min read 5K   2   2
How to start making an app more cloud-native and a demonstration of how to move the legacy app’s functionality into an Azure Serverless Function app
This is Part 6 of a 6-part series that demonstrates how to take a monolithic Python application and gradually modernize both the application and its data using Azure tools and services. This article discusses how to start making the app more cloud-native, and demonstrates how to begin moving the legacy app’s functionality into Azure function-based microservices.

This article is a sponsored article. Articles such as these are intended to provide you with information on products and services that we consider useful and of value to developers

Throughout this series, we’ve explored how to modernize a real-world Django legacy app in many ways.

In the first article, we replaced the SQLite database with PostgreSQL and populated it with sample data. The second article demonstrated setting up an Azure Database for PostgreSQL and migrating the app’s data to Azure.

We created the app via the Azure Portal in the third article and deployed it using the VS Code Azure App Service extension. The fourth article showed how to containerize our legacy Python app, create an AKS cluster, and deploy it using Visual Studio Code.

In the fifth article, we created a Cosmos DB database, then adapted our app to work with it using the Djongo Mapper and Cosmos DB’s MongoDB API.

In this final article of the series, we’ll explore how to start making the app more cloud-native. We’ll demonstrate how to move the legacy app’s functionality into an Azure Serverless Function app.

You can follow the steps in this article to get your application running or download and open this GitHub repository folder to get the final project. You should know Python and Django to follow along.

Benefits of Azure Serverless Functions

The Microsoft Azure Functions serverless compute service enables developers to build applications faster. They don't have to worry about setting up or maintaining infrastructure. Serverless app development also enables developers to create code that runs natively on a cloud platform.

The pricing model is another serverless architecture benefit. With Microsoft Azure Functions, developers can allocate resources on-demand with no upfront costs or commitments. Azure Functions are highly available, and you can configure them to scale automatically as your user base grows and use increases.

Azure Functions are best suited for small apps like our Django-based backend app, which can work independently of other websites.

Setting Up an Azure Function App

We’ll create an Azure Function App, either directly through the Azure Portal or using a VS Code extension, allowing us to interact with Azure Functions directly from our favorite IDE.

Open VS Code to access the code from the previous article of this series. Click the Extensions tab, as shown in the screenshot below. Then, search for “Azure Functions” and install that package.

Title: Inserting image...

The Azure Functions extension lets you quickly create, debug, manage, and deploy serverless apps from within VS Code. These tools integrate seamlessly with your Azure account, enabling rapid development and straightforward deployment.

Now it’s time to create our Azure Function. Select the Azure tab and click the Create Function icon within the Functions section.

Image 2

We still don’t have a Function project on Azure, though. We’ll create it locally now, then upload it to the cloud later.

A popup now asks if you would like to create a new project. Click Yes.

Image 3

Azure functions support numerous programming languages, like Python, JavaScript, TypeScript, C#, PowerShell, and Java. Choose Python.

Image 4

Now we choose our Function project’s template. There are many forms of Azure Functions triggers for various uses, depending on when the functions should run. For example, you might want a function to run once a day at 6 AM, or whenever a message queue processes an item.

In our app, we want HTTP triggers that will respond to HTTP requests from the Teams tab, so choose that option.

Image 5

Now we name the Azure function “az-function-conduit”:

Image 6

Then, we provide the authorization level. We make it public by choosing Anonymous.

Image 7

Next, popups will ask whether to overwrite the .gitignore and requirements.txt files. Answer No to both questions.

Image 8

Image 9

We now have our first Azure function.

Image 10

Now, we select the Functions group and click the Deploy to the Function App button:

Image 11

We still have no Function App in Azure, so we create it by clicking the first option, + Create new Function App in Azure.

Image 12

Name the project “conduit-function-app”.

Image 13

Notice how VS Code now displays a new folder where you can conveniently browse data from your Function App stored in the Azure cloud. This includes files, logs, and settings.

Image 14

Click the Explorer tab to view your source code. Note that:

  • Our Azure Function is in a separate Python module.
  • The host.json metadata file contains our Function’s configuration in a Function App instance.
  • The local.settings.json file provides the settings when the app runs locally.

Image 15

We must ensure Python support for Azure Functions next. So, open the requirements.txt file and add this line:

Azure-CLI
azure-functions

Now that our az-function-conduit function is ready, we can debug it locally to ensure it’s working as we expect. Click on the debug icon and select Attach to Python Functions, or press the F5 key.

Image 16

As soon as you start debugging, the terminal window appears, and a URL hosts the function locally.

Image 17

Open this URL in a browser window. Since our function app is virtually empty, the browser displays a standard template message for Azure Functions:

Image 18

Running Django Inside an Azure Function

At this point, we have a Conduit module (based on the Django REST framework) and an Azure Function module in the same project. Since this article aims to demonstrate how to move our Django app into Azure Functions, we could migrate code from the Conduit module to the az-function-conduit app. However, this approach takes a lot of work without much benefit.

Fortunately, Django implements Web Server Gateway Interface (WSGI). When deployed to a web server, WSGI enables you to forward requests to web apps written in Python. We can take advantage of WSGI by keeping the Django code inside the Conduit module untouched and telling the Azure Function module to redirect the invocations to the Django handler.

So, open the \az-function-conduit\__init__.py file and replace the code there with the following snippet:

Python
import logging

import azure.functions as func
from conduit.wsgi import application

def main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:
    return func.WsgiMiddleware(application).handle(req, context)

The WsgiMiddleware method adapts a WSGI-supported Python server framework such as Django into Azure Functions in the code above. We can use it by calling the .handle() function or exposing the .main property in a HttpTrigger event.

Next, open the \az-function-conduit\function.json file and add this line:

JSON
"route": "{*route}"

Like this:

JavaScript
{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ],
      "route": "{*route}"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
  ]
}

Then open the \conduit\settings.py file and replace the ALLOWED_HOSTS to enable any host to serve the application:

Python
ALLOWED_HOSTS = ['*']

Image 19

Defining the Application Settings

Using environment variables is a common way to define an app’s configuration, depending on its environment.

Since the database configurations depend on the project's Azure credentials, it's beneficial to modify the configuration without touching the app's source code and keep secrets outside the source code repository.

So, now open the \conduit\settings.py file, where our database settings are located, and use Python’s os module to access the environment settings as follows:

Python
DATABASES = {
    'default': {
        'ENGINE': 'djongo',
        'ENFORCE_SCHEMA': False,
        'NAME': os.getenv('DATABASE_NAME'),
        'CLIENT': {
            'host': os.getenv('DATABASE_HOST'),
            'port': 10255,
            'username': os.getenv('DATABASE_USER'),
            'password': os.getenv('DATABASE_PASSWORD'),
            'authMechanism': 'SCRAM-SHA-1',
            'ssl': True,
            'tlsAllowInvalidCertificates': True,
            'retryWrites': False
        }   
    }   
}

Then, open Azure Portal and locate your Azure Cosmos DB API for MongoDB account. Click the Connection String tab to see the database configuration keys that we’ll use in our app.

Image 20

Back in VS Code, click the Azure tab, select conduit-function-app, and expand the Application Settings node.

Image 21

Right-click the Application Settings node and select Add New Setting.

Image 22

You’ll provide a new setting key and value here. Repeat this step for each application setting name and its value.

  • DATABASE_NAME: conduit_db
  • DATABASE_HOST: <<your-azure-cosmos-account>>.mongo.cosmos.azure.com
  • DATABASE_USER: <<your-azure-cosmos-account>>
  • DATABASE_PASSWORD: <<your-azure-cosmos-password>>

The new application settings will appear in a list, like the screenshot below:

Image 23

Now it’s time to upload these database configurations to your Azure Function app. Right-click Application Settings and choose the Upload Local Settings menu item.

Image 24

Testing the Azure Function App

Now that we’ve uploaded our database settings to the cloud, let’s test the Conduit app running on the Azure Function. Open the Azure Portal and search for and click Function App:

Image 25

Next, click your Azure function app’s name.

Image 26

In the Overview tab, click the URL link.

Image 27

This action opens a new browser tab with the Azure Functions app’s base address.

Image 28

To list the articles, add /api/articles to the URL like this:

https://<<YOUR-FUNCTION-APP>>.azurewebsites.net/api/articles

Image 29

Next, navigate to the /api/articles/create-a-new-implementation-ukwcnm path to browse a specific article’s details, like this:

https:// <<YOUR-FUNCTION-APP>>.azurewebsites.net/api/articles/create-a-new-implementation-ukwcnm

Image 30

To view that particular article’s comments, navigate to the /api/articles/create-a-new-implementation-ukwcnm/comments path:

https:// <<YOUR-FUNCTION-APP>>.azurewebsites.net/api/articles/create-a-new-implementation-ukwcnm/comments

Image 31

Our legacy app’s articles are now available in the cloud via an Azure Function app.

Conclusion

In this final article in the Modernizing Python Apps and Data on Azure series, we discussed moving the legacy app into Azure Serverless Functions. This new approach had some fundamental differences in using the Django Rest Framework compared to the previous articles. Instead of hosting the Django app in an Azure App Service, where we can build, deploy, and scale web apps on a fully-managed platform, we used Azure Functions to listen and respond to events such as HTTP requests.

In moving our app into a serverless compute service, we learned how to create and configure an Azure Function in a Function App. Then we used a WSGI middleware to adapt the Django Rest framework app into the Azure Function.

Integrating your Django Rest Framework app into an Azure Function empowers you to write less code, maintain less infrastructure, and save money. You can avoid the inconvenience of deploying and maintaining servers as the Azure infrastructure provides all the up-to-date resources needed to keep your application running.

Moving a legacy application into the cloud may seem daunting at first. However, by breaking the task into stages and employing handy tools, including Azure’s many options, you can modernize your app to become low-maintenance, flexible, scalable, and resilient in the cloud.

To learn more about how to build and deploy your Python apps in the cloud, check out Python App Development - Python on Azure.

This article is part of the series 'Modernizing Python Apps and Data on Azure View All

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Instructor / Trainer Alura Cursos Online
Brazil Brazil

Comments and Discussions

 
QuestionGreat article Pin
Ryan Peden4-May-22 12:32
professionalRyan Peden4-May-22 12:32 
AnswerRe: Great article Pin
Marcelo Ricardo de Oliveira4-May-22 16:22
Marcelo Ricardo de Oliveira4-May-22 16:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.