Azure Developer Python
Azure Developer Python
b GET STARTED
Get started
Web apps
g TUTORIAL
AI
f QUICKSTART
g TUTORIAL
f QUICKSTART
SQL databases
Machine learning
c HOW-TO GUIDE
Create an ML experiment
Create ML pipelines
Serverless functions
c HOW-TO GUIDE
Developer tools
b GET STARTED
If you're using Azure at work, talk to your company's cloud administrator to get your
credentials used to sign-in to Azure.
Otherwise, you can create an Azure account for free and receive 12 months of popular
services for free and a $200 credit to explore Azure for 30 days.
There are several tools you can use to create and manage Azure resources, depending on your
scenario:
Azure portal - If you're new to Azure and want a web-based user interface to create
and manage a couple of resources.
Azure CLI - If you're more comfortable with command line interfaces.
Azure PowerShell - If you prefer a PowerShell style syntax in their CLI.
Azure Developer CLI - When you want to create repeatable deployments involving many
Azure resources with intricate dependencies. Requires learning Bicep templates.
Azure Tools extension pack - The extension pack contains extensions for working with
some of the most popular Azure services in one convenient package.
You can also use the Azure Management Libraries for Python to create and manage
resources. The management libraries allow you to use Python to implement custom
deployment and management functionality. Here are a few articles that can help you get
started:
Use your favorite tools to write your Python app. If you use Visual Studio Code, you should try
the Python extension for Visual Studio Code .
Most of the instructions in this set of articles use a virtual environment because it's a best
practice. Feel free to use any virtual environment you want, but the article instructions
standardize on venv .
At some point, you might want to install and reference the Azure SDK for Python client
libraries without having to follow the instructions in an article. The Azure SDK Overview is a
great starting point.
Authenticate your app to Azure
When you use the Azure SDK for Python, you must add authentication logic to your app. How
your app authenticates depends on whether you're running your app locally during
development and testing, hosting the app on your own servers, or hosting the app in Azure.
Read Authenticate Python apps to Azure services by using the Azure SDK for Python to
understand more about authentication on Azure.
You'll also need to set up access policies that control what identities (service principals and/or
application IDs) are able to access those resources. Access policies are managed through Azure
Role-Based Access Control (RBAC); some services have more specific access controls as well. As
a cloud developer working with Azure, make sure to familiarize yourself with Azure RBAC
because you use it with just about any resource that has security concerns.
If you're building web apps or APIs (Django, Flask, FastAPI, and so on), consider:
If you're building a web application, see Configure your local environment for deploying
Python web apps on Azure.
Also, if you're building a web API, you should consider using Azure API Management.
Azure Functions
Azure App Service WebJobs
Azure Container Apps
Next steps
Develop a Python web app
Develop a container app
Learn to use the Azure libraries for Python
This article offers a curated list of top learning resources for Python developers who are new to
building AI applications. It includes links to quickstart guides, sample projects, official
documentation, training courses, and other helpful materials.
ノ Expand table
Link Description
OpenAI SDK for The GitHub source code version of the OpenAI Python library, which provides
Python convenient access to the OpenAI API from applications written in the Python
language.
Samples
ノ Expand table
Link Description
Streaming chat A notebook example that demonstrates how to get chat completions to work by
completions using the Azure endpoints. The example focuses on chat completions, but also
introduces other operations available with the API.
Azure embeddings A notebook example that demonstrates how to use embeddings with Azure
endpoints. The example focuses on embeddings, but also introduces other
operations available with the API.
Documentation
ノ Expand table
Link Description
Switch from OpenAI to A guidance article on the small changes you need to make to your code,
Azure OpenAI so you can swap back and forth between OpenAI and the Azure OpenAI
Service.
Quickstart: Get started A quickstart that demonstrates how to set up the services you need and
generating text with Azure write code to prompt a model by using Python.
OpenAI Service
Quickstart: Get started using A quickstart that demonstrates how to work with system, assistant, and
GPT-35-Turbo and GPT-4 user roles to tailor content in response to certain questions.
with Azure OpenAI Service
Quickstart: Chat with Azure A quickstart that helps you add your own data, such as a PDF or other
OpenAI models by using document.
your own data
Quickstart: Get started using A quickstart that demonstrates how to instruct a model to use the built-in
Azure OpenAI Assistants Python code interpreter to solve math problems step by step. This
(Preview) example provides a starting point to use your own AI assistants accessed
through custom instructions.
Deploy model and generate An article with minimal, straightforward detailed steps to deploy a model
text that can programmatically chat.
OpenAI with Microsoft Entra A look at authentication by using Microsoft Entra ID and Azure role-based
ID role-based access control access control.
OpenAI with Azure AD- An article with more complex security scenarios that require Azure role-
managed identities for based access control. Explore how to authenticate to your OpenAI
Azure resources resource with Microsoft Entra ID.
Azure OpenAI in Microsoft A compilation of useful Azure OpenAI in Microsoft Foundry Models
Foundry Models samples resources and code samples to help you get started and accelerate your
technology adoption journey.
Quickstart: Use images in A quickstart that shows how to programmatically ask a model to describe
your AI chats the contents of an image.
Quickstart: Generate images A quickstart that demonstrates how to programmatically generate images
with Azure OpenAI Service by using Dall-E based on a prompt.
Samples
ノ Expand table
Link Description
Integrate speech into your Samples for the Azure Cognitive Services Speech SDK. Links to samples for
apps with Azure AI Speech speech recognition, translation, speech synthesis, and more.
SDK Samples
Extract, classify, and The client Library for Text Analytics. These APIs are part of the Azure AI
understand text within Language service, which provides Natural Language Processing (NLP)
documents using Text features for understanding and analyzing text.
Analytics in Python
Document Translation in A quickstart article that uses Document Translation to translate a source
Python document into a target language while preserving structure and text
formatting.
Question answering in A quickstart article with steps to get an answer (and confidence score) from
Python a body of text that you send along with your question.
Conversational Language The client library for Conversational Language Understanding (CLU). CLU is
Understanding in Python a cloud-based conversational AI service that can extract intents and entities
in conversations. CLU acts like an orchestrator to select the best candidate
to analyze conversations to get the best response from apps like QnA, Luis,
and Conversation App.
Analyze images Sample code and setup documents for the Microsoft Azure AI Image
Analysis SDK.
Link Description
Azure AI Content Safety The SDK can help detect harmful user-generated and AI-generated content
SDK for Python in applications and services. Content Safety includes text and image APIs
that allow you to detect material that is harmful.
Documentation
ノ Expand table
Content Safety An AI service that detects unwanted content. Content Safety API Quickstart
reference
Language Build apps with industry-leading natural language Text Analytics API Quickstart
understanding capabilities. reference
Search Bring AI-powered cloud search to your Search API reference Quickstart
applications.
Speech Speech to text, text to speech, translation, and Speech API Quickstart
speaker recognition. reference
Translator Use AI-powered translation to translate more than Translation API Quickstart
100 in-use, at-risk and endangered languages and reference
dialects.
Vision Analyze content in images and videos. Image Analysis API Quickstart
reference
Training
ノ Expand table
Link Description
Generative AI for Learn the fundamentals of building Generative AI apps with our 18-lesson
beginners workshop comprehensive course by Microsoft Cloud Advocates.
Get started with Azure Azure AI services are building blocks of AI functionality you can integrate into
AI services your applications. Complete this learning path to explore how to provision,
Link Description
secure, monitor, and deploy Azure AI services resources and use them to build
intelligent solutions.
Microsoft Azure AI Complete this learning path to understand how large language models form
Fundamentals: the foundation of generative AI. Explore how Azure OpenAI Service provides
Generative AI access to the latest generative AI technology. Learn how Azure OpenAI prompts
and responses can be fine-tuned and how Microsoft's responsible AI principles
drive ethical AI advancements.
Develop Generative AI Azure OpenAI Service provides access to OpenAI's powerful large language
solutions with Azure models such as ChatGPT, GPT, Codex, and Embeddings models. Complete this
OpenAI Service learning path for developers and explore how to generate code, images, and
text by using the Azure OpenAI SDK and other Azure services.
Build AI apps with Complete this learning path to explore Azure AI and Azure Machine Learning
Azure Database for Services integrations provided by the Azure AI extension for Azure Database for
PostgreSQL PostgreSQL - Flexible Server. Learn how these services can enable you to build
AI-powered apps.
AI application templates
AI application templates supply you with well-maintained, easy to deploy reference
implementations that provide a high-quality starting point for your AI apps.
There are two categories of AI app templates, building blocks and end-to-end solutions.
Building blocks are smaller-scale samples that focus on specific scenarios and tasks. End-to-
end solutions are comprehensive reference samples that include documentation, source code,
and deployment features. You can build on the solutions and extend them for your own
purposes.
To review a list of key templates available for each programming language, see AI app
templates.
To browse all available templates, see the AI app templates on the Azure Developer CLI
gallery .
This article shows how to deploy and run the Chat with your own data sample by using
example code for Python . This sample chat application is built with Python, Azure OpenAI
Service, and Retrieval Augmented Generation (RAG) through Azure AI Search.
The app provides answers to user questions about employee benefits at a fictional company. It
uses Retrieval-Augmented Generation (RAG) to reference content from supplied PDF files,
which may include:
An employee handbook
A benefits overview document
A list of company roles and expectations
By analyzing these documents, the app can respond to natural language queries with accurate,
contextually relevant answers. This approach demonstrates how you can use your own data to
power intelligent, domain-specific chat experiences with Azure OpenAI and Azure AI Search.
You also learn how to configure the app’s settings to modify its response behavior.
After completing the steps in this article, you can begin customizing the project with your own
code. This article is part of a series that guides you through building a chat app with Azure
OpenAI Service and Azure AI Search. Other articles in the series include:
.NET
Java
JavaScript
JavaScript frontend with Python backend
7 Note
This article is based on one or more AI app templates, which serve as well-maintained
reference implementations. These templates are designed to be easy to deploy and
provide a reliable, high-quality starting point for building your own AI applications.
A web application that hosts the interactive chat interface (usually built with Python Flask
or JavaScript/React) and sends user questions to the backend for processing.
An Azure AI Search resource that performs intelligent search over indexed documents
(PDFs, Word files, etc.) and returns relevant document excerpts (chunks) for use in
responses.
An Azure OpenAI Service instance that:
Converts documents and user questions into vector representations for semantic
similarity search.
Extracts important keywords to refine Azure AI Search queries.
Synthesizes final responses using the retrieved data and user query.
User submits a question: A user enters a natural language question through the web app
interface.
Azure OpenAI processes the question: The backend uses Azure OpenAI to:
Generate an embedding of the question using the text-embedding-ada-002 model.
Optionally extract keywords to refine search relevance
Azure AI Search retrieves relevant data: The embedding or keywords are used to to
perform a semantic search over indexed content (such as, PDFs) in Azure AI Search.
Combine results with the question: The most relevant document excerpts (chunks) are
combined with the user’s original question.
Azure OpenAI generates a response: The combined input is passed to a GPT model (such
as, gpt-35-turbo or gpt-4), which generates a context-aware answer.
The response is returned to the user: The generated answer is displayed in the chat
interface.
Prerequisites
A development container environment is available with all dependencies required to
complete this article. You can run the development container in GitHub Codespaces (in a
browser) or locally by using Visual Studio Code.
Access granted to Azure OpenAI in your Azure subscription. In most cases, you can
create custom content filters and manage severity levels with general access to Azure
OpenAI models. Registration for approval-based access isn't required for general
access. For more information, see Limited Access features for Azure AI services.
A GitHub account. Required to fork the repository and use GitHub Codespaces or
clone it locally.
To complete this sample, there may be a small cost incurred from using services like Azure
OpenAI, AI Search, and storage. Once you're done evaluating or deploying the app, you can
delete all provisioned resources to avoid ongoing charges.
For a detailed breakdown of expected costs, see the Cost estimation in the GitHub repository
for the sample.
For the simplest and most streamlined setup, use GitHub Codespaces . GitHub
Codespaces runs a development container managed by GitHub and provides Visual Studio
Code for the Web as the user interface (UI). This environment includes all required tools,
SDKs, extensions, and dependencies preinstalled—so you can start developing
immediately without manual configuration.
) Important
All GitHub accounts can use GitHub Codespaces for up to 60 hours free each month
with 2 core instances. If you exceed the free quota or use larger compute options,
standard GitHub Codespaces billing rates apply. For more information, see GitHub
Codespaces - Monthly included storage and core hours .
1. To begin working with the sample project, create a new GitHub codespace on the
main branch of the Azure-Samples/azure-search-openai-demo GitHub repository.
Right-click the GitHub Codespaces - Open option at the top of the repository page
and select Open link in new window. This ensures that the development container is
launched in a full-screen, dedicated browser tab, giving you access to both the
source code and the built-in documentation.
2. On the Create a new codespace page, review the codespace configuration settings,
and then select Create codespace:
Wait for the GitHub codespace to start. The startup process can take a few minutes.
3. After the GitHub codespace opens, sign in to Azure with the Azure Developer CLI by
entering the following command in the Terminal pane of the codespace:
Bash
azd auth login
a. Copy the security code in the Terminal pane and select Enter. A browser window
opens.
b. At the prompt, paste the security code into the browser field.
You complete the remaining GitHub Codespaces tasks in this article in the context of this
development container.
Use the folloowing steps to deploy the app with the Azure Developer CLI (azd).
) Important
1. In the Visual Studio Code Terminal pane, create the Azure resources and deploy the
source code by running the following azd command:
Bash
azd up
2. The process prompts you for one or more of the following settings based on your
configuration:
Environment name: This value is used as part of the resource group name. Enter a
short name with lowercase letters and dashes ( - ), such as myenv. Uppercase letters,
numbers, and special characters aren't supported.
Subscription: Select a subscription to create the resources. If you don't see your
desired subscription, use the arrow keys to scroll the full list of available
subscriptions.
Location: This region location is used for most resources, including hosting. Select a
region location near you geographically.
Location for OpenAI model or Document Intelligence resource: Select the location
nearest you geographically. If the region you selected for your Location is available
for this setting, select the same region.
It take can take some time for the app to deploy. Wait for the deployment to complete
before continuing.
3. After the app successfully deploys, the Terminal pane displays an endpoint URL:
1. In the chat app, select the What happens in a performance review? option, or enter the
same text in the chat text box. The app returns the initial response:
3. GitHub Codespaces opens the right Citation pane with three tabbed regions and the
focus is on the Citation tab:
GitHub Codespaces provides three tabs of information to help you understand how the
chat app generated the answer:
ノ Expand table
Tab Description
Thought Displays a script of the question/answer interactions in the chat. You can view the
Process content provided by the chat app system , questions entered by the user , and
clarifications made by the system assistant .
Supporting Lists the information used to answer your question and the source material. The
Content number of source material citations is specified by the Developer settings. The
default number of citations is 3.
Citation Shows the original source contain for the selected citation.
4. When you're done, select the currently selected tab in the right pane. The right pane
closes.
ノ Expand table
Setting Description
Override prompt Overrides the prompt used to generate the answer based on the question and
template search results.
Setting Description
Temperature Sets the temperature of the request to the large language model (LLM) that
generates the answer. Higher temperatures result in more creative responses, but
they might be less grounded.
Seed Sets a seed to improve the reproducibility of the model's responses. The seed can be
any integer.
Minimum search Sets a minimum score for search results returned from Azure AI Search. The score
score range depends on whether you use Hybrid (default), Vectors only, or Text only for
the Retrieval mode setting.
Minimum Sets a minimum score for search results returned from the semantic reranker. The
reranker score score always ranges between 0-4. The higher the score, the more semantically
relevant the result is to the question.
Retrieve this Sets the number of search results to retrieve from Azure AI Search. More results can
many search increase the likelihood of finding the correct answer, but might lead to the model
results getting 'lost in the middle.' You can see the returned sources in the Thought Process
and Supporting Content tabs of the Citation pane.
Include category Specifies the categories to include when generating the search results. Use the
dropdown list to make your selection. The default action is to include All categories.
Exclude category Specifies any categories to exclude from the search results. There are no categories
used in the default data set.
Use semantic Enables the Azure AI Search semantic ranker, a model that reranks search results
ranker for based on semantic similarity to the user's query.
retrieval
Use semantic Sends semantic captions to the LLM instead of the full search result. A semantic
captions caption is extracted from a search result during the process of semantic ranking.
Suggest follow- Asks the LLM to suggest follow-up questions based on the user's query.
up questions
Retrieval mode Sets the retrieval mode for the Azure AI Search query. The default action is Vectors +
Text (Hybrid), which uses a combination of vector search and full text search. The
Vectors option uses only vector search. The Text option uses only full text search.
The Hybrid approach is optimal.
Stream chat Continuously streams the response to the chat UI as the content is generated.
completion
responses
The following steps walk you through the process of changing the settings.
3. In the chat app, reask the question, this time by entering the text in the question box:
text
4. Select the Developer settings option again, and unselect Use semantic ranker for
retrieval option. Close the settings.
5. Ask the same question again, and notice the difference in the answer from the chat app.
With the Semantic ranker: "During a performance review at Contoso Electronics, your
supervisor will discuss your performance over the past year and provide feedback on
areas for improvement. You will also have the opportunity to discuss your goals and
objectives for the upcoming year. The review is a two-way dialogue between managers
and employees, and it is encouraged for employees to be honest and open during the
process (1). The feedback provided during the review should be positive and constructive,
aimed at helping employees develop and grow in their roles. Employees will receive a
written summary of their performance review, which will include a rating of their
performance, feedback, and goals and objectives for the upcoming year (1)."
Without the Semantic ranker: "During a performance review at Contoso Electronics, your
supervisor will discuss your performance over the past year and provide feedback on
areas for improvement. It is a two-way dialogue where you are encouraged to be honest
and open (1). The feedback provided during the review should be positive and
constructive, aimed at helping you develop and grow in your role. You will receive a
written summary of the review, including a rating of your performance, feedback, and
goals for the upcoming year (1)."
Clean up resources
After you complete the exercise, it's a best practice to remove any resources that are no longer
required.
Delete the Azure resources and remove the source code by running the following azd
command:
Bash
purge : Deleted resources are immediately purged. This option allows you to reuse the
GitHub Codespaces
Deleting the GitHub Codespaces environment ensures that you can maximize the amount
of free per-core hours entitlement that you get for your account.
) Important
For more information about your GitHub account's entitlements, see GitHub
Codespaces - Monthly included storage and core hours .
1. Sign in to the GitHub Codespaces dashboard .
2. On the dashboard, locate your currently running codespaces sourced from the
Azure-Samples/azure-search-openai-demo GitHub repository:
3. Open the context menu for the codespace and select Delete:
Get help
This sample repository offers troubleshooting information .
If your issue isn't addressed, add your issue to the repository's Issues webpage.
Related content
Get the source code for the sample used in this article
Build a chat app with Azure OpenAI best practice solution architecture
Access control in Generative AI Apps with Azure AI Search
Build an Enterprise ready OpenAI solution with Azure API Management
Outperforming vector search with hybrid retrieval and ranking capabilities
Get started with chat document security for
Python
テ Summarize this article for me
When you build a chat application by using the Retrieval Augmented Generation (RAG) pattern
with your own data, make sure that each user receives an answer based on their permissions.
Follow the process in this article to add document access control to your chat app.
Authorized user: This person should have access to answers contained within the
documents of the chat app.
Unauthorized user: This person shouldn't have access to answers from secured
documents they don't have authorization to see.
7 Note
This article uses one or more AI app templates as the basis for the examples and
guidance in the article. AI app templates provide you with well-maintained reference
implementations that are easy to deploy. They help to ensure a high-quality starting point
for your AI apps.
Architectural overview
Without a document security feature, the enterprise chat app has a simple architecture by
using Azure AI Search and Azure OpenAI Models in Microsoft Foundry. An answer is
determined from queries to Azure AI Search where the documents are stored, in combination
with a response from an Azure OpenAI GPT model. No user authentication is used in this
simple flow.
To add security for the documents, you need to update the enterprise chat app:
Because the authorization isn't natively contained in Azure AI Search, you need to add a field
to hold user or group information, and then filter any documents that don't match. To
implement this technique, you need to:
Create a document access control field in your index dedicated to storing the details of
users or groups with document access.
Populate the document's access control field with the relevant user or group details.
Update this access control field whenever there are changes in user or group access
permissions.
If your index updates are scheduled with an indexer, changes are picked up on the next indexer
run. If you don't use an indexer, you need to manually reindex.
In this article, the process of securing documents in Azure AI Search is made possible with
example scripts, which you as the search administrator would run. The scripts associate a single
document with a single user identity. You can take these scripts and apply your own security
and production requirements to scale to your needs.
Parameter Purpose
AZURE_USE_AUTHENTICATION When set to true , enables user sign-in to the chat app and
Azure App Service authentication. Enables Use oid security
filter in the chat app Developer settings.
Use the following sections to understand the security profiles supported in this sample. This
article configures the Enterprise profile.
Environment variables:
AZURE_USE_AUTHENTICATION=true
AZURE_ENABLE_GLOBAL_DOCUMENTS_ACCESS=true
AZURE_ENFORCE_ACCESS_CONTROL=true
Environment variables:
AZURE_USE_AUTHENTICATION=true
AZURE_ENABLE_GLOBAL_DOCUMENTS_ACCESS=true
AZURE_ENFORCE_ACCESS_CONTROL=true
AZURE_ENABLE_UNAUTHENTICATED_ACCESS=true
Prerequisites
A development container environment is available with all the dependencies that are
required to complete this article. You can run the development container in GitHub Codespaces
(in a browser) or locally by using Visual Studio Code.
GitHub account
) Important
All GitHub accounts can use GitHub Codespaces for up to 60 hours free each month
with two core instances. For more information, see GitHub Codespaces monthly
included storage and core hours .
1. Start the process to create a new GitHub codespace on the main branch of the
Azure-Samples/azure-search-openai-demo GitHub repository.
2. Right-click the following button, and select Open link in new windows to have the
development environment and the documentation available at the same time.
3. On the Create codespace page, review the codespace configuration settings, then
select Create new codespace.
4. Wait for the codespace to start. This startup process can take a few minutes.
5. In the terminal at the bottom of the screen, sign in to Azure with the Azure
Developer CLI.
Bash
azd auth login
Azure CLI
az account list --query "[].{subscription_id:id, name:name, tenantId:tenantId}" -o
table
If you get an error about your tenant's conditional access policy, you need a second tenant
without a conditional access policy.
Your first tenant, associated with your user account, is used for the AZURE_TENANT_ID
environment variable.
Your second tenant, without conditional access, is used for the AZURE_AUTH_TENANT_ID
environment variable to access Microsoft Graph. For tenants with a conditional access
policy, find the ID of a second tenant without a conditional access policy or create a new
tenant.
Console
azd env set AZURE_USE_AUTHENTICATION true
azd env set AZURE_ENABLE_GLOBAL_DOCUMENTS_ACCESS true
azd env set AZURE_ENFORCE_ACCESS_CONTROL true
2. Run the following command to set the tenant, which authorizes the user sign-in to the
hosted application environment. Replace <YOUR_TENANT_ID> with the tenant ID.
Console
azd env set AZURE_TENANT_ID <YOUR_TENANT_ID>
7 Note
If you have a conditional access policy on your user tenant, you need to specify an
authentication tenant.
Bash
azd up
ノ Expand table
Prompt Answer
Wait 5 or 10 minutes after the app deploys to allow the app to start up.
4. Select the URL labeled (✓) Done: Deploying service webapp to open the chat application
in a browser.
5. Agree to the app authentication pop-up.
6. When the chat app appears, notice in the upper-right corner that your user is signed in.
7. Open Developer settings and notice that both of the following options are selected and
disabled for change:
9. You get an answer like: The provided sources do not contain specific information about
the role of a Product Manager at Contoso Electronics.
Azure Storage
Account name
Container name
Blob/document URL for role_library.pdf
User's ID in Microsoft Entra ID
When this information is known, update the Azure AI Search index oids field for the
role_library.pdf document.
3. Use the following Azure CLI commands to get the URL of the role_library.pdf blob in
the content container.
Azure CLI
az storage blob url \
--account-name <REPLACE_WITH_AZURE_STORAGE_ACCOUNT \
--container-name 'content' \
--name 'role_library.pdf'
ノ Expand table
Parameter Purpose
Python
python ./scripts/[Link] --acl-type oids --acl-action add --acl
<REPLACE_WITH_YOUR_USER_OBJECT_ID> --url <REPLACE_WITH_YOUR_DOCUMENT_URL>
ノ Expand table
Parameter Purpose
-v Verbose output.
--acl- Add to a Search index field. Other options include enable_acls , remove , remove_all ,
action and view .
console.
Loading azd .env file from current environment...
Creating Python virtual environment "app/backend/.venv"...
Installing dependencies from "[Link]" into virtual environment (in
quiet mode)...
Running [Link]. Arguments to script: -v --acl-type oids --acl-action add
--acl 00000000-0000-0000-0000-000000000000 --url
[Link]
Found 58 search documents with storageUrl
[Link]
Adding acl 00000000-0000-0000-0000-000000000000 to 58 search documents
3. Optionally, use the following command to verify that your permission is listed for the file
in Azure AI Search.
Python
python ./scripts/[Link] -v --acl-type groups --acl-action view --url
<REPLACE_WITH_YOUR_DOCUMENT_URL>
ノ Expand table
Parameter Purpose
-v Verbose output.
--acl- View a Search index field oids . Other options include enable_acls , remove ,
action remove_all , and add .
console.
Loading azd .env file from current environment...
Creating Python virtual environment "app/backend/.venv"...
Installing dependencies from "[Link]" into virtual environment (in
quiet mode)...
Running [Link]. Arguments to script: -v --acl-type oids --acl-action view
--acl 00000000-0000-0000-0000-000000000000 --url
[Link]
Found 58 search documents with storageUrl
[Link]
[00000000-0000-0000-0000-000000000000]
The array at the end of the output includes your USER_OBJECT_ID parameter and is used to
determine if the document is used in the answer with Azure OpenAI.
4. Select gptkbindex.
JSON
{
"search": "*",
"select": "sourcefile, oids",
"filter": "oids/any()"
}
This JSON searches all documents where the oids field has any value and returns the
sourcefile and oids fields.
7. If the role_library.pdf doesn't have your OID, return to the Provide user access to a
document in Azure Search section and complete the steps.
2. Enter the same query so that the role_library content is used in the Azure OpenAI
answer: What does a product manager do? .
3. View the result, which now includes the appropriate answer from the role library
document.
Clean up resources
The following steps walk you through the process of cleaning up the resources you used.
Run the following Azure Developer CLI command to delete the Azure resources and remove
the source code.
Bash
azd down --purge
GitHub Codespaces
Deleting the GitHub Codespaces environment ensures that you can maximize the amount
of free per-core hours entitlement that you get for your account.
) Important
For more information about your GitHub account's entitlements, see GitHub
Codespaces monthly included storage and core hours .
2. Locate your currently running codespaces that are sourced from the Azure-
Samples/azure-search-openai-demo GitHub repository.
3. Open the context menu for the codespace and then select Delete.
Get help
The sample repository offers troubleshooting information .
Troubleshooting
This section helps you troubleshoot issues specific to this article.
Provide authentication tenant
When your authentication is in a separate tenant from your hosting application, you need to
set that authentication tenant with the following process.
1. Run the following command to configure the sample to use a second tenant for the
authentication tenant.
Console
azd env set AZURE_AUTH_TENANT_ID <REPLACE-WITH-YOUR-TENANT-ID>
ノ Expand table
Parameter Purpose
AZURE_AUTH_TENANT_ID If AZURE_AUTH_TENANT_ID is set, it's the tenant that hosts the app.
Console
azd up
Related content
Build a chat app with Azure OpenAI best-practices solution architecture.
Learn about access control in generative AI apps with Azure AI Search .
Build an enterprise-ready Azure OpenAI solution with Azure API Management .
See Azure AI Search: Outperforming vector search with hybrid retrieval and ranking
capabilities .
This sample implements a chat app by using Python, Azure OpenAI Service, and Retrieval
Augmented Generation (RAG) in Azure AI Search to get answers about employee benefits at a
fictitious company. The app is seeded with PDF files that include the employee handbook, a
benefits document, and a list of company roles and expectations.
After you finish this procedure, you can start modifying the new project with your custom code
and redeploy, knowing that your chat app is accessible only through the private network.
Architectural overview
The default deployment creates a chat app with public endpoints.
For chat apps enriched with private data, securing access to your chat app is crucial. This article
presents a solution by using a virtual network.
Within the virtual network, there's a separate subnet for the Azure App Service app versus the
other back-end Azure services. This structure makes it easy to apply different network security
group rules to each subnet.
Within the virtual network, the services use private endpoints to communicate with each other.
Each private endpoint is associated with a private Domain Name System (DNS) zone to resolve
the private endpoint's name to an IP address within the virtual network.
Deployment steps
We recommend that you deploy the solution twice. Deploy once with public access to validate
that the chat app is working correctly. Deploy again with private access to secure your chat app
by using a virtual network.
Prerequisites
A development container environment is available with all dependencies that are required to
finish this article. You can run the development container in GitHub Codespaces (in a browser)
or locally by using Visual Studio Code.
Codespaces (recommended)
Administrator or Owner.
A GitHub account.
Deploying with private networking adds extra cost to your deployment. Once you're done
evaluating or deploying the app, you can delete all provisioned resources to avoid ongoing
charges.
For a detailed breakdown of expected costs, see the Before you begin in the GitHub
repository for the sample.
) Important
All GitHub accounts can use GitHub Codespaces for up to 60 hours free each month
with two core instances. For more information, see GitHub Codespaces monthly
included storage and core hours .
1. Start the process to create a new GitHub codespace on the main branch of the
Azure-Samples/azure-search-openai-demo GitHub repository.
2. Right-click the following button, and select Open link in new windows to have the
development environment and the documentation available at the same time.
3. On the Create codespace page, review the codespace configuration settings, and
then select Create codespace.
4. Wait for the codespace to start. This startup process can take a few minutes.
5. In the terminal at the bottom of the screen, sign in to Azure with the Azure
Developer CLI:
Bash
6. Copy the code from the terminal and then paste it into a browser. Follow the
instructions to authenticate with your Azure account.
The remaining tasks in this article take place in the context of this development container.
Custom settings
This solution configures and deploys the infrastructure based on custom settings configured
with the Azure Developer CLI. The following table explains the custom settings for this solution.
ノ Expand table
Setting Description
AZURE_USE_VPN_GATEWAY Controls deployment of a VPN gateway for the virtual network. If you
don't use this and public access is disabled, you need a different way to
connect to the virtual network. The TRUE value means that a VPN gateway
is deployed for connectivity.
1. Run the following command to configure this solution for public access:
Console
azd env set AZURE_PUBLIC_NETWORK_ACCESS Enabled
When you're asked for an environment name, remember that the environment name is
used to create the resource group. Enter a meaningful name. If you're on a team or in an
organization, include your name, as in morgan-chat-private-endpoints . Make note of the
environment name. You need it later to find the resources in the Azure portal.
2. Run the following command to include provisioning the virtual network resources.
Remember that the deployment doesn't restrict access until the second deployment.
Console
azd env set AZURE_USE_PRIVATE_ENDPOINT true
Console
azd up
Provisioning resources is the most time-consuming part of the deployment process. Wait
for the deployment to finish before you continue.
4. At the end of the deployment process, the app endpoint appears. Copy that endpoint
into a browser to open the chat app. Select one of the questions on the cards and then
wait for the answer.
Make note of the endpoint URL because you need it again later in the article.
1. Run the following command to use a VPN gateway for accessing the virtual network:
Console
azd env set AZURE_USE_VPN_GATEWAY true
Console
azd env set AZURE_PUBLIC_NETWORK_ACCESS Disabled
3. Run the following command to change the resource configuration. This command doesn't
redeploy the application code because only the infrastructure configuration changed.
Console
azd provision
4. After the provisioning finishes, open the chat app in a browser again. The chat app is no
longer accessible because the public endpoint is disabled.
Clean up resources
The following steps walk you through the process of cleaning up the resources you used.
GitHub Codespaces
Deleting the GitHub Codespaces environment ensures that you can maximize the amount
of free per-core hours entitlement that you get for your account.
) Important
For more information about your GitHub account's entitlements, see GitHub
Codespaces monthly included storage and core hours .
2. Locate your currently running codespaces that are sourced from the Azure-
Samples/azure-search-openai-demo GitHub repository.
3. Open the context menu for the codespace and then select Delete.
Get help
This sample repository offers troubleshooting information .
If your issue isn't addressed, add your issue to the repository's Issues webpage.
Related content
See the enterprise chat app GitHub repository .
Build a chat app with Azure OpenAI best-practices solution architecture.
Learn about access control in generative AI apps with Azure AI Search .
This article shows you how to evaluate a chat app's answers against a set of correct or ideal
answers (known as ground truth). Whenever you change your chat application in a way that
affects the answers, run an evaluation to compare the changes. This demo application offers
tools that you can use today to make it easier to run evaluations.
Use provided sample prompts tailored to the subject domain. These prompts are already
in the repository.
Generate sample user questions and ground truth answers from your own documents.
Run evaluations by using a sample prompt with the generated user questions.
Review analysis of answers.
7 Note
This article uses one or more AI app templates as the basis for the examples and
guidance in the article. AI app templates provide you with well-maintained reference
implementations that are easy to deploy. They help to ensure a high-quality starting point
for your AI apps.
Architectural overview
Key components of the architecture include:
Azure-hosted chat app: The chat app runs in Azure App Service.
Microsoft AI Chat Protocol: The protocol provides standardized API contracts across AI
solutions and languages. The chat app conforms to the Microsoft AI Chat Protocol ,
which allows the evaluations app to run against any chat app that conforms to the
protocol.
Azure AI Search: The chat app uses Azure AI Search to store the data from your own
documents.
Sample questions generator: The tool can generate many questions for each document
along with the ground truth answer. The more questions there are, the longer the
evaluations.
Evaluator: The tool runs sample questions and prompts against the chat app and returns
the results.
Review tool: The tool reviews the results of the evaluations.
Diff tool: The tool compares the answers between evaluations.
When you deploy this evaluation to Azure, the Azure OpenAI Service endpoint is created for
the GPT-4 model with its own capacity. When you evaluate chat applications, it's important that
the evaluator has its own Azure OpenAI resource by using GPT-4 with its own capacity.
Prerequisites
An Azure subscription. Create one for free .
Complete the previous chat app procedure to deploy the chat app to Azure. This resource
is required for the evaluations app to work. Don't complete the "Clean up resources"
section of the previous procedure.
You need the following Azure resource information from that deployment, which is
referred to as the chat app in this article:
Chat API URI. The service backend endpoint shown at the end of the azd up process.
Azure AI Search. The following values are required:
Resource name: The name of the Azure AI Search resource name, reported as
Search service during the azd up process.
Index name: The name of the Azure AI Search index where your documents are
stored. You can find it in the Azure portal for the Search service.
The Chat API URL allows the evaluations to make requests through your backend
application. The Azure AI Search information allows the evaluation scripts to use the same
deployment as your backend, loaded with the documents.
After you have this information collected, you shouldn't need to use the chat app
development environment again. This article refers to it later, several times, to indicate
how the evaluations app uses the chat app. Don't delete the chat app resources until you
finish the entire procedure in this article.
A development container environment is available with all the dependencies that are
required to complete this article. You can run the development container in GitHub
Codespaces (in a browser) or locally by using Visual Studio Code.
GitHub account
Open a development environment
Follow these instructions to set up a preconfigured development environment with all the
required dependencies to complete this article. Arrange your monitor workspace so that you
can see this documentation and the development environment at the same time.
This article was tested with the switzerlandnorth region for the evaluation deployment.
) Important
All GitHub accounts can use GitHub Codespaces for up to 60 hours free each month
with two core instances. For more information, see GitHub Codespaces monthly
included storage and core hours .
1. Start the process to create a new GitHub codespace on the main branch of the
Azure-Samples/ai-rag-chat-evaluator GitHub repository.
3. On the Create codespace page, review the codespace configuration settings, and
then select Create new codespace.
4. Wait for the codespace to start. This startup process can take a few minutes.
5. In the terminal at the bottom of the screen, sign in to Azure with the Azure
Developer CLI:
Bash
6. Copy the code from the terminal and then paste it into a browser. Follow the
instructions to authenticate with your Azure account.
7. Provision the required Azure resource, Azure OpenAI Service, for the evaluations app:
Bash
azd up
This AZD command doesn't deploy the evaluations app, but it does create the Azure
OpenAI resource with a required GPT-4 deployment to run the evaluations in the
local development environment.
The remaining tasks in this article take place in the context of this development container.
The name of the GitHub repository appears in the search bar. This visual indicator helps
you distinguish the evaluations app from the chat app. This ai-rag-chat-evaluator repo is
referred to as the evaluations app in this article.
Prepare environment values and configuration
information
Update the environment values and configuration information with the information you
gathered during Prerequisites for the evaluations app.
Bash
cp .[Link] .env
2. Run this command to get the required values for AZURE_OPENAI_EVAL_DEPLOYMENT and
AZURE_OPENAI_SERVICE from your deployed resource group. Paste those values into the
.env file.
shell
3. Add the following values from the chat app for its Azure AI Search instance to the .env
file, which you gathered in the Prerequisites section.
Bash
AZURE_SEARCH_SERVICE="<service-name>"
AZURE_SEARCH_INDEX="<index-name>"
1. Create a new file named my_config.json and copy the following content into it:
JSON
{
"testdata_path": "my_input/[Link]",
"results_dir": "my_results/experiment<TIMESTAMP>",
"target_url": "[Link]
"target_parameters": {
"overrides": {
"top": 3,
"temperature": 0.3,
"retrieval_mode": "hybrid",
"semantic_ranker": false,
"prompt_template": "<READFILE>my_input/prompt_refined.txt",
"seed": 1
}
}
}
The overrides object contains any configuration settings that are needed for the
application. Each application defines its own set of settings properties.
2. Use the following table to understand the meaning of the settings properties that are
sent to the chat app.
ノ Expand table
Settings Description
property
semantic_ranker Whether to use semantic ranker, a model that reranks search results based on
semantic similarity to the user's query. We disable it for this tutorial to reduce
costs.
temperature The temperature setting for the model. The default is 0.3 .
prompt_template An override of the prompt used to generate the answer based on the question
and search results.
seed The seed value for any calls to GPT models. Setting a seed results in more
consistent results across evaluations.
3. Change the target_url value to the URI value of your chat app, which you gathered in
the Prerequisites section. The chat app must conform to the chat protocol. The URI has
the following format: [Link] . Make sure the protocol and the chat
route are part of the URI.
Generate sample data
To evaluate new answers, they must be compared to a ground truth answer, which is the ideal
answer for a particular question. Generate questions and answers from documents that are
stored in Azure AI Search for the chat app.
Bash
python -m evaltools generate --output=my_input/[Link] --persource=2 --
numquestions=14
The question-and-answer pairs are generated and stored in my_input/[Link] (in JSONL
format ) as input to the evaluator that's used in the next step. For a production evaluation,
you would generate more question-and-answer pairs. More than 200 are generated for this
dataset.
7 Note
Only a few questions and answers are generated per source so that you can quickly
complete this procedure. It isn't meant to be a production evaluation, which should have
more questions and answers per source.
ノ Expand table
results_dir my_results/experiment_refined
prompt_template <READFILE>my_input/prompt_refined.txt
txt
If there isn't enough information below, say you don't know. Do not generate
answers that don't use the sources below. If asking a clarifying question to
the user would help, ask the question.
Use clear and concise language and write in a confident yet friendly tone. In
your answers, ensure the employee understands how your response connects to the
information in the sources and include all citations necessary to help the
employee validate the answer provided.
Each source has a name followed by a colon and the actual information. Always
include the source name for each fact you use in the response. Use square
brackets to reference the source, e.g. [[Link]]. Don't combine sources, list
each source separately, e.g. [[Link]][[Link]].
Bash
python -m evaltools evaluate --config=my_config.json --numquestions=14
This script created a new experiment folder in my_results/ with the evaluation. The folder
contains the results of the evaluation.
ノ Expand table
evaluate_parameters.json The parameters used for the evaluation. Similar to [Link] but
includes other metadata like time stamp.
eval_results.jsonl Each question and answer, along with the GPT metrics for each
question-and-answer pair.
ノ Expand table
Property New value
results_dir my_results/experiment_weak
prompt_template <READFILE>my_input/prompt_weak.txt
txt
You are a helpful assistant.
Bash
python -m evaltools evaluate --config=my_config.json --numquestions=14
ノ Expand table
The default temperature is 0.7. The higher the temperature, the more creative the
answers.
text
Your job is to answer questions to the best of your ability. You will be given
sources but you should IGNORE them. Be creative!
2. The configuration object should look like the following example, except that you replaced
results_dir with your path:
JSON
{
"testdata_path": "my_input/[Link]",
"results_dir": "my_results/prompt_ignoresources_temp09",
"target_url": "[Link]
"target_parameters": {
"overrides": {
"temperature": 0.9,
"semantic_ranker": false,
"prompt_template": "<READFILE>my_input/prompt_ignoresources.txt"
}
}
}
Bash
Bash
python -m evaltools summary my_results
Value Description
Groundedness Checks how well the model's responses are based on factual, verifiable
information. A response is considered grounded if it's factually accurate and
reflects reality.
Relevance Measures how closely the model's responses align with the context or the prompt.
A relevant response directly addresses the user's query or statement.
Coherence Checks how logically consistent the model's responses are. A coherent response
maintains a logical flow and doesn't contradict itself.
Citation Indicates if the answer was returned in the format requested in the prompt.
4. The results should indicate that all three evaluations had high relevance while the
experiment_ignoresources_temp09 had the lowest relevance.
1. Select two of the evaluations to compare, and then use the same review tool to compare
the answers.
Bash
python -m evaltools diff my_results/experiment_refined
my_results/experiment_ignoresources_temp09
Compare different answers to understand how the prompt and question affect the answer
quality.
Generate a separate set of questions and ground truth answers for each document in the
Azure AI Search index. Then rerun the evaluations to see how the answers differ.
Alter the prompts to indicate shorter or longer answers by adding the requirement to the
end of the prompt. An example is Please answer in about 3 sentences.
To delete the Azure resources and remove the source code, run the following Azure Developer
CLI command:
Bash
azd down --purge
Clean up GitHub Codespaces and Visual Studio Code
GitHub Codespaces
Deleting the GitHub Codespaces environment ensures that you can maximize the amount
of free per-core hours entitlement that you get for your account.
) Important
For more information about your GitHub account's entitlements, see GitHub
Codespaces monthly included storage and core hours .
2. Locate your currently running codespaces that are sourced from the Azure-
Samples/ai-rag-chat-evaluator GitHub repository.
3. Open the context menu for the codespace, and then select Delete.
Return to the chat app article to clean up those resources.
JavaScript
Python
Related content
See the evaluations repository .
See the enterprise chat app GitHub repository .
Build a chat app with Azure OpenAI best-practices solution architecture.
Learn about access control in generative AI apps with Azure AI Search .
Build an enterprise-ready Azure OpenAI solution with Azure API Management .
See Azure AI Search: Outperforming vector search with hybrid retrieval and ranking
capabilities .
Learn how to add load balancing to your application to extend the chat app beyond the Azure
OpenAI Models in Microsoft Foundry token and model quota limits. This approach uses Azure
Container Apps to create three Azure OpenAI endpoints and a primary container to direct
incoming traffic to one of the three endpoints.
Chat app
If you haven't deployed the chat app yet, wait until after the load balancer sample is
deployed.
If you already deployed the chat app once, change the environment variable to
support a custom endpoint for the load balancer and redeploy it again.
7 Note
This article uses one or more AI app templates as the basis for the examples and
guidance in the article. AI app templates provide you with well-maintained reference
implementations that are easy to deploy. They help to ensure a high-quality starting point
for your AI apps.
The container app sits in front of a set of Azure OpenAI resources. The container app solves
two scenarios: normal and throttled. During a normal scenario where token and model quota is
available, the Azure OpenAI resource returns a 200 back through the container app and app
server.
When a resource is in a throttled scenario because of quota limits, the container app can retry a
different Azure OpenAI resource immediately to fulfill the original chat app request.
Prerequisites
An Azure subscription. Create one for free .
Dev containers are available for both samples with all the dependencies that are
required to complete this article. You can run the dev containers in GitHub Codespaces (in
a browser) or locally by using Visual Studio Code.
GitHub account
) Important
All GitHub accounts can use GitHub Codespaces for up to 60 hours free each month
with two core instances. For more information, see GitHub Codespaces monthly
included storage and core hours .
Bash
azd auth login --use-device-code
2. Set an environment variable to use Azure CLI authentication to the post provision step:
Bash
azd config set [Link] "true"
3. Deploy the load balancer app:
Bash
azd up
Select a subscription and region for the deployment. They don't have to be the same
subscription and region as the chat app.
Bash
azd env get-values
Initial deployment
1. Open the chat app sample's dev container by using one of the following choices.
ノ Expand table
Bash
azd auth login
Bash
azd env new <name>
4. Add the following environment variable, which tells the chat app's backend to use a
custom URL for the Azure OpenAI requests:
Bash
azd env set OPENAI_HOST azure_custom
5. Add the following environment variable. Substitute <CONTAINER_APP_URL> for the URL
from the previous section. This action tells the chat app's backend what the value is
of the custom URL for the Azure OpenAI request.
Bash
azd env set AZURE_OPENAI_CUSTOM_URL <CONTAINER_APP_URL>
Bash
azd up
Use the chat app with the confidence that it scales across many users without running out of
quota.
2. From the list of resources in the group, select the Azure Container Apps resource.
3. Select Monitoring > Log stream to view the log.
5. Look for the logs, which reference the Azure OpenAI resources. Each of the three
resources has its numeric identity in the log comment that begins with Proxying to
[Link] , where 3 indicates the third Azure OpenAI resource.
When the load balancer receives status that the request exceeds quota, the load balancer
automatically rotates to another resource.
Bash
azd up
Clean up resources
When you're finished with the chat app and the load balancer, clean up the resources. The
Azure resources created in this article are billed to your Azure subscription. If you don't expect
to need these resources in the future, delete them to avoid incurring more charges.
.NET
JavaScript
Python
Bash
purge : Deleted resources are immediately purged so that you can reuse the Azure
GitHub Codespaces
Deleting the GitHub Codespaces environment ensures that you can maximize the amount
of free per-core hours entitlement that you get for your account.
) Important
For more information about your GitHub account's entitlements, see GitHub
Codespaces monthly included storage and core hours .
2. Locate your currently running codespaces that are sourced from the azure-
samples/openai-aca-lb GitHub repository.
3. Open the context menu for the codespace, and then select Delete.
Get help
If you have trouble deploying the Azure Container Apps load balancer, add your issue to the
repository's Issues webpage.
Sample code
Samples used in this article include:
Related content
Use Azure Load Testing to load test your chat app.
Learn how to add enterprise-grade load balancing to your application to extend the chat app
beyond the Azure OpenAI Models in Microsoft Foundry token and model quota limits. This
approach uses Azure API Management to intelligently direct traffic between three Azure
OpenAI resources.
Chat app:
Wait to deploy the chat app until after the load balancer sample is deployed.
If you already deployed the chat app once, change the environment variable to
support a custom endpoint for the load balancer and redeploy it again.
Load balancer with Azure API Management.
7 Note
This article uses one or more AI app templates as the basis for the examples and
guidance in the article. AI app templates provide you with well-maintained reference
implementations that are easy to deploy. They help to ensure a high-quality starting point
for your AI apps.
The API Management resource, as an API layer, sits in front of a set of Azure OpenAI resources.
The API layer applies to two scenarios: normal and throttled. During a normal scenario where
token and model quota is available, the Azure OpenAI resource returns a 200 back through the
API layer and backend app server.
When a resource is throttled because of quota limits, the API layer can retry a different Azure
OpenAI resource immediately to fulfill the original chat app request.
Prerequisites
An Azure subscription. Create one for free .
Dev containers are available for both samples, with all the dependencies that are
required to complete this article. You can run the dev containers in GitHub Codespaces (in
a browser) or locally by using Visual Studio Code.
) Important
All GitHub accounts can use GitHub Codespaces for up to 60 hours free each month
with two core instances. For more information, see GitHub Codespaces monthly
included storage and core hours .
Bash
azd auth login
Bash
azd up
Select a subscription and region for the deployment. They don't have to be the same
subscription and region as the chat app.
4. Wait for the deployment to finish before you continue. This process might take up to 30
minutes.
Bash
azd env get-values | grep APIM_GATEWAY_URL
Initial deployment
1. Open the chat app sample's dev container by using one of the following choices.
ノ Expand table
Bash
azd auth login
Finish the sign-in instructions.
Bash
azd env new <name>
4. Add the following environment variable, which tells the chat app's backend to use a
custom URL for the Azure OpenAI requests:
Bash
azd env set OPENAI_HOST azure_custom
5. Add this environment variable to tell the chat app’s backend the custom URL for the
Azure OpenAI request:
Bash
azd env set AZURE_OPENAI_CUSTOM_URL <APIM_GATEWAY_URL>
Bash
azd up
Bash
azd env set OPENAI_CAPACITY 50
2. Redeploy the load balancer:
Bash
azd up
Clean up resources
When you're finished with the chat app and the load balancer, clean up the resources. The
Azure resources created in this article are billed to your Azure subscription. If you don't expect
to need these resources in the future, delete them to avoid incurring more charges.
.NET
JavaScript
Python
Bash
azd down --purge --force
purge : Deleted resources are immediately purged. You can reuse the Azure OpenAI
Clean up resources
GitHub Codespaces
Deleting the GitHub Codespaces environment ensures that you can maximize the amount
of free per-core hours entitlement that you get for your account.
) Important
For more information about your GitHub account's entitlements, see GitHub
Codespaces monthly included storage and core hours .
2. Locate your currently running codespaces that are sourced from the azure-
samples/openai-apim-lb GitHub repository.
3. Open the context menu for the GitHub Codespaces item, and then select Delete.
Get help
If you have trouble deploying the Azure API Management load balancer, add your issue to the
repository's Issues webpage.
Sample code
Samples used in this article include:
Related content
View Azure API Management diagnostic data in Azure Monitor.
Use Azure Load Testing to load test your chat app.
7 Note
This article uses one or more AI app templates as the basis for the examples and
guidance in the article. AI app templates provide you with well-maintained reference
implementations that are easy to deploy. They help to ensure a high-quality starting point
for your AI apps.
Prerequisites
An Azure subscription. Create one for free .
Dev containers are available for both samples with all the dependencies that are
required to complete this article. You can run the dev containers in GitHub Codespaces (in
a browser) or locally by using Visual Studio Code.
Python chat app with RAG. If you configured your chat app to use one of the load
balancing solutions, this article helps you test the load balancing. The load balancing
solutions include Azure Container Apps.
Bash
python -m pip install locust
2. Start Locust, which uses the Locust test file [Link] . You can find it at the root of
the repository. The sample has a ChatUser class that simulates a user asking questions
and receiving answers from the chat app.
Bash
locust ChatUser
3. After Locust starts successfully, it launches a local web interface that you use to configure
and monitor the load test. Open the running Locust website, such as
[Link] .
ノ Expand table
Property Value
Number of 20
users
Ramp up 1
Clean up resources
When you're finished with load testing, clean up the resources. The Azure resources created in
this article are billed to your Azure subscription. If you don't expect to need these resources in
the future, delete them to avoid incurring more charges. After you delete resources specific to
this article, remember to return to the other chat app tutorial and follow the clean-up steps.
Get help
If you have trouble using this load tester, add your issue to the repository's Issues webpage.
This article walks you through setting up your local environment to develop Python web
apps and deploy them to Azure. Your web app can be pure Python or use one of the
common Python-based web frameworks like Django , Flask , or FastAPI .
Python web apps developed locally can be deployed to services such as Azure App
Service, Azure Container Apps, or Azure Static Web Apps. There are many options for
deployment. For example, for App Service deployment, you can choose to deploy from
code, a Docker container, or a Static Web App. If you deploy from code, you can deploy
with Visual Studio Code, with the Azure CLI, from a local Git repository, or with GitHub
actions. If you deploy in a Docker Container, you can do so from Azure Container
Registry, Docker Hub, or any private registry.
Before continuing with this article, we suggest you review the Set up your dev
environment for guidance on setting up your dev environment for Python and Azure.
Below, we'll discuss setup and configuration specific to Python web app development.
After you get your local environment setup for Python web app development, you'll be
ready to tackle these articles:
Quickstart: Create a Python (Django or Flask) web app in Azure App Service.
Tutorial: Deploy a Python (Django or Flask) web app with PostgreSQL in Azure
Create and deploy a Flask web app to Azure with a system-assigned managed
identity
Tip
Make sure you have the Python extension installed. For an overview of working
with Python in VS Code, see Getting Started with Python in VS Code .
In VS Code, you work with Azure resources through VS Code extensions . You can
install extensions from the Extensions View or the key combination Ctrl+Shift+X. For
Python web apps, you'll likely be working with one or more of the following extensions:
The Azure App Service extension enables you to interact with Azure App Service
from within Visual Studio Code. App Service provides fully managed hosting for
web applications including websites and web APIs.
The Azure Static Web Apps extension enables you to create Azure Static Web
Apps directly from VS Code. Static Web Apps is serverless and a good choice for
static content hosting.
The Docker extension to build and work with containers locally. For example,
you can run a containerized Python web app on Azure App Service using Web
Apps for Containers .
The Azure Container Apps extension to create and deploy containerized apps
directly from Visual Studio Code.
There are other extensions such as the Azure Storage , Azure Databases , and
Azure Resources extensions. You can always add these and other extensions as
needed.
Extensions in Visual Studio Code are accessible as you would expect in a typical IDE
interface and with rich keyword support using the VS Code command palette . To
access the command palette, use the key combination Ctrl+Shift+P. The command
palette is a good way to see all the possible actions you can take on an Azure resource.
The screenshot below shows some of the actions for App Service.
While there are popular options available in Python for managing environments like
virtualenv or venv , the Visual Studio Code Dev Container extension (based on the
open Dev Container specification ) lets you use a Docker container as a full-featured
containerized environment. It enables developers to define a consistent and easily
reproducible toolchain with all the necessary tools, dependencies, and extensions pre-
configured. This means if you have system requirements, shell configurations, or use
other languages entirely, you can use a Dev Container to explicitly configure all of those
parts of your project that might live outside of a basic Python environment.
For example, a developer can configure a single Dev Container to include everything
needed to work on a project, including a PostgreSQL database server along with the
project database and sample data, a Redis server, Nginx, front-end code, client libraries
like React, and so on. In addition, the container would contain the project code, the
Python runtime, and all the Python project dependencies with the correct versions.
Finally, the container can specify Visual Studio Code extensions to be installed so the
entire team has the same tooling available. So when a new developer joins the team, the
whole environment, including tooling, dependencies, and data, is ready to be cloned to
their local machine, and they can begin working immediately.
In general, see Visual Studio | Python documentation for all documentation related
to using Python on Visual Studio 2022.
For setup steps, see Install Python support in Visual Studio which walks you
through the steps of installing the Python workload into Visual Studio 2022.
For general workflow of using Python for web development, see Quickstart: Create
your first Python web app using Visual Studio. This article is useful for
understanding how to build a Python web application from scratch (but does not
include deployment to Azure).
For using Visual Studio 2022 to manage Azure resources and deploy to Azure, see
Azure Development with Visual Studio. While much of the documentation here
specifically mentions .NET, the tooling for managing Azure resources and
deploying to Azure works the same regardless of the programming language.
When there's no built-in tool available in Visual Studio 2022 for a given Azure
management or deployment task, you can always use Azure CLI commands.
ノ Expand table
Command Description
az webapp Manages web apps. Includes the subcommands create and up to create a web
app or to create and deploy from a local workspace, respectively.
az group Manages resource groups and template deployments. Use the subcommand
create to make a resource group to put your Azure resources in.
az config Manages Azure CLI configuration. To save keystrokes, you can define a default
location or resource group that other commands use automatically.
Here's an example Azure CLI command to create a web app and associated resources,
and deploy it to Azure in one command using az webapp up. Run the command in the
root directory of your web app.
bash
Azure CLI
az webapp up \
--runtime PYTHON:3.9 \
--sku B1 \
--logs
For more about this example, see Quickstart: Deploy a Python (Django or Flask) web app
to Azure App Service.
Keep in mind that for some of your Azure workflow you can also use the Azure CLI from
an Azure Cloud Shell. Azure Cloud Shell is an interactive, authenticated, browser-
accessible shell for managing Azure resources.
ノ Expand table
The azure-identity package allows your web app to authenticate with Microsoft Entra
ID. For authentication in your web app code, it's recommended that you use the
DefaultAzureCredential in the azure-identity package. Here's an example of how to
access Azure Storage. The pattern is similar for other Azure resources.
Python
azure_credential = DefaultAzureCredential()
blob_service_client = BlobServiceClient(
account_url=account_url,
credential=azure_credential)
Below is an example of how you might get started quickly with these frameworks locally.
Running these commands, you'll end up with an application, albeit a simple one that
could be deployed to Azure. Run these commands inside a virtual environment.
Django
Django
Django
Django
[Link]
At this point, add a [Link] file and then you can deploy the web app to Azure
or containerize it with Docker and then deploy it.
Next steps
Quickstart: Create a Python (Django or Flask) web app in Azure App Service.
Tutorial: Deploy a Python (Django or Flask) web app with PostgreSQL in Azure
Create and deploy a Flask web app to Azure with a system-assigned managed
identity
Feedback
Was this page helpful? Yes No
Python web Azure Developer CLI ( azd ) templates are the fastest and easiest way to build,
configure, and deploy Python web applications to Azure. This article provides contextual
background information to help you understand the components involved and how the
templates simplify deployment.
The best way to begin is to follow the quickstart to create your first Python web app and
deploy it to Azure in minutes with azd templates. If you prefer not to set up a local
development environment, you can follow the quickstart by using GitHub Codespaces for a
fully cloud-based experience with all tools preconfigured.
These templates offer the easiest possible starting point for building and deploying Python
web applications by:
Once your environments are set up, the templates provide the fastest way to start building
your Python web app. You can:
These templates reflect proven design patterns and best practices, enabling you to:
The template is designed to be a starting point—you can freely customize the logic and
expand or remove Azure resources to fit your project.
The Bicep files are fully editable—you can add or customize Azure services as your app
evolves. Similar to the previous task, you can modify the Bicep templates to add more
Azure services, as needed.
Deploy starter app to provisioned Azure resources. Once resources are provisioned, your
application is automatically deployed to the Azure environment. You can now:
See your app running in the cloud within minutes.
Test its behavior.
Decide what functionality or configuration to update next.
(Optional) Set up GitHub repository and CI/CD pipeline. You can optionally initialize a
GitHub repository with a GitHub Actions continuous integration/continuous delivery
(CI/CD) pipeline to:
Automate deployments on code changes.
Collaborate with team members.
Push updates to Azure by merging into the main branch.
This integration helps you adopt DevOps best practices from the start.
The following tables list the Python web azd template monikers that are available for use with
the azd init command. The tables identify the technologies implemented in each template
and provide a link to the corresponding GitHub repository, where you can contribute changes.
Django
The following azd templates are available for the Django web framework .
ノ Expand table
Infrastructure-as-Code (IaC): Provided via Bicep files to define and provision the required
Azure resources, such as:
App Service or Container Apps
Azure Databases (such as PostgreSQL, Cosmos DB)
Azure AI services, Storage, and more
These templates are fully customizable, giving you a strong foundation to build on and
adapt to your project’s specific needs.
To perform the tasks defined by an azd web template, you use various Python azd commands.
For detailed descriptions of these commands, see Quickstart: Deploy an Azure Developer CLI
template. The quickstart walks you through the steps to use a specific azd template. You only
need to run five essential command-line instructions to the production-hosting environment
and the local-development environment.
ノ Expand table
azd init -- Create a new project from a template and create a copy of the application code on
template your local computer. The command prompts you to provide an environment name
<template name> (like "myapp") that's used as a prefix in the naming of the deployed resources.
azd auth login Sign in to Azure. The command opens a browser window where you can sign in to
Azure. After you sign in, the browser window closes and the command completes.
The azd auth login command is required only the first time you use the Azure
Developer CLI ( azd ) per session.
azd up Provision the cloud resources and deploy the app to those resources.
azd deploy Deploy changes to the application source code to resources already provisioned by
the azd up command.
azd down Delete the Azure resources and the CI/CD pipeline, if it was used.
Tip
When you work with the azd commands, watch for prompts to enter more information.
After you execute the azd up command, you might be prompted to select a subscription,
if you have more than one. You might also be prompted to specify your region. You can
change the answers to prompts by editing the environment variables stored in the
/.azure/ folder of the template.
After completing the essential tasks provided by the azd template, you have a personal copy
of the original template where you can modify any file, as needed.
Application Code: Customize the Python project code to implement your own design,
routes, and business logic.
Infrastructure-as-Code (Bicep): Update the Bicep files to provision additional Azure
services, change configurations, or remove unneeded resources.
This flexible starting point allows you to build on top of a well-structured foundation while
tailoring the app to your real-world use case.
You can also modify the infrastructure-as-code configuration if you need to change the Azure
resources. For more information, see the What can I edit or delete section later in this article.
To modify a provisioned resource, you edit the appropriate Bicep files in the template.
To initiate the reprovisioning task, use the azd provision command.
The Azure Developer CLI ( azd ) provides an easy way to set up a CI/CD pipeline for your new
Python web app. When you merge commits or pull requests into your main branch, the
pipeline automatically builds and publishes the changes to your Azure resources.
To set up the CI/CD pipeline, you designate the GitHub repository and desired settings to
enable the pipeline.
To create the pipeline, use the azd pipeline config command.
After you configure the pipeline, each time code changes are merged to the main branch of
the repository, the pipeline deploys the changes to your provisioned Azure services.
You can create many resources and complete the deployment steps by using several tools:
Azure portal
The Azure CLI
Visual Studio Code with the Azure Tools extension
You can also follow an end-to-end tutorial that features Python web development frameworks:
/ Root directory The root folder for each template contains many different kinds of
files and folders for different purposes.
/.azure azd The .azure folder is created after you run the azd init command.
configuration The folder stores configuration files for the environment variables
files used by the azd commands. You can change the values of the
environment variables to customize the app and the Azure
resources. For more information, see Environment-specific .env file.
/.devcontainer Dev Container Dev Containers allow you to create a container-based development
configuration environment complete with all of the resources you need for
files software development inside of Visual Studio Code. The
.devcontainer folder is created after Visual Studio Code generates a
Dev Container configuration file in response to a template
command.
/.github GitHub Actions This folder contains configuration settings for the optional GitHub
configuration Actions CI/CD pipeline, linting, and tests. If you don't want to set up
files the GitHub Actions pipeline by using azd pipeline config
command, you can modify or deleted the [Link] file.
/infra Bicep files The infra folder holds the Bicep configuration files. Bicep allows you
to declare the Azure resources you want deployed to your
environment. You should only modify the [Link] and [Link]
files. For more information, see Quickstart: Scaling services
deployed with the azd Python web templates by using Bicep.
/src Starter project The src folder contains various code files required to prepare the
code files starter project. Examples of the files include templates required by
the web framework, static files, Python (.py) files for the code logic
and data models, a [Link] file, and more. The specific files
depend on the web framework, the data access framework, and so
on. You can modify these files to suit your project requirements.
/.[Link] Template The .cruft JSON file is used internally to generate the Python web
generation file azd templates. You can safely delete this file, as needed.
/.gitattributes File with This file provides git with important configuration settings for
attribute handling files and folders. You can modify this file, as needed.
settings for git
/.gitignore File with The .gitignore file informs git about the files and folders to exclude
ignored items (ignore) when writing to the GitHub repository for the template.
for git You can modify this file, as needed.
/[Link] azd up This configuration file contains the configuration settings for the
configuration azd up command. It specifies the services and project folders to
Folder/file(s) Purpose Description
/*.md Markdown A template can include various Markdown (.md) format files for
format files different purposes. You can safely delete Markdown files.
/docker- Docker This YML file creates the container package for the Python web
[Link] compose application before the app deploys to Azure.
settings
/[Link] Python build The TOML file contains the build system requirements of Python
settings file projects. You can modify this file to identify your tool preferences,
such as a specific linter or unit testing framework.
Tip
As you modify template files for your program, be sure to practice good version control.
This approach can help you restore your repository to a previous working version, if new
changes cause program issues.
Related content
Create and deploy Python web apps to Azure with azd templates
Create and deploy Python web apps from GitHub Codespaces to Azure with azd
templates
Quickstart: Create and deploy a Python
web app to Azure using an azd template
Article • 12/16/2024
This quickstart guides you through the easiest and fastest way to create and deploy a
Python web and database solution to Azure. By following the instructions in this
quickstart, you will:
Choose an azd template based on the Python web framework, Azure database
platform, and Azure web hosting platform you want to build on.
Use CLI commands to run an azd template to create a sample web app and
database, and create and configure the necessary Azure resources, then deploy the
sample web app to Azure.
Edit the web app on your local computer and use an azd command to redeploy.
Use an azd command to clean up Azure resources.
It should take less than 15 minutes to complete this tutorial. Upon completion, you can
start modifying the new project with your custom code.
To learn more about these azd templates for Python web app development:
Prerequisites
An Azure subscription - Create one for free
Choose a template
Choose an azd template based on the Python web framework, Azure web hosting
platform, and Azure database platform you want to build on.
1. Select a template name (first column) from the following list of templates in the
following tables. You'll use the template name during the azd init step in the next
section.
Django
ノ Expand table
The GitHub repository (last column) is only provided for reference purposes. You should
only clone the repository directly if you want to contribute changes to the template.
Otherwise, follow the instructions in this quickstart to use the azd CLI to interact with
the template in a normal workflow.
1. At a terminal, navigate to a folder on your local computer where you typically store
your local git repositories, then create a new folder named azdtest. Then, change
into that directory using the cd command.
shell
mkdir azdtest
cd azdtest
shell
Substitute <template name> with one of the templates from the tables you selected
in a previous step, such as azure-django-postgres-aca for example.
When prompted for an environment name, use azdtest or any other name. The
environment name is used when naming Azure resource groups and resources. For
best results, use a short name, lower case latters, no special characters.
3. To authenticate azd to your Azure account, enter the following commands in your
terminal and follow the prompt:
shell
Follow the instructions when prompted to "Pick an account" or log into your Azure
account. Once you have successfully authenticated, the following message is
displayed in a web page: "Authentication complete. You can return to the
application. Feel free to close this browser tab."
When you close the tab, the shell displays the message:
Output
Logged in to Azure.
4. Ensure that Docker Desktop is open and running in the background before
attempting the next step.
5. To create the necessary Azure resources, enter the following commands in your
terminal and answer any prompts:
shell
azd up
) Important
Once azd up completes successfully, the sample web app will be available on
the public internet and your Azure Subscription will begin accruing charges
for all resources that are created. The creators of the azd templates
intentionally chose inexpensive tiers but not necessarily free tiers since free
tiers often have restricted availability.
Follow the instructions when prompted to choose Azure Subscription to use for
payment, then select an Azure location to use. Choose a region that is close to you
geographically.
Executing azd up could take several minutes since it's provisioning and deploying
multiple Azure services. As progress is displayed, watch for errors. If you see errors,
try the following to fix the problem:
Delete the azd-quickstart folder and the quickstart instructions from the
beginning.
When prompted, choose a simpler name for your environment. Only use
lower-case letters and dashes. No numbers, upper-case letters, or special
characters.
Choose a different location.
If you still have problems, see the Troubleshooting section at the bottom of this
document.
) Important
Once you have finished working with the sample web app, use azd down to
remove all of the services that were created by azd up .
Copy the first URL after the word - Endpoint: and paste it into the location bar of
a web browser to see the sample web app project running live in Azure.
7. Open a new tab in your web browser, copy the second URL from the previous step
and paste it into the location bar. The Azure portal displays all of the services in
your new resource group that have been deployed to host the sample web app
project.
1. Open Visual Studio Code and open the azdtest folder created earlier.
2. This template is configured to optionally use Dev Containers. When you see the
Dev Container notification appear in Visual Studio Code, select the "Reopen in
Container" button.
3. Use Visual Studio Code's Explorer view to navigate to src/templates folder, and
open the [Link] file. Locate the following line of code:
HTML
4. To redeploy the app with your change, in your terminal run the following
command:
Shell
azd deploy
Since you're using Dev Containers and are connected remotely into the container's
shell, don't use Visual Studio Code's Terminal pane to run azd commands.
5. Once the command completes, refresh your web browser to see the update.
Depending on the web hosting platform being used, it could take several minutes
before your changes are visible.
You're now ready to edit and delete files in the template. For more information, see
What can I edit or delete in the template?
Clean up resources
1. Clean up the resources created by the template by running the azd down
command.
Shell
azd down
The azd down command deletes the Azure resources and the GitHub Actions
workflow. When prompted, agree to deleting all resources associated with the
resource group.
You may also delete the azdtest folder, or use it as the basis for your own
application by modifying the files of the project.
Troubleshooting
If you see errors during azd up , try the following steps:
Run azd down to remove any resources that may have been created. Alternatively,
you can delete the resource group that was created in the Azure portal.
Delete the azdtest folder on your local computer.
In the Azure portal, search for Key Vaults. Select to Manage deleted vaults, choose
your subscription, select all key vaults that contain the name azdtest or whatever
you named your environment, and select Purge.
Retry the steps in this quickstart again. This time when prompted, choose a simpler
name for your environment. Try a short name, lower-case letters, no numbers, no
upper-case letters, no special characters.
When retrying the quickstart steps, choose a different location.
See the FAQ for a more comprehensive list of possible issues and solutions.
Related Content
Learn more about the Python web azd templates
Learn more about the azd commands.
Learn what each of the folders and files in the project do and what you can edit or
delete?
Learn more about Dev Containers .
Update the Bicep templates to add or remove Azure services. Don't know Bicep?
Try this Learning Path: Fundamentals of Bicep
Use azd to set up a GitHub Actions CI/CD pipeline to redeploy on merge to main
branch
Set up monitoring so that you can Monitor your app using the Azure Developer
CLI
Feedback
Was this page helpful? Yes No
This quickstart guides you through the easiest and fastest way to create and deploy a
Python web and database solution to Azure. By following the instructions in this
quickstart, you will:
Choose an Azure Developer CLI ( azd ) template based on the Python web
framework, Azure database platform, and Azure web hosting platform you want to
build on.
Create a new GitHub Codespace containing code generated from the azd
template you selected.
Use GitHub Codespaces and the online Visual Studio Code's bash terminal. The
terminal allows you to use Azure Developer CLI commands to run an azd template
to create a sample web app and database, and create and configure the necessary
Azure resources, then deploy the sample web app to Azure.
Edit the web app in a GitHub Codespace and use an azd command to redeploy.
Use an azd command to clean up Azure resources.
Close and reopen your GitHub Codespace.
Publish your new code to a GitHub repository.
It should take less than 25 minutes to complete this tutorial. Upon completion, you can
start modifying the new project with your custom code.
To learn more about these azd templates for Python web app development:
Prerequisites
An Azure subscription - Create one for free
A GitHub Account - Create one for free
) Important
Both GitHub Codespaces and Azure are paid subscription based services. After
some free allotments, you may be charged for using these services. Following this
quickstart could affect these allotments or billing. When possible, the azd
templates were built using the least expensive tier of options, but some may not be
free. Use the Azure Pricing calculator to better understand the costs. For more
information, see GitHub Codespaces pricing for more details.
1. From the following list of templates, choose one that uses the technologies that
you want to use in your new web application.
Django
ノ Expand table
2. For your convenience, the last column of each table contains a link that creates a
new Codespace and initializes the azd template in your GitHub account. Right-
click and select "Open in new tab" on the "New Codespace" link next to the
template name you selected to initiate the setup process.
During this process, you may be prompted to log into your GitHub account, and
you're asked to confirm that you want to create the Codespace. Select the "Create
Codespace" button to see the "Setting up your codespace" page.
3. After a few minutes, a web-based version of Visual Studio Code is loaded in a new
browser tab with the Python web template loaded as a workspace in the Explorer
view.
1. In the web-based Visual Studio Code, the terminal should be open by default. If it
isn't, use the tilde ~ key to open the terminal. Furthermore, by default, the
terminal should be a bash terminal. If it isn't, change to bash in the upper right
hand area of the terminal window.
Bash
azd auth login begins the process of authenticating your Codespace to your
Azure account.
Output
Start by copying the next code: XXXXXXXXX
Then press enter and continue to log in from your browser...
4. When successful, the following message is displayed back in the Codespaces tab at
the terminal:
Output
Bash
azd up
Once you answer those questions, the output from azd indicates the deployment
is progressing.
) Important
Once azd up completes successfully, the sample web app will be available on
the public internet and your Azure Subscription will begin accruing charges
for all resources that are created. The creators of the azd templates
intentionally chose inexpensive tiers but not necessarily free tiers since free
tiers often have restricted availability. Once you have finished working with
the sample web app, use azd down to remove all of the services that were
created by azd up .
Follow the instructions when prompted to choose Azure Subscription to use for
payment, then select an Azure location to use. Choose a region that is close to you
geographically.
Executing azd up could take several minutes since it's provisioning and deploying
multiple Azure services. As progress is displayed, watch for errors. If you see errors,
see the Troubleshooting section at the bottom of this document.
Output
If you see a default screen or error screen, the app may be starting up. Please wait
5-10 minutes to see if the issue resolves itself before troubleshooting.
Ctrl + click the first URL after the word - Endpoint: to see the sample web app
project running live in Azure.
7. Ctrl + click the second URL from the previous step to view the provisioned
resources in the Azure portal.
1. Return to the browser tab containing Visual Studio Code, and use Visual Studio
Code's Explorer view to navigate to src/templates folder, and open the [Link]
file. Locate the following line of code:
HTML
<h1 id="page-title">Welcome to ReleCloud</h1>
HTML
2. To redeploy the app with your change, run the following command in the terminal:
Bash
azd deploy
3. Once the command completes, refresh the browser tab with the ReleCloud website
to see the update. Depending on the web hosting platform being used, it could
take several minutes before your changes are visible.
You're now ready to edit and delete files in the template. For more information, see
What can I edit or delete in the template?
Clean up resources
Clean up the resources created by the template by running the azd down command.
Bash
azd down
The azd down command deletes the Azure resources and the GitHub Actions workflow.
When prompted, agree to deleting all resources associated with the resource group.
2. Open your web browser and a new tab, and navigate to:
[Link]
3. Near the bottom, you'l see a list of recent Codespaces. Look for the one you
created in a section titled "Owned by Azure-Samples".
4. Select the ellipsis to the right of this Codespace to view a context menu. From here
you can rename the codespace, publish to a new repository, change machine type,
stop the codespace, and more.
1. From the context menu for the codespace, select "Publish to a new repository".
2. In the "Publish to a new repository" dialog, rename your new repo and choose
whether you want it to be a public or private repo. Select "Create repository".
3. After a few moments, the repository will be created and the code you generated
earlier in this Quickstart will be pushed to the new repository. Select the "See
repository" button to navigate to the new repo.
4. To reopen and continue editing code, select the green "< > Code" drop-down,
switch to the Codespaces tab, and select the name of the Codespace you were
working on previously. You should now be returned to your Codespace Visual
Studio Code development environment.
5. Use the Source Control pane to create new branches and stage and commit new
changes to your code.
Troubleshooting
If you see errors during azd up , try the following:
Run azd down to remove any resources that may have been created. Alternatively,
you can delete the resource group that was created in the Azure portal.
Go to the Codespaces page for your GitHub account, find the Codespace created
during this Quickstart, select the ellipsis at the right and choose "Delete" from the
context menu.
In the Azure portal, search for Key Vaults. Select to Manage deleted vaults, choose
your subscription, select all key vaults that contain the name azdtest or whatever
you named your environment, and select Purge.
Retry the steps in this quickstart again. This time when prompted, choose a simpler
name for your environment. Try a short name, lower-case letters, no numbers, no
upper-case letters, no special characters.
When retrying the quickstart steps, choose a different location.
See the FAQ for a more comprehensive list of possible issues and solutions.
Related content
Learn more about the Python web azd templates
Learn more about the azd commands.
Learn what each of the folders and files in the project do and what you can edit or
delete?
Learn more about GitHub Codespaces
Update the Bicep templates to add or remove Azure services. Don't know Bicep?
Try this Learning Path: Fundamentals of Bicep
Use azd to set up a GitHub Actions CI/CD pipeline to redeploy on merge to main
branch
Set up monitoring so that you can Monitor your app using the Azure Developer
CLI
Feedback
Was this page helpful? Yes No
The Python web azd templates allow you to quickly create a new web application and
deploy it to Azure. The azd templates were designed to use low-cost Azure service
options. Undoubtedly, you'll want to adjust the service levels (or skus) for each of the
services defined in the template for your scenario.
In this Quickstart, you'll update the appropriate bicep template files to scale up existing
services and add new services to your deployment. Then, you'll run the azd provision
command and view the change you made to the Azure deployment.
Prerequisites
An Azure subscription - Create one for free
Deploy a template
To begin, you need a working azd deployment. Once you have that in place, you're able
to modify the Bicep files generated by the azd template.
1. Follow steps 1 through 7 in the Quickstart article. In step 2, use the azure-django-
postgres-flexible-appservice template. For your convenience, here's the entire
shell
mkdir azdtest
cd azdtest
azd init --template azure-django-postgres-flexible-appservice
azd auth login
azd up
Once azd up finishes, open the Azure portal, navigate to the Azure App Service
that was deployed in your new Resource Group and take note of the App Service
pricing plan (see the App Service plan's Overview page, Essentials section, "Pricing
plan" value).
2. In step 1 of the Quickstart article, you were instructed to create the azdtest folder.
Open that folder in Visual Studio Code.
3. In the Explorer pane, navigate to the infra folder. Observe the subfolders and files
in the infra folder.
The [Link] file orchestrates the creation of all the services deployed when
performing an azd up or azd provision . It calls into other files, like [Link] and
[Link], which in turn call into files contained in the \core subfolder.
The \core subfolder is a deeply nested folder structure containing bicep templates
for many Azure services. Some of the files in the \core subfolder are referenced by
the three top level bicep files ([Link], [Link] and [Link]) and some aren't
used at all in this project.
7 Note
Not all SKU changes can be made after the fact. Some research may be necessary
to better understand your scaling options.
1. Open the [Link] file and locate the appService module definition. In particular,
look for the property setting:
Bicep
sku: {
name: 'B1'
}
Bicep
sku: {
name: 'S1'
}
) Important
As a result of this change, the price per hour will increase slightly. Details
about the different service plans and their associated costs can be found on
the App Service pricing page .
2. Assuming you already have the application deployed in Azure, use the following
command to deploy changes to the infrastructure while not redeploying the
application code itself.
shell
azd provision
You shouldn't be prompted for a location and subscription. Those values are saved
in the .azure<environment-name>.env file where <environment-name> is the
environment name you provided during azd init .
3. When azd provision is complete, confirm your web application still works. Also
find the App Service Plan for your Resource Group and confirm that the Pricing
Plan is set to the Standard Service Plan (S1).
This concludes the Quickstart, however there are many Azure services that can help you
build more scalable and production-ready applications. A great place to start would be
to learn about Azure API Management, Azure Front Door, Azure CDN, and Azure Virtual
Network, to name a few.
Clean up resources
Clean up the resources created by the template by running the azd down command.
shell
azd down
The azd down command deletes the Azure resources and the GitHub Actions workflow.
When prompted, agree to deleting all resources associated with the resource group.
You can also delete the azdtest folder, or use it as the basis for your own application by
modifying the files of the project.
Related Content
Learn more about the Python web azd templates
Learn more about the azd commands.
Learn what each of the folders and files in the project do and what you can edit or
delete?
Update the Bicep templates to add or remove Azure services. Don't know Bicep?
Try this Learning Path: Fundamentals of Bicep
Use azd to set up a GitHub Actions CI/CD pipeline to redeploy on merge to main
branch
Set up monitoring so that you can Monitor your app using the Azure Developer
CLI
Feedback
Was this page helpful? Yes No
In this quickstart, you deploy a Python web app (Django, Flask, or FastAPI) to Azure App
Service. Azure App Service is a fully managed web hosting service that supports Python apps
hosted in a Linux server environment.
7 Note
This article contains current instructions on deploying a Python web app using Azure App
Service. Python on Windows is no longer supported.
Flask
Bash
mkdir flask-quickstart
cd flask-quickstart
azd init --template [Link]
webapp-quickstart
azd up
Bash
azd down
Sample application
This quickstart can be completed using either Flask, Django, or FastAPI. A sample application in
each framework is provided to help you follow along with this quickstart. Download or clone
the sample application to your local workstation.
Flask
Console
Flask
Console
cd msdocs-python-flask-webapp-quickstart
Windows
Console
py -m venv .venv
.venv\scripts\activate
Console
Console
flask run
Azure CLI
Azure CLI commands can be run on a computer with the Azure CLI installed.
Azure CLI has a command az webapp up that will create the necessary resources and
deploy your application in a single step.
If necessary, log in to Azure using az login.
Azure CLI
az login
Create the webapp and other resources, then deploy your code to Azure using az webapp
up.
Azure CLI
The --runtime parameter specifies what version of Python your app is running. This
example uses Python 3.13. To list all available runtimes, use the command az webapp
list-runtimes --os linux --output table .
The --sku parameter defines the size (CPU, memory) and cost of the app service
plan. This example uses the B1 (Basic) service plan, which will incur a small cost in
your Azure subscription. For a full list of App Service plans, view the App Service
pricing page.
The --logs flag configures default logging required to enable viewing the log stream
immediately after launching the webapp.
You can optionally specify a name with the argument --name <app-name> . If you don't
provide one, then a name will be automatically generated.
You can optionally include the argument --location <location-name> where
<location_name> is an available Azure region. You can retrieve a list of allowable
regions for your Azure account by running the az appservice list-locations command.
The command may take a few minutes to complete. While the command is running, it
provides messages about creating the resource group, the App Service plan, and the app
resource, configuring logging, and doing ZIP deployment. It then returns a message that
includes the app's URL, which is the app's URL on Azure.
7 Note
Zip deploy all files from the current working directory, with build automation
enabled.
Cache the parameters locally in the .azure/config file so that you don't need to
specify them again when deploying later with az webapp up or other az webapp
commands from the project folder. The cached values are used automatically by
default.
Having issues? Refer first to the Troubleshooting guide. If that doesn't help, let us know .
To learn more about how App Service runs Python apps and how you can configure and
customize its behavior with your app, see Configure a Linux Python app for Azure App Service.
Azure CLI
App Service automatically detects the presence of a Flask app. No additional configuration
is needed for this quickstart.
The Python sample code is running a Linux container in App Service using a built-in image.
Congratulations! You've deployed your Python app to App Service.
Having issues? Refer first to the Troubleshooting guide. If that doesn't help, let us know .
Stream logs
Azure App Service captures all message output to the console to assist you in diagnosing
issues with your application. The sample apps include print() statements to demonstrate this
capability.
Flask
Python
@[Link]('/')
def index():
print('Request for index page received')
return render_template('[Link]')
@[Link]('/[Link]')
def favicon():
return send_from_directory([Link](app.root_path, 'static'),
'[Link]',
mimetype='image/[Link]')
@[Link]('/hello', methods=['POST'])
def hello():
name = [Link]('name')
if name:
print('Request for hello page received with name=%s' % name)
return render_template('[Link]', name = name)
else:
print('Request for hello page received with no name or blank name --
redirecting')
return redirect(url_for('index'))
You can review the contents of the App Service diagnostic logs by using the Azure CLI, VS
Code, or the Azure portal.
Azure CLI
First, you need to configure Azure App Service to output logs to the App Service filesystem
by using the az webapp log config command.
bash
Azure CLI
bash
Azure CLI
Refresh the home page in the app or attempt other requests to generate some log
messages. The output should look similar to the following.
Output
Having issues? Refer first to the Troubleshooting guide. If that doesn't help, let us know .
Clean up resources
When you're finished with the sample app, you can remove all of the resources for the app
from Azure. Removing the resource group ensures that you don't incur extra charges and helps
keep your Azure subscription uncluttered. Removing the resource group also removes all
resources in the resource group and is the fastest way to remove all Azure resources for your
app.
Azure CLI
Delete the resource group by using the az group delete command.
Azure CLI
az group delete \
--name msdocs-python-webapp-quickstart \
--no-wait
The --no-wait argument allows the command to return before the operation is complete.
Next steps
Tutorial: Python (Flask) web app with PostgreSQL
Prerequisites
An Azure account with an active subscription. If you don't have an Azure account, you can
create one for free .
A GitHub account. You can also get one for free .
Knowledge of Python with Flask development.
(Optional) To try GitHub Copilot, a GitHub Copilot account . A 30-day free trial is
available.
Skip to the end
If you just want to see the sample app in this tutorial running in Azure, run the following
commands in the Azure Cloud Shell , and follow the prompt:
Bash
mkdir msdocs-flask-postgresql-sample-app
cd msdocs-flask-postgresql-sample-app
azd init --template msdocs-flask-postgresql-sample-app
azd up
7 Note
If you're following along with this tutorial with your own app, look at the [Link]
file description in [Link] to see what packages you need.
Tip
You can ask GitHub Copilot about this repository. For example:
The Name for the web app. It's used as part of the DNS name for your app.
The Region to run the app physically in the world. It's also part of the DNS name for your
app.
The Runtime stack for the app. The version of Python to use for your app.
The Hosting plan for the app. The pricing tier that includes the set of features and scaling
capacity for your app.
The Resource Group for the app. A resource group lets you group the Azure resources for
the application in a logical container.
Sign in to the Azure portal and follow these steps to create your Azure App Service
resources.
Step 2: In the Create Web App + Database page, fill out the form as follows.
1. Resource Group: Select Create new and use a name of msdocs-flask-postgres-tutorial.
2. Region: Any Azure region near you.
3. Name: msdocs-python-postgres-XYZ.
4. Runtime stack: Python 3.14.
5. Database: PostgreSQL - Flexible Server is selected by default as the database engine. The
server name and database name are also set by default to appropriate values.
6. Add Azure Cache for Redis?: No.
7. Hosting plan: Basic. When you're ready, you can scale up to a production pricing tier.
8. Select Review + create.
9. After validation completes, select Create.
Step 3: The deployment takes a few minutes. After deployment completes, select Go to
resource. Deployment creates the following resources:
Resource group: The container for all the created resources.
App Service plan: Defines the compute resources for App Service. Deployment creates a
Linux plan in the Basic tier.
App Service: Represents your app and runs in the App Service plan.
Virtual network: Integrated with the App Service app and isolates back-end network
traffic.
Network interfaces: Represents private IP addresses, one for each of the private
endpoints.
Azure Database for PostgreSQL flexible server: Accessible only from within the virtual
network. A database and a user are created for you on the server.
Private DNS zones: Enables DNS resolution of the key vault and the database server in
the virtual network.
Retrieving the connection secrets from the App Service app's environment variables.
Creating a key vault.
Creating a Key Vault connection with the system-assigned managed identity.
Updating the service connectors to store the secrets in the key vault.
Step 3: Back in the GitHub codespace of your sample fork, run git pull origin starter-no-
infra . This command pulls the newly committed workflow file into your codespace.
Step 5:
1. Select the Source Control extension.
2. In the textbox, type a commit message like Configure Azure database connection . Or,
select and let GitHub Copilot generate a commit message for you.
3. Select Commit, then confirm with Yes.
4. Select Sync changes 1, then confirm with OK.
Step 7: You're taken to your GitHub repository. The GitHub action is running. The workflow file
defines two separate stages, build and deploy. Wait for the GitHub run to show a status of
Success. It takes about 5 minutes.
Step 2: In the SSH session, run flask db upgrade . If it succeeds, App Service is connecting
successfully to the database.
Tip
In the SSH session, only changes to files in /home can persist beyond app restarts.
Changes outside of /home aren't persisted.
Step 2: Add a few restaurants to the list. Congratulations, you're running a web app in Azure
App Service, with secure connectivity to Azure Database for PostgreSQL.
Stream diagnostic logs
Azure App Service captures all console logs to help you diagnose issues with your application.
The sample app includes print() statements to demonstrate this capability as shown here.
Python
@[Link]('/', methods=['GET'])
def index():
print('Request for index page received')
restaurants = [Link]()
return render_template('[Link]', restaurants=restaurants)
Step 2: From the left menu, select Log stream. You see the logs for your app, including
platform logs and logs from inside the container.
To learn more about logging in Python apps, see Set up Azure Monitor for your Python
application.
Clean up resources
When you're finished, you can delete all of the resources from your Azure subscription by
deleting the resource group.
Step 3:
1. To confirm your deletion, enter the resource group name.
2. Select Delete.
3. Confirm with Delete again.
Troubleshooting
Here are some issues you might encounter while trying to work through this tutorial and steps
to resolve them.
If you encounter any errors related to connecting to the database, check if the app settings
( AZURE_POSTGRESQL_USER , AZURE_POSTGRESQL_PASSWORD , AZURE_POSTGRESQL_HOST , and
AZURE_POSTGRESQL_NAME ) were changed or deleted. Without that connection string, the migrate
The App Service plan is created in Basic tier and can be scaled up or down. See App
Service pricing .
The PostgreSQL flexible server is created in the lowest burstable tier Standard_B1ms, with
the minimum storage size, which can be scaled up or down. See Azure Database for
PostgreSQL pricing .
The virtual network doesn't incur a charge unless you configure extra functionality, such
as peering. See Azure Virtual Network pricing .
The private DNS zone incurs a small charge. See Azure DNS pricing .
terminal
git add .
git commit -m "<some-message>"
git push origin main
How do I debug errors during the GitHub Actions deployment?
If a step fails in the autogenerated GitHub workflow file, try modifying the failed command to
generate more verbose output. For example, you can get verbose output from the python
command by adding the -d option. Commit and push your changes to trigger another
deployment to App Service.
In a single chat session, the questions and answers build on each other. You can adjust
your questions to fine-tune the answer you get.
By default, GitHub Copilot doesn't have access to any file in your repository. To ask
questions about a file, open the file in the editor first.
To let GitHub Copilot have access to all of the files in the repository when preparing its
answers, begin your question with @workspace . For more information, see Use the
@workspace agent .
In the chat session, GitHub Copilot can suggest changes and, with @workspace , even
where to make the changes, but it's not allowed to make the changes for you. It's up to
you to add the suggested changes and test it.
Related content
Advance to the next tutorial to learn how to secure your app with a custom domain and
certificate.
You can configure passwordless connections to Azure services using Service Connector or you
can configure them manually. This tutorial shows how to use Service Connector. For more
information about passwordless connections, see Passwordless connections for Azure services.
For information about Service Connector, see the Service Connector documentation.
This tutorial demonstrates how to create and deploy a Python web app using the Azure CLI.
Run the commands in this tutorial in any Bash environment with the Azure CLI installed, such
as your local environment or the Azure Cloud Shell .
For examples of using a user-assigned managed identity, see Create and deploy a Django web
app to Azure with a user-assigned managed identity.
Console
git clone [Link]
[Link]
Console
cd msdocs-flask-web-app-managed-identity
Examine authentication code
The sample web app needs to authenticate to two different data stores:
Azure blob storage server where it stores and retrieves photos submitted by reviewers.
An Azure Database for PostgreSQL - Flexible Server database where it stores restaurants
and reviews.
service principals, depending on the environment it's running in, without making changes to
code. For example, in a local development environment, the app can run under the identity of
the developer signed in to the Azure CLI, while in Azure, as in this tutorial, it can run under its
system-assigned managed identity.
In either case, the security principal that the app runs under must have a role on each Azure
resource the app uses that permits it to perform the actions on the resource that the app
requires. In this tutorial, you use service connectors to automatically enable the system-
assigned managed identity on your app in Azure and to assign that identity appropriate roles
on your Azure storage account and Azure Database for PostgreSQL server.
After the system-assigned managed identity is enabled and is assigned appropriate roles on
the data stores, you can use DefaultAzureCredential to authenticate with the required Azure
resources.
The following code is used to create a blob storage client to upload photos in [Link] . An
instance of DefaultAzureCredential is supplied to the client, which it uses to acquire access
tokens to perform operations against Azure storage.
Python
azure_credential = DefaultAzureCredential()
blob_service_client = BlobServiceClient(
account_url=account_url,
credential=azure_credential)
An instance of DefaultAzureCredential is also used to get an access token for Azure Database
for PostgreSQL in ./azureproject/get_conn.py . In this case, the token is acquired directly by
calling get_token on the credential instance and passing it the appropriate scope value. The
token is then used in the place of the password in the PostgreSQL connection URI returned to
the caller.
Python
azure_credential = DefaultAzureCredential()
token = azure_credential.get_token("[Link]
conn = str(current_app.[Link]('DATABASE_URI')).replace('PASSWORDORTOKEN',
[Link])
To learn more about authenticating your apps with Azure services, see Authenticate Python
apps to Azure services by using the Azure SDK for Python. To learn more about
DefaultAzureCredential , including how to customize the credential chain it evaluates for your
Bash
LOCATION="eastus"
RAND_ID=$RANDOM
RESOURCE_GROUP_NAME="msdocs-mi-web-app"
APP_SERVICE_NAME="msdocs-mi-web-$RAND_ID"
DB_SERVER_NAME="msdocs-mi-postgres-$RAND_ID"
ADMIN_USER="demoadmin"
ADMIN_PW="ChAnG33#ThsPssWD$RAND_ID"
) Important
The ADMIN_PW must contain 8 to 128 characters from three of the following
categories: English uppercase letters, English lowercase letters, numbers, and
nonalphanumeric characters. When creating usernames or passwords do not use the
$ character. Later you create environment variables with these values where the $
character has special meaning within the Linux container used to run Python apps.
Azure CLI
az group create --location $LOCATION --name $RESOURCE_GROUP_NAME
3. Create a PostgreSQL server with the az postgres flexible-server create command. (This
and subsequent commands use the line continuation character for Bash Shell ('\'). Change
the line continuation character for your shell if needed.)
Azure CLI
az postgres flexible-server create \
--resource-group $RESOURCE_GROUP_NAME \
--name $DB_SERVER_NAME \
--location $LOCATION \
--admin-user $ADMIN_USER \
--admin-password $ADMIN_PW \
--sku-name Standard_D2ds_v4
The sku-name is the name of the pricing tier and compute configuration. For more
information, see Azure Database for PostgreSQL pricing . To list available SKUs, use az
postgres flexible-server list-skus --location $LOCATION .
Azure CLI
az postgres flexible-server execute \
--name $DB_SERVER_NAME \
--admin-user $ADMIN_USER \
--admin-password $ADMIN_PW \
--database-name postgres \
--querytext 'create database restaurant;'
Azure CLI
az webapp up \
--resource-group $RESOURCE_GROUP_NAME \
--name $APP_SERVICE_NAME \
--runtime PYTHON:3.9 \
--sku B1
The sku defines the size (CPU, memory) and cost of the app service plan. The B1 (Basic)
service plan incurs a small cost in your Azure subscription. For a full list of App Service
plans, view the App Service pricing page.
2. Configure App Service to use the [Link] in the repo with the az webapp config set
command.
Azure CLI
az webapp config set \
--resource-group $RESOURCE_GROUP_NAME \
--name $APP_SERVICE_NAME \
--startup-file "[Link]"
1. Add a PostgreSQL service connector with the az webapp connection create postgres-
flexible command. The system-assigned managed identity is used to authenticate the
web app to the target resource, PostgreSQL in this case.
Azure CLI
az webapp connection create postgres-flexible \
--resource-group $RESOURCE_GROUP_NAME \
--name $APP_SERVICE_NAME \
--target-resource-group $RESOURCE_GROUP_NAME \
--server $DB_SERVER_NAME \
--database restaurant \
--client-type python \
--system-identity
2. Add a storage service connector with the az webapp connection create storage-blob
command.
This command also adds a storage account and adds the web app with role Storage Blob
Data Contributor to the storage account.
Azure CLI
STORAGE_ACCOUNT_URL=$(az webapp connection create storage-blob \
--new true \
--resource-group $RESOURCE_GROUP_NAME \
--name $APP_SERVICE_NAME \
--target-resource-group $RESOURCE_GROUP_NAME \
--client-type python \
--system-identity \
--query configurations[].value \
--output tsv)
STORAGE_ACCOUNT_NAME=$(cut -d . -f1 <<< $(cut -d / -f3 <<<
$STORAGE_ACCOUNT_URL))
Create a container in the storage account
The sample Python app stores photos submitted by reviewers as blobs in a container in your
storage account.
When a user submits a photo with their review, the sample app writes the image to the
container using its system-assigned managed identity for authentication and
authorization. You configured this functionality in the last section.
When a user views the reviews for a restaurant, the app returns a link to the photo in blob
storage for each review that has one associated with it. For the browser to display the
photo, it must be able to access it in your storage account. The blob data must be
available for read publicly through anonymous (unauthenticated) access.
To enhance security, storage accounts are created with anonymous access to blob data
disabled by default. In this section, you enable anonymous read access on your storage
account and then create a container named photos that provides public (anonymous) access to
its blobs.
1. Update the storage account to allow anonymous read access to blobs with the az storage
account update command.
Azure CLI
az storage account update \
--name $STORAGE_ACCOUNT_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--allow-blob-public-access true
Enabling anonymous access on the storage account doesn't affect access for individual
blobs. You must explicitly enable public access to blobs at the container-level.
2. Create a container called photos in the storage account with the az storage container
create command. Allow anonymous read (public) access to blobs in the newly created
container.
Azure CLI
az storage container create \
--account-name $STORAGE_ACCOUNT_NAME \
--name photos \
--public-access blob \
--account-key $(az storage account keys list --account-name
$STORAGE_ACCOUNT_NAME \
--query [0].value --output tsv)
7 Note
For brevity, this command uses the storage account key to authorize with the
storage account. For most scenarios, Microsoft's recommended approach is to use
Microsoft Entra ID and Azure role-based access control (Azure RBAC) roles. For a
quick set of instructions, see Quickstart: Create, download, and list blobs with
Azure CLI. Several Azure roles permit you to create containers in a storage account,
including Owner, Contributor, Storage Blob Data Owner, and Storage Blob Data
Contributor.
To learn more about anonymous read access to blob data, see Configure anonymous read
access for containers and blobs.
It can take a minute or two for the app to start. If you see a default app page that isn't the
default sample app page, wait a minute and refresh the browser.
2. Test the functionality of the sample app by adding a restaurant and some reviews with
photos for the restaurant.
The restaurant and review information is stored in Azure Database for PostgreSQL and
the photos are stored in Azure Storage. Here's an example screenshot:
Clean up
In this tutorial, all the Azure resources were created in the same resource group. Removing the
resource group removes with the az group delete command removes all resources in the
resource group and is the fastest way to remove all Azure resources used for your app.
Azure CLI
az group delete --name $RESOURCE_GROUP_NAME
You can optionally add the --no-wait argument to allow the command to return before the
operation is complete.
Next steps
Create and deploy a Django web app to Azure with a user-assigned managed identity
Deploy a Python (Django or Flask) web app with PostgreSQL in Azure App Service
In this tutorial, you create a user-assigned managed identity and assign it to the App Service so
that it can access the database and storage account resources. For an example of using a
system-assigned managed identity, see Create and deploy a Flask Python web app to Azure
with system-assigned managed identity. User-assigned managed identities are recommended
because they can be used by multiple resources, and their life cycles are decoupled from the
resource life cycles with which they're associated. For more information about best practices
for using managed identities, see Managed identity best practice recommendations.
This tutorial shows you how to deploy the Python web app and create Azure resources using
the Azure CLI. While the commands in this tutorial use the Bash shell, you can run the tutorial
commands in any Bash environment with the CLI installed, such as your local environment or
the Azure Cloud Shell . With some modification you can run these commands in other
environments like Windows command shell (ex. modifying syntax to set and use environment
variables).
Console
git clone [Link]
[Link]
Console
cd msdocs-django-web-app-managed-identity
Azure blob storage server where it stores and retrieves photos submitted by reviewers.
An Azure Database for PostgreSQL - Flexible Server database where it stores restaurants
and reviews.
service principals, depending on the environment it's running in, without making changes to
code. For example, in a local development environment, the app can run under the identity of
the developer signed in to the Azure CLI, while in Azure, as in this tutorial, it can run under a
user-assigned managed identity.
In either case, the security principal that the app runs under must have a role on each Azure
resource the app uses that permits it to perform the actions on the resource that the app
requires. In this tutorial, you use Azure CLI commands to create a user-assigned managed
identity and assign it to your app in Azure. You then manually assign that identity appropriate
roles on your Azure storage account and Azure Database for PostgreSQL server. Finally, you set
the AZURE_CLIENT_ID environment variable for your app in Azure to configure
DefaultAzureCredential to use the managed identity.
After the user-assigned managed identity is configured on your app and its runtime
environment, and is assigned appropriate roles on the data stores, you can use
DefaultAzureCredential to authenticate with the required Azure resources.
The following code is used to create a blob storage client to upload photos in
./restaurant_review/[Link] . An instance of DefaultAzureCredential is supplied to the client,
which it uses to acquire access tokens to perform operations against Azure storage.
Python
azure_credential = DefaultAzureCredential()
blob_service_client = BlobServiceClient(
account_url=account_url,
credential=azure_credential)
An instance of DefaultAzureCredential is also used to get an access token for Azure Database
for PostgreSQL in ./azureproject/get_conn.py . In this case, the token is acquired directly by
calling get_token on the credential instance and passing it the appropriate scope value. The
token is then used to set the password in the PostgreSQL connection URI.
Python
azure_credential = DefaultAzureCredential()
token = azure_credential.get_token("[Link]
[Link]['default']['PASSWORD'] = [Link]
To learn more about authenticating your apps with Azure services, see Authenticate Python
apps to Azure services by using the Azure SDK for Python. To learn more about
DefaultAzureCredential , including how to customize the credential chain it evaluates for your
Bash
LOCATION="eastus"
RAND_ID=$RANDOM
RESOURCE_GROUP_NAME="msdocs-mi-web-app"
APP_SERVICE_NAME="msdocs-mi-web-$RAND_ID"
DB_SERVER_NAME="msdocs-mi-postgres-$RAND_ID"
ADMIN_USER="demoadmin"
ADMIN_PW="ChAnG33#ThsPssWD$RAND_ID"
UA_NAME="UAManagedIdentityPythonTest$RAND_ID"
) Important
The ADMIN_PW must contain 8 to 128 characters from three of the following
categories: English uppercase letters, English lowercase letters, numbers, and
nonalphanumeric characters. When creating usernames or passwords do not use the
$ character. Later you create environment variables with these values where the $
character has special meaning within the Linux container used to run Python apps.
Azure CLI
az group create --location $LOCATION --name $RESOURCE_GROUP_NAME
3. Create a PostgreSQL flexible server with the az postgres flexible-server create command.
(This and subsequent commands use the line continuation character for Bash Shell ('\').
Change the line continuation character for other shells.)
Azure CLI
az postgres flexible-server create \
--resource-group $RESOURCE_GROUP_NAME \
--name $DB_SERVER_NAME \
--location $LOCATION \
--admin-user $ADMIN_USER \
--admin-password $ADMIN_PW \
--sku-name Standard_D2ds_v4 \
--active-directory-auth Enabled \
--public-access [Link]
The sku-name is the name of the pricing tier and compute configuration. For more
information, see Azure Database for PostgreSQL pricing . To list available SKUs, use az
postgres flexible-server list-skus --location $LOCATION .
4. Add your Azure account as a Microsoft Entra admin for the server with the az postgres
flexible-server ad-admin create command.
Azure CLI
ACCOUNT_EMAIL=$(az ad signed-in-user show --query userPrincipalName --output
tsv)
ACCOUNT_ID=$(az ad signed-in-user show --query id --output tsv)
echo $ACCOUNT_EMAIL, $ACCOUNT_ID
az postgres flexible-server ad-admin create \
--resource-group $RESOURCE_GROUP_NAME \
--server-name $DB_SERVER_NAME \
--display-name $ACCOUNT_EMAIL \
--object-id $ACCOUNT_ID \
--type User
5. Configure a firewall rule on your server with the az postgres flexible-server firewall-rule
create command. This rule allows your local environment access to connect to the server.
(If you're using the Azure Cloud Shell, you can skip this step.)
Azure CLI
IP_ADDRESS=<your IP>
az postgres flexible-server firewall-rule create \
--resource-group $RESOURCE_GROUP_NAME \
--name $DB_SERVER_NAME \
--rule-name AllowMyIP \
--start-ip-address $IP_ADDRESS \
--end-ip-address $IP_ADDRESS
Use any tool or website that shows your IP address to substitute <your IP> in the
command. For example, you can use the What's My IP Address? website.
Azure CLI
az postgres flexible-server execute \
--name $DB_SERVER_NAME \
--admin-user $ADMIN_USER \
--admin-password $ADMIN_PW \
--database-name postgres \
--querytext 'create database restaurant;'
Azure CLI
az webapp up \
--resource-group $RESOURCE_GROUP_NAME \
--location $LOCATION \
--name $APP_SERVICE_NAME \
--runtime PYTHON:3.9 \
--sku B1
The sku defines the size (CPU, memory) and cost of the App Service plan. The B1 (Basic)
service plan incurs a small cost in your Azure subscription. For a full list of App Service
plans, view the App Service pricing page.
2. Configure App Service to use the [Link] in the sample repo with the az webapp config
set command.
Azure CLI
az webapp config set \
--resource-group $RESOURCE_GROUP_NAME \
--name $APP_SERVICE_NAME \
--startup-file "[Link]"
When a user submits a photo with their review, the sample app writes the image to the
container using managed identity and DefaultAzureCredential to access the storage
account.
When a user views the reviews for a restaurant, the app returns a link to the photo in blob
storage for each review that has one associated with it. For the browser to display the
photo, it must be able to access it in your storage account. The blob data must be
available for read publicly through anonymous (unauthenticated) access.
In this section, you create a storage account and container that permits public read access to
blobs in the container. In later sections, you create a user-assigned managed identity and
configure it to write blobs to the storage account.
Azure CLI
STORAGE_ACCOUNT_NAME="msdocsstorage$RAND_ID"
az storage account create \
--name $STORAGE_ACCOUNT_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--location $LOCATION \
--sku Standard_LRS \
--allow-blob-public-access true
2. Create a container called photos in the storage account with the az storage container
create command.
Azure CLI
az storage container create \
--account-name $STORAGE_ACCOUNT_NAME \
--name photos \
--public-access blob \
--auth-mode login
7 Note
It's possible that the command fails. For example, you might get an error indicating
that network rules are blocking the request to create the storage account. If the
command fails, enter the following command to make sure to assign an Azure role
with the permission to create containers to your Azure user account.
Azure CLI
az role assignment create --role "Storage Blob Data Contributor" --assignee
$ACCOUNT_EMAIL --scope
"/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP_NAME/provid
ers/[Link]/storageAccounts/$STORAGE_ACCOUNT_NAME"
For more information, see Quickstart: Create, download, and list blobs with Azure
CLI. Several Azure roles permit you to create containers in a storage account,
including Owner, Contributor, Storage Blob Data Owner, and Storage Blob Data
Contributor.
1. Use the az identity create command to create a user-assigned managed identity and
output the client ID to a variable for later use.
Azure CLI
UA_CLIENT_ID=$(az identity create --name $UA_NAME --resource-group
$RESOURCE_GROUP_NAME --query clientId --output tsv)
echo $UA_CLIENT_ID
2. Use the az account show command to get your subscription ID and output it to a variable
that can be used to construct the resource ID of the managed identity.
Azure CLI
SUBSCRIPTION_ID=$(az account show --query id --output tsv)
RESOURCE_ID="/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP_NAM
E/providers/[Link]/userAssignedIdentities/$UA_NAME"
echo $RESOURCE_ID
3. Assign the managed identity to the App Service with the az webapp identity assign
command.
Azure CLI
export MSYS_NO_PATHCONV=1
az webapp identity assign \
--resource-group $RESOURCE_GROUP_NAME \
--name $APP_SERVICE_NAME \
--identities $RESOURCE_ID
4. Create App Service app settings that contain the client ID of the managed identity and
other configuration info with the az webapp config appsettings set command.
Azure CLI
az webapp config appsettings set \
--resource-group $RESOURCE_GROUP_NAME \
--name $APP_SERVICE_NAME \
--settings AZURE_CLIENT_ID=$UA_CLIENT_ID \
STORAGE_ACCOUNT_NAME=$STORAGE_ACCOUNT_NAME \
STORAGE_CONTAINER_NAME=photos \
DBHOST=$DB_SERVER_NAME \
DBNAME=restaurant \
DBUSER=$UA_NAME
The sample app uses environment variables (app settings) to define connection information for
the database and storage account but these variables don't include passwords. Instead,
authentication is done passwordless with DefaultAzureCredential .
The sample app code uses the DefaultAzureCredential class constructor without passing the
user-assigned managed identity client ID to the constructor. In this scenario, the fallback is to
check for the AZURE_CLIENT_ID environment variable, which you set as an app setting.
1. Create a role assignment for the managed identity to enable access to the storage
account with the az role assignment create command.
Azure CLI
export MSYS_NO_PATHCONV=1
az role assignment create \
--assignee $UA_CLIENT_ID \
--role "Storage Blob Data Contributor" \
--scope "/subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCE_GROUP_NAME"
The command specifies the scope of the role assignment to the resource group. For more
information, see Understand role assignments.
Azure CLI
ACCOUNT_EMAIL_TOKEN=$(az account get-access-token --resource-type oss-rdbms --
output tsv --query accessToken)
az postgres flexible-server execute \
--name $DB_SERVER_NAME \
--admin-user $ACCOUNT_EMAIL \
--admin-password $ACCOUNT_EMAIL_TOKEN \
--database-name postgres \
--querytext "select * from pgaadauth_create_principal('"$UA_NAME"', false,
false);select * from pgaadauth_list_principals(false);"
If you have trouble running the command, make sure you added your user account as
Microsoft Entra admin for the PosgreSQL server and that you allow access to your IP
address in the firewall rules. For more information, see section Create an Azure
PostgreSQL flexible server.
It can take a minute or two for the app to start. If you see a default app page that isn't the
default sample app page, wait a minute and refresh the browser.
2. Test the functionality of the sample app by adding a restaurant and some reviews with
photos for the restaurant.
The restaurant and review information is stored in Azure Database for PostgreSQL and
the photos are stored in Azure Storage. Here's an example screenshot:
Clean up
In this tutorial, all the Azure resources were created in the same resource group. Removing the
resource group removes with the az group delete command removes all resources in the
resource group and is the fastest way to remove all Azure resources used for your app.
Azure CLI
You can optionally add the --no-wait argument to allow the command to return before the
operation is complete.
Next steps
Create and deploy a Flask web app to Azure with a system-assigned managed identity
Deploy a Python (Django or Flask) web app with PostgreSQL in Azure App Service
Azure Blob Storage is ideal for storing large amounts of unstructured data such as text, images,
and videos. Because blob storage also provides static website hosting support, it's a great
option in cases where you don't require a web server to render content. Although you're
limited to hosting static content such as HTML, CSS, JavaScript, and image files, you can use
serverless architectures including Azure Functions and other Platform as a service (PaaS)
services.
Static websites have some limitations. For example, If you want to configure headers, you'll
have to use Azure Content Delivery Network (Azure CDN). There's no way to configure headers
as part of the static website feature itself. Also, AuthN and AuthZ are not supported.
If these features are important for your scenario, consider using Azure Static Web Apps . It's a
great alternative to static websites and is also appropriate in cases where you don't require a
web server to render content. You can configure headers and AuthN / AuthZ is fully supported.
Azure Static Web Apps also provides a fully managed continuous integration and continuous
delivery (CI/CD) workflow from GitHub source to global deployment.
If you need a web server to render content, you can use Azure App Service .
A blob storage container named $web is created for you within the storage account if it
doesn't already exist. Add your website's files to the $web container to make them accessible
through the static website's primary endpoint.
Files in the $web container are case-sensitive, served through anonymous access requests and
are available only through read operations.
Uploading content
You can use any of these tools to upload content to the $web container:
" Azure CLI
" Azure PowerShell module
" AzCopy
" Azure Storage Explorer
" Azure portal
" Azure Pipelines
" Visual Studio Code extension and Channel 9 video demonstration
Viewing content
Users can view site content from a browser by using the public URL of the website. You can
find the URL by using the Azure portal, Azure CLI, or PowerShell. See Find the website URL.
The index document that you specify when you enable static website hosting appears when
users open the site and don't specify a specific file (For example:
[Link] ).
If the server returns a 404 error, and you haven't specified an error document when you
enabled the website, then a default 404 page is returned to the user.
7 Note
Cross-Origin Resource Sharing (CORS) support for Azure Storage is not supported with
static website.
Secondary endpoints
If you set up redundancy in a secondary region, you can also access website content by using a
secondary endpoint. Data is replicated to secondary regions asynchronously. Therefore, the
files that are available at the secondary endpoint aren't always in sync with the files that are
available on the primary endpoint.
While the primary static website endpoint isn't affected, a change to the anonymous access
level does impact the primary blob service endpoint.
For example, if you change the anonymous access level of the $web container from Private (no
anonymous access) to Blob (anonymous read access for blobs only), then the level of
anonymous access to the primary static website endpoint
[Link] doesn't change.
Disabling anonymous access on a storage account by using the anonymous access setting of
the storage account doesn't affect static websites that are hosted in that storage account. For
more information, see Remediate anonymous read access to blob data (Azure Resource
Manager deployments).
It's easier to enable HTTP access for your custom domain, because Azure Storage natively
supports it. To enable HTTPS, you'll have to use Azure CDN because Azure Storage doesn't yet
natively support HTTPS with custom domains. see Map a custom domain to an Azure Blob
Storage endpoint for step-by-step guidance.
If the storage account is configured to require secure transfer over HTTPS, then users must use
the HTTPS endpoint.
Tip
Consider hosting your domain on Azure. For more information, see Host your domain in
Azure DNS.
If you want to use headers to control caching, see Control Azure CDN caching behavior with
caching rules.
Permissions
The permission to be able to enable static website is
[Link]/storageAccounts/blobServices/write or shared key. Built in roles that provide
this access include Storage Account Contributor.
Pricing
You can enable static website hosting free of charge. You're billed only for the blob storage
that your site utilizes and operations costs. For more details on prices for Azure Blob Storage,
check out the Azure Blob Storage Pricing Page .
Metrics
You can enable metrics on static website pages. Once you've enabled metrics, traffic statistics
on files in the $web container are reported in the metrics dashboard.
To enable metrics on your static website pages, see Enable metrics on static website pages.
Feature support
Support for this feature might be impacted by enabling Data Lake Storage Gen2, Network File
System (NFS) 3.0 protocol, or the SSH File Transfer Protocol (SFTP). If you've enabled any of
these capabilities, see Blob Storage feature support in Azure Storage accounts to assess
support for this feature.
Yes. Storage account network security rules, including IP-based and VNET firewalls, are
supported for the static website endpoint, and may be used to protect your website.
No. A static website only supports anonymous read access for files in the $web container.
You can configure a custom domain with a static website by using Azure Content Delivery
Network (Azure CDN). Azure CDN provides consistent low latencies to your website from
anywhere in the world.
You can configure a custom SSL certificate with a static website by using Azure CDN. Azure
CDN provides consistent low latencies to your website from anywhere in the world.
A 404 error can happen if you refer to a file name by using an incorrect case. For example:
[Link] instead of [Link] . File names and extensions in the url of a static website are
case-sensitive even though they're served over HTTP. This can also happen if your Azure CDN
endpoint isn't yet provisioned. Wait up to 90 minutes after you provision a new Azure CDN for
the propagation to complete.
Why isn't the root directory of the website not redirecting to the
default index page?
In the Azure portal, open the static website configuration page of your account and locate the
name and extension that is set in the Index document name field. Ensure that this name is
exactly the same as the name of the file located in the $web container of the storage account.
File names and extensions in the url of a static website are case-sensitive even though they're
served over HTTP.
Enabling a private endpoint for blobs in a storage account restricts access to that storage
account to only resources within the same virtual network. Consequently, this restriction
prevents external access to the static website hosted in the storage account, making the static
website content inaccessible. The private endpoint configuration limits access to all storage
account resources, including the static website content, to resources within the same virtual
network where the private endpoint is enabled. The resolution would be to create a private
endpoint specifically for the web. The static website needs a dedicated private end point for
the $web domain.
Next steps
Host a static website in Azure Storage
Map a custom domain to an Azure Blob Storage endpoint
Azure Functions
Azure App Service
Build your first serverless web app
Tutorial: Host your domain in Azure DNS
Quickstart: Build your first static site
with Azure Static Web Apps
Article • 04/02/2024
Azure Static Web Apps publishes a website by building an app from a code repository.
In this quickstart, you deploy an application to Azure Static Web apps using the Visual
Studio Code extension.
Prerequisites
GitHub account
Azure account
Visual Studio Code
Azure Static Web Apps extension for Visual Studio Code
Install Git
Create a repository
This article uses a GitHub template repository to make it easy for you to get started. The
template features a starter app to deploy to Azure Static Web Apps.
No Framework
7 Note
Azure Static Web Apps requires at least one HTML file to create a web app. The
repository you create in this step includes a single [Link] file.
Bash
Next, open Visual Studio Code and go to File > Open Folder to open the cloned
repository in the editor.
7 Note
You are required to sign in to Azure and GitHub in Visual Studio Code to
continue. If you are not already authenticated, the extension prompts you to
sign in to both services during the creation process.
No Framework
ノ Expand table
Setting Value
9. Once the app is created, a confirmation notification is shown in Visual Studio Code.
If GitHub presents you with a button labeled Enable Actions on this repository,
select the button to allow the build action to run on your repository.
As the deployment is in progress, the Visual Studio Code extension reports the
build status to you.
Once the deployment is complete, you can navigate directly to your website.
10. To view the website in the browser, right-click the project in the Static Web Apps
extension, and select Browse Site.
Clean up resources
If you're not going to continue to use this application, you can delete the Azure Static
Web Apps instance through the extension.
In the Visual Studio Code Azure window, return to the Resources section and under
Static Web Apps, right-click my-first-static-web-app and select Delete.
Related content
Video series: Deploy websites to the cloud with Azure Static Web Apps
Next steps
Add an API
Feedback
Was this page helpful? Yes No
This article shows you how to run FastAPI and Postgres together in a GitHub Codespaces
environment. Codespaces is a cloud-hosted development environment that allows you to
create configurable and repeatable development environments.
You can open the sample repo in a browser or in an integrated development environment
(IDE) like Visual Studio Code with the GitHub Codespaces extension .
Alternatively, you can clone the sample repository locally. When you open the project in Visual
Studio Code, you can use Dev Containers to run it using Dev Containers . Dev Containers
requires that Docker Desktop to be installed locally. If Docker isn’t installed, you can run the
project using GitHub Codespaces as the development environment.
When using GitHub Codespaces, keep in mind that you have a fixed number of core hours free
per month. This tutorial requires less than one core hour to complete. For more information,
see About billing for GitHub Codespaces .
You can also use this setup as a starting point and modify the sample to run other Python web
frameworks such as Django or Flask.
The sample repo has all the configuration needed to create an environment with a
FastAPI app using a Postgres database. You can create a similar project following the
steps in Setting up a Python project for GitHub Codespaces .
3. When the container finishes building, confirm that you see Codespaces in the lower left
corner of the browser, and see the sample repo.
The codespace key configuration files are [Link], Dockerfile, and docker-
[Link]. For more information, see GitHub Codespaces overview .
Tip
You can also run the codespace in Visual Studio Code. Select Codespaces in lower
left corner of the browser or ( Ctrl + Shift + P / Ctrl + Command + P ) and type
"Codespaces". Then select Open in VS Code. Also, if you stop the codespace and go
back to the repo and open it again in GitHub Codespaces, you have the option to
open it in VS Code or a browser.
4. Select the .[Link] file and create a copy called .env with the same contents.
The .env contains environment variables that are used in the code to connect to the
database.
5. If a terminal window isn't already open, open one by opening the Command Palette
( Ctrl + Shift + P / Ctrl + Command + P ), typing "Terminal: Create New Terminal", and
selecting it to create a new terminal.
6. Select the PORTS tab in the terminal window to confirm that PostgreSQL is running on
port 5432.
Bash
If you don't see or missed the notification, go to PORTS and find the Local Address for
port 8000. Use the URL listed there.
9. Add /docs on the end of the preview URL to see the Swagger UI , which allows you to
test the API methods.
The API methods are generated from the OpenAPI interface that FastAPI creates from the
code.
10. On the Swagger page, run the POST method to add a restaurant.
JSON
{
"name": "Restaurant 1",
"address": "Restaurant 1 address"
}
The SQLTools extension should be installed when the container is created. If the SQLTools
extension doesn't appear in the Activity Bar, close the codespace and reopen.
2. Expand the Local database node until you find the restaurants table, right select Show
Table Records.
Clean up
To stop using the codespace, close the browser. (Or, close VS Code if you opened it that way.)
If you plan on using the codespace again, you can keep it. Only running codespaces incur CPU
charges. A stopped codespace incurs only storage costs.
Next steps
Develop a Python web app
Develop a container app
Learn to use the Azure libraries for Python
Configure a custom startup file for Python
apps on Azure App Service
Article • 04/22/2025
In this article, you learn when and how to configure a custom startup file for a Python web app
hosted on Azure App Service. While a startup file isn't required for local development, Azure
App Service runs your deployed web app within a Docker container that can utilize startup
commands if provided.
Custom Gunicorn Arguments: You want to start the Gunicorn default web server with
extra arguments beyond its defaults, which are --bind=[Link] --timeout 600 .
Alternative Frameworks or Servers: Your app is built with a framework other than Flask or
Django, or you want to use a different web server besides Gunicorn.
Non-Standard Flask Application Structure: You have a Flask app whose main code file is
named something other than [Link] or [Link]*, or the app object is named
something other than app .
In other words, a custom startup command is required unless your project has an [Link] or
[Link] file in the root folder with a Flask app object named app .
For more information, see Configure Python Apps - Container startup process.
1. Create a file in your project named [Link], [Link], or another name of your choice
that contains your startup commands. See the later sections in this article for specifics on
Django, Flask, and other frameworks.
2. Commit the file to your code repository so it can be deployed with the rest of the app.
3. In Visual Studio Code, select the Azure icon in the Activity Bar, expand RESOURCES, find
and expand your subscription, expand App Services, and right-click the App Service, and
select Open in Portal.
4. In the Azure portal , on the Configuration page for the App Service, select General
settings, enter the name of your startup file (like [Link] or [Link]) under Stack
settings > Startup Command, then select Save.
7 Note
Instead of using a startup command file, you can put the startup command itself
directly in the Startup Command field on the Azure portal. Using a startup command
file is recommended because it stores your configuration in your repository. This
enables version control to track changes and simplifies redeployment to other Azure
App Service instances.
If you access your Azure App Service site before deploying your application code, an
"Application Error" appears because no code is available to process the request.
sh
# <module> is the folder that contains [Link]. If you need to use a subfolder,
# specify the parent of <module> using --chdir.
gunicorn --bind=[Link] --timeout 600 <module>.wsgi
If you want to modify any Gunicorn arguments, such as increasing the timeout value to 1,200
seconds( --timeout 1200 ), create a custom startup command file. This allows you to override
the default settings with your specific requirements. For more information, see Container
startup process - Django app.
Different file name and/or app object name: If the app's main code file is [Link] and
the app object is named myapp , the startup command is as follows:
text
Startup file is in a subfolder: If the startup file is myapp/[Link] and the app object is
app , then use Gunicorn's --chdir argument to specify the folder and then name the
text
In this situation, create a shim file that imports the app object from the module, and then
have Gunicorn launch the app using the shim. The python-sample-vscode-flask-tutorial
code, for example, contains [Link] with the following contents:
Python
txt
To use a framework other than Django or Flask (such as Falcon , FastAPI , etc.), or to use a
different web server:
In your startup command, identify the WSGI callable as described in the previous section
for Flask.
To launch a web server other than Gunicorn, use a python -m command instead of
invoking the server directly. For example, the following command starts the uvicorn
server, assuming that the WSGI callable is named app and is found in [Link]:
sh
You use python -m because web servers installed via [Link] aren't added to the
Python global environment and therefore can't be invoked directly. The python -m
command invokes the server from within the current virtual environment.
Deploy Python web apps to App Service by
using GitHub Actions (Linux)
06/23/2025
This article describes how to use the continuous integration and continuous delivery (CI/CD)
platform in GitHub Actions to deploy a Python web app to Azure App Service on Linux. Your
GitHub Actions workflow automatically builds the code and deploys it to the App Service
instance whenever there's a commit to the repository. You can add other automation in your
GitHub Actions workflow, such as test scripts, security checks, and multistages deployment.
Existing app: To use an existing Python web app, make sure the app is committed to a
GitHub repository.
New app: If you need a new Python web app, you can fork and clone the
[Link] GitHub repository.
The sample code supports the Flask in Visual Studio Code tutorial, and provides a
functioning Python application.
7 Note
If your app uses Django and a SQLite database, it won't work for these procedures.
SQLite is not supported in most cloud-hosted environments due to its local file-based
storage limitations. Consider switching to a cloud-compatible database such as
PostgreSQL or Azure Cosmos DB. For more information, see Review Django
considerations later in this article.
3. In Cloud Shell, select the Bash option from the dropdown menu:
4. In Cloud Shell, clone your repository by using the git clone command.
Tip
To paste commands or text into Cloud Shell, use the Ctrl+Shift+V keyboard shortcut,
or right-click and select Paste from the context menu.
For the Flask sample app, you can use the following command. Replace the <github-
user> portion with the name of the GitHub account where you forked the repo:
Bash
If your app is in a different repo, set up GitHub Actions for the particular repo.
Replace the <github-user> portion with the name of the GitHub account where you
forked the repo, and provide the actual repo name in the <repo-name> placeholder:
Bash
7 Note
Cloud Shell is backed by an Azure Storage account in a resource group named
cloud-shell-storage-<your-region>. That storage account contains an image of the
Cloud Shell file system, which stores the cloned repository. There's a small cost for
this storage. You can delete the storage account after you complete this article,
along with other resources you create.
5. In Cloud Shell, change directory into the repository folder for your Python app, so the az
webapp up command recognizes the app as Python. For the Flask sample app, you use
the following command:
Bash
cd python-sample-vscode-flask-tutorial
6. In Cloud Shell, use the az webapp up command to create an App Service instance and do
the initial deployment for your app:
Bash
For the <app-service-name> placeholder, specify an App Service name that's unique
in Azure. The name must be 3-60 characters long and can contain only letters,
numbers, and hyphens. The name must start with a letter and end with a letter or
number.
For a list of available runtimes on your system, use the az webapp list-runtimes
command.
When you enter the runtime value in the command, use the PYTHON:X.Y format,
where X.Y is the Python major and minor version.
You can also specify the region location of the App Service instance by using the --
location parameter. For a list of available locations, use the az account list-
locations --output table command.
7. If your app has a custom startup script, use the az webapp config command to initiate the
script.
If your app doesn't have a custom startup script, continue to the next step.
For the Flask sample app, you need to access the startup script in the [Link] file
by running the following command:
Bash
Provide your resource group name and App Service instance name in the
<resource-group-name> and <app-service-name> placeholders. To find the resource
group name, check the output from the previous az webapp up command. The
resource group name includes the Azure account name followed by the _rg suffix, as
in <azure-account-name>_rg_.
8. To view the running app, open a browser and go to the deployment endpoint for your
App Service instance. In the following URL, replace the <app-service-name> placeholder
with your App Service instance name:
URL
[Link]
If you see a generic page, wait a few seconds for the App Service instance to start, and
refresh the page.
If you continue to see a generic page, confirm you deployed from the correct folder.
For the Flask sample app, confirm you deployed from the python-sample-vscode-
flask-tutorial folder. Also check that you set the startup command correctly.
1. In Cloud Shell, confirm you're in the root directory for your system ( ~ ) and not in an app
subfolder, such as python-sample-vscode-flask-tutorial.
2. Add GitHub Actions with the az webapp deployment github-actions add command.
Replace any placeholders with your specific values:
Bash
If the system encounters an existing workflow file with the same App Service
instance name, follow the prompts to choose whether to overwrite the workflow.
You can use the --force parameter with the command to automatically overwrite
any conflicting workflows.
3. Get the details of a source control deployment configuration with the az webapp
deployment source show command. Replace the placeholder parameters with your
specific values:
Bash
4. In the command output, confirm the values for the repoUrl and branch properties. These
values should match the values you specified with the add command.
Each workflow is made up of one or more jobs, and each job is a set of steps. Each step is a
shell script or an action. Each job has an Action section in the workflow file.
In terms of the workflow set up with your Python code for deployment to Azure App Service,
the workflow has the following actions:
ノ Expand table
Action Description
webapps- Deploy the web app by using a publish profile credential to authenticate in Azure. The
deploy credential is stored in a GitHub secret .
The workflow is triggered on push events to the specified branch. The event and branch are
defined at the beginning of the workflow file. For example, the following code snippet shows
the workflow is triggered on push events to the main branch:
YAML
on:
push:
branches:
- main
To see your authorized apps and revoke permissions under your GitHub accounts, go to
Settings > Integrations/Applications:
Workflow publish profile secret
In the .github/workflows/<workflow-name>.yml workflow file added to your repo, there's a
placeholder for publish profile credentials required for the deploy job of the workflow. The
publish profile information is stored encrypted in the repository.
To view the secret, go to Settings > Security > Secret and variables > Actions:
In this article, the GitHub action authenticates with a publish profile credential. There are other
ways to authenticate, such as with a service principal or OpenID Connect. For more
information, see Deploy to App Service using GitHub Actions.
1. In a browser, go to your fork of the sample repository (or the repository you used), and
select the branch you set as part of the trigger:
2. Make a small change to your Python web app.
2. Select the workflow in the list of workflows, and then select Run workflow.
For a failed job, look at the output of job tasks for an indication of the failure.
Here are some common issues to investigate:
If the app fails because of a missing dependency, then your [Link] file wasn't
processed during deployment. This behavior happens if you created the web app directly
on the portal rather than by using the az webapp up command as shown in this article.
If you provisioned the app service through the portal, the build action
SCM_DO_BUILD_DURING_DEPLOYMENT setting might not be set. This setting must be set to
true . The az webapp up command sets the build action automatically.
If you see an error message regarding "TLS handshake timeout," run the workflow
manually by selecting Trigger auto deployment under the Actions tab of the app repo.
You can determine if the timeout is a temporary issue.
If you set up continuous deployment for the container app as shown in this article, the
initial workflow file .github/workflows/<workflow-name>.yml is created automatically for
you. If you modified the file, remove the modifications to see if they're causing the failure.
To avoid hard-coding variable values in your workflow YAML file, consider configuring the
variables in GitHub and referring to the variable names in the script. You can create encrypted
secrets for a repository or for an environment (account repository). For more information, see
Using secrets in GitHub Actions .
The Configure Python app on App Service - Container startup process article describes how
App Service automatically looks for a [Link] file within your app code, which typically contains
the app object. When you used the webapp config set command to set the startup command,
you used the --startup-file parameter to specify the file that contains the app object. The
webapp config set command isn't available in the webapps-deploy action. Instead, you can
use the startup-command parameter to specify the startup command. For example, the
following code shows how to specify the startup command in the workflow file:
YAML
startup-command: [Link]
When you use Django, you typically want to migrate the data models by using the python
[Link] migrate command after you deploy the app code. You can run the migrate
Azure CLI
Disconnect GitHub Actions with the following Azure CLI az webapp deployment github-
actions remove command. Replace any placeholders with your specific values:
Bash
Clean up resources
To avoid incurring charges on the Azure resources created in this article, delete the resource
group that contains the App Service instance and the App Service Plan.
Azure CLI
Anywhere the Azure CLI is installed, including the Azure Cloud Shell, you can use the az
group delete command to delete a resource group:
Bash
Related content
Common repositories and workflows for GitHub Actions
Command reference - az webapp deployment github-actions
Use Azure Pipelines to build and deploy a
Python web app to Azure App Service
Azure DevOps Services
This tutorial shows you how to use Azure Pipelines for continuous integration and continuous
delivery (CI/CD) to build and deploy a Python web app to Azure App Service on Linux. Your
pipeline automatically builds and deploys your Python web app to App Service whenever
there's a commit to your app code repository.
To understand more about Azure Pipelines concepts, watch the following video:
[Link]
3816085087e9&locale=en-
us&embedUrl=%2Fazure%2Fdevops%2Fpipelines%2Fecosystems%2Fpython-webapp
Prerequisites
ノ Expand table
Product Requirements
2. Clone your fork to your local machine by using git clone <your-forked-repository-
url>.git .
Bash
4. To test the app, go to [Link] in a browser window, and verify that you see
the title Visual Studio Flask Tutorial.
5. Close the browser window and stop the Flask server by using Ctrl + C .
The Cloud Shell appears along the bottom of the browser. Make sure Bash is selected as the
environment in the dropdown menu. You can maximize the Cloud Shell window to give
yourself more room.
Tip
To paste into Cloud Shell, use Ctrl + Shift + V or right-click and select Paste from the
context menu.
Bash
Bash
cd python-sample-vscode-flask-tutorial
3. Run the az webapp up command to provision the App Service web app and do the first
deployment. Use the --name <your-web-app-name> parameter to assign a name that's
unique across Azure, such as a personal or company name along with an app identifier,
like --name <your-name>-flaskpipelines . Running az webapp up with no parameters
assigns a randomly generated web app name that's unique in Azure.
Azure CLI
az webapp up --name <your-web-app-name>
The az webapp up command recognizes the app as a Python app, and takes the following
actions:
4. Deploys all files from the current working directory to a ZIP archive, with build
automation enabled.
5. Caches the parameters locally in the .azure/config file so you don't need to specify them
again when deploying from the project folder with az webapp up or other az webapp
commands. The commands use the cached values automatically by default.
You can override the default actions with your own values by using the command parameters.
For more information, see az webapp up.
The az webapp up command produces the following JSON output for the sample web app:
JSON
{
"URL": <your-web-app-url>,
"appserviceplan": <your-app-service-plan-name>,
"location": <your-azure-region>,
"name": <your-web-app-name>,
"os": "Linux",
"resourcegroup": <your-resource-group>,
"runtime_version": "python|3.11",
"runtime_version_detected": "-",
"sku": <sku>,
"src_path": <repository-source-path>
}
Record the URL , resourcegroup , and runtime_version values to use later in this tutorial.
Azure CLI
az webapp config set --resource-group <your-resource-group> --name <your-web-app-
name> --startup-file [Link]
When the command completes, the JSON output shows all the configuration settings for your
web app.
To see the running app, open a browser and go to the URL shown in the az webapp up
command output. If you see a generic page, wait a few seconds for the App Service to start,
then refresh the page. Verify that you see the title Visual Studio Flask Tutorial.
Connect your Azure DevOps project to your Azure
subscription
To use Azure Pipelines to deploy to your Azure App Service web app, you need to connect your
Azure DevOps project to your Azure resources.
3. On the Service connections page, select New service connection or Create service
connection if this service connection is the first in the project.
4. On the New service connection screen, select Azure Resource Manager and then select
Next.
5. On the New Azure service connection screen, select your Identity type. This example
uses App registration (automatic), which is recommended. For more information about
authentication methods, see Connect to Azure by using an Azure Resource Manager
service connection.
8. Select Save.
The new connection appears in the Service connections list, and is ready to use in your
pipeline.
Create a pipeline
Create a pipeline to build and deploy your Python web app to Azure App Service.
2. On the Pipelines page, select New pipeline, or Create pipeline if this pipeline is the first
in the project.
3. On the Where is your code screen, select GitHub. You might be prompted to sign into
GitHub.
4. On the Select a repository screen, select your forked sample repository. GitHub might
prompt you to enter your GitHub password again, or to install the Azure Pipelines
GitHub app. Follow onscreen instructions to install the app. For more information, see
GitHub app authentication.
5. On the Configure your pipeline page, select Python to Linux Web App on Azure.
6. On the next screen, select your Azure subscription and select Continue.
7. On the next screen, select your Azure web app and select Validate and configure.
Azure Pipelines creates an [Link] file and displays it in the YAML pipeline editor.
The following complete example YAML pipeline file defines your CI/CD pipeline as a series of
stages, jobs, and steps, where each step contains the details for different tasks and scripts. The
generated YAML code automatically populates the placeholders with values for your app and
connection.
yml
trigger:
- main
variables:
# Azure Resource Manager connection created during pipeline creation
azureServiceConnectionId: '<GUID>'
# Environment name
environmentName: '<your-webapp-name>'
pythonVersion: '3.11'
stages:
- stage: Build
displayName: Build stage
jobs:
- job: BuildJob
pool:
vmImage: $(vmImageName)
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '$(pythonVersion)'
displayName: 'Use Python $(pythonVersion)'
- script: |
python -m venv antenv
source antenv/bin/activate
python -m pip install --upgrade pip
pip install setuptools
pip install -r [Link]
workingDirectory: $(projectRoot)
displayName: "Install requirements"
- task: ArchiveFiles@2
displayName: 'Archive files'
inputs:
rootFolderOrFile: '$(projectRoot)'
includeRootFolder: false
archiveType: zip
archiveFile: $([Link])/$([Link]).zip
replaceExistingArchive: true
- upload: $([Link])/$([Link]).zip
displayName: 'Upload package'
artifact: drop
- stage: Deploy
displayName: 'Deploy Web App'
dependsOn: Build
condition: succeeded()
jobs:
- deployment: DeploymentJob
pool:
vmImage: $(vmImageName)
environment: $(environmentName)
strategy:
runOnce:
deploy:
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '$(pythonVersion)'
displayName: 'Use Python version'
- task: AzureWebApp@1
displayName: 'Deploy Azure Web App : $(webAppName)'
inputs:
azureSubscription: $(azureServiceConnectionId)
appName: $(webAppName)
package: $([Link])/drop/$([Link]).zip
Variables
The variables section at the beginning of the YAML file defines the following variables:
ノ Expand table
Variable Description
vmImageName The name of the operating system to use for the build agent.
environmentName The name of the environment to deploy to, which is automatically created
when the deployment job runs.
pythonVersion The version of Python to use on the build and deployment agents.
Build stage
The build stage contains a single job that runs on the operating system defined in the
vmImageName variable, in this case ubuntu-latest .
yml
- job: BuildJob
pool:
vmImage: $(vmImageName)
1. First, the UsePythonVersion task selects the version of Python to use, as defined in the
pythonVersion variable.
yml
- task: UsePythonVersion@0
inputs:
versionSpec: '$(pythonVersion)'
displayName: 'Use Python $(pythonVersion)'
2. The next step uses a script that creates a virtual Python environment and installs the app's
dependencies from [Link] . The workingDirectory parameter specifies the
location of the app code.
yml
- script: |
python -m venv antenv
source antenv/bin/activate
python -m pip install --upgrade pip
pip install setuptools
pip install -r ./[Link]
workingDirectory: $(projectRoot)
displayName: "Install requirements"
3. The ArchiveFiles task creates a ZIP archive that contains the built web app.
yml
- task: ArchiveFiles@2
displayName: 'Archive files'
inputs:
rootFolderOrFile: '$(projectRoot)'
includeRootFolder: false
archiveType: zip
archiveFile: $([Link])/$([Link]).zip
replaceExistingArchive: true
ノ Expand table
Parameter Description
includeRootFolder Whether to include the root folder in the .zip file. Set to false . If set to
true , the contents of the .zip file are put in a folder named s and the
task can't find the app code.
replaceExistingArchive Indicates whether to replace an existing archive if the file already exists.
Set to true .
4. The .zip file then uploads to the pipeline as an artifact named drop . The deployment
stage uses the .zip file to deploy the app.
yml
- upload: $([Link])/$([Link]).zip
displayName: 'Upload package'
artifact: drop
The upload parameter sets the location and name of the .zip file to upload.
The artifact parameter sets the name of the created artifact to drop .
Deployment stage
The deployment stage runs if the build stage completes successfully. The dependsOn and
condition keywords define this behavior.
yml
dependsOn: Build
condition: succeeded()
yml
- deployment: DeploymentJob
pool:
vmImage: $(vmImageName)
environment: $(environmentName)
The deployment keyword indicates that the job is a deployment job targeting an
environment to deploy to. The environment is automatically created in your project when
the job is run.
The pool parameter specifies the deployment agent pool and uses the default agent pool
if a name isn't specified. The agent runs on the operating system defined in the
vmImageName variable, in this case ubuntu-latest .
yml
strategy:
runOnce:
deploy:
steps:
The runOnce keyword specifies that the deployment job runs once.
The deploy keyword specifies the steps to run in the deployment job.
1. UsePythonVersion@0 selects the version of Python to use, same as in the Build stage.
2. AzureWebApp@1 deploys the web app and the drop ZIP artifact.
yml
- task: AzureWebApp@1
displayName: 'Deploy Azure Web App : <your-web-app-name>'
inputs:
azureSubscription: $(azureServiceConnectionId)
appName: $(webAppName)
package: $([Link])/drop/$([Link]).zip
Also, because the python-vscode-flask-tutorial repository contains the app startup command in
a file named [Link], you can specify the app startup command by adding the parameter:
startUpCommand: '[Link]' .
2. On the Save and run screen, add a commit message if desired and then select Save and
run.
You can watch the pipeline run by selecting the Stages or Jobs on the pipeline Summary
page. Each job and stage displays a green check mark as it completes successfully. If
errors occur, they appear in the summary or in the job steps.
You can quickly return to the YAML editor by selecting the vertical dots at the upper right
on the Summary page and selecting Edit pipeline.
3. From the deployment job, select the Deploy Azure Web App task to display its output.
4. From the output, select the URL after App Service Application URL. The app should
appear as follows:
7 Note
1. On the portal page for your web app, select Configuration from the left navigation
menu.
2. On the Application Settings tab, select New Application Setting.
3. In the popup that appears, set Name to SCM_DO_BUILD_DURING_DEPLOYMENT , set Value
to true , and select OK.
4. Select Save at the top of the Configuration page.
5. Run the pipeline again. The dependencies should now install during deployment.
As explained in Container startup process, App Service automatically looks for a [Link] file in
your app code, which typically contains the app object. If you want to customize the startup
command, use the startUpCommand parameter in the AzureWebApp@1 step of your YAML pipeline
file.
When you use Django, you typically want to migrate the data models using [Link] migrate
after deploying the app code. You can add startUpCommand with a post-deployment script for
this purpose. For example, here's the startUpCommand property in the AzureWebApp@1 task.
yml
- task: AzureWebApp@1
displayName: 'Deploy Azure Web App : $(webAppName)'
inputs:
azureSubscription: $(azureServiceConnectionId)
appName: $(webAppName)
package: $([Link])/drop/$([Link]).zip
startUpCommand: 'python [Link] migrate'
The following script elements illustrate this process. Place them before the ArchiveFiles@2 task
in the [Link] file. For more information, see Run cross-platform scripts.
yml
# The | symbol is a continuation character, indicating a multi-line script.
# A single-line script can immediately follow "- script:".
- script: |
python -m venv .env
source .env/bin/activate
pip install setuptools
pip install -r [Link]
- script: |
# Put commands to run tests here
displayName: 'Run tests'
- script: |
echo Deleting .env
deactivate
rm -rf .env
displayName: 'Remove .env before zip'
You can also use a task like PublishTestResults@2 to publish the test results to your pipeline.
For more information, see Run tests.
Clean up resources
If you're finished with the Azure resources you created in this tutorial, delete them to avoid
incurring further charges.
Delete the Azure DevOps project you created. Deleting the project deletes the pipeline
and service connection.
Delete the Azure resource group that contains the App Service and the App Service Plan.
In the Azure portal, go to the resource group, select Delete resource group, and follow
the prompts.
Delete the Azure storage account that maintains the Cloud Shell file system. Close Cloud
Shell, then find the resource group that begins with cloud-shell-storage-. Select Delete
resource group, and follow the prompts.
Related content
Customize Python apps in Azure Pipelines
Configure Python app on App Service
In this quickstart, you use a sample web app to show you how to sign in users and call
Microsoft Graph API in your workforce tenant. The sample app uses the Microsoft
Authentication Library to handle authentication.
Before you begin, use the Choose a tenant type selector at the top of this page to select
tenant type. Microsoft Entra ID provides two tenant configurations, workforce and external. A
workforce tenant configuration is for your employees, internal apps, and other organizational
resources. An external tenant is for your customer-facing apps.
Prerequisites
An Azure account with an active subscription. If you don't already have one, Create an
account for free .
This Azure account must have permissions to manage applications. Any of the following
Microsoft Entra roles include the required permissions:
Application Administrator
Application Developer
A workforce tenant. You can use your Default Directory or set up a new tenant.
Visual Studio Code or another code editor.
Node
Register a new app in the Microsoft Entra admin center , configured for Accounts in
this organizational directory only. Refer to Register an application for more details.
Record the following values from the application Overview page for later use:
Application (client) ID
Directory (tenant) ID
Add the following redirect URIs using the Web platform configuration. Refer to How
to add a redirect URI in your application for more details.
Redirect URI: [Link]
Front-channel logout URL: [Link]
Add a client secret to your app registration. Do not use client secrets in production
apps. Use certificates or federated credentials instead. For more information, see add
credentials to your application.
[Link]
Node
Download the .zip file , then extract it to a file path where the length of the name is
fewer than 260 characters or clone the repository:
To clone the sample, open a command prompt and navigate to where you wish to
create the project, and enter the following command:
Console
Node
In the ms-identity-node folder, open the App/.env file, then replace the following
placeholders:
ノ Expand table
After you make changes, your file should look similar to the following snippet:
env
CLOUD_INSTANCE=[Link]
TENANT_ID=aaaabbbb-0000-cccc-1111-dddd2222eeee
CLIENT_ID=00001111-aaaa-2222-bbbb-3333cccc4444
CLIENT_SECRET=A1b-C2d_E3f.H4...
REDIRECT_URI=[Link]
POST_LOGOUT_REDIRECT_URI=[Link]
GRAPH_API_ENDPOINT=[Link]
EXPRESS_SESSION_SECRET=6DP6v09eLiW7f1E65B8k
Node
1. To start the server, run the following commands from within the project directory:
Console
cd App
npm install
npm start
2. Go to [Link] .
The first time you sign in, you're prompted to provide your consent to allow the
application to sign you in and access your profile. After you're signed in successfully, you'll
be redirected back to the application home page.
Related content
Node
Learn how to build a [Link] web app that signs in users and calls Microsoft Graph
API in Tutorial: Sign in users and acquire a token for Microsoft Graph in a [Link] &
Express web app.
Quickstart: Azure Key Vault secret client
library for Python
テ Summarize this article for me
Get started with the Azure Key Vault secret client library for Python. Follow these steps to install
the package and try out example code for basic tasks. By using Key Vault to store secrets, you
avoid storing secrets in your code, which increases the security of your app.
API reference documentation | Library source code | Package (Python Package Index)
Prerequisites
An Azure subscription - create one for free .
Python 3.7+.
Azure CLI or Azure PowerShell.
This quickstart assumes you're running Azure CLI or Azure PowerShell in a Linux terminal
window.
Sign in to Azure
Azure CLI
Azure CLI
az login
If the CLI can open your default browser, it will do so and load an Azure sign-in page.
Otherwise, open a browser page at [Link] and enter the
authorization code displayed in your terminal.
terminal
pip install azure-identity
terminal
pip install azure-keyvault-secrets
Azure CLI
Azure CLI
Azure CLI
Console
export KEY_VAULT_NAME=<your-unique-keyvault-name>
Azure CLI
az role assignment create --role "Key Vault Secrets Officer" --assignee "<upn>" --
scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group-
name>/providers/[Link]/vaults/<your-unique-keyvault-name>"
Python
import os
from [Link] import SecretClient
from [Link] import DefaultAzureCredential
keyVaultName = [Link]["KEY_VAULT_NAME"]
KVUri = f"[Link]
credential = DefaultAzureCredential()
client = SecretClient(vault_url=KVUri, credential=credential)
client.set_secret(secretName, secretValue)
print(" done.")
retrieved_secret = client.get_secret(secretName)
poller = client.begin_delete_secret(secretName)
deleted_secret = [Link]()
print(" done.")
terminal
python kv_secrets.py
If you encounter permissions errors, make sure you have the appropriate Azure RBAC role
assigned. See the Grant access to your key vault step.
Rerunning the code with the same secret name may produce the error, "(Conflict) Secret
<name> is currently in a deleted but recoverable state." Use a different secret name.
Code details
method should be used at runtime. This approach enables your app to use different
authentication methods in different environments (local vs. production) without implementing
environment-specific code.
In the example code, the name of your key vault is expanded using the value of the KVUri
variable, in the format: "[Link]
Python
credential = DefaultAzureCredential()
client = SecretClient(vault_url=KVUri, credential=credential)
Save a secret
Once you've obtained the client object for the key vault, you can store a secret using the
set_secret method:
Python
client.set_secret(secretName, secretValue)
Calling set_secret generates a call to the Azure REST API for the key vault.
When Azure handles the request, it authenticates the caller's identity (the service principal)
using the credential object you provided to the client.
Retrieve a secret
To read a secret from Key Vault, use the get_secret method:
Python
retrieved_secret = client.get_secret(secretName)
The secret value is contained in retrieved_secret.value .
You can also retrieve a secret with the Azure CLI command az keyvault secret show or the
Azure PowerShell cmdlet Get-AzKeyVaultSecret.
Delete a secret
To delete a secret, use the begin_delete_secret method:
Python
poller = client.begin_delete_secret(secretName)
deleted_secret = [Link]()
The begin_delete_secret method is asynchronous and returns a poller object. Calling the
poller's result method waits for its completion.
You can verify that the secret had been removed with the Azure CLI command az keyvault
secret show or the Azure PowerShell cmdlet Get-AzKeyVaultSecret.
Once deleted, a secret remains in a deleted but recoverable state for a time. If you run the code
again, use a different secret name.
Clean up resources
If you want to also experiment with certificates and keys, you can reuse the Key Vault created in
this article.
Otherwise, when you're finished with the resources created in this article, use the following
command to delete the resource group and all its contained resources:
Azure CLI
Azure CLI
az group delete --resource-group myResourceGroup
Next steps
Overview of Azure Key Vault
Azure Key Vault developer's guide
Key Vault security overview
Secrets-specific security best practices
Authenticate with Key Vault
Completing this quickstart incurs a small cost of a few USD cents or less in your Azure account.
Make sure to select your preferred development language at the top of the article.
Prerequisites
An Azure account with an active subscription. Create an account for free .
Python versions that are supported by Azure Functions. For more information, see How to
install Python .
In Visual Studio Code, select F1 to open the command palette, and then search for and run the
command Azure Functions: Install or Update Core Tools.
This command tries to either start a package-based installation of the latest version of Core
Tools or update an existing package-based installation. If you don't have npm or Homebrew
installed on your local computer, you must instead manually install or update Core Tools.
1. In Visual Studio Code, press F1 to open the command palette. Search for and run the
command Azure Functions: Create New Project... .
2. Choose the directory location for your project workspace and choose Select. You should
either create a new folder or choose an empty folder for the project workspace. Don't
choose a project folder that is already part of a workspace.
ノ Expand table
Prompt Selection
Select a Python interpreter to Choose your preferred Python interpreter. If an option isn't
create a virtual environment shown, type in the full path to your Python binary.
Authorization level Choose FUNCTION , which requires an access key to call your
function endpoint. For more information, see Authorization
level.
Using this information, Visual Studio Code generates a code project for Azure Functions
with an HTTP trigger function endpoint. You can view the local project files in the
Explorer. To learn more about files that are created, see Generated project files.
JSON
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
This setting tells the local Functions host to use the storage emulator for the storage
connection required by the Python v2 model. When you publish your project to Azure,
this setting uses the default storage account instead. If you use an Azure Storage account
during local development, set your storage account connection string here.
2. Check the bottom bar and verify that Azurite emulation services are running. If so, you
can now run your function locally.
1. To start the function locally, press F5 or the Run and Debug icon in the left-hand side
Activity bar. The Terminal panel displays the Output from Core Tools. Your app starts in
the Terminal panel. You can see the URL endpoint of your HTTP-triggered function
running locally.
If you have trouble running on Windows, make sure that the default terminal for Visual
Studio Code isn't set to WSL Bash.
2. With Core Tools still running in Terminal, choose the Azure icon in the activity bar. In the
Workspace area, expand Local Project > Functions. Right-click (Windows) or Ctrl - click
(macOS) the new function and choose Execute Function Now....
3. In Enter request body you see the request message body value of { "name": "Azure" } .
Press Enter to send this request message to your function.
4. When the function executes locally and returns a response, a notification is raised in
Visual Studio Code. Information about the function execution is shown in Terminal panel.
5. With the Terminal panel focused, press Ctrl + C to stop Core Tools and disconnect the
debugger.
After you verify that the function runs correctly on your local computer, you can optionally use
AI tools, such as GitHub Copilot in Visual Studio Code, to update template-generated function
code.
Copilot prompt
Modify the function to accept name, email, and age from the JSON body of the
request. If any of these parameters are missing from the query string, read
them from the JSON body. Return all three parameters in the JSON response,
applying these rules:
Title-case the name
Lowercase the email
Convert age to an integer if possible, otherwise return "not provided"
Use sensible defaults if any parameter is missing
You can customize your prompt to add specifics as needed. Then run the app again locally and
verify that it works as expected after the code changes. This time, use a message body like:
JSON
{ "name": "devon torres", "email": "[Link]@[Link]", "age": "34" }
Tip
GitHub Copilot is powered by AI, so surprises and mistakes are possible. If you encounter
any errors during execution, paste the error message in the chat window, select Agent
mode, and ask Copilot to help resolve the error. For more information, see Copilot
FAQs .
When running in Agent mode, the results of this customization depend on the specific
tools available to your agent.
When you're satisfied with your app, use Visual Studio Code to publish the project directly to
Azure.
Sign in to Azure
Before you can create Azure resources or publish your app, you must sign in to Azure.
1. If you aren't already signed in, in the Activity bar, select the Azure icon. Then under
Resources, select Sign in to Azure.
If you're already signed in and can see your existing subscriptions, go to the next section.
If you don't yet have an Azure account, select Create an Azure Account. Students can
select Create an Azure for Students Account.
2. When you are prompted in the browser, select your Azure account and sign in by using
your Azure account credentials. If you create a new account, you can sign in after your
account is created.
3. After you successfully sign in, you can close the new browser window. The subscriptions
that belong to your Azure account are displayed in the side bar.
1. In Visual Studio Code, select F1 to open the command palette. At the prompt ( > ), enter
and then select Azure Functions: Create Function App in Azure.
ノ Expand table
Prompt Action
Select subscription Select the Azure subscription to use. The prompt doesn't appear when
you have only one subscription visible under Resources.
Enter a new function Enter a globally unique name that's valid in a URL path. The name you
app name enter is validated to make sure that it's unique in Azure Functions.
Select a location for Select an Azure region. For better performance, select a region near
new resources you. Only regions supported by Flex Consumption plans are displayed.
Select a runtime stack Select the language version you currently run locally.
Select resource Select Managed identity, which is the most secure option for
authentication type connecting to the default host storage account.
In the Azure: Activity Log panel, the Azure extension shows the status of individual
resources as they're created in Azure.
3. When the function app is created, the following related resources are created in your
Azure subscription. The resources are named based on the name you entered for your
function app.
A notification is displayed after your function app is created and the deployment package
is applied.
Tip
By default, the Azure resources required by your function app are created based on
the name you enter for your function app. By default, the resources are created with
the function app in the same, new resource group. If you want to customize the
names of the associated resources or reuse existing resources, publish the project
with advanced create options.
) Important
Deploying to an existing function app always overwrites the contents of that app in Azure.
1. In the command palette, enter and then select Azure Functions: Deploy to Function App.
2. Select the function app you just created. When prompted about overwriting previous
deployments, select Deploy to deploy your function code to the new function app
resource.
3. When deployment is completed, select View Output to view the creation and deployment
results, including the Azure resources that you created. If you miss the notification, select
the bell icon in the lower-right corner to see it again.
2. Select your new function app resource and HttpExample as your function.
4. When the function executes in Azure, the response is displayed in the notification area.
Expand the notification to review the full response.
Troubleshooting
Use the following table to resolve the most common issues encountered when using this
article.
ノ Expand table
Problem Solution
Can't create a local Make sure you have the Azure Functions extension installed.
function project?
Can't run the Make sure you have the latest version of Azure Functions Core Tools installed.
function locally? When running on Windows, make sure that the default terminal shell for Visual
Problem Solution
Can't deploy Review the Output for error information. The bell icon in the lower right corner is
function to Azure? another way to view the output. Did you publish to an existing function app? That
action overwrites the content of that app in Azure.
Couldn't run the Remember to use the query string to send in parameters, or use the request body
cloud-based for custom handlers.
Function app?
Clean up resources
When you continue to the next step and add an Azure Storage queue binding to your function,
you'll need to keep all your resources in place to build on what you've already done.
Otherwise, you can use the following steps to delete the function app and its related resources
to avoid incurring any further costs.
1. In Visual Studio Code, select the Azure icon to open the Azure explorer.
2. In the Resource Groups section, find your resource group.
3. Right-click the resource group and select Delete.
To learn more about Functions costs, see Estimating Consumption plan costs.
Next steps
You used Visual Studio Code to create a function app with a simple HTTP-triggered function. In
the next articles, you expand that function by connecting to either Azure Cosmos DB or Azure
Storage. To learn more about connecting to other Azure services, see Add bindings to an
existing function in Azure Functions. If you want to learn more about security, see Securing
Azure Functions.
Completing this quickstart incurs a small cost of a few USD cents or less in your Azure account.
Make sure to select your preferred development language at the top of the article.
Prerequisites
An Azure account with an active subscription. Create an account for free .
Python 3.11
Azure CLI
The jq command line JSON processor , used to parse JSON output, and is also available
in Azure Cloud Shell.
Windows
The following steps use a Windows installer (MSI) to install Core Tools v4.x. For more
information about other package-based installers, see the Core Tools readme .
Download and run the Core Tools installer, based on your version of Windows:
v4.x - Windows 64-bit (Recommended. Visual Studio Code debugging requires 64-
bit.)
v4.x - Windows 32-bit
If you previously used Windows installer (MSI) to install Core Tools on Windows, you
should uninstall the old version from Add Remove Programs before installing the latest
version.
bash
Bash
Bash
source .venv/bin/activate
If Python didn't install the venv package on your Linux distribution, run the following
command:
Bash
sudo apt-get install python3-venv
1. In a terminal or command prompt, run this func init command to create a function app
project in the current folder:
Console
func init --worker-runtime python
Console
func new --name HttpExample --template "HTTP trigger" --authlevel "function"
A new code file is added to your project. In this case, the --name argument is the unique
name of your function ( HttpExample ) and the --template argument specifies an HTTP
trigger.
The project root folder contains various files for the project, including configurations files
named [Link] and [Link]. Because [Link] can contain secrets
downloaded from Azure, the file is excluded from source control by default in the .gitignore file.
1. Use this command to start the local Azure Functions runtime host in the root of the
project folder:
Console
func start
...
Http Functions:
2. Copy the URL of your HttpExample function from this output to a browser and browse to
the function URL. You should receive a success response with a "hello world" message.
7 Note
Because access key authorization isn't enforced when running locally, the function
URL returned doesn't include the access key value and you don't need it to call your
function.
3. When you're done, use Ctrl+C and choose y to stop the functions host.
Use the Azure CLI commands in these steps to create the required resources.
Azure CLI
az login
The az login command signs you into your Azure account. Skip this step when running in
Azure Cloud Shell.
2. If you haven't already done so, use this az extension add command to install the
Application Insights extension:
Azure CLI
az extension add --name application-insights
In this example, replace <REGION> with a region near you that supports the Flex
Consumption plan. Use the az functionapp list-flexconsumption-locations command to
view the list of currently supported regions.
Azure CLI
az storage account create --name <STORAGE_NAME> --location "<REGION>" --
resource-group "AzureFunctionsQuickstart-rg" \
--sku "Standard_LRS" --allow-blob-public-access false --allow-shared-key-access
false
In this 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. This new account can only be accessed by using Microsoft Entra-
authenticated identities that have been granted permissions to specific resources.
5. Use this script to create a user-assigned managed identity, parse the returned JSON
properties of the object using jq , and grant Storage Blob Data Owner permissions in the
default storage account:
Azure CLI
output=$(az identity create --name "func-host-storage-user" --resource-group
"AzureFunctionsQuickstart-rg" --location <REGION> \
--query "{userId:id, principalId: principalId, clientId: clientId}" -o json)
If you don't have the jq utility in your local Bash shell, it's available in Azure Cloud Shell.
In this example, replace <STORAGE_NAME> and <REGION> with your default storage account
name and region, respectively.
The az identity create command creates an identity named func-host-storage-user . The
returned principalId is used to assign permissions to this new identity in the default
storage account by using the az role assignment create command. The az storage
account show command is used to obtain the storage account ID.
6. Use this az functionapp create command to create the function app in Azure:
Azure CLI
<APP_NAME> : a globally unique name appropriate to you. The <APP_NAME> is also the
This command creates a function app running in your specified language runtime on
Linux in the Flex Consumption Plan, which is free for the amount of usage you incur here.
The command also creates an associated Azure Application Insights instance in the same
resource group, with which you can use to monitor your function app executions and
view logs. For more information, see Monitor Azure Functions. The instance incurs no
costs until you activate it.
7. Use this script to add your user-assigned managed identity to the Monitoring Metrics
Publisher role in your Application Insights instance:
Azure CLI
appInsights=$(az monitor app-insights component show --resource-group
"AzureFunctionsQuickstart-rg" \
--app <APP_NAME> --query "id" --output tsv)
principalId=$(az identity show --name "func-host-storage-user" --resource-group
"AzureFunctionsQuickstart-rg" \
--query principalId -o tsv)
az role assignment create --role "Monitoring Metrics Publisher" --assignee
$principalId --scope $appInsights
In this example, replace <APP_NAME> with the name of your function app. The az role
assignment create command adds your user to the role. The resource ID of your
Application Insights instance and the principal ID of your user are obtained by using the
az monitor app-insights component show and az identity show commands, respectively.
1. Use this script to get the client ID of the user-assigned managed identity and uses it to
define managed identity connections to both storage and Application Insights:
Azure CLI
clientId=$(az identity show --name func-host-storage-user \
--resource-group AzureFunctionsQuickstart-rg --query 'clientId' -o tsv)
az functionapp config appsettings set --name <APP_NAME> --resource-group
"AzureFunctionsQuickstart-rg" \
--settings AzureWebJobsStorage__accountName=<STORAGE_NAME> \
AzureWebJobsStorage__credential=managedidentity
AzureWebJobsStorage__clientId=$clientId \
APPLICATIONINSIGHTS_AUTHENTICATION_STRING="ClientId=$clientId;Authorization=AAD
"
In this script, replace <APP_NAME> and <STORAGE_NAME> with the names of your function
app and storage account, respectively.
2. Run the az functionapp config appsettings delete command to remove the existing
AzureWebJobsStorage connection string setting, which contains a shared secret key:
Azure CLI
az functionapp config appsettings delete --name <APP_NAME> --resource-group
"AzureFunctionsQuickstart-rg" --setting-names AzureWebJobsStorage
In this example, replace <APP_NAME> with the names of your function app.
At this point, the Functions host can connect to the storage account securely by using
managed identities instead of shared secrets. You can now deploy your project code to the
Azure resources.
Deploy the function project to Azure
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.
1. In your root project folder, run this func azure functionapp publish command:
Console
func azure functionapp publish <APP_NAME>
In this example, replace <APP_NAME> with the name of your app. A successful deployment
shows results similar to the following output (truncated for simplicity):
...
...
Deployment successful.
Remote build succeeded!
Syncing triggers...
Functions in msdocs-azurefunctions-qs:
HttpExample - [httpTrigger]
Invoke url: [Link]
[Link]/api/httpexample
2. In your local terminal or command prompt, run this command to get the URL endpoint
value, including the access key:
In this example, again replace <APP_NAME> with the name of your app.
3. Copy the returned endpoint URL and key, which you use to invoke the function endpoint.
Paste the URL and access key you copied into a browser address bar.
[Link]
In this case, you must also provide an access key in the query string when making a GET
request to the endpoint URL. Using an access key is recommended to limit access from random
clients. When making a POST request using an HTTP client, you should instead provide the
access key in the x-functions-key header.
When you navigate to this URL, the browser should display similar output as when you ran the
function locally.
Clean up resources
If you continue to the next step and add an Azure Storage queue output binding, keep all your
resources in place as you'll build on what you've already done.
Otherwise, use the following command to delete the resource group and all its contained
resources to avoid incurring further costs.
Azure CLI
Azure CLI
az group delete --name AzureFunctionsQuickstart-rg
Next steps
Connect to Azure Queue Storage
Azure Functions lets you connect Azure services and other resources to functions
without having to write your own integration code. These bindings, which represent
both input and output, are declared within the function definition. Data from bindings is
provided to the function as parameters. A trigger is a special type of input binding.
Although a function has only one trigger, it can have multiple input and output
bindings. To learn more, see Azure Functions triggers and bindings concepts.
In this article, you learn how to use Visual Studio Code to connect Azure Storage to the
function you created in the previous quickstart article. The output binding that you add
to this function writes data from the HTTP request to a message in an Azure Queue
storage queue.
Most bindings require a stored connection string that Functions uses to access the
bound service. To make it easier, you use the storage account that you created with your
function app. The connection to this account is already stored in an app setting named
AzureWebJobsStorage .
Install Azure Storage Explorer . Storage Explorer is a tool that you'll use to
examine queue messages generated by your output binding. Storage Explorer is
supported on macOS, Windows, and Linux-based operating systems.
This article assumes that you're already signed in to your Azure subscription from Visual
Studio Code. You can sign in by running Azure: Sign In from the command palette.
1. Press F1 to open the command palette, then search for and run the command
Azure Functions: Download Remote Settings... .
2. Choose the function app you created in the previous article. Select Yes to all to
overwrite the existing local settings.
) Important
3. Copy the value AzureWebJobsStorage , which is the key for the storage account
connection string value. You use this connection to verify that the output binding
works as expected.
Your project has been configured to use extension bundles, which automatically installs
a predefined set of extension packages.
Extension bundles is already enabled in the [Link] file at the root of the project, which
should look like the following example:
JSON
{
"version": "2.0",
"extensionBundle": {
"id": "[Link]",
"version": "[3.*, 4.0.0)"
}
}
Now, you can add the storage output binding to your project.
By using the queue_output decorator, the binding direction is implicitly 'out' and type is
Azure Storage Queue. Add the following decorator to your function code in
HttpExample\function_app.py:
Python
@app.queue_output(arg_name="msg", queue_name="outqueue",
connection="AzureWebJobsStorage")
In this code, arg_name identifies the binding parameter referenced in your code,
queue_name is name of the queue that the binding writes to, and connection is the name
of an application setting that contains the connection string for the Storage account. In
quickstarts you use the same storage account as the function app, which is in the
AzureWebJobsStorage setting. When the queue_name doesn't exist, the binding creates it
on first use.
Python
app = [Link](http_auth_level=[Link])
@[Link](route="HttpExample")
@app.queue_output(arg_name="msg", queue_name="outqueue",
connection="AzureWebJobsStorage")
def HttpExample(req: [Link], msg: [Link] [[Link]]) ->
[Link]:
[Link]('Python HTTP trigger function processed a request.')
name = [Link]('name')
if not name:
try:
req_body = req.get_json()
except ValueError:
pass
else:
name = req_body.get('name')
if name:
[Link](name)
return [Link](f"Hello, {name}. This HTTP triggered
function executed successfully.")
else:
return [Link](
"This HTTP triggered function executed successfully. Pass a
name in the query string or in the request body for a personalized
response.",
status_code=200
)
The msg parameter is an instance of the [Link] class. The set method
writes a string message to the queue. In this case, it's the name passed to the function in
the URL query string.
2. With the Core Tools running, go to the Azure: Functions area. Under Functions,
expand Local Project > Functions. Right-click (Ctrl-click on Mac) the HttpExample
function and select Execute Function Now....
3. In the Enter request body, you see the request message body value of { "name":
"Azure" } . Press Enter to send this request message to your function.
Because you're using the storage connection string, your function connects to the Azure
storage account when running locally. A new queue named outqueue is created in your
storage account by the Functions runtime when the output binding is first used. You'll
use Storage Explorer to verify that the queue was created along with the new message.
1. Run the Azure Storage Explorer tool, select the connect icon on the left, and
select Add an account.
2. In the Connect dialog, choose Add an Azure account, choose your Azure
environment, and then select Sign in....
After you successfully sign in to your account, you see all of the Azure subscriptions
associated with your account. Choose your subscription and select Open Explorer.
2. Expand the Queues node, and then select the queue named outqueue.
The queue contains the message that the queue output binding created when you
ran the HTTP-triggered function. If you invoked the function with the default name
value of Azure, the queue message is Name passed to the function: Azure.
3. Run the function again, send another request, and you see a new message in the
queue.
2. Choose the function app that you created in the first article. Because you're
redeploying your project to the same app, select Deploy to dismiss the warning
about overwriting files.
3. After the deployment completes, you can again use the Execute Function Now...
feature to trigger the function in Azure.
4. Again view the message in the storage queue to verify that the output binding
generates a new message in the queue.
Clean up resources
In Azure, resources refer to function apps, functions, storage accounts, and so forth.
They're grouped into resource groups, and you can delete everything in a group by
deleting the group.
You've created resources to complete these quickstarts. You may be billed for these
resources, depending on your account status and service pricing . If you don't need
the resources anymore, here's how to delete them:
1. In Visual Studio Code, press F1 to open the command palette. In the command
palette, search for and select Azure: Open in portal .
2. Choose your function app and press Enter . The function app page opens in the
Azure portal.
3. In the Overview tab, select the named link next to Resource group.
4. On the Resource group page, review the list of included resources, and verify that
they're the ones you want to delete.
Deletion may take a couple of minutes. When it's done, a notification appears for a
few seconds. You can also select the bell icon at the top of the page to view the
notification.
Next steps
You've updated your HTTP triggered function to write data to a Storage queue. Now you
can learn more about developing Functions using Visual Studio Code:
In this article, you integrate an Azure Storage queue with the function and storage
account you created in the previous quickstart article. You achieve this integration by
using an output binding that writes data from an HTTP request to a message in the
queue. Completing this article incurs no extra costs beyond the few USD cents of the
previous quickstart. To learn more about bindings, see Azure Functions triggers and
bindings concepts.
) Important
This article currently shows how to connect to your Azure Storage account by using
the connection string, which contains a shared secret key. Using a connection string
makes it easier for you to verify data updates in the storage account. For the best
security, you should instead use managed identities when connecting to your
storage account. For more information, see Connections in the Developer Guide.
Earlier, you created an Azure Storage account for function app's use. The connection
string for this account is stored securely in app settings in Azure. By downloading the
setting into the [Link] file, you can use the connection to write to a Storage
queue in the same account when running the function locally.
1. From the root of the project, run the following command, replacing <APP_NAME>
with the name of your function app from the previous step. This command
overwrites any existing values in the file.
func azure functionapp fetch-app-settings <APP_NAME>
) Important
Because the [Link] file contains secrets downloaded from Azure, always
exclude this file from source control. The .gitignore file created with a local
functions project excludes the file by default.
When using the Python v2 programming model, binding attributes are defined directly
in the function_app.py file as decorators. From the previous quickstart, your
function_app.py file already contains one decorator-based binding:
Python
app = [Link]()
@app.function_name(name="HttpTrigger1")
@[Link](route="hello", auth_level=[Link])
The route decorator adds HttpTrigger and HttpOutput binding to the function, which
enables your function be triggered when http requests hit the specified route.
To write to an Azure Storage queue from this function, add the queue_output decorator
to your function code:
Python
@app.queue_output(arg_name="msg", queue_name="outqueue",
connection="AzureWebJobsStorage")
In the decorator, arg_name identifies the binding parameter referenced in your code,
queue_name is name of the queue that the binding writes to, and connection is the name
of an application setting that contains the connection string for the Storage account. In
quickstarts you use the same storage account as the function app, which is in the
AzureWebJobsStorage setting (from [Link] file). When the queue_name doesn't
For more information on the details of bindings, see Azure Functions triggers and
bindings concepts and queue output configuration.
Python
app = [Link](http_auth_level=[Link])
@[Link](route="HttpExample")
@app.queue_output(arg_name="msg", queue_name="outqueue",
connection="AzureWebJobsStorage")
def HttpExample(req: [Link], msg: [Link] [[Link]]) ->
[Link]:
[Link]('Python HTTP trigger function processed a request.')
name = [Link]('name')
if not name:
try:
req_body = req.get_json()
except ValueError:
pass
else:
name = req_body.get('name')
if name:
[Link](name)
return [Link](f"Hello, {name}. This HTTP triggered
function executed successfully.")
else:
return [Link](
"This HTTP triggered function executed successfully. Pass a
name in the query string or in the request body for a personalized
response.",
status_code=200
)
The msg parameter is an instance of the [Link] class. The set method
writes a string message to the queue. In this case, it's the name passed to the function in
the URL query string.
Observe that you don't need to write any code for authentication, getting a queue
reference, or writing data. All these integration tasks are conveniently handled in the
Azure Functions runtime and queue output binding.
Console
func start
Toward the end of the output, the following lines must appear:
7 Note
If HttpExample doesn't appear as shown above, you likely started the host
from outside the root folder of the project. In that case, use Ctrl+C to stop the
host, go to the project's root folder, and run the previous command again.
2. Copy the URL of your HTTP function from this output to a browser and append the
query string ?name=<YOUR_NAME> , making the full URL like
[Link] . The browser should
display a response message that echoes back your query string value. The terminal
in which you started your project also shows log output as you make requests.
3. When you're done, press Ctrl + C and type y to stop the functions host.
Tip
During startup, the host downloads and installs the Storage binding extension and
other Microsoft binding extensions. This installation happens because binding
extensions are enabled by default in the [Link] file with the following properties:
JSON
{
"version": "2.0",
"extensionBundle": {
"id": "[Link]",
"version": "[1.*, 2.0.0)"
}
}
If you encounter any errors related to binding extensions, check that the above
properties are present in [Link].
1. Open the function project's [Link] file and copy the connection string
value. In a terminal or command window, run the following command to create an
environment variable named AZURE_STORAGE_CONNECTION_STRING , and paste your
specific connection string in place of <MY_CONNECTION_STRING> . (This environment
variable means you don't need to supply the connection string to each subsequent
command using the --connection-string argument.)
bash
Bash
export AZURE_STORAGE_CONNECTION_STRING="<MY_CONNECTION_STRING>"
2. (Optional) Use the az storage queue list command to view the Storage queues in
your account. The output from this command must include a queue named
outqueue , which was created when the function wrote its first message to that
queue.
Azure CLI
3. Use the az storage message get command to read the message from this queue,
which should be the value you supplied when testing the function earlier. The
command reads and removes the first message from the queue.
bash
Azure CLI
Because the message body is stored base64 encoded, the message must be
decoded before it's displayed. After you execute az storage message get , the
message is removed from the queue. If there was only one message in outqueue ,
you won't retrieve a message when you run this command a second time and
instead get an error.
In the LocalFunctionsProj folder, use the func azure functionapp publish command to
redeploy the project, replacing <APP_NAME> with the name of your app.
Browser
Copy the complete Invoke URL shown in the output of the publish command
into a browser address bar, appending the query parameter &name=Functions .
The browser should display the same output as when you ran the function
locally.
2. Examine the Storage queue again, as described in the previous section, to verify
that it contains the new message written to the queue.
Clean up resources
After you finish, use the following command to delete the resource group and all its
contained resources to avoid incurring further costs.
Azure CLI
Next steps
You've updated your HTTP triggered function to write data to a Storage queue. Now you
can learn more about developing Functions from the command line using Core Tools
and Azure CLI:
Feedback
Was this page helpful? Yes No
Azure offers a wide range of fully managed database and storage solutions, including
relational, NoSQL, and in-memory databases, with support for both proprietary and open-
source technologies. You can also choose from object, block, and file storage services. The
following articles can help you get started using these options with Python on Azure.
Databases
PostgreSQL: Build scalable, secure, and fully managed enterprise apps using open-source
PostgreSQL. You can scale single-node PostgreSQL for high performance or migrate
existing PostgreSQL and Oracle workloads to the cloud.
Quickstart: Use Python to connect and query data in Azure Database for PostgreSQL -
Flexible Server
Quickstart: Use Python to connect and query data in Azure Database for PostgreSQL -
Single Server
Deploy a Python (Django or Flask) web app with PostgreSQL in Azure App Service
MySQL: Build scalable applications using a fully managed, intelligent MySQL database in
the cloud.
Quickstart: Use Python to connect and query data in Azure Database for MySQL -
Flexible Server
Quickstart: Use Python to connect and query data in Azure Database for MySQL
Azure SQL: Build scalable applications with a fully managed and intelligent SQL database
platform in the cloud.
Quickstart: Use Python to query a database in Azure SQL Database or Azure SQL
Managed Instance
Azure Data Lake Storage Gen2: Scalable, secure data lake optimized for high-
performance analytics.
Use Python to manage directories and files in Azure Data Lake Storage Gen2
Use Python to manage ACLs in Azure Data Lake Storage Gen2
File storage: Simple, secure, and serverless enterprise-grade cloud file shares.
Develop for Azure Files with Python
Redis Cache: Accelerate application performance with a scalable, in-memory data store
compatible with open source.
Quickstart: Use Azure Cache for Redis in Python
Azure Data Factory: A fully managed data integration service that lets you visually build,
orchestrate, and automate data movement and transformation across various data
sources.
Quickstart: Create a data factory and pipeline using Python
Transform data by running a Python activity in Azure Databricks
Azure Event Hubs: A fully managed, hyper-scale telemetry ingestion service designed to
collect, transform, and store millions of events per second from connected devices and
applications.
Send events to or receive events from event hubs by using Python
Capture Event Hubs data in Azure Storage and read it by using Python (azure-
eventhub)
HDInsight: A fully managed cloud service that runs popular open-source frameworks like
Hadoop and Spark, backed by a 99.9% SLA for enterprise-grade big data analytics.
Use Spark & Hive Tools for Visual Studio Code
Azure Databricks: A fully managed, fast, easy and collaborative Apache® Spark™ based
analytics platform optimized for big data and AI workloads on Azure.
Connect to Azure Databricks from Excel, Python, or R
Get Started with Azure Databricks
Tutorial: Azure Data Lake Storage Gen2, Azure Databricks & Spark
Azure Synapse Analytics: A fully managed analytics service that unifies data integration,
enterprise data warehousing, and big data analytics into a single platform.
Quickstart: Use Python to query a database in Azure SQL Database or Azure SQL
Managed Instance (includes Azure Synapse Analytics)
Machine learning for Python apps on Azure
06/12/2025
The following articles help you get started with Azure Machine Learning. Azure Machine
Learning v2 REST APIs, Azure CLI extension, and Python SDK are designed to streamline the
entire machine learning lifecycle and accelerate production workflows. The links in this article
target v2, which is recommended if you're starting a new machine learning project.
Getting started
In Azure Machine Learning, the workspace is the main resource that organizes and manages
everything you create, such as datasets, models, and experiments.
Deploy models
Deploy models for low-latency, real-time machine learning predictions.
Data access
With Azure Machine Learning, you can import data from your local computer or connect to
existing cloud storage services.
This article explains how to take a Python project—such as a web application—and deploy it as
a Docker container in Azure. It covers the general containerization workflow, Azure deployment
options for containers, and Python-specific container configurations within Azure. Building and
deploying Docker containers in Azure follows a standard process across languages, with
Python-specific configurations in the Dockerfile, [Link], and settings for web
frameworks like Django , Flask , and FastAPI .
ノ Expand table
Dev Build Python Docker images locally Code: Clone your app code locally using Git (with
in your development environment. Docker installed).
Hybrid Build Docker images in Azure, but Code: Clone the code locally (not necessary for Docker
initiate the process from your local to be installed).
environment.
Build: To trigger builds in Azure, use VS Code (with
remote extensions) or the Azure CLI.
Azure Use Azure Cloud Shell to build and Code: Clone the GitHub repo in Azure Cloud Shell.
deploy containers entirely in the
cloud. Build: Use Azure CLI or Docker CLI in Cloud Shell.
The end goal of these workflows is to have a container running in one of the Azure resources
supporting Docker containers as listed in the next section.
ノ Expand table
Service Description
Web App for Azure App Service is a fully managed hosting platform for containerized web
Containers applications, including websites and web APIs. It supports scalable deployments and
integrates seamlessly with CI/CD workflows using Docker Hub, Azure Container Registry,
and GitHub. This service is ideal for developers who want a simple and efficient path to
deploy containerized apps, while also benefiting from the full capabilities of the Azure
App Service platform. By packaging your application and all its dependencies into a
single deployable container, you gain both portability and ease of management—
without needing to manage infrastructure.
Azure Azure Container Apps (ACA) is a fully managed serverless container service powered by
Container Kubernetes and open-source technologies like Dapr , KEDA , and envoy . Its design
Apps (ACA) incorporates industry best practices and is optimized for executing general-purpose
containers. ACA abstracts away the complexity of managing a Kubernetes infrastructure
Service Description
—direct access to the Kubernetes API isn't required or supported. Instead, it offers
higher-level application constructs such as revisions, scaling, certificates, and
environments to simplify development and deployment workflows. This service is ideal
for development teams looking to build and deploy containerized microservices with
minimal operational overhead, allowing them to focus on application logic instead of
infrastructure management.
Azure Azure Container Instances (ACI) is a serverless offering that provides a single pod of
Container Hyper-V isolated containers on demand. Billing is based on actual resource consumption
Instances (ACI) rather than pre-allocated infrastructure, making it well-suited for short-lived or burstable
workloads. Unlike other container services, ACI doesn't include built-in support for
concepts like scaling, load balancing, or TLS certificates. Instead, it typically functions as
a foundational container building block, often integrated with Azure services like Azure
Kubernetes Service (AKS) for orchestration. ACI excels as a lightweight choice when the
higher-level abstractions and features of Azure Container Apps aren't needed
Example: Create a container image for deployment to Azure Container Instances. (The
tutorial isn't Python-specific, but the concepts shown apply to all languages.)
Azure Azure Kubernetes Service (AKS) is a fully managed Kubernetes option in Azure that gives
Kubernetes you complete control over your Kubernetes environment. It supports direct access to the
Service (AKS) Kubernetes API and can run any standard Kubernetes workload. The full cluster resides
in your subscription, with the cluster configurations and operations within your control
and responsibility. ACI is ideal for teams seeking a fully managed container solution,
while AKS gives you full control over the Kubernetes cluster, requiring you to manage
configurations, networking, scaling, and operations. Azure handles the control plane and
infrastructure provisioning, but the day-to-day operation and security of the cluster are
within your team's control. This service is ideal for teams that want the flexibility and
power of Kubernetes with the added benefit of Azure’s managed infrastructure, while
still maintaining full ownership over the cluster environment.
Example: Deploy an Azure Kubernetes Service cluster using the Azure CLI.
Tip
You can think of Docker containers as offering capabilities similar to Python virtual
environments—but with broader advantages in reproducibility, isolation, and portability. Unlike
virtual environments, Docker containers can run consistently across different operating systems
and environments, as long as a container runtime is available.
A Docker container includes your Python project code along with everything it needs to run,
such as dependencies, environment settings, and system libraries. To create a container, you
first build a Docker image from your project code and configuration, and then start a container,
which is a runnable instance of that image.
For containerizing Python projects, the key files are described in the following table:
ノ Expand table
[Link] This file contains the definitive list of Python dependencies needed for your application.
Docker uses this list during the image build process to install all required packages.
This ensures consistency between development and deployment environments.
Project file Description
Dockerfile This file contains instructions for building your Python Docker image, including the
base image selection, dependency installation, code copying, and container startup
commands. It defines the complete execution environment for your application. For
more information, see the section Dockerfile instructions for Python.
.dockerignore This file specifies the files and directories that should be excluded when copying
content to the Docker image with the COPY command in the Dockerfile. This file uses
patterns similar to .gitignore for defining exclusions. The .dockerignore file supports
exclusion patterns similar to .gitignore files. For more information, see .dockerignore
file .
Excluding files helps image build performance, but should also be used to avoid adding
sensitive information to the image where it can be inspected. For example, the
.dockerignore should contain lines to ignore .env and .venv (virtual environments).
ノ Expand table
Django 8000
The following table shows how to set the port for different Azure container solutions.
ノ Expand table
Web App for By default, App Service assumes your custom container is listening on either port 80 or
Containers port 8080. If your container listens to a different port, set the WEBSITES_PORT app
Azure How to set web app port
container
solution
setting in your App Service app. For more information, see Configure a custom
container for Azure App Service.
Azure Azure Container Apps lets you expose your container app to the public web, to your
Containers Apps virtual network, or to other container apps within the same environment by enabling
ingress. Set the ingress targetPort to the port your container listens to for incoming
requests. Application ingress endpoint is always exposed on port 443. For more
information, see Set up HTTPS or TCP ingress in Azure Container Apps.
Azure Container You define the port on which your app is listening during container or pod creation.
Instances, Azure Your container image should include a web framework, an application server (for
Kubernetes example, gunicorn, uvicorn), and optionally a web server (for example, nginx). In more
complex scenarios, you might split responsibilities across two containers—one for the
application server and another for the web server. In that case, the web server
container typically exposes ports 80 or 443 for external traffic.
Python Dockerfile
A Dockerfile is a text file that contains instructions for building a Docker image for a Python
application. The first instruction typically specifies the base image to start from. Subsequent
instructions then detail actions such as installing necessary software, copying application files,
and configuring the environment to create a runnable image. The following table provides
Python-specific examples for commonly used Dockerfile instructions.
ノ Expand table
FROM Sets the base image for subsequent instructions. FROM python:3.8-slim
EXPOSE Tells Docker that the container listens to a specified port EXPOSE 5000
at runtime.
COPY Copies files or directories from the specified source and COPY . /app
adds them to the filesystem of the container at the
specified destination path.
RUN Runs a command inside the Docker image. For example, RUN python -m pip install -r
pull in dependencies. The command runs once at build [Link]
time.
CMD The command provides the default for executing a CMD ["gunicorn", "--bind",
container. There can only be one CMD instruction. "[Link]:5000", "wsgi:app"]
The Docker build command builds Docker images from a Dockerfile and a context. A build’s
context is the set of files located in the specified path or URL. Typically, you build an image
from the root of your Python project and the path for the build command is "." as shown in the
following example.
Bash
The build process can refer to any of the files in the context. For example, your build can use a
COPY instruction to reference a file in the context. Here's an example of a Dockerfile for a
Python project using the Flask framework:
Dockerfile
FROM python:3.8-slim
EXPOSE 5000
WORKDIR /app
COPY . /app
# Creates a non-root user with an explicit UID and adds permission to access the
/app folder.
RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser
/app
USER appuser
# Provides defaults for an executing container; can be overridden with Docker CLI.
CMD ["gunicorn", "--bind", "[Link]:5000", "wsgi:app"]
You can create a Dockerfile by hand or create it automatically with VS Code and the Docker
extension. For more information, see Generating Docker files .
The Docker build command is part of the Docker CLI. When you use IDEs like VS Code or
PyCharm, the UI commands for working with Docker images call the build command for you
and automate specifying options.
Working with Python Docker images and
containers
Create and run Docker containers from an existing image, a pulled image, or directly from
a Dockerfile.
Connect and work with container registries like Docker Hub, GitLab, JetBrains Space,
Docker V2, and other self-hosted Docker registries.
(VS Code only) Add a Dockerfile and Docker compose files that are tailored for your
Python project.
To set up VS Code and PyCharm to run Docker containers in your dev environment, use the
following steps.
VS Code
ノ Expand table
Instructions Screenshot
You can also select the Azure icon on the VS Code extensions
bar.
If you aren't signed in, select Sign in to Azure and follow the
prompts.
Use a CLI when you want finer control over build and run arguments, and for automation. For
example, the following command shows how to use the Azure CLI az acr build to specify the
Docker image name.
Bash
az acr build --registry <registry-name> \
--resource-group <resource-group> \
--target pythoncontainerwebapp:latest .
As another example, consider the following command that shows how to use the Docker CLI
run command. The example shows how to run a Docker container that communicates to a
MongoDB instance in your dev environment, outside the container. The different values to
complete the command are easier to automate when specified in a command line.
Bash
For more information about this scenario, see Build and test a containerized Python web app
locally.
Packages like python-dotenv are often used to read key-value pairs from an .env file and set
them as environment variables. An .env file is useful when running in a virtual environment but
isn't recommended when working with containers. Don't copy the .env file into the Docker
image, especially if it contains sensitive information and the container will be made public.
Use the .dockerignore file to exclude files from being copied into the Docker image. For more
information, see the section Virtual environments and containers in this article.
The first two options have the same drawback as noted with .env files, namely that you're
hardcoding potentially sensitive information into a Docker image. You can inspect a Docker
image and see the environment variables, for example, with the command docker image
inspect .
The third option with BuildKit allows you to pass secret information to be used in the
Dockerfile for building docker images in a safe way that won't end up stored in the final image.
The fourth option of passing in environment variables with the Docker run command means
the Docker image doesn't contain the variables. However, the variables are still visible
inspecting the container instance (for example, with docker container inspect ). This option
may be acceptable when access to the container instance is controlled or in testing or dev
scenarios.
Here's an example of passing environment variables using the Docker CLI run command and
using the --env argument.
Bash
In VS Code (Docker extension) or PyCharm (Docker plugin), UI tools simplify managing Docker
images and containers by executing standard docker CLI commands (such as docker build,
docker run) in the background.
Finally, specifying environment variables when deploying a container in Azure is different than
using environment variables in your dev environment. For example:
For Web App for Containers, you configure application settings during configuration of
App Service. These settings are available to your app code as environment variables and
accessed using the standard [Link] pattern. You can change values after initial
deployment when needed. For more information, see Access app settings as environment
variables.
For Azure Container Apps, you configure environment variables during initial
configuration of the container app. Subsequent modification of environment variables
creates a revision of the container. In addition, Azure Container Apps allows you to define
secrets at the application level and then reference them in environment variables. For
more information, see Manage secrets in Azure Container Apps.
As another option, you can use Service Connector to help you connect Azure compute services
to other backing services. This service configures the network settings and connection
information (for example, generating environment variables) between compute services and
target backing services in management plane.
Running a container with VS Code or PyCharm, as shown in the section VS Code and
PyCharm, you can see logs in terminal windows opened when Docker run executes.
If you're using the Docker CLI run command with the interactive flag -it , you see
output following the command.
In Docker Desktop , you can also view logs for a running container.
When you deploy a container in Azure, you also have access to container logs. Here are several
Azure services and how to access container logs in Azure portal.
ノ Expand table
Web App for Go to the Diagnose and solve problems resource to view logs. Diagnostics is an
Containers intelligent and interactive experience to help you troubleshoot your app with no
configuration required. For a real-time view of logs, go to the Monitoring - Log stream.
For more detailed log queries and configuration, see the other resources under
Monitoring.
For these services, here are the Azure CLI commands to access logs.
ノ Expand table
There's also support for viewing logs in VS Code. You must have Azure Tools for VS Code
installed. Below is an example of viewing Web Apps for Containers (App Service) logs in VS
Code.
Next steps
Containerized Python web app on Azure with MongoDB
Deploy a Python web app on Azure Container Apps with PostgreSQL
Deploy a containerized Flask or FastAPI
web app on Azure App Service
09/22/2025
This tutorial shows you how to deploy a Python Flask or FastAPI web app to Azure App
Service using the Web App for Containers feature. This approach provides a streamlined path
for developers who want the benefits of a fully managed platform while deploying their app as
a single containerized artifact with all dependencies included. For more information about
using containers in Azure, see Comparing Azure container options.
In this tutorial, you use the Docker CLI and Docker to optionally build and test a Docker
image locally. You then use the Azure CLI to push the Docker image to Azure Container
Registry (ACR) and deploy it to Azure App Service. The web app is configured with its system-
assigned managed identity for secure, passwordless access to pull the image from ACR using
Azure role-based access control (RBAC). You can also deploy with Visual Studio Code with
the Azure Tools Extension installed.
For an example of building and creating a Docker image to run on Azure Container Apps, see
Deploy a Flask or FastPI web app on Azure Container Apps.
7 Note
This tutorial demonstrates how to create a Docker image that can be deployed to Azure
App Service. However, using a Docker image is not required to deploy to App Service. You
can also deploy your application code directly from your local workspace to App Service
without creating a Docker image. For an example, see Quickstart: Deploy a Python
(Django or Flask) web app to Azure App Service.
Prerequisites
To complete this tutorial, you need:
An Azure account where you can deploy a web app to Azure App Service and Azure
Container Registry. If you don't have an Azure subscription, create a free account
before you begin.
Azure CLI to create a Docker image and deploy it to App Service. And optionally,
Docker and the Docker CLI to create a Docker and test it in your local environment.
Get the sample code
In your local environment, get the code.
Flask
Bash
Flask
Dockerfile
# syntax=docker/dockerfile:1
FROM python:3.11
WORKDIR /code
COPY [Link] .
COPY . .
EXPOSE 50505
50505 is used for the container port (internal) in this example, but you can use any free
port.
Flask==3.1.0
gunicorn
dockerignore
.git*
**/*.pyc
.venv/
Configure gunicorn
Gunicorn can be configured with a [Link] file. When the [Link] file is
located in the same directory where gunicorn is run, you don't need to specify its location in
the Dockerfile. For more information about specifying the configuration file, see Gunicorn
settings .
In this tutorial, the suggested configuration file configures gunicorn to increase its number of
workers based on the number of CPU cores available. For more information about
[Link] file settings, see Gunicorn configuration .
Flask
text
max_requests = 1000
max_requests_jitter = 50
log_file = "-"
bind = "[Link]:50505"
workers = (multiprocessing.cpu_count() * 2) + 1
threads = workers
timeout = 120
Build and run the image locally
Build the image locally.
Flask
Bash
7 Note
If the docker build command returns an error, make sure the docker deamon is running.
On Windows, make sure that Docker Desktop is running.
Flask
Bash
Open the [Link] URL in your browser to see the web app running locally.
The --detach option runs the container in the background. The --publish option maps the
container port to a port on the host. The host port (external) is first in the pair, and the
container port (internal) is second. For more information, see Docker run reference .
Azure CLI
az login
2. Run the az upgrade command to make sure your version of the Azure CLI is current.
Azure CLI
az upgrade
Azure CLI
RESOURCE_GROUP_NAME=<resource-group-name>
LOCATION=<location>
az group create --name $RESOURCE_GROUP_NAME --location $LOCATION
An Azure resource group is a logical container into which Azure resources are deployed
and managed. When creating a resource group, you specify a location such as eastus.
Replace <location> with the location you choose. Certain SKUs are unavailable in certain
locations, so you might get an error indicating this. Use a different location and try again.
4. Create an Azure Container Registry with the az acr create command. Replace <container-
registry-name> with a unique name for your instance.
Azure CLI
CONTAINER_REGISTRY_NAME=<container-registry-name>
az acr create --resource-group $RESOURCE_GROOUP_NAME \
--name $CONTAINER_REGISTRY_NAME --sku Basic
7 Note
The registry name must be unique in Azure. If you get an error, try a different name.
Registry names can consist of 5-50 alphanumeric characters. Hyphens and
underscores are not allowed. To learn more, see Azure Container Registry name
rules. If you use a different name, make sure that you use your name rather than
webappacr123 in the commands that reference the registry and registry artifacts in
following sections.
An Azure Container Registry is a private Docker registry that stores images for use in
Azure Container Instances, Azure App Service, Azure Kubernetes Service, and other
services. When creating a registry, you specify a name, SKU, and resource group.
Azure CLI
az acr build \
--resource-group $RESOURCE_GROUP_NAME \
--registry $CONTAINER_REGISTRY_NAME \
--image webappsimple:latest .
The --registry option specifies the registry name, and the --image option specifies the image
name. The image name is in the format [Link]/repository:tag .
Azure CLI
2. Set an environment variable to your subscription ID. It's used in the --scope parameter in
the next command.
Azure CLI
The command for creating the environment variable is shown for the Bash shell. Change
the syntax as appropriate for other environments.
Azure CLI
Notes:
The web app name must be unique in Azure. If you get an error, try a different
name. The name can consist of alphanumeric characters and hyphens, but can't start
or end with a hyphen. To learn more, see [Link] name rules.
If you're using a name different than webappacr123 for your Azure Container
Registry, make sure you update the --container-image-name parameter
appropriately.
It can take a few minutes for the web app to be created. You can check the
deployment logs with the az webapp log tail command. For example, az webapp log
tail --resource-group web-app-simple-rg --name webappsimple123 . If you see entries
Clean up
All the Azure resources created in this tutorial are in the same resource group. Removing the
resource group removes all resources in the resource group and is the fastest way to remove
all Azure resources used for your app.
To remove resources, use the az group delete command.
Azure CLI
You can also remove the group in the Azure portal or in Visual Studio Code and the Azure
Tools Extension .
Next steps
For more information, see the following resources:
This tutorial series shows you how to containerize a Python web app and then either run it
locally or deploy it to Azure App Service . App Service Web App for Containers allows you
to focus on building your containers without worrying about managing and maintaining an
underlying container orchestrator. When you are building web apps, Azure App Service is a
good option for taking your first steps with containers. This container web app can use either a
local MongoDB instance or Azure DocumentDB (with MongoDB compatibility) to store data.
For more information about using containers in Azure, see Comparing Azure container options.
Build and run a Docker container locally. See Build and run a containerized Python web
app locally.
Build a Docker container image directly in Azure. See Build a containerized Python web
app in Azure.
Configure an App Service to create a web app based on the Docker container image. See
Deploy a containerized Python app to App Service.
After completing the articles in this tutorial series, you'll have the basis for Continuous
Integration (CI) and Continuous Deployment (CD) of a Python web app to Azure.
Service overview
The service diagram supporting this tutorial shows two environments: developer environment
and Azure environment. It highlights the key Azure services used in the development process.
Developer environment
The components supporting the developer environment in this tutorial include:
Local Development System: A personal computer used for coding, building, and testing
the Docker container.
Docker Containerization: Docker is employed to package the app and its dependencies
into a portable container.
Development Tools: Includes a code editor and other necessary tools for software
development.
Local MongoDB Instance: A local MongoDB database utilized for data storage during
development.
Azure environment
The components supporting the Azure environment in this tutorial include:
Azure Container Registry allows you to store and manage Docker images and their
components in Azure. It provides a registry located near your deployments in Azure
that gives you the ability to control access using your Microsoft Entra groups and
permissions.
In this tutorial, Azure Container Registry is the registry source, but you can also use
Docker Hub or a private registry with minor modifications.
Authentication
In this tutorial, you build a Docker image, either locally or in Azure, and then deploy it to Azure
App Service. The App Service pulls the container image from an Azure Container Registry
repository.
To securely pull images from the repository, App Service utilizes a system-assigned managed
identity. This managed identity grants the web app permissions to interact with other Azure
resources, eliminating the need for explicit credentials. For this tutorial, the managed identity is
configured during setup of App Service to use a registry container image.
The tutorial sample web app uses MongoDB to store data. The sample code connects to Azure
DocumentDB via a connection string.
Prerequisites
To complete this tutorial, you need:
Visual Studio Code or Azure CLI, depending on your tool of choice. If you use Visual
Studio Code, you need the Docker extension and Azure App Service extension .
Sample app
The end result of this tutorial is a restaurant review app, deployed and running in Azure, that
looks like the following screenshot.
In this tutorial, you build a Python restaurant review app that utilizes MongoDB for data
storage. For an example app using PostgreSQL, see Create and deploy a Flask web app to
Azure with a managed identity.
Next step
Build and test locally
Last updated on 02/04/2026
Build and run a containerized Python web
app locally
Article • 04/17/2025
In this part of the tutorial series, you learn how to build and run a containerized Django or a
Flask Python web app on your local computer. To store data for this app, you can use either
a local MongoDB instance or Azure Cosmos DB for MongoDB. This article is part 2 of a 5-part
tutorial series. We recommend that you complete part 1 before starting this article.
The following service diagram highlights the local components covered in this article In this
article, you also learn how to use Azure Cosmos DB for MongdoDB with a local Docker image,
rather than a local instance of MongoDB.
Git clone
1. Clone either the Django or Flask repository into a local folder by using one of the
following commands:
Django
Console
# Django
git clone [Link]
[Link]
Django
Console
# Django
cd msdocs-python-django-container-web-app
Tip
If you're new to the Azure CLI, see Get started with Azure CLI to learn how to download
and install the Azure CLI locally or how to run Azure CLI commands in Azure Cloud Shell.
Azure CLI
Docker is required to build the Docker image using the Docker CLI. Once Docker is
installed, open a terminal window and navigate to the sample folder.
7 Note
The steps in this section require the Docker daemon to be running. In some
installations, for example on Windows, you need to open Docker Desktop , which
starts the daemon, before proceeding.
1. Confirm that Docker is accessible by running the following command in the root
folder of the sample app.
Console
docker
If, after running this command, you see help for the Docker CLI , Docker is
accessible. Otherwise, make sure Docker is installed and that your shell has access to
the Docker CLI.
2. Build the Docker image for the Python web app by using the Docker build
command.
The general form of the command is docker build --rm --pull --file "<path-to-
project-root>/Dockerfile" --label "[Link]-by=docker-cli" --tag "
<container-name>:latest" "<path-to-project-root>" .
If you're at the root folder of the project, use the following command to build the
Docker image. The dot (".") at the end of the command refers to the current directory
in which the command runs. To force a rebuild, add --no-cache .
Bash
Console
#!/bin/bash
docker build --rm --pull \
--file "Dockerfile" \
--label "[Link]-by=docker-cli" \
--tag "msdocspythoncontainerwebapp:latest" \
.
3. Confirm the image was built successfully by using the Docker images command.
Console
docker images
The command returns a list of images by REPOSITORY name, TAG, and CREATED date
among other image characteristics.
At this point, you have a local Docker image named "msdocspythoncontainerwebapp" with the
tag "latest". Tags help define version details, intended use, stability, and other relevant
information. For more information, see Recommendations for tagging and versioning container
images.
7 Note
Images that are built from VS Code or by using the Docker CLI directly can also be viewed
with the Docker Desktop application.
Set up MongoDB
Your Python web app requires a MongoDB database named restaurants_reviews and a
collection named restaurants_reviews are required to store data. In this tutorial, you use both a
local installation of MongoDB and a Azure Cosmos DB for MongoDB instance to create and
access the database and collection.
) Important
Don't use a MongoDB database you use in production. In this tutorial, you store the
MongoDB connection string to the one of these MongoDB instances in an environment
variable (which is observable by anyone capable of inspecting your container - such as by
using docker inspect ).
Local MongoDB
Let's start by creating a local instance of MongoDB using the Azure CLI.
You can check for the installation of MongoDB by using the MongoDB Shell (mongosh) .
If the following commands don't work, you may need to explicitly install mongosh or
connect mongosh to your MongoDB server .
Use the following command to open the MongoDB shell and get the version of both
the MongoDB shell and the MongoDB server:
Console
mongosh
Tip
To return just the version of MongoDB server installed on your system, close
and reopen the MongoDB shell and use the following command: mongosh --
quiet --exec '[Link]()'
In some setups, you can also directly invoke the Mongo daemon in your bash shell.
Console
mongod --version
2. Edit the [Link] file in the \MongoDB\Server\8.0\bin folder and add your computer's
local IP address to the bindIP key.
The bindip key in the MongoD configuration file defines the hostnames and IP
addresses that MongoDB listens for client connections. Add the current IP of your local
development computer. The sample Python web app running locally in a Docker
container communicates to the host computer with this address.
For example, part of the configuration file should look like this:
yml
net:
port: 27017
bindIp: [Link],<local-ip-address>
) Important
You need administrative privileges to save the changes you make to this
configuration file.
4. Restart MongoDB to pick up changes to the configuration file.
5. Open a MongoDB shell and run the following command to set the database name to
"restaurants_reviews" and the collection name to "restaurants_reviews". You can also
create a database and collection with the VS Code MongoDB extension or any other
MongoDB-aware tool.
mongosh
> help
> use restaurants_reviews
> db.restaurants_reviews.insertOne({})
> show dbs
> exit
After you complete the previous step, the local MongoDB connection string is
"mongodb://[Link]:27017/", the database name is "restaurants_reviews", and the collection
name is "restaurants_reviews".
7 Note
In part 4 of this tutorial series, you use the Azure Cosmos DB for MongoDB instance to run
the web app in Azure App Service.
Before running the following script, replace the location, the resource group, and Azure
Cosmos DB for MongoDB account name with appropriate values (optional). We recommend
using the same resource group for all the Azure resources created in this tutorial to make them
easier to delete when you're finished.
Bash
Azure CLI
#!/bin/bash
# LOCATION: The Azure region. Use the "az account list-locations -o table"
command to find a region near you.
LOCATION='westus'
# RESOURCE_GROUP_NAME: The resource group name, which can contain underscores,
hyphens, periods, parenthesis, letters, and numbers.
RESOURCE_GROUP_NAME='msdocs-web-app-rg'
# ACCOUNT_NAME: The Azure Cosmos DB for MongDB account name, which can contain
lowercase letters, hyphens, and numbers.
ACCOUNT_NAME='msdocs-cosmos-db-account-name'
echo "Copy the Primary MongoDB Connection String from the list above"
When the script completes, copy the Primary MongoDB Connection String from the output of
the last command to your clipboard or other location.
Output
{
"connectionStrings": [
{
"connectionString": ""mongodb://msdocs-cosmos-
db:pnaMGVtGIRAZHUjsg4GJBCZMBJ0trV4eg2IcZf1TqV...5oONz0WX14Ph0Ha5IeYACDbuVrBPA==@ms
[Link]/?
ssl=true&replicaSet=globaldb&retrywrites=false&maxIdleTimeMS=120000&appName=@msdoc
s-cosmos-db@"",
"description": "Primary MongoDB Connection String",
"keyKind": "Primary",
"type": "MongoDB"
},
...
]
}
After you complete the previous step, you have an Azure Cosmos DB for MongoDB connection
string of the form mongodb://<server-name>:<password>@<server-
name>.[Link]/?ssl=true&<other-parameters> , a database named
restaurants_reviews , and a collection named restaurants_reviews .
For more information about how to use the Azure CLI to create a Cosmos DB for MongoDB
account and to create databases and collections, see Create a database and collection for
MongoDB for Azure Cosmos DB using Azure CLI. You can also use PowerShell, the VS Code
Azure Databases extension , and Azure portal.
Tip
In the VS Code Azure Databases extension, you can right-click on the MongoDB server
and get the connection string.
7 Note
When the web app is deployed to Azure, the web app gets connection information from
environment values set as App Service configuration settings and none of the
modifications for the local development environment scenario apply.
Azure CLI
MongoDB local
Use the following commands with your local instance of MongoDB to run the Docker
image locally.
Bash
Bash
#!/bin/bash
# Define variables
# Set the port number based on the framework being used:
# 8000 for Django, 5000 for Flask
export PORT=<port-number> # Replace with actual port (e.g., 8000 or
5000)
2. Confirm that the container is running. In another console window, run the docker
container ls command.
Console
docker container ls
Console
Bash
Bash
#!/bin/bash
# PORT=8000 for Django and 5000 for Flask
export PORT=<port-number>
export CONNECTION_STRING="<connection-string>"
2. Open a new console window, run the following docker container ls command to
confirm that the container is running.
Console
docker container ls
Console
You can also start a container from an image and stop it with the Docker Desktop
application.
Next step
Build a container image in Azure
Build a containerized Python web app in
Azure
Article • 04/17/2025
In this part of the tutorial series, you learn how to build a containerized Python web app
directly in Azure Container Registry without installing Docker locally. Building the Docker image
in Azure is often faster and easier than creating the image locally and then pushing it to the
Azure Container Registry. Additionally, cloud-based image building eliminates the need for
Docker to run in your development environment.
App Service enables you to run containerized web apps and deploy them through the
continuous integration/continuous deployment (CI/CD) capabilities of Docker Hub, Azure
Container Registry, and Visual Studio Team Services. This article is part 3 of a 5-part tutorial
series about how to containerize and deploy a Python web app to Azure App Service. In this
part of the tutorial, you learn how to build the containerized Python web app in Azure.
Azure App Service lets you deploy and run containerized web apps using CI/CD pipelines from
platforms like Docker Hub, Azure Container Registry, and Azure DevOps. This article is part 3 of
a 5-part tutorial series.
In part 2 of this tutorial series, you built and ran the container image locally. In contrast, in this
part of the tutorial, you build (containerize) the same Python web app directly into a Docker
image in the Azure Container Registry. Building the image in Azure is typically faster and easier
than building locally and then pushing the image to a registry. Also, building in the cloud
doesn't require Docker to be running in your dev environment.
Once the Docker image is in Azure Container Registry, it can be deployed to Azure App service.
Azure CLI
Azure CLI commands can be run in the Azure Cloud Shell or in your local development
environment with the Azure CLI installed.
7 Note
Bash
Azure CLI
#!/bin/bash
# Use the resource group that you created in part 2 of this tutorial
series.
RESOURCE_GROUP_NAME='msdocs-web-app-rg'
# REGISTRY_NAME must be unique within Azure and contain 5-50
alphanumeric characters.
REGISTRY_NAME='msdocscontainerregistryname'
In the JSON output of the command, locate the loginServer value. This value
represents the fully qualified registry name (all lowercase) and contains the registry
name.
2. If you're using the Azure CLI on your local machine, execute the az acr login
command to log in to the container registry.
Azure CLI
The command adds "[Link]" to the name to create the fully qualified registry
name. If successful, you see the message "Login Succeeded".
7 Note
In the Azure Cloud Shell, the az acr login command isn't necessary, as
authentication is handled automatically through your Cloud Shell session.
However, if you encounter authentication issues, you can still use it.
The Azure Cloud Shell allows you to construct the image entirely in the cloud,
independent of your local environment.
Alternatively, you can use VS Code or the Azure CLI to create it in Azure from your
local setup, without needing Docker to be running locally.
Azure CLI commands can be run in your local development environment with the Azure
CLI installed or in Azure Cloud Shell .
1. In the console, navigate to the root folder for your cloned repository from part 2 of
this tutorial series.
Azure CLI
The last argument in the command is the fully qualified path to the repo. When
running in Azure Cloud Shell, use [Link]
[Link] for the Django sample app and
[Link]
for the Flask sample app.
3. Confirm the container image was created with the az acr repository list command.
Azure CLI
Next step
Deploy web app
Deploy a containerized Python app to App
Service
05/21/2025
In this part of the tutorial series, you learn how to deploy a containerized Python web
application to Azure App Service Web App for Containers. This fully managed service lets you
run containerized apps without having to maintain your own container orchestrator.
At the end of this article, you have a secure, production-ready App Service web app running
from a Docker container image. The app uses a system-assigned managed identity to pull the
image from Azure Container Registry and retrieve secrets from Azure Key Vault.
Azure CLI
Azure CLI commands can be run in the Azure Cloud Shell or on a local machine with the
Azure CLI installed.
) Important
We recommend using Azure Cloud Shell for all CLI-based steps in this tutorial
because it:
The Key Vault is configured to use role-based access control (RBAC) to manage access
through Azure roles instead of traditional access policies. The web app uses its system-
assigned managed identity to retrieve secrets securely at runtime.
7 Note
Creating the Key Vault early ensures that roles can be assigned before any attempt to
access secrets. It also helps avoid propagation delays in role assignments. Since Key
Vault doesn’t depend on the App Service, provisioning it early improves reliability and
sequencing.
1. In this step, you use the az keyvault create command to create an Azure Key Vault
with RBAC enabled.
Bash
Azure CLI
#!/bin/bash
RESOURCE_GROUP_NAME="msdocs-web-app-rg"
LOCATION="westus"
KEYVAULT_NAME="${RESOURCE_GROUP_NAME}-kv"
az keyvault create \
--name "$KEYVAULT_NAME" \
--resource-group "$RESOURCE_GROUP_NAME" \
--location "$LOCATION" \
--enable-rbac-authorization true
7 Note
The web app must be created before assigning access to ACR or Key Vault because
the managed identity is only created at deployment time. Also, assigning the
container image during creation ensures the app starts up correctly with the intended
configuration.
1. In this step, you use the az appservice plan create command to provision the
compute environment for your app.
Bash
Azure CLI
#!/bin/bash
APP_SERVICE_PLAN_NAME="msdocs-web-app-plan"
Bash
Azure CLI
#!/bin/bash
APP_SERVICE_NAME="msdocs-website-name" #APP_SERVICE_NAME must be
globally unique as it becomes the website name in the URL
`[Link]
# Use the same registry name as in part 2 of this tutorial series.
REGISTRY_NAME="msdocscontainerregistryname" #REGISTRY_NAME is the
registry name you used in part 2 of this tutorial.
CONTAINER_NAME="$REGISTRY_NAME.[Link]/msdocspythoncontainerwebapp
:latest" #CONTAINER_NAME is of the form
"[Link]/repo_name:tag".
az webapp create \
--resource-group "$RESOURCE_GROUP_NAME" \
--plan "$APP_SERVICE_PLAN_NAME" \
--name "$APP_SERVICE_NAME" \
--assign-identity '[system]' \
--deployment-container-image-name "$CONTAINER_NAME"
7 Note
When running this command, you may see the following error:
Output
This error occurs because the web app tries to use admin credentials to access
ACR, which credentials are disabled by default. It's safe to ignore this message:
the next step configures the web app to use its managed identity to
authenticate with ACR.
Grant Secrets Officer Role to logged-in user
To store secrets in Azure Key Vault, the user running the script must have the Key Vault
Secrets Officer role. This role allows creating and managing secrets within the vault.
In this step, the script assigns that role to the currently logged-in user. This user can then
securely store application secrets, such as the MongoDB connection string and the app’s
SECRET_KEY .
This role assignment is the first of two Key Vault–related role assignments. Later, the web
app’s system-assigned managed identity is granted access to retrieve secrets from the
vault.
Using Azure RBAC ensures secure, auditable access based on identity, eliminating the
need for hard-coded credentials.
7 Note
The user must be assigned the Key Vault Secrets Officer role before before
attempting to store any secrets in the key vault. This assignment is done using the az
role assignment create command scoped to the Key Vault.
1. In this step, you use the az role assignment create command to assign the role at the
Key Vault scope.
Bash
Azure CLI
#!/bin/bash
CALLER_ID=$(az ad signed-in-user show --query id -o tsv)
echo $CALLER_ID # Verify this value retrieved successfully. In
production, poll to verify this value is retrieved successfully.
Enabling the web app to use its managed identity when accessing ACR
Assigning the AcrPull role to that identity on the target ACR
1. In this step, you retrieve the principal ID (unique object ID) of the web app’s
managed identity using the az webapp identity show command. Next, you enable the
use of the managed identity for ACR authentication by setting the
acrUseManagedIdentityCreds property to true using az webapp config set. You then
assign the AcrPull role to the web app’s managed identity using the az role
assignment create command. This role grants the web app permission to pull images
from the registry.
Bash
Azure CLI
#!/bin/bash
PRINCIPAL_ID=$(az webapp identity show \
--name "$APP_SERVICE_NAME" \
--resource-group "$RESOURCE_GROUP_NAME" \
--query principalId \
-o tsv)
echo $PRINCIPAL_ID # Verify this value retrieved successfully. In
production, poll for successful 'AcrPull' role assignment using `az
role assignment list`.
1. In this step, you use the unique identifier (principal ID) of the web app’s system-
assigned managed identity to grant the web app access to the Key Vault with the Key
Vault Secrets User role using the az role assignment create command.
Bash
Azure CLI
#!/bin/bash
7 Note
While this tutorial stores only the connection string and secret key in the key vault,
you can optionally store other application settings such as the MongoDB database
name or collection name in Key Vault as well.
1. In this step, you use the az cosmosdb keys list command to retrieve the MongoDB
connection string. You then use the az keyvault secret set command to store both the
connection string and a randomly generated secret key in Key Vault.
Bash
Azure CLI
#!/bin/bash
ACCOUNT_NAME="msdocs-cosmos-db-account-name"
This approach avoids hardcoding secrets and allows the app to securely retrieve sensitive
values like the MongoDB connection string and secret key during execution.
1. In this step, you use the az webapp config appsettings set command to add
application settings that reference the Key Vault secrets. Specifically, this sets the
MongoConnectionString and MongoSecretKey app settings to reference the
Bash
Azure CLI
#!/bin/bash
MONGODB_NAME="restaurants_reviews"
MONGODB_COLLECTION_NAME="restaurants_reviews"
CONNECTION_STRING="@[Link](SecretUri=[Link]
[Link]/secrets/MongoConnectionString)" \
SECRET_KEY="@[Link](SecretUri=[Link]
[Link]/secrets/MongoSecretKey)" \
DB_NAME="$MONGODB_NAME" \
COLLECTION_NAME="$MONGODB_COLLECTION_NAME"
7 Note
In the next step, you'll register a webhook in ACR to notify the web app when a new
image is pushed.
1. In this step, you use the az webapp deployment container config command to enable
continuous deployment from ACR to the web app.
Bash
Azure CLI
#!/bin/bash
az webapp deployment container config \
--name "$APP_SERVICE_NAME" \
--resource-group "$RESOURCE_GROUP_NAME" \
--enable-cd true
Register an ACR Webhook for continuous
deployment
To automate deployments, register a webhook in Azure Container Registry (ACR) that
notifies the web app whenever a new container image is pushed. The webhook allows the
app to automatically pull and run the latest version.
The webhook configured in Azure Container Registry (ACR) sends a POST request to the
web app’s SCM endpoint (SERVICE_URI) whenever a new image is pushed to the
msdocspythoncontainerwebapp repository. This action triggers the web app to pull and
deploy the updated image, completing the continuous deployment pipeline between ACR
and Azure App Service.
7 Note
It must end with /api/registry/webhook . If you receive a URI error, confirm that the
path is correct.
1. In this step, use the az acr webhook create command to register the webhook and
configure it to trigger on push events.
Bash
Azure CLI
#!/bin/bash
CREDENTIAL=$(az webapp deployment list-publishing-credentials \
--resource-group "$RESOURCE_GROUP_NAME" \
--name "$APP_SERVICE_NAME" \
--query publishingPassword --output tsv)
# Web app publishing credentials may not be available immediately. In
production, poll until non-empty.
SERVICE_URI="[Link]
[Link]/api/registry/webhook"
Once the site appears, try adding a restaurant and submitting a review to confirm that the
app is functioning correctly.
7 Note
The az webapp browse command isn't supported in Cloud Shell. If you're using Cloud
Shell, manually open a browser and navigate to the site URL.
If you're using the Azure CLI locally, you can use the az webapp browse command to open
the site in your default browser:
Azure CLI
7 Note
The az webapp browse command isn't supported in Cloud Shell. Open a browser
window and navigate to the website URL instead.
Troubleshoot deployment
If you don't see the sample app, try the following steps.
With container deployment and App Service, always check the Deployment Center / Logs
page in the Azure portal. Confirm that the container was pulled and is running. The initial
pull and running of the container can take a few moments.
Try to restart the App Service and see if that resolves your issue.
If there are programming errors, those errors show up in the application logs. On the
Azure portal page for the App Service, select Diagnose and solve problems/Application
logs.
The sample app relies on a connection to Azure Cosmos DB for MongoDB. Confirm that
the App Service has application settings with the correct connection info.
Confirm that managed identity is enabled for the App Service and is used in the
Deployment Center. On the Azure portal page for the App Service, go to the App Service
Deployment Center resource and confirm that Authentication is set to Managed
Identity.
Check that the webhook is defined in the Azure Container Registry. The webhook enables
the App Service to pull the container image. In particular, check that Service URI ends
with "/api/registry/webhook". If not, add it.
Different Azure Container Registry skus have different features, including number of
webhooks. If you're reusing an existing registry, you could see the message: "Quota
exceeded for resource type webhooks for the registry SKU Basic. Learn more about
different SKU quotas and upgrade process: [Link] . If you see this
message, use a new registry, or reduce the number of registry webhooks in use.
Next step
Clean up resources
Containerize tutorial cleanup and next
steps
Article • 04/17/2025
In this part of the tutorial series, you learn how to clean up resources used in Azure so you
don't incur other charges and help keep your Azure subscription uncluttered.
Clean up resources
At the end of a tutorial or project, it's important to clean up any Azure resources you no longer
need. This helps you:
Avoid unnecessary charges – Resources left running can continue to accrue costs.
Keep your Azure subscription organized – Removing unused resources makes it easier to
manage and navigate your subscription.
In this tutorial, all the Azure resources were created in the same resource group. Removing the
resource group removes all resources in the resource group and is the fastest way to remove
all Azure resources used for your app.
Tip
If you plan to continue development or testing, you can leave the resources running. Just
be aware of potential costs.
Azure CLI
Azure CLI commands can be run in the Azure Cloud Shell or on a workstation with the
Azure CLI installed.
You can optionally add the --no-wait argument to allow the command to return before the
operation is complete.
VS Code
To work with Azure resources in VS Code, you must have the Azure Tools extension pack
installed and be signed into Azure from VS Code.
1. In the Azure view in VS Code (from the Azure Tools extension), expand RESOURCES
and find your subscription.
5. In the confirmation dialog, enter the exact name of the resource group.
Next steps
After completing this tutorial, here are some next steps you can take to build upon what you
learned and move the tutorial code and deployment closer to production ready:
Map a custom DNS name to your app, see Tutorial: Map custom DNS name to your app.
Monitor App Service for availability, performance, and operation, see Monitoring App
Service and Set up Azure Monitor for your Python application.
Introduction to Python
This tutorial shows you how to containerize a Python Flask or FastAPI web app and
deploy it to Azure Container Apps. Azure Container Apps uses Docker container
technology to host both built-in images and custom images. For more information
about using containers in Azure, see Comparing Azure container options.
In this tutorial, you use the Docker CLI and the Azure CLI to create a Docker image
and deploy it to Azure Container Apps. You can also deploy with Visual Studio Code
and the Azure Tools Extension .
Prerequisites
To complete this tutorial, you need:
An Azure account where you can deploy a web app to Azure Container Apps. (An
Azure Container Registry and Log Analytics workspace are created for you in the
process.)
Azure CLI, Docker , and the Docker CLI installed in your local environment.
Flask
Bash
Flask
Dockerfile
# syntax=docker/dockerfile:1
FROM python:3.11
WORKDIR /code
COPY [Link] .
COPY . .
EXPOSE 50505
50505 is used for the container port (internal) in this example, but you can use any
free port.
Python
Flask==2.2.2
gunicorn
Werkzeug==2.2.2
Configure gunicorn
Gunicorn can be configured with a [Link] file. When the [Link]
file is located in the same directory where gunicorn is run, you don't need to
specify its location in the ENTRYPOINT or CMD instruction of the Dockerfile. For more
information about specifying the configuration file, see Gunicorn settings .
In this tutorial, the suggested configuration file configures GUnicorn to increase its
number of workers based on the number of CPU cores available. For more
information about [Link] file settings, see Gunicorn configuration .
text
max_requests = 1000
max_requests_jitter = 50
log_file = "-"
bind = "[Link]:50505"
workers = (multiprocessing.cpu_count() * 2) + 1
threads = workers
timeout = 120
dockerignore
.git*
**/*.pyc
.venv/
Flask
Bash
Flask
Bash
The --detach option runs the container in the background. The --publish option maps
the container port to a port on the host. The host port (external) is first in the pair, and
the container port (internal) is second. For more information, see Docker run
reference .
Flask
Azure CLI
az containerapp up \
--resource-group web-flask-aca-rg --name web-aca-app \
--ingress external --target-port 50505 --source .
When deployment completes, you have a resource group with the following resources
inside of it:
The URL for the deployed app is in the output of the az containerapp up command.
Open the URL in your browser to see the web app running in Azure. The form of the
URL will look like the following [Link]
info>.[Link] , where the <generated-text> and <location-info> are
In more complex update scenarios, you can redeploy with the az acr build and az
containerapp update commands together to update the container app.
Clean up
All the Azure resources created in this tutorial are in the same resource group. Removing
the resource group removes all resources in the resource group and is the fastest way to
remove all Azure resources used for your app.
Flask
Azure CLI
You can also remove the group in the Azure portal or in Visual Studio Code and the
Azure Tools Extension .
Next steps
For more information, see the following resources:
Feedback
Was this page helpful? Yes No
There are several options to build and deploy cloud-native and containerized Python web apps
on Azure. This tutorial series covers Azure Container Apps. Container Apps is good for running
general-purpose containers, especially for applications that span many microservices deployed
in containers.
In this tutorial series, you create one container. To deploy a Python web app as a container to
Azure App Service, see Containerized Python web app on Azure with MongoDB.
The procedures in this tutorial series guide you to complete these tasks:
" Build a Docker image from a Python web app and store the image in Azure Container
Registry.
" Configure Azure Container Apps to host the Docker image.
" Set up GitHub Actions to update the container with a new Docker image triggered by
changes to your GitHub repository. This step is optional.
" Set up continuous integration and continuous delivery (CI/CD) of a Python web app to
Azure.
In this first part of the series, you learn foundational concepts for deploying a Python web app
on Azure Container Apps.
Service overview
The following diagram shows how you'll use your local environment, GitHub repositories, and
Azure services in this tutorial series.
Azure Container Apps enables you to run microservices and containerized applications on
a serverless platform. A serverless platform means that you enjoy the benefits of running
containers with minimal configuration. With Azure Container Apps, your applications can
dynamically scale based on characteristics such as HTTP traffic, event-driven processing,
or CPU or memory load.
Container Apps pulls Docker images from Azure Container Registry. Changes to container
images trigger an update to the deployed container. You can also configure GitHub
Actions to trigger updates.
Azure Container Registry enables you to work with Docker images in Azure. Because
Container Registry is close to your deployments in Azure, you have control over access.
You can use your Microsoft Entra groups and permissions to control access to Docker
images.
In this tutorial series, the registry source is Azure Container Registry. But you can also use
Docker Hub or a private registry with minor modifications.
The sample code stores application data in a PostgreSQL database. The container app
connects to PostgreSQL by using a user-assigned managed identity. Connection
information is stored in environment variables configured explicitly or through an Azure
service connector.
GitHub :
The sample code for this tutorial series is in a GitHub repo that you fork and clone locally.
To set up a CI/CD workflow with GitHub Actions , you need a GitHub account.
You can still follow along with this tutorial series without a GitHub account, if you work
locally or in Azure Cloud Shell to build the container image from the sample code repo.
To automate this process, an optional step in the tutorial series shows you how to build a
CI/CD pipeline by using GitHub Actions. The pipeline automatically builds and deploys your
code to Container Apps whenever a new commit is pushed to your GitHub repository.
To set up CI/CD, you authorize Azure Container Apps as an OAuth app for your GitHub
account. As an OAuth app, Container Apps writes a GitHub Actions workflow file to your repo
with information about Azure resources and jobs to update them. The workflow updates Azure
resources by using the credentials of a Microsoft Entra service principal (or an existing one)
with role-based access for Container Apps and a username and password for Azure Container
Registry. Credentials are stored securely in your GitHub repo.
Finally, the sample web app in this tutorial series stores data in a PostgreSQL database. The
sample code connects to PostgreSQL via a connection string. When the app is running in
Azure, it connects to the PostgreSQL database by using a user-assigned managed identity. The
code uses DefaultAzureCredential to dynamically update the password in the connection string
with a Microsoft Entra access token during runtime. This mechanism prevents the need to
hardcode the password in the connection string or an environment variable, and it provides an
extra layer of security.
The tutorial series walks you through creating the managed identity and granting it an
appropriate PostgreSQL role and permissions so that it can access and update the database.
During the configuration of Container Apps, the tutorial series walks you through configuring
the managed identity on the app and setting up environment variables that contain connection
information for the database. You can also use an Azure service connector to accomplish the
same thing.
Prerequisites
To complete this tutorial series, you need:
Visual Studio Code or the Azure CLI, depending on what tool you use:
For Visual Studio Code, you need the Container Apps extension .
You can use the Azure CLI through Azure Cloud Shell.
Python packages:
psycopg2-binary for connecting to PostgreSQL.
Flask or Django as a web framework.
Sample app
The Python sample app is a restaurant review app that saves restaurant and review data in
PostgreSQL. At the end of the tutorial series, you'll have a restaurant review app deployed and
running in Azure Container Apps that looks like the following screenshot.
Next step
Build and deploy a Python web app with Azure Container Apps and PostgreSQL
This article is part of a tutorial series about how to containerize and deploy a Python web app
to Azure Container Apps. Container Apps enables you to deploy containerized apps without
managing complex infrastructure.
" Containerize a Python sample web app (Django or Flask) by building a container image in
the cloud.
" Deploy the container image to Azure Container Apps.
" Define environment variables that enable the container app to connect to an Azure
Database for PostgreSQL - Flexible Server instance, where the sample app stores data.
The following diagram highlights the tasks in this tutorial: building and deploying a container
image.
Prerequisites
If you don't have an Azure subscription, create a free account before you begin.
Azure CLI
You can run Azure CLI commands in Azure Cloud Shell or on a workstation with the
Azure CLI installed.
If you're running locally, follow these steps to sign in and install the necessary modules for
this tutorial:
Azure CLI
az login
2. Make sure you're running the latest version of the Azure CLI:
Azure CLI
az upgrade
3. Install or upgrade the containerapp and rdbms-connect Azure CLI extensions by using
the az extension add command:
Azure CLI
az extension add --name containerapp --upgrade
az extension add --name rdbms-connect --upgrade
7 Note
To list the extensions installed on your system, you can use the az extension list
command. For example:
Azure CLI
Follow the steps to fork the repo to your GitHub account. You can also download the
code repo directly to your local machine without forking or a GitHub account. But if you
use the download method, you won't be able to set up continuous integration and
continuous delivery (CI/CD) in the next tutorial in this series.
2. At the command prompt in your console, use the git clone command to clone the
forked repo into the python-container folder:
Console
# Django
git clone [Link]
[Link] python-container
# Flask
# git clone [Link]
[Link] python-container
Console
cd python-container
Azure CLI
1. If you're running commands in a Git Bash shell on a Windows computer, enter the
following command before proceeding:
Azure CLI
#!/bin/bash
export MSYS_NO_PATHCONV=1
Azure CLI
#!/bin/bash
RESOURCE_GROUP_NAME=<resource-group-name>
LOCATION=<location>
az group create \
--name $RESOURCE_GROUP_NAME \
--location $LOCATION
Azure CLI
#!/bin/bash
REGISTRY_NAME=<registry-name> #The name that you use for *\<registry-name>*
must be unique within Azure, and it must contain 5 to 50 alphanumeric
characters.
az acr create \
--resource-group $RESOURCE_GROUP_NAME \
--name $REGISTRY_NAME \
--sku Basic \
--admin-enabled true
Azure CLI
az acr login --name $REGISTRY_NAME
The command adds "[Link]" to the name to create the fully qualified registry
name. If the sign-in is successful, the message "Login Succeeded" appears. If you're
accessing the registry from a subscription that's different from the one in which you
created the registry, use the --suffix switch.
If sign-in fails, make sure the Docker daemon is running on your system.
Azure CLI
#!/bin/bash
az acr build \
--registry $REGISTRY_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--image pythoncontainer:latest .
The dot ( . ) at the end of the command indicates the location of the source
code to build. If you aren't running this command in the sample app's root
directory, specify the path to the code.
If you're running the command in Azure Cloud Shell, use git clone to first pull
the repo into the Cloud Shell environment. Then change directory into the root
of the project so that the dot ( . ) is interpreted correctly.
If you leave out the -t (same as --image ) option, the command queues a local
context build without pushing it to the registry. Building without pushing can
be useful to check that the image builds.
6. Confirm that the container image was created by using the az acr repository list
command:
Azure CLI
az acr repository list --name $REGISTRY_NAME
7 Note
The steps in this section create a container registry in the Basic service tier. This tier is
cost-optimized, with a feature set and throughput targeted for developer scenarios, and is
suitable for the requirements of this tutorial. In production scenarios, you would most
likely use either the Standard or Premium service tier. These tiers provide enhanced levels
of storage and throughput.
To learn more, see Azure Container Registry service tiers. For information about pricing,
see Azure Container Registry pricing .
Azure CLI
1. Use the az postgres flexible-server create command to create the PostgreSQL server
in Azure. It isn't uncommon for this command to run for a few minutes before it
finishes.
Azure CLI
#!/bin/bash
ADMIN_USERNAME=demoadmin
ADMIN_PASSWORD=<admin-password> # Use a strong password that meets the
requirements for PostgreSQL.
POSTGRES_SERVER_NAME=<postgres-server-name>
az postgres flexible-server create \
--resource-group $RESOURCE_GROUP_NAME \
--name $POSTGRES_SERVER_NAME \
--location $LOCATION \
--admin-user $ADMIN_USERNAME \
--admin-password $ADMIN_PASSWORD \
--version 16 \
--tier Burstable \
--sku-name Standard_B1ms \
--public-access [Link] \
--microsoft-entra-auth Enabled \
--storage-size 32 \
--backup-retention 7 \
--high-availability Disabled \
--yes
<location>: Use the same location that you used for the web app. <location> is
one of the Azure location Name values from the output of the command az
account list-locations -o table .
) Important
When you're creating usernames or passwords, do not use the dollar sign
($) character. Later, when you create environment variables with these
values, that character has a special meaning within the Linux container that
you use to run Python apps.
--version : Use 16 . It specifies the PostgreSQL version to use for the server.
--tier : Use Burstable . It specifies the pricing tier for the server. The Burstable
tier is a lower-cost option for workloads that don't need the full CPU
continuously, and is suitable for the requirements of this tutorial.
--sku-name : The name of the pricing tier and compute configuration; for
--public-access : Use [Link] . It allows public access to the server from any
on the server.
--storage-size : Use 32 . It specifies the storage size in gigabytes (GB) for the
7 Note
If you plan to work with the PostgreSQL server from your local workstation by
using tools, you need to add a firewall rule for your workstation's IP address by
using the az postgres flexible-server firewall-rule create command.
2. Use the az ad signed-in-user show command to get the object ID of your user
account. You use this ID in the next command.
Azure CLI
#!/bin/bash
CALLER_OBJECT_ID=$(az ad signed-in-user show --query id -o tsv)
CALLER_DISPLAY_NAME=$(az ad signed-in-user show --query userPrincipalName -
o tsv)
3. Use the az postgres flexible-server ad-admin create command to add your user
account as a Microsoft Entra administrator on the PostgreSQL server:
Azure CLI
#!/bin/bash
az postgres flexible-server microsoft-entra-admin create \
--server-name "$POSTGRES_SERVER_NAME" \
--resource-group "$RESOURCE_GROUP_NAME" \
--display-name "$CALLER_DISPLAY_NAME" \
--object-id "$CALLER_OBJECT_ID" \
--type User
4. Use the az postgres flexible-server firewall-rule create command to add a rule that
allows your web app to access the PostgreSQL flexible server. In the following
command, you configure the server's firewall to accept connections from your
development workstation by using your public IP address:
Azure CLI
MY_IP=$(curl -s [Link])
az postgres flexible-server firewall-rule create \
--name "$POSTGRES_SERVER_NAME" \
--resource-group "$RESOURCE_GROUP_NAME" \
--rule-name allow-my-ip \
--start-ip-address "$MY_IP" \
--end-ip-address "$MY_IP"
```
7 Note
The steps in this section create a PostgreSQL server with a single vCore and limited
memory in the Burstable pricing tier. The Burstable tier is a lower-cost option for
workloads that don't need the full CPU continuously, and is suitable for the requirements
of this tutorial. For production workloads, you might upgrade to either the General
Purpose or Memory Optimized pricing tier. These tiers provide higher performance but
increase costs.
To learn more, see Compute options in Azure Database for PostgreSQL - Flexible Server.
For information about pricing, see Azure Database for PostgreSQL pricing .
Azure CLI
Azure CLI
#!/bin/bash
DATABASE_NAME=restaurants_reviews
az postgres flexible-server db create \
--resource-group $RESOURCE_GROUP_NAME \
--server-name $POSTGRES_SERVER_NAME \
--database-name $DATABASE_NAME
You could also use the az postgres flexible-server connect command to connect to the
database and then work with psql commands. When you're working with psql, it's often
easier to use Azure Cloud Shell because the shell includes all the dependencies for you.
You can also connect to the Azure Database for PostgreSQL flexible server and create a
database by using psql or an IDE that supports PostgreSQL, like Visual Studio Code. For steps
using psql, see Configure the managed identity on the PostgreSQL database later in this article.
7 Note
To create a user-assigned managed identity, your account needs the Managed Identity
Contributor role assignment.
Azure CLI
Use the az identity create command to create a user-assigned managed identity:
Azure CLI
UA_MANAGED_IDENTITY_NAME=<managed-identity-name> # Use a unique name for the
managed identity, such as-"my-ua-managed-id".
az identity create \
--name $UA_MANAGED_IDENTITY_NAME
--resource-group $RESOURCE_GROUP_NAME
Azure CLI
1. Get an access token for your Azure account by using the az account get-access-
token command. You use the access token in the next steps.
Azure CLI
#!/bin/bash
MY_ACCESS_TOKEN=$(az account get-access-token --resource-type oss-rdbms --
output tsv --query accessToken)
echo $MY_ACCESS_TOKEN
2. Add the user-assigned managed identity as database role on your PostgreSQL server
by using the az postgres flexible-server execute command:
Azure CLI
#!/bin/bash
az postgres flexible-server execute \
--name "$POSTGRES_SERVER_NAME" \
--admin-user "$CALLER_DISPLAY_NAME" \
--admin-password "$ACCESS_TOKEN" \
--database-name postgres \
--querytext "SELECT * FROM
pgaadauth_create_principal('$UA_MANAGED_IDENTITY_NAME', false, false);"
7 Note
Azure CLI
#!/bin/bash
SQL_GRANTS=$(cat <<EOF
GRANT CONNECT ON DATABASE $DATABASE_NAME TO "$UA_MANAGED_IDENTITY_NAME";
GRANT USAGE, CREATE ON SCHEMA public TO "$UA_MANAGED_IDENTITY_NAME";
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO
"$UA_MANAGED_IDENTITY_NAME";
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE,
DELETE ON TABLES TO "$UA_MANAGED_IDENTITY_NAME";
EOF
)
This Azure CLI command connects to the restaurants_reviews database on the server
and issues the following SQL commands:
SQL
GRANT CONNECT ON DATABASE restaurants_reviews TO "my-ua-managed-id";
GRANT USAGE ON SCHEMA public TO "my-ua-managed-id";
GRANT CREATE ON SCHEMA public TO "my-ua-managed-id";
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "my-ua-managed-id";
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO "my-ua-managed-id";
Deploy the web app to Container Apps
Container apps are deployed to Azure Container Apps environments, which act as a secure
boundary. In the following steps, you create the environment and a container inside the
environment. You then configure the container so that the website is visible externally.
Azure CLI
Azure CLI
#!/bin/bash
APP_ENV_NAME=<app-env-name> # Use a unique name for the environment, such
as "python-container-env".
az containerapp env create \
--name $APP_ENV_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--location $LOCATION
2. Get the sign-in credentials for the Azure Container Registry instance by using the az
acr credential show command:
Azure CLI
#!/bin/bash
REGISTRY_CREDS=$(az acr credential show -n "$REGISTRY_NAME" --query "
[username,passwords[0].value]" -o tsv)
REGISTRY_USERNAME=$(echo "$REGISTRY_CREDS" | head -n1)
REGISTRY_PASSWORD=$(echo "$REGISTRY_CREDS" | tail -n1)
You use the username and one of the passwords returned from the command's
output when you create the container app in step 5.
3. Use the az identity show command to get the client ID and resource ID of the user-
assigned managed identity:
Azure CLI
UA_CLIENT_ID=$(az identity show \
--name "$UA_MANAGED_IDENTITY_NAME" \
--resource-group "$RESOURCE_GROUP_NAME" \
--query clientId -o tsv)
UA_RESOURCE_ID=$(az identity show \
--name "$UA_MANAGED_IDENTITY_NAME" \
--resource-group "$RESOURCE_GROUP_NAME" \
--query id -o tsv)
You use the value of the client ID (GUID) and the resource ID from the command's
output when you create the container app in step 5. The resource ID has the
following form: /subscriptions/<subscription-id>/resourcegroups/pythoncontainer-
rg/providers/[Link]/userAssignedIdentities/my-ua-managed-id .
Azure CLI
AZURE_SECRET_KEY=$(python -c 'import secrets; print(secrets.token_hex())')
You use the secret key value to set an environment variable when you create the
container app in step 5.
7 Note
The command that this step shows is for a Bash shell. Depending on your
environment, you might need to invoke Python by using python3 . On Windows,
you need to enclose the command in the -c parameter in double quotation
marks rather than single quotation marks. You also might need to invoke Python
by using py or py -3 , depending on your environment.
Azure CLI
az containerapp create \
--name "$CONTAINER_APP_NAME" \
--resource-group "$RESOURCE_GROUP_NAME" \
--environment "$APP_ENV_NAME" \
--image "$REGISTRY_NAME.[Link]/$IMAGE_NAME" \
--target-port "$TARGET_PORT" \
--ingress external \
--registry-server "$REGISTRY_NAME.[Link]" \
--registry-username "$REGISTRY_USERNAME" \
--registry-password "$REGISTRY_PASSWORD" \
--user-assigned "$UA_RESOURCE_ID" \
--env-vars \
DBHOST="$POSTGRES_SERVER_NAME" \
DBNAME="$DATABASE_NAME" \
DBUSER="$UA_MANAGED_IDENTITY_NAME" \
RUNNING_IN_PRODUCTION=1 \
AZURE_CLIENT_ID="$UA_CLIENT_ID" \
AZURE_SECRET_KEY="$AZURE_SECRET_KEY"
6. For Django only, migrate and create a database schema. (In the Flask sample app, it's
done automatically, and you can skip this step.)
Azure CLI
az containerapp exec \
--name $CONTAINER_APP_NAME \
--resource-group $RESOURCE_GROUP_NAME
Here's an example of the sample website after the addition of a restaurant and two reviews.
Troubleshoot deployment
Go to the Overview page of the container app and look for Application Url.
In VS Code:
1. Go to the Azure view (Ctrl+Shift+A) and expand the subscription that you're working in.
2. Expand the Container Apps node, expand the managed environment, right-click python-
container-app, and then select Browse. VS Code opens the browser with the application
URL.
If you run the Build Image in Azure task again, check whether your registry from a previous
run exists. If so, use it.
To check admin status in the portal, go to your Azure Container Registry instance, select the
Access keys resource, and ensure that Admin user is enabled.
The sample code used in this tutorial checks for the existence of the container environment
variable RUNNING_IN_PRODUCTION , which can be set to any value (like 1 ).
Next step
Configure continuous deployment for a Python web app in Azure Container Apps
Last updated on 02/06/2026
Tutorial: Configure continuous deployment
for a Python web app in Azure Container
Apps
06/18/2025
This article is part of a tutorial series about how to containerize and deploy a Python web app
to Azure Container Apps. Container Apps enables you to deploy containerized apps without
managing complex infrastructure.
Prerequisites
To set up continuous deployment, you need:
The resources (and their configuration) that you created in the previous tutorial, which
includes an instance of Azure Container Registry and a container app in Azure Container
Apps.
A GitHub account where you forked the sample code (Django or Flask ) and that you
can connect to from Azure Container Apps. (If you downloaded the sample code instead
of forking, be sure to push your local repo to your GitHub account.)
Optionally, Git installed in your development environment to make code changes and
push to your repo in GitHub. Alternatively, you can make the changes directly in GitHub.
In this section, you set up continuous deployment by using a GitHub Actions workflow. With
continuous deployment, a new Docker image and container revision are created based on a
trigger. The trigger in this tutorial is any change to the main branch of your repository, such as
with a pull request. When the workflow is triggered, it creates a new Docker image, pushes it to
the Azure Container Registry instance, and updates the container app to a new revision by
using the new image.
Azure CLI
You can run Azure CLI commands in Azure Cloud Shell or on a workstation where Azure
CLI is installed.
If you're running commands in a Git Bash shell on a Windows computer, enter the
following command before proceeding:
Bash
export MSYS_NO_PATHCONV=1
Azure CLI
az ad sp create-for-rbac \
--name <app-name> \
--role Contributor \
--scopes "/subscriptions/<subscription-ID>/resourceGroups/<resource-
group-name>"
In the command:
<app-name> is an optional display name for the service principal. If you leave
off the --name option, a GUID is generated as the display name.
<subscription-ID> is the GUID that uniquely identifies your subscription in
Azure. If you don't know your subscription ID, you can run the az account show
command and copy it from the id property in the output.
<resource-group-name> is the name of a resource group that contains the
Azure Container Apps container. Role-based access control (RBAC) is on the
resource group level. If you followed the steps in the previous tutorial, the
name of the resource group is pythoncontainer-rg .
Save the output of this command for the next step. In particular, save the client ID
( appId property), client secret ( password property), and tenant ID ( tenant property).
Azure CLI
In the command:
0000-00000000 .
If you followed the steps for the portal, the service principal was automatically created for you.
If you followed the steps for the Azure CLI, you explicitly created the service principal before
you configured continuous deployment.
If you haven't already, make a fork of the sample repository (Django or Flask ). You can
make your code change directly in GitHub or in your development environment from a
command line with Git .
GitHub
1. Go to your fork of the sample repository and start in the main branch.
2. Make a change:
a. Go to the /templates/[Link] file. (For Django, the path is
restaurant_review/templates/restaurant_review/[Link].)
b. Select Edit and change the phrase Azure Restaurant Review to Azure Restaurant
Review - Redeployed .
3. On the bottom of the page you're editing, make sure that Commit directly to the
main branch is selected. Then select the Commit changes button.
7 Note
This tutorial shows making a change directly in the main branch. In typical software
workflows, you make a change in a branch other than main and then create a pull request
to merge the change into main. Pull requests also kick off the workflow.
GitHub
On GitHub , go to your fork of the sample repository and open the Actions tab.
Workflow secrets
The .github/workflows/<workflow-name>.yml workflow file that was added to the repo includes
placeholders for credentials that are needed for the build and container app update jobs of the
workflow. The credential information is stored encrypted in the repository's Settings area,
under Security > Secrets and variables > Actions.
If credential information changes, you can update it here. For example, if the Azure Container
Registry passwords are regenerated, you need to update the REGISTRY_PASSWORD value. For
more information, see Encrypted secrets in the GitHub documentation.
Troubleshoot
If you get an error that contains "InvalidSchema: No connection adapters were found":
Check the shell that you're running in. If you're using a Bash shell, set the
MSYS_NO_PATHCONV variables as export MSYS_NO_PATHCONV=1 .
For more information, see the GitHub issue Unable to create service principal with Azure
CLI from Git Bash shell .
If you get an error that contains "More than one application have the same display name":
The name is already taken for the service principal. Choose another name, or leave off the
--name argument. A GUID will be automatically generated as a display name.
If there's a failed workflow, drill into the workflow file. There should be two jobs: build and
deploy. For a failed job, check the output of the job's tasks to look for problems.
If there's an error message that contains "TLS handshake timeout," run the workflow
manually. In the repo, on the Actions tab, select Trigger auto deployment to see if the
timeout is a temporary issue.
If you set up continuous deployment for the container app as shown in this tutorial, the
workflow file (.github/workflows/<workflow-name>.yml) is created automatically for you.
You shouldn't need to modify this file for this tutorial. If you did, revert your changes and
try the workflow.
Check that the GitHub Actions workflow ran and that you checked the change into the
branch that triggers the workflow.
Check the Azure Container Registry instance to see if a new Docker image was created
with a time stamp after your change to the branch.
Check the logs of the container app to see if there's a programming error:
Go to the container app. On the service menu, select Continuous deployment, and then
select Disconnect.
Remove resources
If you're done with the tutorial series and you don't want to incur extra costs, remove the
resources that you used.
Removing a resource group removes all resources in the group and is the fastest way to
remove resources. For an example of how to remove resource groups, see Containerize tutorial
cleanup.
Related content
If you plan to build on this tutorial, here are some next steps that you can take:
Azure Kubernetes Service (AKS) is a managed Kubernetes service that lets you quickly deploy
and manage clusters. In this quickstart, you learn how to:
7 Note
This article includes steps to deploy a cluster with default settings for evaluation purposes
only. Before you deploy a production-ready cluster, we recommend that you familiarize
yourself with our baseline reference architecture to consider how it aligns with your
business requirements.
If you don't have an Azure account, create a free account before you begin.
Use the Bash environment in Azure Cloud Shell. For more information, see Get started
with Azure Cloud Shell.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you're running
on Windows or macOS, consider running Azure CLI in a Docker container. For more
information, see How to run the Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login
command. To finish the authentication process, follow the steps displayed in your
terminal. For other sign-in options, see Authenticate to Azure using Azure CLI.
When you're prompted, install the Azure CLI extension on first use. For more
information about extensions, see Use and manage extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To
upgrade to the latest version, run az upgrade.
Make sure that the identity you're using to create your cluster has the appropriate
minimum permissions. For more information on access and identity for AKS, see Access
and identity options for Azure Kubernetes Service (AKS).
If you have multiple Azure subscriptions, select the appropriate subscription ID in which
the resources should be billed using the az account set command. For more information,
see How to manage Azure subscriptions – Azure CLI.
Dependent upon your Azure subscription, you might need to request a vCPU quota
increase. For more information, see Increase VM-family vCPU quotas.
Azure CLI
Azure CLI
Azure CLI
The RANDOM_ID variable's value is a six character alphanumeric value appended to the resource
group and cluster name so that the names are unique. Use the echo command to view variable
values like echo $RANDOM_ID .
Azure CLI
Output
{
"id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-
eeeeee4e4e4e/resourceGroups/myAKSResourceGroup<randomIDValue>",
"location": "westus",
"managedBy": null,
"name": "myAKSResourceGroup<randomIDValue>",
"properties": {
"provisioningState": "Succeeded"
},
"tags": null,
"type": "[Link]/resourceGroups"
}
Azure CLI
az aks create \
--resource-group $MY_RESOURCE_GROUP_NAME \
--name $MY_AKS_CLUSTER_NAME \
--node-count 1 \
--generate-ssh-keys
7 Note
When you create a new cluster, AKS automatically creates a second resource group to
store the AKS resources. For more information, see Why are two resource groups created
with AKS?
1. Configure kubectl to connect to your Kubernetes cluster using the az aks get-credentials
command. This command downloads credentials and configures the Kubernetes CLI to
use them.
Azure CLI
2. Verify the connection to your cluster using the kubectl get command. This command
returns a list of the cluster nodes.
Azure CLI
Store front: Web application for customers to view products and place orders.
Product service: Shows product information.
Order service: Places orders.
RabbitMQ : Message queue for an order queue.
7 Note
YAML
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: rabbitmq
spec:
serviceName: rabbitmq
replicas: 1
selector:
matchLabels:
app: rabbitmq
template:
metadata:
labels:
app: rabbitmq
spec:
nodeSelector:
"[Link]/os": linux
containers:
- name: rabbitmq
image: [Link]/mirror/docker/library/rabbitmq:3.10-
management-alpine
ports:
- containerPort: 5672
name: rabbitmq-amqp
- containerPort: 15672
name: rabbitmq-http
env:
- name: RABBITMQ_DEFAULT_USER
value: "username"
- name: RABBITMQ_DEFAULT_PASS
value: "password"
resources:
requests:
cpu: 10m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
volumeMounts:
- name: rabbitmq-enabled-plugins
mountPath: /etc/rabbitmq/enabled_plugins
subPath: enabled_plugins
volumes:
- name: rabbitmq-enabled-plugins
configMap:
name: rabbitmq-enabled-plugins
items:
- key: rabbitmq_enabled_plugins
path: enabled_plugins
---
apiVersion: v1
data:
rabbitmq_enabled_plugins: |
[rabbitmq_management,rabbitmq_prometheus,rabbitmq_amqp1_0].
kind: ConfigMap
metadata:
name: rabbitmq-enabled-plugins
---
apiVersion: v1
kind: Service
metadata:
name: rabbitmq
spec:
selector:
app: rabbitmq
ports:
- name: rabbitmq-amqp
port: 5672
targetPort: 5672
- name: rabbitmq-http
port: 15672
targetPort: 15672
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
replicas: 1
selector:
matchLabels:
app: order-service
template:
metadata:
labels:
app: order-service
spec:
nodeSelector:
"[Link]/os": linux
containers:
- name: order-service
image: [Link]/azure-samples/aks-store-demo/order-service:latest
ports:
- containerPort: 3000
env:
- name: ORDER_QUEUE_HOSTNAME
value: "rabbitmq"
- name: ORDER_QUEUE_PORT
value: "5672"
- name: ORDER_QUEUE_USERNAME
value: "username"
- name: ORDER_QUEUE_PASSWORD
value: "password"
- name: ORDER_QUEUE_NAME
value: "orders"
- name: FASTIFY_ADDRESS
value: "[Link]"
resources:
requests:
cpu: 1m
memory: 50Mi
limits:
cpu: 75m
memory: 128Mi
startupProbe:
httpGet:
path: /health
port: 3000
failureThreshold: 5
initialDelaySeconds: 20
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 3000
failureThreshold: 3
initialDelaySeconds: 3
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
port: 3000
failureThreshold: 5
initialDelaySeconds: 3
periodSeconds: 3
initContainers:
- name: wait-for-rabbitmq
image: busybox
command: ['sh', '-c', 'until nc -zv rabbitmq 5672; do echo waiting
for rabbitmq; sleep 2; done;']
resources:
requests:
cpu: 1m
memory: 50Mi
limits:
cpu: 75m
memory: 128Mi
---
apiVersion: v1
kind: Service
metadata:
name: order-service
spec:
type: ClusterIP
ports:
- name: http
port: 3000
targetPort: 3000
selector:
app: order-service
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: product-service
spec:
replicas: 1
selector:
matchLabels:
app: product-service
template:
metadata:
labels:
app: product-service
spec:
nodeSelector:
"[Link]/os": linux
containers:
- name: product-service
image: [Link]/azure-samples/aks-store-demo/product-service:latest
ports:
- containerPort: 3002
env:
- name: AI_SERVICE_URL
value: "[Link]
resources:
requests:
cpu: 1m
memory: 1Mi
limits:
cpu: 2m
memory: 20Mi
readinessProbe:
httpGet:
path: /health
port: 3002
failureThreshold: 3
initialDelaySeconds: 3
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
port: 3002
failureThreshold: 5
initialDelaySeconds: 3
periodSeconds: 3
---
apiVersion: v1
kind: Service
metadata:
name: product-service
spec:
type: ClusterIP
ports:
- name: http
port: 3002
targetPort: 3002
selector:
app: product-service
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: store-front
spec:
replicas: 1
selector:
matchLabels:
app: store-front
template:
metadata:
labels:
app: store-front
spec:
nodeSelector:
"[Link]/os": linux
containers:
- name: store-front
image: [Link]/azure-samples/aks-store-demo/store-front:latest
ports:
- containerPort: 8080
name: store-front
env:
- name: VUE_APP_ORDER_SERVICE_URL
value: "[Link]
- name: VUE_APP_PRODUCT_SERVICE_URL
value: "[Link]
resources:
requests:
cpu: 1m
memory: 200Mi
limits:
cpu: 1000m
memory: 512Mi
startupProbe:
httpGet:
path: /health
port: 8080
failureThreshold: 3
initialDelaySeconds: 5
periodSeconds: 5
readinessProbe:
httpGet:
path: /health
port: 8080
failureThreshold: 3
initialDelaySeconds: 3
periodSeconds: 3
livenessProbe:
httpGet:
path: /health
port: 8080
failureThreshold: 5
initialDelaySeconds: 3
periodSeconds: 3
---
apiVersion: v1
kind: Service
metadata:
name: store-front
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: store-front
type: LoadBalancer
For a breakdown of YAML manifest files, see Deployments and YAML manifests .
If you create and save the YAML file locally, then you can upload the manifest file to your
default directory in Cloud Shell by selecting the Upload/Download files button and
selecting the file from your local file system.
2. Deploy the application using the kubectl apply command and specify the name of your
YAML manifest.
Azure CLI
Azure CLI
runtime="5 minutes"
endtime=$(date -ud "$runtime" +%s)
while [[ $(date -u +%s) -le $endtime ]]
do
STATUS=$(kubectl get pods -l app=store-front -o 'jsonpath=
{..[Link][?(@.type=="Ready")].status}')
echo $STATUS
if [ "$STATUS" == 'True' ]
then
export IP_ADDRESS=$(kubectl get service store-front --output 'jsonpath=
{..[Link][0].ip}')
echo "Service IP Address: $IP_ADDRESS"
break
else
sleep 10
fi
done
Azure CLI
curl $IP_ADDRESS
Results:
HTML
<!doctype html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" href="/[Link]">
<title>store-front</title>
<script defer="defer" src="/js/[Link]"></script>
<script defer="defer" src="/js/[Link]"></script>
<link href="/css/[Link]" rel="stylesheet">
</head>
<body>
<div id="app"></div>
</body>
</html>
Output
To view the application website, open a browser and enter the IP address. The page looks like
the following example.
Azure CLI
Next steps
In this quickstart, you deployed a Kubernetes cluster and then deployed a simple multi-
container application to it. This sample application is for demo purposes only and doesn't
represent all the best practices for Kubernetes applications. For guidance about how to create
full solutions with AKS for production, see AKS solution guidance.
To learn more about AKS and do a complete code-to-deployment example, continue to the
Kubernetes cluster tutorial.
AKS tutorial
Use the Azure libraries (SDK) for Python
Article • 02/06/2025
The open-source Azure libraries for Python simplify provisioning, managing, and using
Azure resources from Python application code.
The libraries support Python 3.8 or later. For more information about supported
versions of Python, see Azure SDKs Python version support policy . If you're using
PyPy , make sure the version you use at least supports the Python version
mentioned previously.
The Azure SDK for Python is composed solely of over 180 individual Python
libraries that relate to specific Azure services. There are no other tools in the SDK.
When you run code locally, authenticating with Azure relies on environment
variables as described in How to authenticate Python apps to Azure services using
the Azure SDK for Python.
To install library packages with pip, use pip install <library_name> using library
names from the package index. To install library packages in conda environments,
use conda install <package_name> using names from the Microsoft channel on
[Link] . For more information, see Install Azure library packages.
Documentation for the libraries is found on the Azure for Python Reference, which
is organized by Azure Service, or the Python API browser, which is organized by
package name.
To try the libraries for yourself, we first recommend setting up your local dev
environment. Then you can try any of the following standalone examples (in any
order): Example: Create a resource group, Example: Create and use Azure Storage,
Example: Create and deploy a web app, Example: Create and query a MySQL
database, and Example: Create a virtual machine.
For demonstration videos, see Introducing the Azure SDK for Python (PyCon
2021) and Using Azure SDKs to interact with Azure resources (PyCon 2020).
The Azure libraries for Python build on top of the underlying Azure REST API,
allowing you to use those APIs through familiar Python paradigms. However, you
can always use the REST API directly from Python code, if desired.
You can find the source code for the Azure libraries on
[Link] . As an open-source project,
contributions are welcome!
Although you can use the libraries with interpreters such as IronPython and Jython
that we don't test against, you may encounter isolated issues and incompatibilities.
The source repo for the library API reference documentation resides on
[Link] .
On 31 March 2023, we retired support for Azure SDK libraries that don't
conform to current Azure SDK guidelines. While older libraries can still be used
beyond 31 March 2023, they'll no longer receive official support and updates
from Microsoft. For more information, see the notice Update your Azure SDK
libraries .
To avoid missing security and performance updates to the Azure SDKs, upgrade
to the latest Azure SDK libraries by 31 March 2023.
To check which Python libraries are impacted, see Azure SDK Deprecated
Releases for Python .
For details on the guidelines we apply to the libraries, see the Python Guidelines:
Introduction .
With the management libraries, you can write configuration and deployment scripts to
perform the same tasks that you can through the Azure portal or the Azure CLI. (As
noted earlier, the Azure CLI is written in Python and uses the management libraries to
implement its various commands.)
The following examples illustrate how to use some of the primary management libraries:
For details on working with each management library, see the [Link] or
[Link] file located in the library's project folder in the SDK GitHub repository . You
can also find more code snippets in the reference documentation and the Azure
Samples.
The article, Example: Use Azure Storage, provides a basic illustration of using client
library.
Different Azure services also provide examples using these libraries. See the following
index pages for other links:
App hosting
Cognitive Services
Data solutions
Identity and security
Machine learning
Messaging and IoT
Other services
For details on working with each client library, see the [Link] or [Link] file
located in the library's project folder in the SDK's GitHub repository . You can also find
more code snippets in the reference documentation and the Azure Samples.
Feedback
Was this page helpful? Yes No
The Azure SDK for Python is composed of many independent libraries, which are listed on the
Python SDK package index.
All the libraries share certain common characteristics and usage patterns, such as installation
and the use of inline JSON for object arguments.
Configure a Python virtual environment using venv or your tool of choice. You can create
the virtual environment locally or in Azure Cloud Shell and run the code there. Be sure
to activate the virtual environment to start using it. To install python, see Install Python .
Bash
Library installation
Choose the installation method that corresponds to your Python environment management
tool, either pip or conda.
pip
pip install retrieves the latest version of a library in your current Python environment.
You can also use pip to uninstall libraries and install specific versions, including preview
versions. For more information, see How to install Azure library packages for Python.
Asynchronous operations
Asynchronous libraries
Many client and management libraries provide async versions ( .aio ). The asyncio library has
been available since Python 3.4, and the async/await keywords were introduced in Python 3.5.
The async versions of the libraries are intended to be used with Python 3.5 and later.
Examples of Azure Python SDK libraries with async versions include: [Link],
[Link], [Link], and [Link].
These libraries need an async transport such as aiohttp to work. The azure-core library
provides an async transport, AioHttpTransport , which is used by the async libraries, so you may
not need to install aiohttp separately.
The following code shows how create a python file thath demonstrates how to create a client
for the async version of the Azure Blob Storage library:
Python
credential = DefaultAzureCredential()
# Close credential
await [Link]()
[Link](run())
The full example is on GitHub at use_blob_auth_async.py . For the synchronous version of this
code, see Example: Upload a blob.
7 Note
You may notice differences in method names in a library depending on its version and
whether it's based on [Link]. Older libraries that aren't based on [Link] typically
use names like create_or_update . Libraries based on [Link] add the begin_ prefix to
method names to better indicate that they are long polling operations. Migrating old code
to a newer [Link]-based library typically means adding the begin_ prefix to method
names, as most method signatures remain the same.
The LROPoller return type means that the operation is asynchronous. Accordingly, you must
call that poller's result method to wait for the operation to finish and obtain its result.
The following code, taken from Example: Create and deploy a web app, shows an example of
using the poller to wait for a result:
Python
# Step 3: With the plan in place, provision the web app itself, which is the
process that can host
# whatever code we want to deploy to it.
poller = app_service_client.web_apps.begin_create_or_update(RESOURCE_GROUP_NAME,
WEB_APP_NAME,
{
"location": LOCATION,
"server_farm_id": plan_result.id,
"site_config": {
"linux_fx_version": "python|3.8"
}
}
)
web_app_result = [Link]()
Exceptions
In general, the Azure libraries raise exceptions when operations fail to perform as intended,
including failed HTTP requests to the Azure REST API. For app code, you can use try...except
blocks around library operations.
For more information on the type of exceptions that may be raised, see the documentation for
the operation in question.
Logging
The most recent Azure libraries use the Python standard logging library to generate log
output. You can set the logging level for individual libraries, groups of libraries, or all libraries.
Once you register a logging stream handler, you can then enable logging for a specific client
object or a specific operation. For more information, see Logging in the Azure libraries.
Proxy configuration
To specify a proxy, you can use environment variables or optional arguments. For more
information, see How to configure proxies.
ノ Expand table
logging_enable bool False Enables logging. For more information, see Logging in the
Azure libraries.
proxies dict {} Proxy server URLs. For more information, see How to
configure proxies.
connection_timeout int 300 The timeout in seconds for making a connection to Azure
REST API endpoints.
read_timeout int 300 The timeout in seconds for completing an Azure REST API
operation (that is, waiting for a response).
retry_total int 10 The number of allowable retry attempts for REST API calls.
Use retry_total=0 to disable retries.
Individual libraries aren't obligated to support any of these arguments, so always consult the
reference documentation for each library for exact details. Also, each library may support other
arguments. For example, for blob storage specific keyword arguments, see the GitHub README
for azure-storage-blob .
For example, suppose you have a ResourceManagementClient object through which you create
a resource group with its create_or_update method. The second argument to this method is of
type ResourceGroup.
To call the create_or_update method, you can create a discrete instance of ResourceGroup
directly with its required arguments ( location in this case):
Python
Python
When you use inline JSON, the Azure libraries automatically convert the inline JSON to the
appropriate object type for the argument in question.
Objects can also have nested object arguments, in which case you can also use nested JSON.
For example, suppose you have an instance of the KeyVaultManagementClient object, and are
calling its create_or_update. In this case, the third argument is of type
VaultCreateOrUpdateParameters, which itself contains an argument of type VaultProperties.
VaultProperties , in turn, contains object arguments of type Sku and list[AccessPolicyEntry]. A
Sku contains a SkuName object, and each AccessPolicyEntry contains a Permissions object.
To call begin_create_or_update with embedded objects, you use code like the following
(assuming tenant_id , object_id , and LOCATION are already defined). You can also create the
necessary objects before the function call.
Python
# Provision a Key Vault using inline parameters
poller = keyvault_client.vaults.begin_create_or_update(
RESOURCE_GROUP_NAME,
KEY_VAULT_NAME_A,
VaultCreateOrUpdateParameters(
location = LOCATION,
properties = VaultProperties(
tenant_id = tenant_id,
sku = Sku(
name="standard",
family="A"
),
access_policies = [
AccessPolicyEntry(
tenant_id = tenant_id,
object_id = object_id,
permissions = Permissions(
keys = ['all'],
secrets = ['all']
)
)
]
)
)
)
key_vault1 = [Link]()
Python
key_vault2 = [Link]()
Because both forms are equivalent, you can choose whichever you prefer and even intermix
them. (The full code for these examples can be found on GitHub .)
If your JSON isn't formed properly, you typically get the error, "DeserializationError: Unable to
deserialize to object: type, AttributeError: 'str' object has no attribute 'get'". A common cause of
this error is that you're providing a single string for a property when the library expects a
nested JSON object. For example, using 'sku': 'standard' in the previous example generates
this error because the sku parameter is a Sku object that expects inline object JSON, in this
case {'name': 'standard'} , which maps to the expected SkuName type.
Next steps
Now that you understand the common patterns for using the Azure libraries for Python, see
the following standalone examples to explore specific management and client library scenarios.
You can try these examples in any order as they're not sequential or interdependent.
The specific type of token-based authentication an app uses to authenticate to Azure resources
depends on where the app is being run. The types of token-based authentication are shown in
the following diagram.
When a developer is running an app during local development: The app authenticates
to Azure by using either an application service principal for local development or the
developer's Azure credentials. These options are discussed in the section Authentication
during local development.
When an app is hosted on Azure: The app authenticates to Azure resources by using a
managed identity. This option is discussed in the section Authentication in server
environments.
When an app is hosted and deployed on-premises: The app authenticates to Azure
resources by using an application service principal. This option is discussed in the section
Authentication in server environments.
DefaultAzureCredential
The DefaultAzureCredential class provided by the Azure Identity client library allows apps to
use different authentication methods depending on the environment in which they're run. In
this way, apps can be promoted from local development to test environments to production
without code changes.
You configure the appropriate authentication method for each environment, and
DefaultAzureCredential automatically detects and uses that authentication method. The use of
Details about using the DefaultAzureCredential class are discussed in the section Use
DefaultAzureCredential in an application.
The token-based authentication methods described in this article allow you to establish
the specific permissions needed by the app on the Azure resource. This practice follows
the principle of least privilege . In contrast, a connection string grants full rights to the
Azure resource.
Anyone or any app with a connection string can connect to an Azure resource, but token-
based authentication methods scope access to the resource to only the apps intended to
access the resource.
With a managed identity, there's no application secret to store. The app is more secure
because there's no connection string or application secret that can be compromised.
The azure-identity package acquires and manages Microsoft Entra tokens for you.
azure-identity makes using token-based authentication as easy to use as a connection
string.
Limit the use of connection strings to initial proof-of-concept apps or development prototypes
that don't access production or sensitive data. Otherwise, the token-based authentication
classes available in the Azure Identity client library are always preferred when they're
authenticating to Azure resources.
ノ Expand table
Authentication Description
method
Apps hosted in Apps hosted in Azure should use a managed identity service principal. Managed
Azure identities are designed to represent the identity of an app hosted in Azure and can
only be used with Azure-hosted apps.
For example, a Django web app hosted in Azure App Service would be assigned a
managed identity. The managed identity assigned to the app would then be used to
authenticate the app to other Azure services.
Apps running in Azure Kubernetes Service (AKS) can use a Workload identity
credential. This credential is based on a managed identity that has a trust
relationship with an AKS service account.
,
Apps hosted Apps hosted outside of Azure (for example, on-premises apps) that need to connect
outside of Azure to Azure services should use an application service principal. An application service
(for example, on- principal represents the identity of the app in Azure and is created through the
premises apps) application registration process.
For example, consider a Django web app hosted on-premises that makes use of
Azure Blob Storage. You would create an application service principal for the app by
using the app registration process. The AZURE_CLIENT_ID , AZURE_TENANT_ID , and
AZURE_CLIENT_SECRET would all be stored as environment variables to be read by the
application at runtime and allow the app to authenticate to Azure by using the
application service principal.
Authentication Description
method
ノ Expand table
Create dedicated In this method, dedicated application service principal objects are set up by
application service principal using the app registration process for use during local development. The
objects to be used during identity of the service principal is then stored as environment variables to
local development. be accessed by the app when it's run in local development.
This method allows you to assign the specific resource permissions needed
by the app to the service principal objects used by developers during local
development. This practice makes sure the application only has access to
the specific resources it needs and replicates the permissions the app will
have in production.
Authenticate the app to In this method, a developer must be signed in to Azure from the Azure CLI,
Azure by using the Azure PowerShell, or Azure Developer CLI on their local workstation. The
developer's credentials application then can access the developer's credentials from the credential
during local development. store and use those credentials to access Azure resources from the app.
This method has the advantage of easier setup because a developer only
needs to sign in to their Azure account through one of the aforementioned
developer tools. The disadvantage of this approach is that the developer's
account likely has more permissions than required by the application. As a
result, the application doesn't accurately replicate the permissions it will
run with in production.
terminal
pip install azure-identity
Azure services are accessed using specialized client classes from the various Azure SDK client
libraries. The following code example shows how to instantiate a DefaultAzureCredential
object and use it with an Azure SDK client class. In this case, it's a BlobServiceClient object
used to access Azure Blob Storage.
Python
from [Link] import DefaultAzureCredential
from [Link] import BlobServiceClient
blob_service_client = BlobServiceClient(
account_url="[Link]
credential=credential)
When this code runs on your local development workstation, it checks environment variables
for an application service principal. If it finds none, it looks for developer credentials from local
tools such as the Azure CLI. Either approach can be used to authenticate the app to Azure
resources during local development.
When deployed to Azure, this same code can also authenticate your app to Azure resources.
DefaultAzureCredential can retrieve environment settings and managed identity
Use a developer account with one of the developer tools supported by the Azure Identity
library.
Use a broker to manage credentials.
Use a service principal.
This article explains how to authenticate using a developer account with tools supported by the
Azure Identity library. In the sections ahead, you learn:
How to use Microsoft Entra groups to efficiently manage permissions for multiple
developer accounts.
How to assign roles to developer accounts to scope permissions.
How to sign-in to supported local development tools.
How to authenticate using a developer account from your app code.
Azure CLI
Azure Developer CLI
Azure PowerShell
Visual Studio Code
The Azure Identity library can detect that the developer is signed-in from one of these tools.
The library can then obtain the Microsoft Entra access token via the tool to authenticate the
app to Azure as the signed-in user.
This approach takes advantage of the developer's existing Azure accounts to streamline the
authentication process. However, a developer's account likely has more permissions than
required by the app, therefore exceeding the permissions the app runs with in production. As
an alternative, you can create application service principals to use during local development,
which can be scoped to have only the access needed by the app.
Create a Microsoft Entra group for local
development
Create a Microsoft Entra group to encapsulate the roles (permissions) the app needs in local
development rather than assigning the roles to individual service principal objects. This
approach offers the following advantages:
Every developer has the same roles assigned at the group level.
If a new role is needed for the app, it only needs to be added to the group for the app.
If a new developer joins the team, a new application service principal is created for the
developer and added to the group, ensuring the developer has the right permissions to
work on the app.
Azure portal
4. On the New group page, fill out the following form fields:
5. Select the No members selected link under Members to add members to the group.
6. In the flyout panel that opens, search for the service principal you created earlier and
select it from the filtered results. Choose the Select button at the bottom of the
panel to confirm your selection.
7. Select Create at the bottom of the New group page to create the group and return
to the All groups page. If you don't see the new group listed, wait a moment and
refresh the page.
Azure portal
1. In the Azure portal, navigate to the Overview page of the resource group that
contains your app.
3. On the Access control (IAM) page, select + Add and then choose Add role
assignment from the drop-down menu. The Add role assignment page provides
several tabs to configure and assign roles.
4. On the Role tab, use the search box to locate the role you want to assign. Select the
role, and then choose Next.
For the Assign access to value, select User, group, or service principal .
For the Members value, choose + Select members to open the Select
members flyout panel.
Search for the Microsoft Entra group you created earlier and select it from the
filtered results. Choose Select to select the group and close the flyout panel.
Select Review + assign at the bottom of the Members tab.
6. On the Review + assign tab, select Review + assign at the bottom of the page.
Developers using Visual Studio Code can authenticate with their developer account
directly through the editor via the broker. Apps that use DefaultAzureCredential or
VisualStudioCodeCredential can then use this account to authenticate app requests
through a seamless single-sign-on experience.
1. In Visual Studio Code, go to the Extensions panel and install the Azure Resources
extension. This extension lets you view and manage Azure resources directly from
Visual Studio Code. It also uses the built-in Visual Studio Code Microsoft
authentication provider to authenticate with Azure.
2. Open the Command Palette in Visual Studio Code, then search for and select Azure:
Sign in.
Tip
Bash
pip install azure-identity-broker
Bash
pip install azure-identity
7 Note
Add the necessary import statements for the [Link] module and the Azure
service client module your app requires.
Use a credential specific to your development tool: this option is best for single
person or single tool scenarios.
Use a credential available for use in any development tool: this option is best for
open-source projects and diverse tool teams.
Python
credential = AzureCliCredential()
blob_service_client = BlobServiceClient(
account_url="[Link]
credential=credential)
Use a DefaultAzureCredential instance optimized for all local development tools. This example
requires the environment variable AZURE_TOKEN_CREDENTIALS set to dev . For more information,
see Exclude a credential type category.
Python
from [Link] import DefaultAzureCredential
from [Link] import BlobServiceClient
credential = DefaultAzureCredential(require_envvar=True)
blob_service_client = BlobServiceClient(
account_url="[Link]
credential=credential)
Tip
When your team uses multiple development tools to authenticate with Azure, prefer
DefaultAzureCredential over tool-specific credentials.
Dedicated application service principals for local development follow the principle of least
privilege. They grant access only to the Azure resources that the app needs during
development. This limited access reduces the risk of unintentionally reaching other resources. It
also helps prevent permission-related bugs when moving to production, where broader
permissions could cause problems.
Create separate app registrations for each developer: This approach provides each
developer with their own service principal, avoiding the need to share credentials and
enabling more granular access control.
Create separate app registrations for each application: This approach ensures each app
only has the permissions it needs, reducing the potential attack surface.
To enable authentication during local development, set environment variables with the
application service principal’s credentials. The Azure SDK for Python detects these variables and
uses them to authenticate requests to Azure services.
The following steps show how to register an app in Azure and create a service principal for the
app. The steps are shown for both the Azure CLI and the Azure portal.
Azure CLI
Azure CLI commands can be run in the Azure Cloud Shell or on a workstation with the
Azure CLI installed.
First, use the az ad sp create-for-rbac command to create a new service principal for the
app. The command also creates the app registration for the app at the same time.
Azure CLI
SERVICE_PRINCIPAL_NAME=<service-principal-name>
az ad sp create-for-rbac --name $SERVICE_PRINCIPAL_NAME
The output of this command is similar to the following. Make note of these values or keep
this window open as you'll need these values in the next steps and won't be able to view
the password (client secret) value again. You can, however, add a new password later
without invalidating the service principal or existing passwords if needed.
JSON
{
"appId": "00001111-aaaa-2222-bbbb-3333cccc4444",
"displayName": "<service-principal-name>",
"password": "Ee5Ff~6Gg7.-Hh8Ii9Jj0Kk1Ll2Mm3_Nn4Oo5Pp6",
"tenant": "aaaabbbb-0000-cccc-1111-dddd2222eeee"
}
Next, you need to get the appID value and store it into a variable. This value is used to set
environment variables in your local development environment so that the Azure SDK for
Python can authenticate to Azure using the service principal.
Azure CLI
APP_ID=$(az ad sp list \
--all \
--query "[?displayName=='$SERVICE_PRINCIPAL_NAME'].appId | [0]" \
--output tsv)
Every developer is assured to have the same roles assigned since roles are assigned at the
group level.
If a new role is needed for the app, it only needs to be added to the Microsoft Entra
group for the app.
If a new developer joins the team, a new application service principal is created for the
developer and added to the group, assuring the developer has the right permissions to
work on the app.
Azure CLI
The az ad group create command is used to create security groups in Microsoft Entra ID.
The --display-name and --main-nickname parameters are required. The name given to the
group should be based on the name of the application. It's also useful to include a phrase
like 'local-dev' in the name of the group to indicate the purpose of the group.
Azure CLI
GROUP_DISPLAY_NAME="<group-name>"
GROUP_MAIL_NICKNAME="<group-mail-nickname>"
GROUP_DESCRIPTION="<group-description>"
az ad group create \
--display-name $GROUP_DISPLAY_NAME \
--mail-nickname $GROUP_MAIL_NICKNAME \
--description $GROUP_DESCRIPTION
To add members to the group, you need the object ID of the application service principal,
which is different than the application ID. Use the az ad sp list to list the available service
principals. The --filter parameter command accepts OData style filters and can be used
to filter the list as shown. The --query parameter limits the columns to only the ones
you're interested in.
Azure CLI
SP_OBJECT_ID=$(az ad sp list \
--filter "startswith(displayName,'$GROUP_DISPLAY_NAME')" \
--query "[0].id" \
--output tsv)
The az ad group member add command can then be used to add members to groups.
Azure CLI
az ad group member add \
--group $GROUP_DISPLAY_NAME \
--member-id $SP_OBJECT_ID
7 Note
By default, the creation of Microsoft Entra security groups is limited to certain privileged
roles in a directory. If you're unable to create a group, contact an administrator for your
directory. If you're unable to add members to an existing group, contact the group owner
or a directory administrator. To learn more, see Manage Microsoft Entra groups and
group membership.
Azure CLI
Use the az role assignment create command to assign a role to a user, group, or
application service principal. You can specify a group with its object ID. You can specify an
application service principal with its appId.
Azure CLI
RESOURCE_GROUP_NAME=<resource-group-name>
SUBSCRIPTION_ID=$(az account show --query id --output tsv)
ROLE_NAME=<role-name>
az role assignment create \
--assignee "$APP_ID" \
--scope "./subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP_NAME"
\
--role "$ROLE_NAME"
![!NOTE] To prevent Git Bash from treating /subscriptions/... as a file path, prepend ./
to the string for the scope parameter and use double quotes around the entire string.
To get the role names that can be assigned, use the az role definition list command.
Azure CLI
az role definition list \
--query "sort_by([].{roleName:roleName, description:description},
&roleName)" \
--output table
For example, to allow the application service principal with the appId of 00001111-aaaa-
2222-bbbb-3333cccc4444 read, write, and delete access to Azure Storage blob containers
Azure CLI
az role assignment create --assignee 00001111-aaaa-2222-bbbb-3333cccc4444 \
--scope "./subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-
eeeeee4e4e4e/resourceGroups/msdocs-python-sdk-auth-example" \
--role "Storage Blob Data Contributor"
For information on assigning permissions at the resource or subscription level using the
Azure CLI, see the article Assign Azure roles using the Azure CLI.
The .env file is never checked into source control since it contains the application secret key
for Azure. The standard .gitignore file for Python automatically excludes the .env file from
check-in.
To use the python-dotenv package, first install the package in your application.
terminal
pip install python-dotenv
Then, create a .env file in your application root directory. Set the environment variable values
with values obtained from the app registration process as follows:
Bash
AZURE_CLIENT_ID=00001111-aaaa-2222-bbbb-3333cccc4444
AZURE_TENANT_ID=aaaabbbb-0000-cccc-1111-dddd2222eeee
AZURE_CLIENT_SECRET=Ee5Ff~6Gg7.-Hh8Ii9Jj0Kk1Ll2Mm3_Nn4Oo5Pp6
Finally, in the startup code for your application, use the python-dotenv library to read the
environment variables from the .env file on startup.
Python
from dotenv import load_dotenv
if ( [Link]['ENVIRONMENT'] == 'development'):
print("Loading environment variables from .env file")
load_dotenv(".env")
terminal
pip install azure-identity
Next, for any Python code that creates an Azure SDK client object in your app:
Python
blob_service_client = BlobServiceClient(
account_url="[Link]
credential=token_credential)
Enables Single Sign-On (SSO): Enables apps to simplify how users authenticate with
Microsoft Entra ID and protects Microsoft Entra ID refresh tokens from exfiltration and
misuse.
Enhanced security: Many security enhancements are delivered with the broker, without
needing to update the app logic.
Enhanced feature support: With the help of the broker, developers can access rich OS
and service capabilities.
System integration: Applications that use the broker plug-and-play with the built-in
account picker, allowing the user to quickly pick an existing account instead of reentering
the same credentials over and over.
Token Protection: Ensures that the refresh tokens are device bound and enables apps to
acquire device bound access tokens. See Token Protection.
Windows provides an authentication broker called Web Account Manager (WAM). WAM
enables identity providers such as Microsoft Entra ID to natively plug into the OS and provide
secure login services to apps. Brokered authentication enables the app for all operations
allowed by the interactive login credentials.
Personal Microsoft accounts and work or school accounts are supported. On supported
Windows versions, the default browser-based UI is replaced with a smoother authentication
experience, similar to built-in Windows apps.
1. In the Azure portal , navigate to Microsoft Entra ID and select App registrations on the
left-hand menu.
b. Under Configure platforms, select the tile for your application type (platform) to
configure its settings, such as mobile and desktop applications.
c. In Custom redirect URIs, enter the following redirect URI for your platform:
ノ Expand table
Linux [Link]
d. Select Configure.
4. Back on the Authentication pane, under Advanced settings, select Yes for Allow public
client flows.
6. To authorize the application for specific resources, navigate to the resource in question,
select API Permissions, and enable Microsoft Graph and other resources you want to
access.
) Important
You must also be the admin of your tenant to grant consent to your application
when you sign in for the first time.
Assign roles
To run your app code successfully with brokered authentication, grant your user account
permissions using Azure role-based access control (RBAC). Assign an appropriate role to your
user account for the relevant Azure service. For example:
Azure Blob Storage: Assign the Storage Account Data Contributor role.
Azure Key Vault: Assign the Key Vault Secrets Officer role.
If an app is specified, it must have API permissions set for user_impersonation Access Azure
Storage (step 6 in the previous section). This API permission allows the app to access Azure
storage on behalf of the signed-in user after consent is granted during sign-in.
1. Install the packages. pywin32 will be used in Windows to retrieve the window currently in
the foreground.
2. Get a reference to the parent window on top of which the account picker dialog should
appear. In the code example below, that will be the line:
Python
current_window_handle = [Link]()
Python
credential =
InteractiveBrowserBrokerCredential(parent_window_handle=current_window_handle)
4. Use the credential to access the Azure service, which is Blob Storage in this example.
Python
import win32gui
from [Link] import InteractiveBrowserBrokerCredential
from [Link] import BlobServiceClient
# To authenticate and authorize with an app, use the following line to get a
credential and
# substitute the <app_id> and <tenant_id> placeholders with the values for your app
and tenant.
# credential =
InteractiveBrowserBrokerCredential(parent_window_handle=current_window_handle,
client_id=<app_id>, tenant_id=<tenant_id>)
credential =
InteractiveBrowserBrokerCredential(parent_window_handle=current_window_handle)
client = BlobServiceClient("[Link]
credential=credential)
For more exact control, such as setting a timeout, you can supply specific arguments to
InteractiveBrowserBrokerCredential such as timeout .
For the code to run successfully, your user account must be assigned an Azure role on the
storage account that allows access to blob containers like Storage Account Data Contributor.
If an app is specified, it must have API permissions set for user_impersonation Access Azure
Storage (step 6 in the previous section). This API permission allows the app to access Azure
storage on behalf of the signed-in user after consent is granted during sign-in.
The following screenshot shows the alternative interactive, brokered authentication experience:
Last updated on 12/13/2025
Authenticate Azure-hosted Python apps to
Azure resources using a system-assigned
managed identity
The recommended approach to authenticate an Azure-hosted app to other Azure resources is
to use a managed identity. This approach is supported for most Azure services, including apps
hosted on Azure App Service, Azure Container Apps, and Azure Virtual Machines. Discover
more about different authentication techniques and approaches on the authentication
overview page. In the sections ahead, you'll learn:
There are two types of managed identities to consider when configuring your hosted app:
System-assigned managed identities are enabled directly on an Azure resource and are
tied to its life cycle. When the resource is deleted, Azure automatically deletes the identity
for you. System-assigned identities provide a minimalistic approach to using managed
identities.
User-assigned managed identities are created as standalone Azure resources and offer
greater flexibility and capabilities. They're ideal for solutions involving multiple Azure
resources that need to share the same identity and permissions. For example, if multiple
virtual machines need to access the same set of Azure resources, a user-assigned
managed identity provides reusability and optimized management.
Tip
Learn more about selecting and managing system-assigned and user-assigned managed
identities in the Managed identity best practice recommendations article.
The sections ahead describe the steps to enable and use a system-assigned managed identity
for an Azure-hosted app. If you need to use a user-assigned managed identity, visit the user-
assigned managed identities article for more information.
You can enable a system-assigned managed identity for an Azure resource using either the
Azure portal or the Azure CLI.
Azure portal
1. In the Azure portal, navigate to the resource that hosts your application code, such as
an Azure App Service or Azure Container App instance.
2. From the resource's Overview page, expand Settings and select Identity from the
navigation.
The following example shows how to assign roles at the resource group scope, since many
apps manage all their related Azure resources using a single resource group.
Azure portal
1. Navigate to the Overview page of the resource group that contains the app with the
system-assigned managed identity.
3. On the Access control (IAM) page, select + Add on the top menu and then choose
Add role assignment to navigate to the Add role assignment page.
4. The Add role assignment page presents a tabbed, multi-step workflow to assign
roles to identities. On the initial Role tab, use the search box at the top to locate the
role you want to assign to the identity.
5. Select the role from the results and then choose Next to move to the Members tab.
7. For the Members option, choose + Select members to open the Select managed
identities panel.
8. On the Select managed identities panel, use the Subscription and Managed identity
dropdowns to filter the search results for your identities. Use the Select search box to
locate the system-identity you enabled for the Azure resource hosting your app.
9. Select the identity and choose Select at the bottom of the panel to continue.
11. On the final Review + assign tab, select Review + assign to complete the workflow.
Local dev environment: During local development only, use a class called
DefaultAzureCredential for an opinionated, preconfigured chain of credentials.
DefaultAzureCredential discovers user credentials from your local tooling or IDE, such as
the Azure CLI or Visual Studio Code. It also provides flexibility and convenience for retries,
wait times for responses, and support for multiple authentication options. Visit the
Authenticate to Azure services during local development article to learn more.
Azure-hosted apps: When your app is running in Azure, use ManagedIdentityCredential
to safely discover the managed identity configured for your app. Specifying this exact
type of credential prevents other available credentials from being picked up
unexpectedly.
terminal
Azure services are accessed using specialized client classes from the various Azure SDK client
libraries. The following code example demonstrates how to create a credential instance and
use it with an Azure SDK service client. In your application code, complete the following steps
to authenticate using a managed identity:
Python
from [Link] import ManagedIdentityCredential
from [Link] import BlobServiceClient
blob_service_client = BlobServiceClient(
account_url="[Link]
credential=credential
)
When developing locally, you can use DefaultAzureCredential which discovers credentials
from local developer tools. When deployed to Azure, switch to ManagedIdentityCredential for
production scenarios:
Python
import os
from [Link] import DefaultAzureCredential, ManagedIdentityCredential
from [Link] import BlobServiceClient
There are two types of managed identities to consider when configuring your hosted app:
System-assigned managed identities are enabled directly on an Azure resource and are
tied to its life cycle. When the resource is deleted, Azure automatically deletes the identity
for you. System-assigned identities provide a minimalistic approach to using managed
identities.
User-assigned managed identities are created as standalone Azure resources and offer
greater flexibility and capabilities. They're ideal for solutions involving multiple Azure
resources that need to share the same identity and permissions. For example, if multiple
virtual machines need to access the same set of Azure resources, a user-assigned
managed identity provides reusability and optimized management.
Tip
Learn more about selecting and managing system-assigned and user-assigned managed
identities in the Managed identity best practice recommendations article.
The sections ahead describe the steps to enable and use a user-assigned managed identity for
an Azure-hosted app. If you need to use a system-assigned managed identity, visit the system-
assigned managed identities article for more information.
Azure portal
1. In the Azure portal, enter Managed identities in the main search bar and select the
matching result under the Services section.
3. On the Create User Assigned Managed Identity page, select a subscription, resource
group, and region for the user-assigned managed identity, and then provide a name.
7. On the new identity's Overview page, copy the Client ID value to use for later when
you configure the application code.
Azure portal
1. In the Azure portal, navigate to the resource that hosts your app code, such as an
Azure App Service or Azure Container App instance.
2. From the resource's Overview page, expand Settings and select Identity from the
navigation.
4. Select + Add to open the Add user assigned managed identity panel.
5. On the Add user assigned managed identity panel, use the Subscription dropdown
to filter the search results for your identities. Use the User assigned managed
identities search box to locate the user-assigned managed identity you enabled for
the Azure resource hosting your app.
6. Select the identity and choose Add at the bottom of the panel to continue.
The following example shows how to assign roles at the resource group scope, since many
apps manage all their related Azure resources using a single resource group.
Azure portal
1. Navigate to the Overview page of the resource group that contains the app with the
user-assigned managed identity.
3. On the Access control (IAM) page, select + Add on the top menu and then choose
Add role assignment to navigate to the Add role assignment page.
4. The Add role assignment page presents a tabbed, multi-step workflow to assign
roles to identities. On the initial Role tab, use the search box at the top to locate the
role you want to assign to the identity.
5. Select the role from the results and then choose Next to move to the Members tab.
7. For the Members option, choose + Select members to open the Select managed
identities panel.
8. On the Select managed identities panel, use the Subscription and Managed identity
dropdowns to filter the search results for your identities. Use the Select search box to
locate the user-assigned managed identity you enabled for the Azure resource
hosting your app.
9. Select the identity and choose Select at the bottom of the panel to continue.
11. On the final Review + assign tab, select Review + assign to complete the workflow.
Authenticate to Azure services from your app
The Azure Identity library provides various credentials—implementations of TokenCredential
adapted to supporting different scenarios and Microsoft Entra authentication flows. Since
managed identity is unavailable when running locally, the steps ahead demonstrate which
credential to use in which scenario:
Local dev environment: During local development only, use a class called
DefaultAzureCredential for an opinionated, preconfigured chain of credentials.
DefaultAzureCredential discovers user credentials from your local tooling or IDE, such as
the Azure CLI or Visual Studio Code. It also provides flexibility and convenience for retries,
wait times for responses, and support for multiple authentication options. Visit the
Authenticate to Azure services during local development article to learn more.
Azure-hosted apps: When your app is running in Azure, use ManagedIdentityCredential
to safely discover the managed identity configured for your app. Specifying this exact
type of credential prevents other available credentials from being picked up
unexpectedly.
terminal
Azure services are accessed using specialized client classes from the various Azure SDK client
libraries. The following code example demonstrates how to create a credential instance and
use it with an Azure SDK service client. In your application code, complete the following steps
to authenticate using a managed identity:
Client ID
The client ID is used to identify a managed identity when configuring applications or
services that need to authenticate using that identity.
Azure CLI
az identity show \
--resource-group <resource-group-name> \
--name <identity-name> \
--query 'clientId'
Python
from [Link] import ManagedIdentityCredential
from [Link] import BlobServiceClient
credential = ManagedIdentityCredential(
client_id="<client-id>"
)
blob_service_client = BlobServiceClient(
account_url="[Link]
credential=credential
)
A different app registration should be created for each environment the app is hosted in.
Creating a different app registration allows environment specific resource permissions to be
configured for each service principal and ensures that an app deployed to one environment
doesn't talk to Azure resources that are part of another environment.
Azure CLI
Azure CLI
APP_NAME=<app-name>
az ad sp create-for-rbac --name $APP_NAME
The output of the command is similar to the following. Make note of these values or keep
this window open as you'll need these values in the next steps and won't be able to view
the password (client secret) value again.
JSON
{
"appId": "00001111-aaaa-2222-bbbb-3333cccc4444",
"displayName": "msdocs-python-sdk-auth-prod",
"password": "Ee5Ff~6Gg7.-Hh8Ii9Jj0Kk1Ll2Mm3_Nn4Oo5Pp6",
"tenant": "aaaabbbb-0000-cccc-1111-dddd2222eeee"
}
Next, you need to get the appID value and store it into a variable. This value is used to set
environment variables in your local development environment so that the Azure SDK for
Python can authenticate to Azure using the service principal.
Azure CLI
APP_ID=$(az ad sp create-for-rbac \
--name $APP_NAME --query appId --output tsv)
Azure CLI
A service principal is assigned a role in Azure using the az role assignment create
command.
Azure CLI
RESOURCE_GROUP_NAME=<resource-group-name>
SUBSCRIPTION_ID=$(az account show --query id --output tsv)
ROLE_NAME=<role-name>
![!NOTE] To prevent Git Bash from treating /subscriptions/... as a file path, prepend ./
to the string for the scope parameter and use double quotes around the entire string.
To get the role names that a service principal can be assigned to, use the az role definition
list command.
Azure CLI
az role definition list \
--query "sort_by([].{roleName:roleName, description:description},
&roleName)" \
--output table
For example, to allow the service principal with the appId of 00001111-aaaa-2222-bbbb-
3333cccc4444 read, write, and delete access to Azure Storage blob containers and data in
Azure CLI
For information on assigning permissions at the resource or subscription level using the
Azure CLI, see the article Assign Azure roles using the Azure CLI.
When using Gunicorn to run Python web apps in a UNIX server environment, environment
variables for an app can be specified by using the EnvironmentFile directive in the
[Link] . See the following example.
[Link]
[Unit]
Description=gunicorn daemon
After=[Link]
[Service]
User=www-user
Group=www-data
WorkingDirectory=/path/to/python-app
EnvironmentFile=/path/to/python-app/py-env/app-environment-variables
ExecStart=/path/to/python-app/py-env/gunicorn --config [Link] wsgi:app
[Install]
WantedBy=[Link]
The file specified in the EnvironmentFile directive should contain a list of environment
variables with their values as follows.
Bash
AZURE_CLIENT_ID=<value>
AZURE_TENANT_ID=<value>
AZURE_CLIENT_SECRET=<value>
terminal
pip install azure-identity
Next, for any Python code that creates an Azure SDK client object in your app, you should:
Python
from [Link] import DefaultAzureCredential
from [Link] import BlobServiceClient
blob_service_client = BlobServiceClient(
account_url="[Link]
credential=token_credential)
From this example, when the code instantiates the DefaultAzureCredential object,
DefaultAzureCredential reads the environment variables AZURE_TENANT_ID , AZURE_CLIENT_ID ,
and AZURE_CLIENT_SECRET for the application service principal information to connect to Azure
with.
Last updated on 11/10/2025
Additional methods to authenticate to
Azure resources from Python apps
This article lists additional methods that apps can use to authenticate to Azure resources. The
methods in this article are less commonly used; when possible, we encourage you to use one
of the methods outlined in authenticating Python apps to Azure using the Azure SDK overview.
Interactive browser authentication enables the application for all operations allowed by the
interactive sign-in credentials. As a result, if you're the owner or administrator of your
subscription, your code has inherent access to most resources in that subscription without
having to assign any specific permissions. For this reason, the use of interactive browser
authentication is discouraged for anything but experimentation.
1. On the Azure portal , navigate to Microsoft Entra ID and select App registrations on the
left-hand menu.
3. Under Advanced settings, select Yes for Allow public client flows.
5. To authorize the application for specific resources, navigate to the resource in question,
select API Permissions, and enable Microsoft Graph and other resources you want to
access. Microsoft Graph is enabled by default.
) Important
You must also be the admin of your tenant to grant consent to your application
when you sign in for the first time.
If you can't configure the device code flow option on your Active Directory, your application
might need to be multitenant. To make this change, navigate to the Authentication panel,
select Accounts in any organizational directory (under Supported account types), and then
select Yes for Allow public client flows.
Python
# Show Azure subscription information
import os
from [Link] import InteractiveBrowserCredential
from [Link] import SubscriptionClient
credential = InteractiveBrowserCredential()
subscription_client = SubscriptionClient(credential)
subscription = next(subscription_client.[Link]())
print(subscription.subscription_id)
For more exact control, such as setting redirect URIs, you can supply specific arguments to
InteractiveBrowserCredential such as redirect_uri .
1. When the application attempts to authenticate, the credential prompts the user with a
URL and an authentication code.
2. The user visits the URL on a separate browser-enabled device (a computer, smartphone,
etc.) and enters the code.
3. The user follows a normal authentication process in the browser.
4. Upon successful authentication, the application is authenticated on the device.
For more information, see Microsoft identity platform and the OAuth 2.0 device authorization
grant flow.
Device code authentication in a development environment enables the application for all
operations allowed by the interactive sign-in credentials. As a result, if you're the owner or
administrator of your subscription, your code has inherent access to most resources in that
subscription without having to assign any specific permissions. However, you can use this
method with a specific client ID, rather than the default, for which you can assign specific
permissions.
get_token
2
loop [Traverse
TokenCredential
collection until
AccessToken received]
Fetch token
3
get_token
4
Result
5
AccessToken
6
Python
# Set up credential based on environment (Azure or local development)
if [Link]("WEBSITE_HOSTNAME"):
credential = ManagedIdentityCredential(client_id=user_assigned_client_id)
else:
credential = AzureCliCredential()
Seamless transitions: Your app can move from local development to your staging or
production environment without changing authentication code.
Improved resiliency: Includes a fallback mechanism that moves to the next credential
when the prior fails to acquire an access token.
"Tear down" a chain: Start with a preconfigured chain and exclude what you don't need.
For this approach, see the DefaultAzureCredential overview section.
"Build up" a chain: Start with an empty chain and include only what you need. For this
approach, see the ChainedTokenCredential overview section.
DefaultAzureCredential overview
DefaultAzureCredential is an opinionated, preconfigured chain of credentials. It's designed to
support many environments, along with the most common authentication flows and developer
tools. In graphical form, the underlying chain looks like this:
CREDENTIALS
Environment Workload Identity Managed Identity Shared Token Cache Visual Studio Code Azure CLI Azure PowerShell Azure Developer CLI Interactive browser Broker
Deployed service
CREDENTIAL TYPES
2 Workload If the app is deployed to an Azure host with Workload Identity Yes
Identity enabled, authenticate that account.
3 Managed If the app is deployed to an Azure host with Managed Identity Yes
Identity enabled, authenticate the app to Azure using that Managed Identity.
5 Visual Studio If the developer authenticated via Visual Studio Code's Azure Yes
Code Resources extension and the azure-identity-broker package is
installed, authenticate that account.
6 Azure CLI If the developer authenticated to Azure using Azure CLI's az login Yes
command, authenticate the app to Azure using that same account.
8 Azure If the developer authenticated to Azure using Azure Developer CLI's Yes
Developer azd auth login command, authenticate with that account.
CLI
10 Broker Authenticates using the default account logged into the OS via a Yes
broker. Requires that the azure-identity-broker package is
installed, since an instance of InteractiveBrowserBrokerCredential
is used.
In its simplest form, you can use the parameterless version of DefaultAzureCredential as
follows:
Python
from [Link] import DefaultAzureCredential
from [Link] import BlobServiceClient
blob_service_client = BlobServiceClient(
account_url="[Link]
credential=credential
)
Python
credential = DefaultAzureCredential(
exclude_environment_credential=True,
exclude_workload_identity_credential=True,
managed_identity_client_id=user_assigned_client_id
)
Managed Identity Shared Token Cache Visual Studio Code Azure CLI Azure PowerShell Azure Developer CLI Broker
7 Note
DefaultAzureCredential constructor.
As more exclude -prefixed keyword parameters are set to True (credential exclusions are
configured), the advantages of using DefaultAzureCredential diminish. In such cases,
ChainedTokenCredential is a better choice and requires less code. To illustrate, these two code
DefaultAzureCredential
Python
credential = DefaultAzureCredential(
exclude_environment_credential=True,
exclude_workload_identity_credential=True,
exclude_shared_token_cache_credential=True,
exclude_visual_studio_code_credential=True,
exclude_azure_powershell_credential=True,
exclude_azure_developer_cli_credential=True,
exclude_broker_credential=True,
managed_identity_client_id=user_assigned_client_id
)
Shared Token Cache Visual Studio Code Azure CLI Azure PowerShell Azure Developer CLI Broker
) Important
To ensure the environment variable is defined and set to a supported string, set parameter
require_envvar to True in the constructor:
Python
credential = DefaultAzureCredential(require_envvar=True)
comparison is performed in a case-insensitive manner. Valid string values for the environment
variable include:
AzureCliCredential
AzureDeveloperCliCredential
AzurePowerShellCredential
EnvironmentCredential
InteractiveBrowserCredential
ManagedIdentityCredential
VisualStudioCodeCredential
WorkloadIdentityCredential
) Important
To ensure the environment variable is defined and set to a supported string, set parameter
require_envvar to True in the constructor:
Python
credential = DefaultAzureCredential(require_envvar=True)
ChainedTokenCredential overview
ChainedTokenCredential is an empty chain to which you add credentials to suit your app's
needs. For example:
Python
credential = ChainedTokenCredential(
AzureCliCredential(),
AzureDeveloperCliCredential()
)
The preceding code sample creates a tailored credential chain comprised of two development-
time credentials. AzureCliCredential is attempted first, followed by
AzureDeveloperCliCredential , if necessary. In graphical form, the chain looks like this:
Tip
library, but with that convenience comes tradeoffs. Once you deploy your app to Azure, you
should understand the app's authentication requirements. For that reason, replace
DefaultAzureCredential with a specific TokenCredential implementation, such as
ManagedIdentityCredential .
Here's why:
Python
import logging
from [Link] import DefaultAzureCredential
Output
order.
The AzureCliCredential.get_token call succeeds and the output also indicates that
DefaultAzureCredential acquired a token from AzureCliCredential . Since
7 Note
In the preceding example, the logging level is set to [Link] . Be careful when using
this logging level, as it can output sensitive information. For example, in this case, the
client ID, tenant ID, and the object ID of the developer's user principal in Azure. All
traceback information has been removed from the output for clarity.
Microsoft Entra ID, when used with Azure Key Vault, provides a robust and secure approach for
authenticating applications to both Azure services and third-party platforms that require access
keys or credentials. This combination eliminates the need to hardcode secrets in application
code, instead relying on managed identities, role-based access control (RBAC), and centralized
secret management via Key Vault. This approach streamlines identity management and
enhances security posture in cloud environments.
Communicate securely with other Azure services like Azure Storage, Cosmos DB, and
more
This article is part of a series that provides a detailed walkthrough of how to authenticate a
Python app with Microsoft Entra ID, Azure Key Vault, and Azure Queue Storage by using the
Azure Python SDK azure-identity library.
Part 1: Background
While many Azure services rely exclusively on role-based access control (RBAC), while others
require access via secrets or keys. Such services include Azure Storage, databases, Azure AI
services, Key Vault, and Event Hubs
When building cloud applications that interact with these services, developers can use the
Azure portal, CLI, or PowerShell to generate and configure service-specific access keys. These
keys are tied to particular access policies to prevent unauthorized access. However, this model
requires your application to manage keys explicitly and authenticate separately with each
service, a process that's both tedious and error-prone.
Embedding secrets directly in code or storing them on developer machines risks exposing
them in:
Source control
Insecure local environments
Accidental logs or configuration exports
Azure Offers Two Key Services to Improve Security and Simplify Authentication:
Azure Key Vault Azure Key Vault provides a secure, cloud-based store for secrets,
including access keys, connection strings, and certificates. By retrieving secrets from Key
Vault only at runtime, applications avoid exposing sensitive data in source code or
configuration files.
With Microsoft Entra managed identities, your application can authenticate once with
Microsoft Entra ID. From there, it can access other Azure services—including Key Vault—
without managing credentials directly.
This walkthrough shows how to use Microsoft Entra managed identity and Key Vault together
in the same app. By using Microsoft Entra ID and Key Vault together, your app never needs to
authenticate itself with individual Azure services, and can easily and securely access any keys
necessary for third-party services.
) Important
This article uses the common, generic term "key" to refer to what are stored as "secrets" in
Azure Key Vault, such as an access key for a REST API. This usage shouldn't be confused
with Key Vault's management of cryptographic keys, which is a separate feature from Key
Vault's secrets.
To generate its response, the API invokes a third-party API that requires an access key.
Instead of storing this key in code or configuration files, the app retrieves it securely at
runtime from Azure Key Vault using Microsoft Entra managed identity.
Before returning its response to the client, the app writes a message to an Azure Storage
Queue for asynchronous processing. The message could represent a task, log, or signal,
though the downstream processing isn't the focus of this scenario.
7 Note
Although public API endpoints are typically protected by their own access keys or
authentication mechanisms, this walkthrough assumes the endpoint is open and
unauthenticated.
The scenario focuses solely on the app's behavior and doesn't demonstrate or involve an
external caller authenticating with the endpoint.
In this example scenario, the main application has three distinct authentication requirements:
The application must authenticate with Azure Key Vault in order to retrieve a securely
stored API key needed to call a third-party service.
Third-party API
Once the API key is retrieved, the application uses it to authenticate with the external
third-party API.
After processing the request, the application must authenticate with Azure Queue Storage
to enqueue a message for asynchronous or deferred processing.
The application uses Azure Key Vault to securely store secrets, such as third-party API
keys or Azure Storage credentials. However, to retrieve those secrets, the app must first
authenticate with Key Vault. This creates a circular problem: The app needs credentials to
access Key Vault, but those credentials must themselves be stored securely. Without a
secure solution, this could lead to hardcoded credentials or insecure configurations in
development environments.
Failure to follow these practices increases the risk of credential leakage or unauthorized
use.
To write messages to Azure Queue Storage, the app typically needs a connection string or
shared access token. These credentials:
Must be stored in a secure location, such as Key Vault
Must not appear in logs, stack traces, or developer tools
Should be accessed only through secure runtime mechanisms
Require proper RBAC configuration if using managed identity
Environment Flexibility
The app must run reliably in both local development and cloud production environments,
using the same codebase and minimal conditional logic.
This means:
No environment-specific secrets embedded in the code
No need to manually toggle credentials or logic paths
Consistent use of identity-based authentication across environments
No secrets in code
Applications no longer require hardcoded connection strings, client secrets, or keys.
Azure can automatically assign a managed identity to your app, allowing secure access to
services, such as Key Vault, Storage, and SQL without additional credentials.
Environment consistency
The same code and identity model work both in local development and Azure-hosted
environments using the Azure SDK’s DefaultAzureCredential.
Azure environment
When the application is deployed to Azure:
In both environments, Azure SDKs use the DefaultAzureCredential , which abstracts away the
identity source and selects the right method automatically.
Use Key Vault to store third-party API keys and other secrets.
Assign managed identity to your deployed app.
Use a service principal for local development and assign it the same access rights.
Use DefaultAzureCredential in your code to abstract authentication logic.
Avoid storing or logging any credentials.
This flow ensures that your app can securely access Azure services without embedding secrets
in code or configuration files. It also allows you to seamlessly switch between local
development and cloud deployment without changing your authentication logic.
In our example scenario, the main application consumes a third-party API that is secured with
an access key. This section demonstrates the API using Azure Functions, but the same
principles apply regardless of how or where the API is implemented—whether you host the
application on another cloud provider or a traditional web server.
The key aspect is that any client requests to the protected endpoint must include the access
key, which the app must manage securely. This section provides an overview of how to
implement such an API using Azure Functions, but you can adapt the principles to your specific
needs.
If the access key is valid, the endpoint returns a JSON response that contains a single property,
"value", the value of which is a number between 1 and 999, such as {"value": 959} .
The endpoint is implemented in Python and deployed to Azure Functions. The code is as
follows:
Python
import logging
import random
import json
To deploy the code, the sample's provisioning script performs the following steps:
1. Create a backing storage account for Azure Functions with the Azure CLI command, az
storage account create for managing state and internal operations.
2. Create an Azure Functions app with the Azure CLI command, az function app create.
3. After waiting 60 seconds for the host to be fully provisioned, deploy the code using the
Azure Functions Core Tools command, func azure functionapp publish.
4. Assign the access key, d0c5atM1cr0s0ft , to the function. (See Securing Azure Functions
for a background on function keys.)
In the provisioning script, this step is accomplished using the az functionapp function
keys set Azure CLI command.
Comments are included to show how to do this step through a REST API call to the
Functions Key Management API if desired. To call that REST API, another REST API call
must be done first to retrieve the Function app's master key.
You can also assign access keys through the Azure portal . On the page for the Functions app,
select Functions, then select the specific function to secure (which is named RandomNumber in
this example). On the function's page, select Function Keys to open the page where you can
create and manage these keys.
The main app in our scenario is a simple Flask app that's deployed to Azure App Service. The
app provides a public API endpoint named /api/v1/getcode, which generates a code for some
other purpose in the app (for example, with two-factor authentication for human users). The
main app also provides a simple home page that displays a link to the API endpoint.
1. Create the App Service host and deploy the code with the Azure CLI command, az
webapp up.
2. Create an Azure Storage account for the main app (using az storage account create).
3. Create a Queue in the storage account named "code-requests" (using az storage queue
create).
4. To ensure that the app is allowed to write to the queue, use az role assignment create to
assign the "Storage Queue Data Contributor" role to the app. For more information about
roles, see How to assign role permissions using the Azure CLI.
The main app code is as follows; explanations of important details are given in the next parts of
this series.
Python
app = Flask(__name__)
[Link]["DEBUG"] = True
number_url = [Link]["THIRD_PARTY_API_ENDPOINT"]
# Next, get the client for the Key Vault. You must have first enabled managed
identity
# on the App Service for the credential to authenticate with Key Vault.
key_vault_url = [Link]["KEY_VAULT_URL"]
keyvault_client = SecretClient(vault_url=key_vault_url, credential=credential)
# Obtain the secret: for this step to work you must add the app's service
principal to
# the key vault's access policies for secret management.
api_secret_name = [Link]["THIRD_PARTY_API_SECRET_NAME"]
vault_secret = keyvault_client.get_secret(api_secret_name)
# The "secret" from Key Vault is an object with multiple properties. The key we
# want for the third-party API is in the value property.
access_key = vault_secret.value
@[Link]('/', methods=['GET'])
def home():
return f'Home page of the main app. Make a request to <a
href="./api/v1/getcode">/api/v1/getcode</a>.'
def random_char(num):
return ''.join([Link](string.ascii_letters) for x in range(num))
@[Link]('/api/v1/getcode', methods=['GET'])
def get_code():
headers = {
'Content-Type': 'application/json',
'x-functions-key': access_key
}
if (r.status_code != 200):
return "Could not get you a code.", r.status_code
data = [Link]()
chars1 = random_char(3)
chars2 = random_char(3)
code_value = f"{chars1}-{data['value']}-{chars2}"
code = { "code": code_value, "timestamp" : str([Link]()) }
# Log a queue message with the code for, say, a process that invalidates
# the code after a certain period of time.
queue_client.send_message(code)
return jsonify(code)
if __name__ == '__main__':
[Link]()
This section reviews the Python libraries imported by the main application and the
environment variables it depends on. When the app is deployed to Azure, these environment
variables are supplied through Application Settings in Azure App Service.
These dependencies are included in the app’s [Link] file and are installed during
deployment or local setup.
txt
flask
requests
[Link]
[Link]
[Link]
When you deploy the app to Azure App Service, Azure automatically installs these
requirements on the host server. When running locally, you install them in your environment
with pip install -r [Link] .
The code file starts with the required import statements for the parts of the libraries used in the
code:
Python
Environment variables
The app code depends on these four environment variables:
ノ Expand table
Variable Value
KEY_VAULT_URL The URL of the Azure Key Vault in which you stored the access key for
the third-party API.
THIRD_PARTY_API_SECRET_NAME The name of the secret in Key Vault that contains the access key for
the third-party API.
STORAGE_QUEUE_URL The URL of an Azure Storage Queue that you configure in Azure, such
as [Link]
requests (see Part 4). Because the queue name is included at the end
of the URL, you don't see the name anywhere in the code.
How you set these variables depends on where the code is running:
When running the code locally, you create these variables within whatever command shell
you're using (such as PowerShell, Bash, or CMD). (If you deploy the app to a virtual
machine, you would create similar server-side variables.) You can also use a library like
python-dotenv , which reads key-value pairs from an .env file and sets them as
environment variables
When the code is deployed to Azure App Service, as is shown in this walkthrough, you
don't have access to the server itself. Instead, you define application settings with the
same names in the App Service configuration. These settings are automatically exposed
to the application as environment variables.
The provisioning scripts create these settings using the Azure CLI command, az webapp config
appsettings set. All four variables are set with a single command.
To create settings through the Azure portal, see Configure an App Service app in the Azure
portal.
When running the code locally, you also need to specify environment variables that contain
information about your local service principal. DefaultAzureCredential looks for these values.
When deployed to App Service, you don't need to set these values as the app's system-
assigned managed identity is used instead to authenticate.
ノ Expand table
Variable Value
AZURE_CLIENT_SECRET A client secret that was generated for the App Registration.
For more information, see Authenticate Python apps to Azure services during local
development using service principals.
Immediately following the import statements, the app's startup code initializes key variables
used throughout the request-handling functions.
First, the application creates the Flask app object, which serves as the foundation for defining
routes and handling incoming HTTP requests. Next, it retrieves the third-party API endpoint
URL from an environment variable. This allows the endpoint to be easily configured without
modifying the codebase:
Python
app = Flask(__name__)
[Link]["DEBUG"] = True
number_url = [Link]["THIRD_PARTY_API_ENDPOINT"]
Next, it obtains the DefaultAzureCredential object, which is the recommended credential to use
when authenticating with Azure services. See Authenticate Azure hosted applications with
DefaultAzureCredential.
Python
credential = DefaultAzureCredential()
When run locally, DefaultAzureCredential looks for the AZURE_TENANT_ID , AZURE_CLIENT_ID , and
AZURE_CLIENT_SECRET environment variables that contain information for the service principal
that you're using for local development. When run in Azure, DefaultAzureCredential defaults
to using the system-assigned managed identity enabled on the app. It's possible to override
the default behavior with application settings, but in this example scenario, we use the default
behavior.
The code next retrieves the third-party API's access key from Azure Key Vault. In the
provisioning script, the Key Vault is created using az keyvault create, and the secret is stored
with az keyvault secret set.
The Key Vault resource itself is accessed through a URL, which is loaded from the
KEY_VAULT_URL environment variable.
Python
key_vault_url = [Link]["KEY_VAULT_URL"]
To retrieve a secret from Azure Key Vault, the application must create a client object that
communicates with the Key Vault service. Since the goal is to read a secret, the app uses the
SecretClient class from the [Link] library. This client requires two inputs:
Python
Creating a SecretClient object does not immediately authenticate the application. The client is
simply a local construct that stores the Key Vault URL and the credential object. Authentication
and authorization happen only when you invoke an operation through the client, such as
get_secret, which generates a REST API call to the Azure resource.
Python
api_secret_name = [Link]["THIRD_PARTY_API_SECRET_NAME"]
vault_secret = keyvault_client.get_secret(api_secret_name)
# The "secret" from Key Vault is an object with multiple properties. The key we
# want for the third-party API is in the value property.
access_key = vault_secret.value
Even if an application's identity is authorized to access Azure Key Vault, it must also be
explicitly authorized to perform specific operations—such as reading secrets. Without this
permission, a call to get_secret() fails, even if the identity is otherwise valid. To address this,
the provisioning script sets a "get secrets" access policy for the app using the Azure CLI
command, az keyvault set-policy. For more information, see Key Vault Authentication and
Grant your app access to Key Vault. The latter article shows how to set an access policy using
the Azure portal. (The article is also written for managed identity, but applies equally to a
service principle used in local development.)
Finally, the app code sets up the client object through which it can write messages to an Azure
Storage Queue. The Queue's URL is in the environment variable STORAGE_QUEUE_URL .
Python
queue_url = [Link]["STORAGE_QUEUE_URL"]
queue_client = QueueClient.from_queue_url(queue_url=queue_url,
credential=credential)
As with Azure Key Vault, the application uses a specific client object from the Azure SDK to
interact with Azure Queue Storage. In this case, it uses the QueueClient class from the azure-
storage-queue library.
To initialize the client, the app uses the from_queue_url method, providing the queue’s fully
qualified URL and a credential object. This credential object is again the
DefaultAzureCredential instance created earlier, which represents the identity under which the
app is running.
As noted earlier in this guide, that authorization is granted by assigning the “Storage Queue
Data Contributor” role to the application's identity - either a managed identity in Azure or a
service principal during local development. This role assignment is done in the provisioning
script using the Azure CLI command az role assignment create.
Assuming all this startup code succeeds, the app has all its internal variables in place to
support its /api/v1/getcode API endpoint.
The app URL path /api/v1/getcode for the API generates a JSON response that contains an
alphanumerical code and a timestamp.
First, the @[Link] decorator tells Flask that the get_code function handles requests to the
/api/v1/getcode URL.
Python
@[Link]('/api/v1/getcode', methods=['GET'])
def get_code():
Next, the app calls the third-party API, the URL of which is in number_url , providing the access
key that it retrieves from the key vault in the header.
Python
headers = {
'Content-Type': 'application/json',
'x-functions-key': access_key
}
if (r.status_code != 200):
return "Could not get you a code.", r.status_code
The example third-party API is deployed to the serverless environment of Azure Functions. The
x-functions-key property in the header is how Azure Functions expects an access key to
appear in a header. For more information, see Azure Functions HTTP trigger - Authorization
keys. If calling the API fails for any reason, the code returns an error message and the status
code.
Assuming that the API call succeeds and returns a numerical value, the app then constructs a
more complex code using that number plus some random characters (using its own
random_char function).
Python
data = [Link]()
chars1 = random_char(3)
chars2 = random_char(3)
code_value = f"{chars1}-{data['value']}-{chars2}"
code = { "code": code_value, "timestamp" : str([Link]()) }
The code variable here contains the full JSON response for the app's API, which includes the
code value and a timestamp. An example response would be {"code":"ojE-161-
pTv","timestamp":"2020-04-15 16:54:48.816549"} .
Before it returns that response, however, it writes a message in the storage queue using the
Queue client's send_message method:
Python
queue_client.send_message(code)
return jsonify(code)
Typically, an app like the one in this example would have another process that asynchronously
pulls messages from the queue for further processing. As mentioned previously, the response
generated by this API endpoint might be used elsewhere in the app with two-factor user
authentication. In that case, the app should invalidate the code after a certain period of time,
for example 10 minutes. A simple way to do this task would be to maintain a table of valid two-
factor authentication codes, which are used by its user sign-in procedure. The app would then
have a simple queue-watching process with the following logic (in pseudo-code):
pseudo
An alternate deployment option is the serverless environment of Azure Functions. In this case,
all the startup code and the API endpoint code would be contained within the same function
that's bound to an HTTP trigger. As with App Service, you use function application settings to
create environment variables for your code.
One piece of the implementation that becomes easier is authenticating with Queue Storage.
Instead of obtaining a QueueClient object using the queue's URL and a credential object, you
create a queue storage binding for the function. The binding handles all the authentication
behind the scenes. With such a binding, your function is given a ready-to-use client object as a
parameter. For more information and example code, see Connect Azure Functions to Azure
Queue Storage.
Next steps
Through this tutorial, you learned how apps authenticate with other Azure services using
managed identity, and how apps can use Azure Key Vault to store any other necessary secrets
for third-party APIs.
The same pattern demonstrated here with Azure Key Vault and Azure Storage applies with all
other Azure services. The crucial step is that you assign the correct role for the app within that
service's page on the Azure portal, or through the Azure CLI. (See How to assign Azure roles).
Be sure to check the service documentation to see whether you need to configure any other
access policies.
Always remember that you need to assign the same roles and access policies to any service
principal you're using for local development.
In short, having completed this walkthrough, you can apply your knowledge to any number of
other Azure services and any number of other external services.
One subject that we haven't touched upon in this tutorial is authentication of users. To explore
this area for web apps, begin with Authenticate and authorize users end-to-end in Azure App
Service.
See also
How to authenticate and authorize Python apps on Azure
Walkthrough sample: [Link]/Azure-Samples/python-integrated-authentication
Microsoft Entra documentation
Azure Key Vault documentation
Authorization in the Azure SDK libraries for
Python
07/11/2025
Authorization in Azure determines what actions authenticated users or services can perform on
resources. This article explores how to implement authorization using the Azure SDK for
Python, covering models, implementation, troubleshooting, and best practices. For detailed
authentication setup, refer to Authenticate Python apps to Azure.
Introduction
Authentication (AuthN) verifies the identity of a user or service, while authorization (AuthZ)
defines what they can do. In Azure, authorization ensures secure access to resources, critical for
protecting applications and data. Developers can implement robust authorization with the
Azure SDK for Python to control access in various workflows, from managing resources to
accessing service-specific data.
Service-specific mechanisms
Some Azure services offer unique authorization methods:
Azure Storage: Uses Shared Access Signatures (SAS) and Access Control Lists (ACLs) for
data access. See Service-Specific Authorization Notes for Azure Storage.
Azure Key Vault: Recommends RBAC over legacy access policies. See Service-Specific
Authorization Notes for Azure Key Vault.
Microsoft Graph: Employs OAuth 2.0 scopes and application permissions. See Service-
Specific Authorization Notes for Microsoft Graph.
identity can successfully list resource groups. If the identity lacks the Reader or higher role on
the subscription or resource group scope, this call returns a 403 Forbidden error.
Python
credential = DefaultAzureCredential()
client = ResourceManagementClient(credential, "<subscription-id>")
resource_groups = client.resource_groups.list()
for rg in resource_groups:
print([Link])
Replace <subscription-id> with your Azure subscription ID, which is usually in the form of
00000000-0000-0000-0000-000000000000 .
This example demonstrates how the SDK uses a credential to request an access token with the
required authorization scope [Link] and access Microsoft
Graph resources. The identity must be authorized in Microsoft Entra ID with appropriate
application permissions (such as [Link] ) to retrieve user data; otherwise, the request
fails with a 403 Forbidden.
) Important
Ensure your app or identity has the [Link] or other required permissions granted
in Microsoft Entra ID.
Python
credential = DefaultAzureCredential()
client = GraphClient(credential=credential, scopes=
["[Link]
response = [Link]("/users")
users = [Link]().get("value", [])
for user in users:
print(user["displayName"])
Learn more about this SDK in the official Build Python apps with Microsoft Graph tutorial.
Check Error Messages: Review the response for details on missing permissions.
Python
import logging
[Link](level=[Link])
Verify Access: Use Azure CLI or the Azure portal to check role assignments:
Azure CLI
Replace <principal-id> with the object ID of your user, service principal, or managed
identity. Replace <scope> with an Azure resource scope, such as a subscription ID, a
resource group name, or a resource. See Work with scopes.
Work with scopes
Often you'll need to provide a scope, like in the example:
Azure CLI
ノ Expand table
Subscription /subscriptions/<subscription-id>
Resource /subscriptions/<subscription-id>/resourceGroups/<resource-group-name>
Group
Resource /subscriptions/<subscription-id>/resourceGroups/<resource-group-
Name name>/providers/<provider-namespace>/<resource-type>/<resource-name>
For example, to list all role assignments for a managed identity at the resource group level:
Azure CLI
Azure CLI
You can retrieve the object ID ( <principal-id> ) of a user or managed identity using:
Azure CLI
Manage access
Manage access through role assignments using:
Azure portal: Add roles via the "Access control (IAM)" service menu
Azure CLI:
Azure CLI
Replace <principal-id> with the object ID of your user, service principal, or managed
identity. Replace <scope> with an Azure resource scope, such as a subscription ID, a
resource group name, or a resource name. See Work with scopes.
For managed identities, assign roles to the identity associated with resources like virtual
machines. Use the Azure portal's "Check access" feature or the Azure CLI to verify effective
permissions.
Azure Storage
RBAC: Manages control plane operations.
SAS and ACLs: Control data plane access, with Microsoft Entra authentication also
supported.
credential = DefaultAzureCredential()
client = BlobServiceClient(account_url="[Link]
name>.[Link]", credential=credential)
containers = client.list_containers()
for container in containers:
print([Link])
credential = DefaultAzureCredential()
client = SecretClient(vault_url="[Link]
credential=credential)
secret = client.get_secret("my-secret")
print([Link])
Microsoft Graph
Uses OAuth 2.0 scopes for delegated permissions and application permissions for daemon
apps. Specify scopes as shown in the earlier example.
Best practices
Least privilege: Assign only necessary permissions (for example, Reader instead of
Contributor).
Prefer RBAC: Especially for Key Vault, for unified access control.
Use Managed Identities: Avoid managing credentials in code.
Limit Graph permissions: Request specific scopes to minimize risks.
Next steps
Azure Role-Based Access Control (RBAC)
Azure CLI Reference
Azure SDK for Python Overview
Azure Key Vault RBAC Guide
Microsoft Graph Permissions Reference
How to install Azure library packages
for Python
Article • 02/05/2025
The Azure SDK for Python is composed of many individual libraries that can be installed
in standard Python or conda environments.
Libraries for standard Python environments are listed in the package index.
With these Azure libraries, you can create and manage resources on Azure services
(using the management libraries, whose package names begin with azure-mgmt ) and
connect with those resources from app code (using the client libraries, whose package
names begin with just azure- ).
pip install retrieves the latest version of a package in your current Python
environment.
On Linux systems, you must install a package for each user separately. Installing
packages for all users with sudo pip install isn't supported.
You can use any package name listed in the package index. On the index page, look
in the Name column for the functionality you need, and then find and select the
PyPI link in the Package column.
You can find version numbers in the package index. On the index page, look in the
Name column for the functionality you need, and then find and select the PyPI link
in the Package column. For example, to install a version of the azure-storage-blob
package you can use: pip install azure-storage-blob==12.19.0 .
To install the latest preview of a package, include the --pre flag on the command
line.
You can use any package name listed in the package index.
You can also use pip freeze or pip list to see all the packages that are installed
in your current Python environment.
You can use any package name listed in the package index.
Uninstall a package
pip
To uninstall a package:
You can use any package name listed in the package index.
Feedback
Was this page helpful? Yes No
This example demonstrates how to use the Azure SDK management libraries in a Python script
to create a resource group. (The Equivalent Azure CLI command is given later in this article. If
you prefer to use the Azure portal, see Create resource groups.)
All the commands in this article work the same in Linux/macOS bash and Windows command
shells unless noted.
Configure a Python virtual environment using venv or your tool of choice. To start using
the virtual environment, be sure to activate it. To install python, see Install Python .
Bash
Azure CLI
#!/bin/bash
# Create a virtual environment
python -m venv .venv
# Activate the virtual environment
source .venv/Scripts/activate # only required for Windows (Git Bash)
Azure CLI
azure-mgmt-resource
azure-identity
2. In your console with the virtual environment activated, install the requirements:
Console
Bash
Azure CLI
#!/bin/bash
export AZURE_RESOURCE_GROUP_NAME=<ResourceGroupName> # Change to your
preferred resource group name
export LOCATION=<Location> # Change to your preferred region
export AZURE_SUBSCRIPTION_ID=$(az account show --query id --output tsv)
Create a Python file named provision_rg.py with the following code. The comments explain the
details:
Python
# Import the needed credential and management objects from the libraries.
import os
print(
f"Provisioned resource group {rg_result.name} in the {rg_result.location}
region"
)
# The return value is another ResourceGroup object with all the details of the
# new group. In this case the call is synchronous: the resource group has been
# provisioned by the time the call returns.
# To update the resource group, repeat the call with different properties, such
# as tags:
rg_result = resource_client.resource_groups.create_or_update(
RESOURCE_GROUP_NAME,
{
"location": LOCATION,
"tags": {"environment": "test", "department": "tech"},
},
)
To use this code in a production environment, authenticate using a service principal by setting
environment variables. This approach enables secure, automated access without relying on
interactive login. For detailed guidance, see How to authenticate Python apps with Azure
services.
Ensure that the service principal is assigned a role with sufficient permissions to create resource
groups and storage accounts. For example, assigning the Contributor role at the subscription
level provides the necessary access. To learn more about role assignments, see Role-based
access control (RBAC) in Azure.
Azure CLI
az login
python provision_rg.py
Azure portal: open the Azure portal , select Resource groups, and check that the group
is listed. If necessary, use the Refresh command to update the list.
Azure CLI: use the az group show command:
Bash
Azure CLI
#!/bin/bash
az group show -n $AZURE_RESOURCE_GROUP_NAME
7: Clean up resources
Run the az group delete command if you don't need to keep the resource group created in this
example. Resource groups don't incur any ongoing charges in your subscription, but resources
in the resource group might continue to incur charges. It's a good practice to clean up any
group that you aren't actively using. The --no-wait argument allows the command to return
immediately instead of waiting for the operation to finish.
Bash
Azure CLI
#!/bin/bash
az group delete -n $AZURE_RESOURCE_GROUP_NAME --no-wait
Azure CLI
See also
Example: List resource groups in a subscription
Example: Create Azure Storage
Example: Use Azure Storage
Example: Create a web app and deploy code
Example: Create and query a database
Example: Create a virtual machine
Use Azure Managed Disks with virtual machines
Complete a short survey about the Azure SDK for Python
Example: Use the Azure libraries to list
resource groups and resources
Article • 04/23/2025
This example demonstrates how to use the Azure SDK management libraries in a Python script
to perform two tasks:
All the commands in this article work the same in Linux/macOS bash and Windows command
shells unless noted.
The Equivalent Azure CLI commands are listed later in this article.
Configure a Python virtual environment using venv or your tool of choice. To start using
the virtual environment, be sure to activate it. To install python, see Install Python .
Bash
Azure CLI
#!/bin/bash
# Create a virtual environment
python -m venv .venv
# Activate the virtual environment
source .venv/Scripts/activate # only required for Windows (Git Bash)
txt
azure-mgmt-resource
azure-identity
In a terminal or command prompt with the virtual environment activated, install the
requirements:
Console
Python
# Import the needed credential and management objects from the libraries.
from [Link] import DefaultAzureCredential
from [Link] import ResourceManagementClient
import os
By default, the code lists resources in "myResourceGroup". To use a different resource group,
set the RESOURCE_GROUP_NAME environment variable to the desired group name.
Python
# Import the needed credential and management objects from the libraries.
from [Link] import DefaultAzureCredential
from [Link] import ResourceManagementClient
import os
print("Resource".ljust(column_width) + "Type".ljust(column_width)
+ "Create date".ljust(column_width) + "Change date".ljust(column_width))
print("-" * (column_width * 4))
To use such code in a production script, you can set environment variables to use a service
principal-based method for authentication. To learn more, see How to authenticate Python
apps with Azure services. You need to ensure that the service principal has sufficient
permissions to create and list resource groups in your subscription by assigning it an
appropriate role in Azure; for example, the Contributor role on your subscription.
Azure CLI
az login
2. Set the AZURE_SUBSCRIPTION_ID environment variable to your subscription ID. (You can run
the az account show command and get your subscription ID from the id property in the
output):
Bash
Bash
export AZURE_SUBSCRIPTION_ID=00000000-0000-0000-0000-000000000000
Console
python list_groups.py
Console
python list_resources.py
Azure CLI
az group list
The following command lists resources within the "myResourceGroup" in the centralus region
(the location argument is necessary to identify a specific data center):
Azure CLI
See also
Example: Provision a resource group
Example: Provision Azure Storage
Example: Use Azure Storage
Example: Provision a web app and deploy code
Example: Provision and query a database
Example: Provision a virtual machine
Use Azure Managed Disks with virtual machines
Complete a short survey about the Azure SDK for Python
Example: Create Azure Storage using the
Azure libraries for Python
05/30/2025
In this article, you learn how to use the Azure management libraries for Python to create a
resource group, along with an Azure Storage account and a Blob storage container.
After provisioning these resources, refer to the section Example: Use Azure Storage to see how
to use the Azure client libraries in Python to upload a file to the Blob container.
The Equivalent Azure CLI commands for bash and PowerShell are listed later in this article. If
you prefer to use the Azure portal, see Create an Azure storage account and Create a blob
container.
Configure a Python virtual environment using venv or your tool of choice. To start using
the virtual environment, be sure to activate it. To install python, see Install Python .
Bash
Azure CLI
#!/bin/bash
# Create a virtual environment
python -m venv .venv
# Activate the virtual environment
source .venv/Scripts/activate # only required for Windows (Git Bash)
azure-mgmt-resource
azure-mgmt-storage
azure-identity
2. In your console with the virtual environment activated, install the requirements:
Console
Bash
Azure CLI
#!/bin/bash
export AZURE_RESOURCE_GROUP_NAME=<ResourceGroupName> # Change to your
preferred resource group name
export LOCATION=<Location> # Change to your preferred region
export AZURE_SUBSCRIPTION_ID=$(az account show --query id --output tsv)
export STORAGE_ACCOUNT_NAME=<StorageAccountName> # Change to your preferred
storage account name
export CONTAINER_NAME=<ContainerName> # Change to your preferred container
name
Python
import os, random
# Import the needed management objects from the libraries. The [Link]
library
# is installed automatically with the other libraries.
from [Link] import DefaultAzureCredential
from [Link] import ResourceManagementClient
from [Link] import StorageManagementClient
from [Link] import BlobContainer
rg_result = resource_client.resource_groups.create_or_update(RESOURCE_GROUP_NAME,
{ "location": LOCATION })
# For details on the previous code, see Example: Provision a resource group
# at [Link]
group
STORAGE_ACCOUNT_NAME = [Link]["STORAGE_ACCOUNT_NAME"]
# Check if the account name is available. Storage account names must be unique
across
# Azure because they're used in URLs.
availability_result = storage_client.storage_accounts.check_name_availability(
{ "name": STORAGE_ACCOUNT_NAME }
)
if not availability_result.name_available:
print(f"Storage name {STORAGE_ACCOUNT_NAME} is already in use. Try another
name.")
exit()
# Step 3: Retrieve the account's primary access key and generate a connection
string.
keys = storage_client.storage_accounts.list_keys(RESOURCE_GROUP_NAME,
STORAGE_ACCOUNT_NAME)
conn_string =
f"DefaultEndpointsProtocol=https;EndpointSuffix=[Link];AccountName=
{STORAGE_ACCOUNT_NAME};AccountKey={[Link][0].value}"
# Step 4: Provision the blob container in the account (this call is synchronous)
CONTAINER_NAME = [Link]["CONTAINER_NAME"]
container = storage_client.blob_containers.create(RESOURCE_GROUP_NAME,
STORAGE_ACCOUNT_NAME, CONTAINER_NAME, BlobContainer())
To use this code in a production environment, authenticate using a service principal by setting
environment variables. This approach enables secure, automated access without relying on
interactive login. For detailed guidance, see How to authenticate Python apps with Azure
services.
Ensure that the service principal is assigned a role with sufficient permissions to create resource
groups and storage accounts. For example, assigning the Contributor role at the subscription
level provides the necessary access. To learn more about role assignments, see Role-based
access control (RBAC) in Azure.
Reference links for classes used in the code
DefaultAzureCredential ([Link])
ResourceManagementClient ([Link])
StorageManagementClient ([Link])
Azure CLI
az login
Console
python provision_blob.py
3. If you want to try using these resources from application code, continue with Example:
Use Azure Storage.
For another example of using the Azure Storage management library, see the Manage Python
Storage sample.
7: Clean up resources
Leave the resources in place if you want to follow the article Example: Use Azure Storage to use
these resources in app code. Otherwise, run the az group delete command if you don't need to
keep the resource group and storage resources created in this example.
Resource groups don't incur any ongoing charges in your subscription, but resources, like
storage accounts, in the resource group might incur charges. It's a good practice to clean up
any group that you aren't actively using. The --no-wait argument allows the command to
return immediately instead of waiting for the operation to finish.
Bash
Azure CLI
#!/bin/bash
az group delete -n $AZURE_RESOURCE_GROUP_NAME --no-wait
Bash
Azure CLI
#!/bin/bash
#!/bin/bash
# Set variables
export LOCATION=<Location> # Change to your preferred region
export AZURE_RESOURCE_GROUP_NAME=<ResourceGroupName> # Change to your
preferred resource group name
export STORAGE_ACCOUNT_NAME=<StorageAccountName> # Change to your preferred
storage account name
export CONTAINER_NAME=<ContainerName> # Change to your preferred container
name
See also
Example: Use Azure Storage
Example: Create a resource group
Example: List resource groups in a subscription
Example: Create a web app and deploy code
Example: Create and query a database
Example: Create a virtual machine
Use Azure Managed Disks with virtual machines
Complete a short survey about the Azure SDK for Python
Example: Access Azure Storage using the
Azure libraries for Python
09/22/2025
In this article, you learn how to use the Azure client libraries in Python application code to
upload a file to an Azure Blob storage container. The article assumes you created the resources
shown in Example: Create Azure Storage.
All the commands in this article work the same in Linux/macOS bash and Windows command
shells unless noted.
Configure a Python virtual environment using venv or your tool of choice. To start using
the virtual environment, be sure to activate it. To install python, see Install Python .
Bash
Azure CLI
#!/bin/bash
# Create a virtual environment
python -m venv .venv
# Activate the virtual environment
source .venv/Scripts/activate # only required for Windows (Git Bash)
txt
azure-storage-blob
azure-identity
Console
txt
Hello there, Azure Storage. I'm a friendly file ready to be stored in a blob.
The Connection string method uses a connection string to access the storage account
directly.
For the following reasons and more, we recommend using the passwordless method whenever
possible:
A connection string authenticates the connecting agent with the Storage account rather
than with individual resources within that account. As a result, a connection string grants
broader authorization than might be needed. With DefaultAzureCredential you can grant
more granular, least privileged permissions over your storage resources to the identity
your app runs under using Azure RBAC.
A connection string contains access info in plain text and therefore presents potential
vulnerabilities if not properly constructed or secured. If such a connection string is
exposed, it can be used to access a wide range of resources within the Storage account.
Passwordless (Recommended)
In the following steps, you configure an application service principal as the application
identity. Application service principals are suitable for use both during local development
and for apps hosted on-premises. To configure DefaultAzureCredential to use the
application service principal, you set the following environment variables:
AZURE_CLIENT_ID , AZURE_TENANT_ID , and AZURE_CLIENT_SECRET .
Notice that a client secret is configured. A client secret is necessary for an application
service principal, but, depending on your scenario, you can also configure
DefaultAzureCredential to use credentials that don't require setting a secret or password
in an environment variable.
1. Create a file named use_blob_auth.py with the following code. The comments explain
the steps.
Python
import os
import uuid
credential = DefaultAzureCredential()
# Create the client object using the storage URL and the credential
blob_client = BlobClient(
storage_url,
container_name="blob-container-01",
blob_name=f"sample-blob-{str(uuid.uuid4())[0:5]}.txt",
credential=credential,
)
Reference links:
DefaultAzureCredential ([Link])
BlobClient ([Link])
bash
Bash
AZURE_STORAGE_BLOB_URL=[Link]
[Link]
3. Use the az ad sp create-for-rbac command to create a new service principal for the
app. The command creates the app registration for the app at the same time. Give
the service principal a name of your choosing.
Azure CLI
az ad sp create-for-rbac --name <service-principal-name>
The output of this command looks like the following JSON snippet. Make note of
these values or keep this window open as you'll need these values in the next step
and won't be able to view the password (client secret) value again. You can, however,
add a new password later without invalidating the service principal or existing
passwords if needed.
JSON
{
"appId": "00001111-aaaa-2222-bbbb-3333cccc4444",
"displayName": "<service-principal-name>",
"password": "Aa1Bb~2Cc3.-Dd4Ee5Ff6Gg7Hh8Ii9_Jj0Kk1Ll2",
"tenant": "aaaabbbb-0000-cccc-1111-dddd2222eeee"
}
Azure CLI commands can be run in the Azure Cloud Shell or on a workstation with
the Azure CLI installed.
Create the following environment variables with the values from the output of the
previous command. These variables tell DefaultAzureCredential to use the
application service principal.
bash
Bash
AZURE_CLIENT_ID=00001111-aaaa-2222-bbbb-3333cccc4444
AZURE_TENANT_ID=aaaabbbb-0000-cccc-1111-dddd2222eeee
AZURE_CLIENT_SECRET=Aa1Bb~2Cc3.-Dd4Ee5Ff6Gg7Hh8Ii9_Jj0Kk1Ll2
Console
python use_blob_auth.py
6. Observe the error "This request is not authorized to perform this operation using this
permission." The error is expected because the local service principal that you're
using doesn't yet have permission to access the blob container.
7. Grant Storage Blob Data Contributor permissions on the blob container to the service
principal using the az role assignment create Azure CLI command:
Azure CLI
The --scope argument identifies where this role assignment applies. In this example,
you grant the "Storage Blob Data Contributor" role to the service principal for the
container named "blob-container-01".
Tip
If the role assignment command returns an error "No connection adapters were
found" when using bash shell, try setting export MSYS_NO_PATHCONV=1 to avoid
path translation. For more information, see this issue .
8. Wait a minute or two for the permissions to propagate, then run the code again to
verify that it now works. If you see the permissions error again, wait a little longer,
then try the code again.
For more information on role assignments, see How to assign role permissions using the
Azure CLI.
) Important
In the preceding steps, your app ran under an application service principal. An
application service principal requires a client secret in its configuration. However, you
can use the same code to run the app under different credential types that don't
require you to explicitly configure a password or secret in the environment. For
example, during development, DefaultAzureCredential can use developer tool
credentials like the credentials you use to sign in via the Azure CLI; or, for apps hosted
in Azure, it can use a managed identity. To learn more, see Authenticate Python apps
to Azure services by using the Azure SDK for Python.
Azure CLI
If you followed the instructions to use passwordless authentication, you can add the --
connection-string parameter to the preceding command with the connection string for your
storage account. To get the connection string, use the az storage account show-connection-
string command.
Azure CLI
Use the entire connection string as the value for the --connection-string parameter.
7 Note
If your Azure user account has the "Storage Blob Data Contributor" role on the container,
you can use the following command to list the blobs in the container:
Azure CLI
6. Clean up resources
Run the az group delete command if you don't need to keep the resource group and storage
resources used in this example. Resource groups don't incur any ongoing charges in your
subscription, but resources, like storage accounts, in the resource group might continue to
incur charges. It's a good practice to clean up any group that you aren't actively using. The --
no-wait argument allows the command to return immediately instead of waiting for the
operation to finish.
Azure CLI
az group delete -n PythonAzureExample-Storage-rg --no-wait
If you followed the instructions to use passwordless authentication, it's a good idea to delete
the application service principal you created. You can use the az ad app delete command.
Replace the <AZURE_CLIENT_ID> placeholder with the app ID of your service principal.
Azure CLI
See also
Quickstart: Azure Blob Storage client library for Python
Example: Create a resource group
Example: List resource groups in a subscription
Example: Create a web app and deploy code
Example: Create Azure Storage
Example: Create and query a database
Example: Create a virtual machine
Use Azure Managed Disks with virtual machines
Complete a short survey about the Azure SDK for Python
Example: Use the Azure libraries to create
and deploy a web app
Article • 04/21/2025
This example shows how to use the Azure SDK management libraries in a Python script to
create and deploy a web app to Azure App Service, with the app code pulled from a GitHub
repository.
The Azure SDK for Python includes management libraries (namespaces beginning with azure-
mgmt ) that let you automate resource configuration and deployment — similar to what you can
do with the Azure portal, Azure CLI, or ARM templates. For examples, see Quickstart: Deploy a
Python (Django or Flask) web app to Azure App Service.
Configure a Python virtual environment using venv or your tool of choice. You can create
the virtual environment locally or in Azure Cloud Shell and run the code there. Be sure
to activate the virtual environment to start using it. To install python, see Install Python .
Bash
txt
azure-mgmt-resource
azure-mgmt-web
azure-identity
In your local development environment, install the requirements using the following code:
Console
2. Next, create an environment variable named REPO_URL and set it to the URL of your
forked repository. This variable is required by the example code in the next section.
bash
Bash
export REPO_URL=<url_of_your_fork>
export AZURE_SUBSCRIPTION_ID=<subscription_id>
Python
import random, os
from [Link] import AzureCliCredential
from [Link] import ResourceManagementClient
from [Link] import WebSiteManagementClient
# Constants we need in multiple places: the resource group name and the region
# in which we provision resources. You can change these values however you want.
RESOURCE_GROUP_NAME = 'PythonAzureExample-WebApp-rg'
LOCATION = "centralus"
rg_result = resource_client.resource_groups.create_or_update(RESOURCE_GROUP_NAME,
{ "location": LOCATION })
# For details on the previous code, see Example: Provision a resource group
# at [Link]
group
#Step 2: Provision the App Service plan, which defines the underlying VM for the
web app.
# Names for the App Service plan and App Service. We use a random number with the
# latter to create a reasonably unique name. If you've already provisioned a
# web app and need to re-run the script, set the WEB_APP_NAME environment
# variable to that name instead.
SERVICE_PLAN_NAME = 'PythonAzureExample-WebApp-plan'
WEB_APP_NAME = [Link]("WEB_APP_NAME", f"PythonAzureExample-WebApp-
{[Link](1,100000):05}")
plan_result = [Link]()
# Step 3: With the plan in place, provision the web app itself, which is the
process that can host
# whatever code we want to deploy to it.
poller = app_service_client.web_apps.begin_create_or_update(RESOURCE_GROUP_NAME,
WEB_APP_NAME,
{
"location": LOCATION,
"server_farm_id": plan_result.id,
"site_config": {
"linux_fx_version": "python|3.8"
}
}
)
web_app_result = [Link]()
# Step 4: deploy code from a GitHub repository. For Python code, App Service on
Linux runs
# the code inside a container that makes certain assumptions about the structure
of the code.
# For more information, see How to configure Python apps,
# [Link]
#
# The create_or_update_source_control method doesn't provision a web app. It only
sets the
# source control configuration for the app. In this case we're simply pointing to
# a GitHub repository.
#
# You can call this method again to change the repo.
REPO_URL = [Link]["REPO_URL"]
poller =
app_service_client.web_apps.begin_create_or_update_source_control(RESOURCE_GROUP_N
AME,
WEB_APP_NAME,
{
"location": "GitHub",
"repo_url": REPO_URL,
"branch": "master",
"is_manual_integration": True
}
)
sc_result = [Link]()
# Step 5: Deploy the code using the repository and branch configured in the
previous step.
#
# If you push subsequent code changes to the repo and branch, you must call this
method again
# or use another Azure tool like the Azure CLI or Azure portal to redeploy.
# Note: By default, the method returns None.
app_service_client.web_apps.sync_repository(RESOURCE_GROUP_NAME, WEB_APP_NAME)
print(f"Deploy code")
To use such code in a production script (for example, to automate VM management), use
DefaultAzureCredential (recommended) with a service principal based method as described in
How to authenticate Python apps with Azure services.
python provision_deploy_web_app.py
Azure CLI
Replace the web app name ( --name ) with the value generated by the script. You don’t need to
change the resource group name ( --resource-group ) unless you changed it in the script. When
you open the site, you should see “Hello, World!” in your browser.
Tip
If you don't see the expected output, wait a few minutes and try again.
You can redeploy your code using the Azure CLI by running the az webapp deployment source
sync command:
Azure CLI
You don’t need to change the resource group name ( --resource-group ) unless you changed it
in the script.
8: Clean up resources
Azure CLI
You do not need to change resource group name ( --resource-group option) unless you
changed it in the script.
If you no longer need the resource group created in this example, you can delete it by running
the az group delete command. While resource groups don’t incur ongoing charges, it’s a good
practice to clean up any unused resources. Use the --no-wait argument to immediately return
control to the command line without waiting for the deletion to complete.
See also
Example: Create a resource group
Example: List resource groups in a subscription
Example: Create Azure Storage
Example: Use Azure Storage
Example: Create and query a MySQL database
Example: Create a virtual machine
Use Azure Managed Disks with virtual machines
Complete a short survey about the Azure SDK for Python
Example: Use the Azure libraries to create a
database
05/30/2025
This example demonstrates how to use the Azure SDK for Python management libraries to
programmatically create an Azure Database for MySQL flexible server and a corresponding
database. It also includes a basic script that uses the mysql-connector-python library (not part
of the Azure SDK) to connect to and query the database.
You can adapt this example to create an Azure Database for PostgreSQL flexible server by
modifying the relevant SDK imports and API calls.
If you prefer to use the Azure CLI, Equivalent Azure CLI commands are provided later in this
article. For a graphical experience, refer to the Azure portal documentation:
Unless otherwise specified, all examples and commands work consistently across Linux/macOS
bash and Windows command shells.
Configure a Python virtual environment using venv or your tool of choice. To start using
the virtual environment, be sure to activate it. To install python, see Install Python .
Bash
Azure CLI
#!/bin/bash
# Create a virtual environment
python -m venv .venv
# Activate the virtual environment
source .venv/Scripts/activate # only required for Windows (Git Bash)
1. In your console, create a [Link] file that lists the management libraries used in
this example:
Azure CLI
azure-mgmt-resource
azure-mgmt-rdbms
azure-identity
mysql-connector-python
7 Note
The mysql-connector-python library isn't part of the Azure SDK. It's a third-party
library that you can use to connect to MySQL databases. You can also use other
libraries, such as PyMySQL or SQLAlchemy , to connect to MySQL databases.
2. In your console with the virtual environment activated, install the requirements:
Console
7 Note
On Windows, attempting to install the mysql library into a 32-bit Python library
produces an error about the mysql.h file. In this case, install a 64-bit version of
Python and try again.
Bash
Azure CLI
#!/bin/bash
export AZURE_RESOURCE_GROUP_NAME=<ResourceGroupName> # Change to your
preferred resource group name
export LOCATION=<Location> # Change to your preferred region
export AZURE_SUBSCRIPTION_ID=$(az account show --query id --output tsv)
export PUBLIC_IP_ADDRESS=$(curl -s [Link]
export DB_SERVER_NAME=<DB_Server_Name> # Change to your preferred DB server
name
export DB_ADMIN_NAME=<DB_Admin_Name> # Change to your preferred admin name
export DB_ADMIN_PASSWORD=<DB_Admin_Passwrod> # Change to your preferred admin
password
export DB_NAME=<DB_Name> # Change to your preferred database name
export DB_PORT=3306
export version=ServerVersion.EIGHT0_21
Python
import random, os
from [Link] import DefaultAzureCredential
from [Link] import ResourceManagementClient
from [Link].mysql_flexibleservers import MySQLManagementClient
from [Link].mysql_flexibleservers.models import Server, ServerVersion
rg_result = resource_client.resource_groups.create_or_update(RESOURCE_GROUP_NAME,
{ "location": LOCATION })
# Retrieve server name, admin name, and admin password from environment variables
db_server_name = [Link]("DB_SERVER_NAME")
db_admin_name = [Link]("DB_ADMIN_NAME")
db_admin_password = [Link]("DB_ADMIN_PASSWORD")
poller = mysql_client.servers.begin_create(RESOURCE_GROUP_NAME,
db_server_name,
Server(
location=LOCATION,
administrator_login=db_admin_name,
administrator_login_password=db_admin_password,
version=ServerVersion[server_version] # Note: dictionary-style enum
access
)
)
server = [Link]()
RULE_NAME = "allow_ip"
ip_address = [Link]["PUBLIC_IP_ADDRESS"]
firewall_rule = [Link]()
db_result = [Link]()
For use in production environments, we recommend that you authenticate with a service
principal by setting the appropriate environment variables. This approach enables secure, non-
interactive access suitable for automation. For setup instructions, see How to authenticate
Python apps with Azure services.
Ensure the service principal is assigned a role with adequate permissions—such as the
Contributor role at the subscription or resource group level. For details on assigning roles, refer
to Role-based access control (RBAC) in Azure.
PostgreSQLManagementClient ([Link].postgresql_flexibleservers)
Azure CLI
az login
python provision_db.py
This code works only for MySQL; you use different libraries for PostgreSQL.
Python
import os
import [Link]
db_server_name = [Link]["DB_SERVER_NAME"]
db_admin_name = [Link]("DB_ADMIN_NAME")
db_admin_password = [Link]("DB_ADMIN_PASSWORD")
db_name = [Link]("DB_NAME")
db_port = [Link]("DB_PORT")
connection = [Link](user=db_admin_name,
password=db_admin_password, host=f"
{db_server_name}.[Link]",
port=db_port, database=db_name,
ssl_ca='./[Link]')
cursor = [Link]()
"""
# Alternate pyodbc connection; include pyodbc in [Link]
import pyodbc
connect_string = f"DRIVER={driver};PORT=3306;SERVER=
{db_server_name}.[Link];" \
f"DATABASE={DB_NAME};UID={db_admin_name};PWD=
{db_admin_password}"
connection = [Link](connect_string)
"""
table_name = "ExampleTable1"
sql_create = f"CREATE TABLE {table_name} (name varchar(255), code int)"
[Link](sql_create)
print(f"Successfully created table {table_name}")
[Link](sql_insert)
print("Successfully inserted data into table")
[Link](sql_select_values)
row = [Link]()
while row:
print(str(row[0]) + " " + str(row[1]))
row = [Link]()
[Link]()
All of this code uses the [Link] API. The only Azure-specific part is the full host
domain for MySQL server ([Link]).
2. Next, download the certificate needed to communicate over TSL/SSL with your Azure
Database for MySQL server. For more information, see Obtain an SSL Certificate in the
Azure Database for MySQL documentation.
Bash
Azure CLI
#!/bin/bash
# Download Baltimore CyberTrust Root certificate required for Azure MySQL
SSL connections
CERT_URL="[Link]
m"
CERT_FILE="[Link]"
echo "Downloading SSL certificate..."
curl -o "$CERT_FILE" "$CERT_URL"
Console
python use_db.py
If you see an error that your client IP address isn't allowed, check that you defined the
environment variable PUBLIC_IP_ADDRESS correctly. If you already created the MySQL server
with the wrong IP address, you can add another in the Azure portal . In the portal, select the
MySQL server, and then select Connection security. Add the IP address of your workstation to
the list of allowed IP addresses.
7: Clean up resources
Run the az group delete command if you don't need to keep the resource group and storage
resources created in this example.
Resource groups don't incur any ongoing charges in your subscription, but resources, like
storage accounts, in the resource group might continue to incur charges. It's a good practice to
clean up any group that you aren't actively using. The --no-wait argument allows the
command to return immediately instead of waiting for the operation to finish.
Bash
Azure CLI
#!/bin/bash
az group delete -n $AZURE_RESOURCE_GROUP_NAME --no-wait
Bash
Azure CLI
#!/bin/bash
#!/bin/bash
# Set variables
export LOCATION=<Location> # Change to your preferred region
export AZURE_RESOURCE_GROUP_NAME=<ResourceGroupName> # Change to your
preferred resource group name
export DB_SERVER_NAME=<DB_Server_Name> # Change to your preferred DB server
name
export DB_ADMIN_NAME=<DB_Admin_Name> # Change to your preferred admin name
export DB_ADMIN_PASSWORD=<DB_Admin_Password> # Change to your preferred admin
password
export DB_NAME=<DB_Name> # Change to your preferred database name
export DB_SERVER_VERSION="5.7"
See also
Example: Create a resource group
Example: List resource groups in a subscription
Example: Create Azure Storage
Example: Use Azure Storage
Example: Create and deploy a web app
Example: Create a virtual machine
Use Azure Managed Disks with virtual machines
Complete a short survey about the Azure SDK for Python
Example: Use the Azure libraries to create a
virtual machine
06/11/2025
In this article, you learn how to use the Azure SDK management libraries in a Python script to
create a resource group that contains a Linux virtual machine.
The Equivalent Azure CLI commands are listed later in this article. If you prefer to use the Azure
portal, see Create a Linux VM and Create a Windows VM.
7 Note
Creating a virtual machine through code is a multi-step process that involves provisioning
a number of other resources that the virtual machine requires. If you're simply running
such code from the command line, it's much easier to use the az vm create command,
which automatically provisions these secondary resources with defaults for any setting you
choose to omit. The only required arguments are a resource group, VM name, image
name, and login credentials. For more information, see Quick Create a virtual machine
with the Azure CLI.
Azure CLI
#!/bin/bash
# Create a virtual environment
python -m venv .venv
# Activate the virtual environment
source .venv/Scripts/activate # only required for Windows (Git Bash)
txt
azure-mgmt-resource
azure-mgmt-compute
azure-mgmt-network
azure-identity
Console
Python
# Import the needed credential and management objects from the libraries.
import os
print(
"Provisioning a virtual machine...some operations might take a \
minute or two."
)
print(
f"Provisioned resource group {rg_result.name} in the \
{rg_result.location} region"
)
vnet_result = [Link]()
print(
f"Provisioned virtual network {vnet_result.name} with address \
prefixes {vnet_result.address_space.address_prefixes}"
)
print(
f"Provisioned virtual subnet {subnet_result.name} with address \
prefix {subnet_result.address_prefix}"
)
ip_address_result = [Link]()
print(
f"Provisioned public IP address {ip_address_result.name} \
with address {ip_address_result.ip_address}"
)
nic_result = [Link]()
print(
f"Provisioning virtual machine {VM_NAME}; this operation might \
take a few minutes."
)
poller = compute_client.virtual_machines.begin_create_or_update(
RESOURCE_GROUP_NAME,
VM_NAME,
{
"location": LOCATION,
"storage_profile": {
"image_reference": {
"publisher": "Canonical",
"offer": "UbuntuServer",
"sku": "16.04.0-LTS",
"version": "latest",
}
},
"hardware_profile": {"vm_size": "Standard_DS1_v2"},
"os_profile": {
"computer_name": VM_NAME,
"admin_username": USERNAME,
"admin_password": PASSWORD,
},
"network_profile": {
"network_interfaces": [
{
"id": nic_result.id,
}
]
},
},
)
vm_result = [Link]()
Ensure that the service principal is assigned a role with sufficient permissions to create resource
groups and storage accounts. For example, assigning the Contributor role at the subscription
level provides the necessary access. To learn more about role assignments, see Role-based
access control (RBAC) in Azure.
Azure CLI
az login
2. Set the AZURE_SUBSCRIPTION_ID environment variable to your subscription ID. (You can run
the az account show command and get your subscription ID from the id property in the
output):
Azure CLI
Console
python provision_vm.py
You can also use the Azure CLI to verify that the VM exists with the az vm list command:
Azure CLI
If you get an error about capacity restrictions, you can try a different size or region. For more
information, see Resolve errors for SKU not available.
6: Clean up resources
Leave the resources in place if you want to continue to use the virtual machine and network
you created in this article. Otherwise, run the az group delete command to delete the resource
group.
Resource groups don't incur any ongoing charges in your subscription, but resources
contained in the group, like virtual machines, might continue to incur charges. It's a good
practice to clean up any group that you aren't actively using. The --no-wait argument allows
the command to return immediately instead of waiting for the operation to finish.
Azure CLI
See also
Example: Create a resource group
Example: List resource groups in a subscription
Example: Create Azure Storage
Example: Use Azure Storage
Example: Create a web app and deploy code
Example: Create and query a database
Use Azure Managed Disks with virtual machines
Complete a short survey about the Azure SDK for Python
The following resources contain more comprehensive examples using Python to create a virtual
machine:
Azure Managed Disks are high-performance, durable block storage designed for use with
Azure Virtual Machines and Azure VMware Solution. They simplify disk management, offer
greater scalability, enhance security, and eliminate the need to manage storage accounts
directly. For more information, see Azure Managed Disks.
For operations on Managed Disks associated with an existing VM, use the azure-mgmt-
compute library.
The code examples in this article demonstrate common operations with Managed Disks using
the azure-mgmt-compute library. These examples are not meant to be run as standalone scripts,
but rather to be integrated into your own code. To learn how to create a
ComputeManagementClient instance from [Link] in your script, see Example -
For more complete examples of how to use the azure-mgmt-compute library, see Azure SDK for
Python samples for compute in GitHub.
Python
poller = compute_client.disks.begin_create_or_update(
'my_resource_group',
'my_disk_name',
{
'location': 'eastus',
'disk_size_gb': 20,
'creation_data': {
'create_option': [Link]
}
}
)
disk_resource = [Link]()
Python
poller = compute_client.disks.begin_create_or_update(
'my_resource_group',
'my_disk_name',
{
'location': 'eastus',
'creation_data': {
'create_option': [Link],
'storage_account_id': '/subscriptions/<subscription-
id>/resourceGroups/<resource-group-
name>/providers/[Link]/storageAccounts/<storage-account-name>',
'source_uri': '[Link]
name>.[Link]/vm-images/[Link]'
}
}
)
disk_resource = [Link]()
Python
poller = compute_client.images.begin_create_or_update(
'my_resource_group',
'my_image_name',
{
'location': 'eastus',
'storage_profile': {
'os_disk': {
'os_type': 'Linux',
'os_state': [Link],
'blob_uri': '[Link]
name>.[Link]/vm-images/[Link]',
'caching': "ReadWrite",
},
},
'hyper_v_generation': HyperVGeneration.V2,
}
)
image_resource = [Link]()
Python
poller = compute_client.disks.begin_create_or_update(
'my_resource_group',
'my_disk_name',
{
'location': 'eastus',
'creation_data': {
'create_option': [Link],
'source_resource_id': managed_disk.id
}
}
)
disk_resource = [Link]()
A Managed Disk is created implicitly when creating a VM from an OS image in Azure. Azure
automatically handles the storage account, so you don't need to specify
storage_profile.os_disk or create a storage account manually.
Python
storage_profile = [Link](
image_reference = [Link](
publisher='Canonical',
offer='UbuntuServer',
sku='16.04-LTS',
version='latest'
)
)
For a complete example showing how to create a virtual machine using the Azure management
libraries for Python, see Example - Create a virtual machine. This example demonstrates how to
use the storage_profile parameter.
Python
storage_profile = [Link](
image_reference = [Link](
id = [Link]
)
)
Python
vm = compute_client.virtual_machines.get(
'my_resource_group',
'my_vm'
)
managed_disk = compute_client.[Link]('my_resource_group', 'myDisk')
vm.storage_profile.data_disks.append({
'lun': 12, # You choose the value, depending of what is available for you
'name': managed_disk.name,
'create_option': [Link],
'managed_disk': {
'id': managed_disk.id
}
})
async_update = compute_client.virtual_machines.begin_create_or_update(
'my_resource_group',
[Link],
vm,
)
async_update.wait()
With Azure Managed Disks, storage account management is no longer required. As a result,
the storage_profile for Virtual Machine Scale Sets used for Virtual Machine Scale Sets can
now match the one used for individual VM creation:
Python
'storage_profile': {
'image_reference': {
"publisher": "Canonical",
"offer": "UbuntuServer",
"sku": "16.04-LTS",
"version": "latest"
}
},
Python
naming_infix = "PyTestInfix"
vmss_parameters = {
'location': [Link],
"overprovision": True,
"upgrade_policy": {
"mode": "Manual"
},
'sku': {
'name': 'Standard_A1',
'tier': 'Standard',
'capacity': 5
},
'virtual_machine_profile': {
'storage_profile': {
'image_reference': {
"publisher": "Canonical",
"offer": "UbuntuServer",
"sku": "16.04-LTS",
"version": "latest"
}
},
'os_profile': {
'computer_name_prefix': naming_infix,
'admin_username': 'Foo12',
'admin_password': 'BaR@123!!!!',
},
'network_profile': {
'network_interface_configurations' : [{
'name': naming_infix + 'nic',
"primary": True,
'ip_configurations': [{
'name': naming_infix + 'ipconfig',
'subnet': {
'id': [Link]
}
}]
}]
}
}
}
Python
async_update = self.compute_client.disks.begin_create_or_update(
'my_resource_group',
'myDisk',
managed_disk
)
async_update.wait()
Update the storage account type of the Managed Disks
This example shows how to change the storage type of a Managed Disk and make it larger.
This is helpful when you need more space or better performance for your data or applications.
Python
async_update = self.compute_client.disks.begin_create_or_update(
'my_resource_group',
'myDisk',
managed_disk
)
async_update.wait()
Python
async_create_image = compute_client.images.create_or_update(
'my_resource_group',
'myImage',
{
'location': 'eastus',
'storage_profile': {
'os_disk': {
'os_type': 'Linux',
'os_state': "Generalized",
'blob_uri': '[Link]
name>.[Link]/vm-images/[Link]',
'caching': "ReadWrite",
}
}
}
)
image = async_create_image.result()
Python
async_snapshot_creation = self.compute_client.snapshots.begin_create_or_update(
'my_resource_group',
'mySnapshot',
{
'location': 'eastus',
'creation_data': {
'create_option': 'Copy',
'source_uri': managed_disk.id
}
}
)
snapshot = async_snapshot_creation.result()
See also
Example: Create a virtual machine
Example: Create a resource group
Example: List resource groups in a subscription
Example: Create Azure Storage
Example: Use Azure Storage
Example: Create and use a MySQL database
Complete a short survey about the Azure SDK for Python
Configure logging in the Azure libraries for
Python
Azure Libraries for Python that are based on [Link] provide logging output using the
standard Python logging library.
1. Acquire the logging object for the desired library and set the logging level.
2. Register a handler for the logging stream.
3. To include HTTP information, pass a logging_enable=True parameter to a client object
constructor, a credential object constructor, or to a specific method.
As a general rule, the best resource for understanding logging usage within the libraries is to
browse the SDK source code at [Link]/Azure/azure-sdk-for-python . We encourage you
to clone this repository locally so you can easily search for details when needed, as the
following sections suggest.
import logging
# ...
This example acquires the logger for the [Link] library, then sets the
logging level to [Link] .
You can call [Link] at any time to change the logging level for different
segments of code.
To set a level for a different library, use that library's name in the [Link] call. For
example, the azure-eventhubs library provides a logger named [Link] , the azure-
storage-queue library provides a logger named [Link] , and so on. (The SDK
source code frequently uses the statement [Link](__name__) , which acquires a
logger using the name of the containing module.)
Python
import logging
The azure logger is used by some libraries instead of a specific logger. For example, the azure-
storage-blob library uses the azure logger.
You can use the [Link] method to check whether any given logging level is
enabled:
Python
print(
f"Logger enabled for ERROR={[Link]([Link])}, "
f"WARNING={[Link]([Link])}, "
f"INFO={[Link]([Link])}, "
f"DEBUG={[Link]([Link])}"
)
Logging levels are the same as the standard logging library levels . The following table
describes the general use of these logging levels in the Azure libraries for Python:
ノ Expand table
[Link] Failures where the application is unlikely to recover (such as out of memory).
[Link] A function fails to perform its intended task (but not when the function can
(default) recover, such as retrying a REST API call). Functions typically log a warning when
raising exceptions. The warning level automatically enables the error level.
[Link] Function operates normally or a service call is canceled. Info events typically
include requests, responses, and headers. The info level automatically enables the
error and warning levels.
Logging level Typical use
[Link] Detailed information that is commonly used for troubleshooting and includes a
stack trace for exceptions. The debug level automatically enables the info, warning,
and error levels. CAUTION: If you also set logging_enable=True , the debug level
includes sensitive information such as account keys in headers and other
credentials. Be sure to protect these logs to avoid compromising security.
The best way to examine the exact logging for a library is to search for the logging levels in the
Azure SDK for Python source code :
1. In the repository folder, navigate into the sdk folder, then navigate into the folder for the
specific service of interest.
_LOGGER.error
_LOGGER.warning
_LOGGER.info
_LOGGER.debug
Python
import logging
# Direct logging output to stdout. Without adding a handler,
# no logging output is visible.
handler = [Link](stream=[Link])
[Link](handler)
This example registers a handler that directs log output to stdout. You can use other types of
handlers as described on [Link] in the Python documentation or use the standard
[Link] method.
Enable HTTP logging for a client object or
operation
By default, logging within the Azure libraries doesn't include any HTTP information. To include
HTTP information in log output, you must explicitly pass logging_enable=True to a client or
credential object constructor or to a specific method.
U Caution
HTTP logging can include sensitive information such as account keys in headers and other
credentials. Be sure to protect these logs to avoid compromising security.
Python
from [Link] import BlobClient
from [Link] import DefaultAzureCredential
# Enable HTTP logging on the client object when using DEBUG level
# endpoint is the Blob storage URL.
client = BlobClient(endpoint, DefaultAzureCredential(), logging_enable=True)
Enabling HTTP logging for a client object enables logging for all operations invoked through
that object.
Python
from [Link] import BlobClient
from [Link] import DefaultAzureCredential
# Enable HTTP logging on the credential object when using DEBUG level
credential = DefaultAzureCredential(logging_enable=True)
Enabling HTTP logging for a credential object enables logging for all operations invoked
through that object, but not for operations in a client object that don't involve authentication.
# Enable HTTP logging for only this operation when using DEBUG level
client.create_container("container01", logging_enable=True)
Python
import logging
import os
import sys
import uuid
logger = [Link]("azure")
[Link]([Link])
print(
f"Logger enabled for ERROR={[Link]([Link])}, "
f"WARNING={[Link]([Link])}, "
f"INFO={[Link]([Link])}, "
f"DEBUG={[Link]([Link])}"
)
try:
credential = DefaultAzureCredential()
storage_url = [Link]["AZURE_STORAGE_BLOB_URL"]
unique_str = str(uuid.uuid4())[0:5]
# Enable logging on the client object
blob_client = BlobClient(
storage_url,
container_name="blob-container-01",
blob_name=f"sample-blob-{unique_str}.txt",
credential=credential,
)
except (
[Link],
[Link]
) as e:
print([Link])
Output
Logger enabled for ERROR=True, WARNING=True, INFO=True, DEBUG=True
Request URL: '[Link]
01/[Link]'
Request method: 'PUT'
Request headers:
'Content-Length': '77'
'x-ms-blob-type': 'BlockBlob'
'If-None-Match': '*'
'x-ms-version': '2023-11-03'
'Content-Type': 'application/octet-stream'
'Accept': 'application/xml'
'User-Agent': 'azsdk-python-storage-blob/12.19.0 Python/3.10.11 (Windows-10-
10.0.22631-SP0)'
'x-ms-date': 'Fri, 19 Jan 2024 19:25:53 GMT'
'x-ms-client-request-id': '8f7b1b0b-b700-11ee-b391-782b46f5c56b'
'Authorization': '*****'
Request body:
b"Hello there, Azure Storage. I'm a friendly file ready to be stored in a blob."
Response status: 201
Response headers:
'Content-Length': '0'
'Content-MD5': 'SUytm0872jZh+KYqtgjbTA=='
'Last-Modified': 'Fri, 19 Jan 2024 19:25:54 GMT'
'ETag': '"0x8DC1924749AE3C3"'
'Server': 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0'
'x-ms-request-id': '7ac499fa-601e-006d-3f0d-4bdf28000000'
'x-ms-client-request-id': '8f7b1b0b-b700-11ee-b391-782b46f5c56b'
'x-ms-version': '2023-11-03'
'x-ms-content-crc64': 'rtHLUlztgxc='
'x-ms-request-server-encrypted': 'true'
'Date': 'Fri, 19 Jan 2024 19:25:53 GMT'
Response content:
b''
7 Note
If you get an authorization error, make sure the identity you're running under is assigned
the "Storage Blob Data Contributor" role on your blob container. To learn more, see Use
blob storage from app code (Passwordless tab).
If your organization requires the use of a proxy server to access internet resources, you need to
set an environment variable with the proxy server information to use the Azure SDK for Python.
Setting the environment variables (HTTP_PROXY and HTTPS_PROXY) causes the Azure SDK for
Python to use the proxy server at run time.
You can obtain your proxy information from your IT/network team, from your browser, or from
network utilities.
You can then configure a proxy globally by using environment variables, or you can specify a
proxy by passing an argument named proxies to an individual client constructor or operation
method.
Global configuration
To configure a proxy globally for your script or app, define HTTP_PROXY or HTTPS_PROXY
environment variables with the server URL. These variables work with any version of the Azure
libraries. Note that HTTPS_PROXY doesn't mean HTTPS proxy, but the proxy for https://
requests.
These environment variables are ignored if you pass the parameter use_env_settings=False to
a client object constructor or operation method.
cmd
Python
import os
[Link]["HTTP_PROXY"] = "[Link]
Custom configuration
For example, the following code from the article Example: use Azure storage specifies an
HTTPS proxy with user credentials with the BlobClient constructor. In this case, the object
comes from the [Link] library, which is based on [Link].
Python
storage_url = "[Link]
You can use the Azure libraries for Python to connect to all regions where Azure is available .
By default, the Azure libraries are configured to connect to the global Azure cloud.
AZURE_CHINA
AZURE_GOVERNMENT
AZURE_PUBLIC_CLOUD
When using DefaultAzureCredential, as shown in the following example, you can specify the
cloud by using the appropriate value from [Link] .
Python
import os
from [Link] import ResourceManagementClient, SubscriptionClient
from [Link] import DefaultAzureCredential, AzureAuthorityHosts
from [Link] import AzureClouds
authority = AzureAuthorityHosts.AZURE_CHINA
# When using sovereign domains (that is, any cloud other than AZURE_PUBLIC_CLOUD),
# you must use an authority with DefaultAzureCredential.
credential = DefaultAzureCredential(authority=authority)
resource_client = ResourceManagementClient(
credential, subscription_id, cloud_setting=AzureClouds.AZURE_CHINA_CLOUD
)
subscription_client = SubscriptionClient(
credential, cloud_setting=AzureClouds.AZURE_CHINA_CLOUD
)
7 Note
The cloud_setting feature is newly added and is rolling out across Azure SDK
management libraries. During this period, some clients support it while others do not. To
check support, look for a cloud_setting parameter on the client constructor. If your
service's client doesn't expose cloud_setting yet, you can still target sovereign clouds
using the previous approach shown in the examples below.
Python
import os
from [Link] import ResourceManagementClient, SubscriptionClient
from [Link] import DefaultAzureCredential, AzureAuthorityHosts
authority = AzureAuthorityHosts.AZURE_CHINA
resource_manager = "[Link]
# When using sovereign domains (that is, any cloud other than AZURE_PUBLIC_CLOUD),
# you must use an authority with DefaultAzureCredential.
credential = DefaultAzureCredential(authority=authority)
resource_client = ResourceManagementClient(
credential,
subscription_id,
base_url=resource_manager,
credential_scopes=[resource_manager + "/.default"],
)
subscription_client = SubscriptionClient(
credential,
base_url=resource_manager,
credential_scopes=[resource_manager + "/.default"],
)
Python
import os
from [Link] import ResourceManagementClient, SubscriptionClient
from [Link] import DefaultAzureCredential
from [Link] import KnownProfiles
resource_client = ResourceManagementClient(
credential, subscription_id,
base_url=endpoint,
profile=KnownProfiles.v2019_03_01_hybrid,
credential_scopes=[audience])
subscription_client = SubscriptionClient(
credential,
base_url=endpoint,
profile=KnownProfiles.v2019_03_01_hybrid,
credential_scopes=[audience])
For example, for Azure Stack, you can use the az cloud show CLI command to return the details
of a registered cloud. The following output shows the values returned for the Azure public
cloud, but the output for an Azure Stack private cloud should be similar.
Output
{
"endpoints": {
"activeDirectory": "[Link]
"activeDirectoryDataLakeResourceId": "[Link]
"activeDirectoryGraphResourceId": "[Link]
"activeDirectoryResourceId": "[Link]
"appInsightsResourceId": "[Link]
"appInsightsTelemetryChannelResourceId":
"[Link]
"attestationResourceId": "[Link]
"azmirrorStorageAccountResourceId": null,
"batchResourceId": "[Link]
"gallery": "[Link]
"logAnalyticsResourceId": "[Link]
"management": "[Link]
"mediaResourceId": "[Link]
"microsoftGraphResourceId": "[Link]
"ossrdbmsResourceId": "[Link]
"portal": "[Link]
"resourceManager": "[Link]
"sqlManagement": "[Link]
"synapseAnalyticsResourceId": "[Link]
"vmImageAliasDoc": "[Link]
specs/main/arm-compute/quickstart-templates/[Link]"
},
"isActive": true,
"name": "AzureCloud",
"profile": "latest",
"suffixes": {
"acrLoginServerEndpoint": ".[Link]",
"attestationEndpoint": ".[Link]",
"azureDatalakeAnalyticsCatalogAndJobEndpoint": "[Link]",
"azureDatalakeStoreFileSystemEndpoint": "[Link]",
"keyvaultDns": ".[Link]",
"mariadbServerEndpoint": ".[Link]",
"mhsmDns": ".[Link]",
"mysqlServerEndpoint": ".[Link]",
"postgresqlServerEndpoint": ".[Link]",
"sqlServerHostname": ".[Link]",
"storageEndpoint": "[Link]",
"storageSyncEndpoint": "[Link]",
"synapseAnalyticsEndpoint": ".[Link]"
}
}
In the preceding code, you can set authority to the value of the [Link]
property, endpoint to the value of the [Link] property, and audience to
the value of [Link] property + ".default".
For more information, see Use Azure CLI with Azure Stack Hub and Get authentication
information for Azure Stack Hub.
Overview of Azure SDK for Python
fundamentals
The articles listed in the following table equip developers with the foundational concepts and
core behaviors that underpin every client library in the Azure SDK for Python. These subjects
are considered fundamentals because they establish the essential building blocks for effective,
idiomatic, and resilient application development across all Azure services.
Whether you work with HTTP retries, handle errors, understand SDK response types, or follow
consistent language design guidelines, these articles provide the baseline knowledge required
to confidently navigate and extend your use of the Azure SDK. Mastering these fundamentals
ensures that you write functional code that's also maintainable, robust, and aligned with best
practices across the Azure ecosystem.
ノ Expand table
Handle errors produced by the Describes the SDK's comprehensive error model. Includes best
Azure SDK for Python practices for handling specific exception types and implementing
resilient error-handling strategies.
HTTP pipeline and retries in the Provides a deep dive into the SDK's internal HTTP pipeline. Shows how
Azure SDK libraries for Python policies like retries, logging, and authentication are layered to manage
requests and responses.
Understand common response Explains how SDK methods return intuitive, strongly typed Python
types in the Azure SDK for objects to simplify how you work with Azure responses and long-
Python running operations.
Azure SDK Language Design Outlines the conventions and design patterns that are used across the
Guidelines for Python SDK to ensure consistency, usability, and alignment with Python best
practices.
The Azure SDK for Python provides a comprehensive error model designed to help developers
build resilient applications. Understanding this error model is crucial for:
This article explores the Azure SDK for Python's error architecture and provides practical
guidance for implementing effective error handling in your applications.
Exception hierarchy
AzureError
├── ClientAuthenticationError
├── ResourceNotFoundError
├── ResourceExistsError
├── ResourceModifiedError
├── ResourceNotModifiedError
├── ServiceRequestError
├── ServiceResponseError
└── HttpResponseError
ノ Expand table
Error Description
AzureError The base exception class for all Azure SDK errors. Use this exception as a
catchall when you need to handle any Azure-related error.
ResourceNotFoundError Raised when attempting to access a resource that doesn't exist. This
exception typically corresponds to HTTP 404 responses.
ResourceExistsError Raised when attempting to create a resource that already exists. This
exception helps prevent accidental overwrites.
ServiceRequestError Raised when the SDK can't send a request to the service. Common causes
include network connectivity issues, Domain Name System resolution
failures, and invalid service endpoints.
ServiceResponseError Raised when the service returns an unexpected response that the SDK can't
process.
HttpResponseError Raised for HTTP error responses (4xx and 5xx status codes). This exception
provides access to the underlying HTTP response details.
Python
from [Link] import ClientAuthenticationError
from [Link] import DefaultAzureCredential
from [Link] import BlobServiceClient
try:
credential = DefaultAzureCredential()
blob_service = BlobServiceClient(
account_url="[Link]
credential=credential
)
# Attempt to list containers
containers = blob_service.list_containers()
except ClientAuthenticationError as e:
print(f"Authentication failed: {[Link]}")
# Don't retry - fix credentials first
Authorization errors (typically HttpResponseError with 403 status) occur when you lack
permissions:
Python
from [Link] import HttpResponseError
try:
blob_client.upload_blob(data)
except HttpResponseError as e:
if e.status_code == 403:
print("Access denied. Check your permissions.")
else:
raise
Resource errors
Handle missing resources gracefully:
Python
try:
blob_client = container_client.get_blob_client("[Link]")
content = blob_client.download_blob().readall()
except ResourceNotFoundError:
print("Blob not found. Using default content.")
content = b"default"
Python
try:
container_client.create_container()
except ResourceExistsError:
print("Container already exists.")
# Continue with existing container
Server errors
Handle server-side failures appropriately:
Python
try:
result = client.process_data(large_dataset)
except HttpResponseError as e:
if 500 <= e.status_code < 600:
print(f"Server error ({e.status_code}). The service may be temporarily
unavailable.")
# Consider retry logic here
else:
raise
Python
from [Link] import (
AzureError,
ClientAuthenticationError,
ResourceNotFoundError,
HttpResponseError
)
try:
# Azure SDK operation
result = client.get_resource()
except ClientAuthenticationError:
# Handle authentication issues
print("Please check your credentials")
except ResourceNotFoundError:
# Handle missing resources
print("Resource not found")
except HttpResponseError as e:
# Handle specific HTTP errors
if e.status_code == 429:
print("Rate limited. Please retry later.")
else:
print(f"HTTP error {e.status_code}: {[Link]}")
except AzureError as e:
# Catch-all for other Azure errors
print(f"Azure operation failed: {e}")
Implement appropriate retry strategies: Some errors warrant retry attempts, while others
don't.
Python
try:
client.perform_operation()
except HttpResponseError as e:
# Extract detailed error information
print(f"Status code: {e.status_code}")
print(f"Error message: {[Link]}")
print(f"Error code: {[Link] if [Link] else 'N/A'}")
Python
from [Link] import BlobServiceClient
from [Link] import RetryPolicy
# Apply to client
blob_service = BlobServiceClient(
account_url="[Link]
credential=credential,
retry_policy=retry_policy
)
Python
from [Link] import ServiceRequestError
import time
Python
class CircuitBreaker:
def __init__(self, failure_threshold=5, recovery_timeout=60):
self.failure_threshold = failure_threshold
self.recovery_timeout = recovery_timeout
self.failure_count = 0
self.last_failure_time = None
[Link] = 'closed' # closed, open, half-open
try:
result = func(*args, **kwargs)
if [Link] == 'half-open':
[Link] = 'closed'
self.failure_count = 0
return result
except Exception as e:
self.failure_count += 1
self.last_failure_time = [Link]()
raise e
Python
from [Link] import HttpResponseError
import json
try:
client.create_resource(resource_data)
except HttpResponseError as e:
# Many Azure services return JSON error details
if [Link] and [Link]():
try:
error_detail = [Link]([Link]())
print(f"Error code: {error_detail.get('error', {}).get('code')}")
print(f"Error message: {error_detail.get('error',
{}).get('message')}")
Python
import logging
from [Link] import AzureError
logger = [Link](__name__)
try:
result = client.perform_operation()
except AzureError as e:
# Log comprehensive error information
[Link](
"Azure operation failed",
extra={
'error_type': type(e).__name__,
'error_message': str(e),
'operation': 'perform_operation',
'timestamp': [Link]().isoformat(),
'request_id': getattr([Link], 'headers', {}).get('x-ms-request-
id') if hasattr(e, 'response') else None
}
)
raise
Python
import logging
import sys
# Configure logging for Azure SDKs
[Link](level=[Link])
For more information about logging, see Configure logging in the Azure libraries for
Python.
) Important
HTTP logging can include sensitive information such as account keys in headers and
other credentials. Be sure to protect these logs to avoid compromising security.
Python
from [Link] import BlobServiceClient
Python
import asyncio
from [Link] import AzureError
Handle cancellations
Python
async def long_running_operation(client):
try:
result = await client.start_long_operation()
# Wait for completion
final_result = await [Link]()
return final_result
except [Link]:
print("Operation cancelled")
# Cleanup if necessary
if hasattr(result, 'cancel'):
await [Link]()
raise
except AzureError as e:
print(f"Operation failed: {e}")
raise
Python
async def process_multiple_resources(client, resource_ids):
tasks = []
for resource_id in resource_ids:
task = client.get_resource(resource_id)
[Link](task)
results = []
errors = []
return results
Anticipate failures: Cloud applications must expect and handle partial failures gracefully.
Use specific exception handling: Catch specific exceptions like ResourceNotFoundError
and ClientAuthenticationError before falling back to general AzureError handling.
Implement smart retry logic: Use built-in retry policies or customize them based on your
needs. Remember that not all errors should trigger retries.
Capture diagnostic information: Always log request IDs, error codes, and time stamps for
effective troubleshooting.
Provide meaningful user feedback: Transform technical errors into user-friendly
messages while you preserve technical details for support.
Test error scenarios: Include error handling in your test coverage to ensure that your
application behaves correctly under failure conditions.
Related content
Review the Azure Core exceptions Module reference.
Learn about troubleshooting authentication and authorization issues.
Explore Azure Monitor OpenTelemetry for comprehensive application monitoring.
Understanding how the HTTP pipeline works is essential for building robust, performant
applications. The pipeline:
This knowledge helps you debug performance issues, optimize resiliency, and customize your
application's interaction with Azure services.
ascii
Client Request → Retry Policy → Authentication Policy → Logging Policy → HTTP
Transport → Azure Service
↓
Client Response ← Retry Policy ← Authentication Policy ← Logging Policy ← HTTP
Transport ← Response
RetryPolicy : Automatically retries requests that fail because of transient errors. This
policy implements intelligent retry logic with exponential backoff to avoid overwhelming
services during outages.
BearerTokenCredentialPolicy : Manages authentication by automatically acquiring and
refreshing access tokens. This policy ensures that your requests include valid
authentication credentials without manual token management.
NetworkTraceLoggingPolicy : Captures detailed information about HTTP requests and
responses for debugging purposes. This policy is invaluable when you troubleshoot
communication issues.
HttpTransport : The lowest layer of the pipeline that actually sends HTTP requests over
the network. In the Azure SDK for Python, this policy is typically implemented by using
requests or aiohttp for asynchronous operations.
Other policies
RedirectPolicy : Handles HTTP redirects automatically.
DistributedTracingPolicy : Integrates with distributed tracing systems for monitoring.
Retry behavior
The Azure SDK for Python implements intelligent retry logic to handle transient failures
automatically. Understanding this behavior helps you build more resilient applications.
408 Request Timeout: The server timed out waiting for the request.
429 Too Many Requests: Rate limiting is in effect.
500 Internal Server Error: Temporary server issue.
502 Bad Gateway: Temporary network issue.
503 Service Unavailable: Service temporarily unavailable.
504 Gateway Timeout: Gateway or proxy timeout.
Default retry configuration
The default retry settings provide a good balance between resilience and performance:
Python
Customize retries
You can customize retry behavior when you create SDK clients to match your application's
specific requirements.
Python
Disable retries
For scenarios where retries aren't appropriate:
Python
from [Link] import RetryPolicy
client = BlobServiceClient(
account_url="[Link]
credential=credential,
retry_policy=no_retry_policy
)
Python
import logging
import sys
Output
Retry attempt 1 for request [GET]
[Link]
Waiting 0.8 seconds before retry
Common retry pitfalls
Retrying non-transient errors: The SDK doesn't retry client errors (4xx) except for 408
and 429.
Ignoring retry latency: Remember that retries add latency to failed operations.
Providing insufficient timeout: Ensure that your overall operation timeout accounts for
retry delays.
Python
from [Link] import PipelineRequest, PipelineResponse
from [Link] import HTTPPolicy
from typing import Any, Optional
class CustomTelemetryPolicy(HTTPPolicy):
"""Custom policy to add telemetry headers"""
return response
Python
from [Link] import BlobServiceClient
Policy ordering
Policies execute in a specific order:
Best practices
Customization guidelines
When you customize retry behavior:
Authentication failures (401, 403): Authentication errors require fixing credentials, not
retrying.
Client errors (400, 404): Client errors indicate problems with the request itself.
Business logic errors: Application-specific errors that don't resolve with retries.
Operational excellence
Log correlation IDs: Include x-ms-client-request-id in logs for Azure support.
Set appropriate timeouts: Balance between reliability and user experience.
Test retry behavior: Verify your application handles retries gracefully.
Monitor performance: Track P95/P99 latencies (percentile-based latency metrics)
including retry overhead.
Related content
Implement resilient applications
Azure SDK for Python makes HTTP requests and receives HTTP responses under the hood. The
SDK abstracts away this complexity so that you can work with intuitive Python objects instead
of raw HTTP responses or JSON payloads.
Understanding the types of objects that you receive from SDK operations is essential for
writing effective Azure applications. This article explains the common response types that you
encounter and how they relate to the underlying HTTP communication.
7 Note
This article examines only the HTTP scenario, not the AMQP scenario.
For example, when you retrieve a blob from Azure Storage, you receive a BlobProperties
object with attributes like name , size , and last_modified rather than a raw JSON dictionary:
Python
from [Link] import BlobServiceClient
Your code calls an SDK method: You invoke a method like get_blob_properties() .
The SDK constructs an HTTP request: The SDK builds the appropriate HTTP request with
headers, authentication, and query parameters.
The Azure service responds: The service returns an HTTP response, typically with a JSON
payload in the response body.
The SDK processes the response: The SDK:
Checks the HTTP status code.
Parses the response body (usually JSON).
Validates the data against expected schemas.
Maps the data to Python model objects.
Your code receives Python objects: You work with the deserialized objects, not raw HTTP
data.
This abstraction allows you to focus on your application logic rather than HTTP protocol
details.
Resource models
Most SDK operations return resource models. These Python objects represent Azure resources.
The models are service specific but follow consistent patterns:
Python
Python
blob_service_client = BlobServiceClient.from_connection_string(connection_string)
container_client = blob_service_client.get_container_client("mycontainer")
Python
from [Link] import SecretClient
def inspect_response(response):
# Access the raw HTTP response
print(f"Request URL: {response.http_request.url}")
print(f"Status code: {response.http_response.status_code}")
print(f"Response headers: {dict(response.http_response.headers)}")
Automatic pagination
The SDK automatically fetches new pages as you iterate:
Python
# List all blobs - could be thousands
blobs = container_client.list_blobs()
Python
blobs = container_client.list_blobs()
# Process by page
for page in blobs.by_page():
print(f"Processing page with {len(list(page))} items")
for blob in page:
process_blob(blob)
Control page size
Many list operations accept a results_per_page parameter:
Python
# Fetch 100 items per page instead of the default
blobs = container_client.list_blobs(results_per_page=100)
Some methods for some Azure services have other mechanisms for controlling page size. For
example, Azure Key Vault and Azure Search use the top kwarg to limit results per call. For an
example that uses the Azure Search search() method, see the source code .
These operations return poller objects that track the operation's progress.
Python
Asynchronous pollers
When you use async/await patterns, you work with AsyncLROPoller :
Python
from [Link] import BlobServiceClient
Python
from [Link] import ComputeManagementClient
from [Link] import LROPoller
Python
def page_response_hook(response):
continuation_token = response.http_response.[Link]('x-ms-continuation')
print(f"Continuation token: {continuation_token}")
return response
blobs = container_client.list_blobs()
for page in blobs.by_page(raw_response_hook=page_response_hook):
for blob in page:
print([Link])
Best practices
Prefer high-level abstractions.
Work with the SDK's resource models rather than raw responses whenever possible.
Avoid accessing any method prefixed with an underscore (_). By convention, those
methods are private in Python. There are no guarantees about issues like breaking
changes compared to public APIs:
Python
Handle pagination properly. Always iterate over paged results instead of converting to a
list:
Python
# Good: Memory-efficient iteration
for blob in container_client.list_blobs():
process_blob(blob)
Use [Link]() for long-running operations. Always use the result() method to
ensure that operations complete successfully:
Python
# Correct: Wait for operation completion
poller = compute_client.virtual_machines.begin_delete(
resource_group_name="myresourcegroup",
vm_name="myvm"
)
[Link]() # Ensures deletion completes
print("VM deleted successfully")
Access raw responses only when needed. Use raw response access sparingly and only for
specific requirements:
Python
blob_client.upload_blob(data, raw_response_hook=log_request_id)
General Guidelines: Core principles that apply to all Azure SDKs regardless of
programming language.
Language-Specific Guidelines: Implementation details optimized for each supported
language, including Python , .NET , Java , TypeScript , and many more. For more
information, see the Table of Contents starting on the General Guidelines: Introduction
page.
These guidelines are developed openly on GitHub, which allows for community review and
contribution.
ノ Expand table
Principle Description
Progressive disclosure Advanced features are available but don't complicate basic usage.
Python-specific guidelines
The rest of this document focuses on the Python guidelines .
Naming conventions
Azure SDKs for Python follow standard Python naming conventions:
Python
list_containers()
get_secret()
create_database()
Python
connection_string = "..."
retry_count = 3
Python
BlobServiceClient
SecretClient
CosmosClient
Python
DEFAULT_CHUNK_SIZE
MAX_RETRIES
Package structure
Azure SDK packages follow a consistent structure:
ascii
azure-<service>-<feature>
├── azure/
│ └── <service>/
│ ├── __init__.py
│ ├── _client.py
│ ├── _models.py
│ └── aio/ # Async implementations
│ └── __init__.py
Client instantiation
Clients provide multiple instantiation methods:
Python
from [Link] import BlobServiceClient
from [Link] import DefaultAzureCredential
# Note: Do not use connection string if you can possibly avoid it!
Authentication
Azure SDKs use consistent authentication patterns:
Python
from [Link] import DefaultAzureCredential, ClientSecretCredential
# Explicit credential
credential = ClientSecretCredential(
tenant_id="tenant-id",
client_id="client-id",
client_secret="secret"
)
Context managers
Most Azure SDK clients implement context manager protocols for automatic resource cleanup:
Python
from [Link] import BlobServiceClient
7 Note
Although most clients support context managers, verify specific client documentation for
availability.
Asynchronous operations
Async clients are provided in separate .aio modules:
Python
from [Link] import BlobServiceClient
import asyncio
Long-running operations
Long-running operations use the begin_ prefix and return poller objects:
Python
from [Link] import BlobServiceClient
client = BlobServiceClient.from_connection_string(conn_str)
container_client = client.get_container_client("mycontainer")
# Or check status
if [Link]():
result = [Link]()
Pagination
List operations return iterables that handle pagination automatically:
Python
from [Link] import BlobServiceClient
client = BlobServiceClient.from_connection_string(conn_str)
# Automatic pagination
for container in client.list_containers():
print([Link])
Return types
Methods return strongly typed model objects rather than dictionaries:
Python
from [Link] import SecretClient
Error handling
Azure SDK exceptions inherit from AzureError and provide specific exception types:
Python
from [Link] import (
AzureError,
ResourceNotFoundError,
ResourceExistsError,
ClientAuthenticationError,
HttpResponseError
)
try:
blob_client.download_blob()
except ResourceNotFoundError:
# Handle missing resource
print("Blob not found")
except ClientAuthenticationError:
# Handle authentication failure
print("Authentication failed")
except HttpResponseError as e:
# Handle HTTP errors
print(f"HTTP {e.status_code}: {[Link]}")
except AzureError as e:
# Handle any other Azure SDK error
print(f"Azure SDK error: {e}")
Configuration options
Clients accept configuration through keyword arguments:
Python
from [Link] import BlobServiceClient
client = BlobServiceClient(
account_url="...",
credential=credential,
# Configuration options
max_single_put_size=64 * 1024 * 1024,
max_block_size=4 * 1024 * 1024,
retry_total=3,
logging_enable=True
)
Python
service_client = BlobServiceClient(...)
Resource client: Operations on specific resources:
Python
container_client = service_client.get_container_client("container")
Python
blob_client = container_client.get_blob_client("[Link]")
blob_client.upload_blob(data)
ノ Expand table
Python
from [Link] import BlobServiceClient
from [Link] import SecretClient
from [Link] import CosmosClient
from [Link] import DefaultAzureCredential
# Consistent authentication
credential = DefaultAzureCredential()
try:
blob_service.get_container_client("container").get_container_properties()
secret_client.get_secret("secret")
cosmos_client.get_database_client("database").read()
except ResourceNotFoundError as e:
print(f"Resource not found: {e}")
Here's an example of implementing a custom client method that follows the Language Design
Guidelines:
Python
:example:
items = client.list_items_with_prefix("test-")
for item in items:
print([Link])
"""
return self.list_items(name_starts_with=prefix, **kwargs)
Related content
Review the complete Azure SDK Design Guidelines .
Read the Azure SDK Releases page .
Azure Python SDK packages are published to PyPI , including beta releases marked with a "b"
in the version number (such as 1.0.0b1). For the latest versions and release history, see the
Azure SDK Releases: Python .
If you're looking for help with using a specific SDK package, you have several options:
Source code and samples: In the Azure SDK for Python GitHub repository, each package
has its own folder. To view its code, select the GitHub link in the "Source" column of the
package index. Most repos include a [Link] file with example usage.
API Reference documentation: To view the API reference, select the Docs link in the same
table. These pages provide an overview of the package, its classes, and their available
methods.
Tutorials and developer guidance: To explore tutorials, how-to guides, and installation
instructions, Visit the Azure for Python developers documentation. For example, to learn
how to install SDK packages, see: How to install Azure library packages for Python.
7 Note
The Name column contains a friendly name for each package. To find the name you need
to use to install the package with pip , use the links in the Package, Docs, or Source
columns. For example, the Name column for the Azure Blob Storage package is "Blobs"
while the package name is azure-storage-blob.
Azure Blob Storage Checkpoint Store PyPI 1.2.0 docs GitHub 1.2.0
Azure Blob Storage Checkpoint Store AIO PyPI 1.2.0 docs GitHub 1.2.0
Resource Management - AKS Developer Hub PyPI 1.0.0b1 docs GitHub 1.0.0b1
Resource Management - App Compliance Automation PyPI 1.0.0 docs GitHub 1.0.0
Resource Management - Arize AI Observability Eval PyPI 1.0.0b1 docs GitHub 1.0.0b1
Resource Management - Azure Stack HCI PyPI 7.0.0 docs GitHub 7.0.0
PyPI 8.0.0b4 GitHub 8.0.0b4
Resource Management - Azure VMware Solution PyPI 9.0.0 docs GitHub 9.0.0
Resource Management - Container Orchestrator Runtime PyPI 1.0.0b1 docs GitHub 1.0.0b1
Resource Management - Container Service Fleet PyPI 3.1.0 docs GitHub 3.1.0
Resource Management - Content Delivery Network PyPI 13.1.1 docs GitHub 13.1.1
Resource Management - Cosmos DB for PostgreSQL PyPI 1.0.0 docs GitHub 1.0.0
PyPI 1.1.0b1 GitHub 1.1.0b1
Resource Management - Data Box Edge PyPI 2.0.0 docs GitHub 2.0.0
Resource Management - Data Lake Analytics PyPI 1.0.0b2 docs GitHub 1.0.0b2
Resource Management - Data Lake Store PyPI 1.0.0 docs GitHub 1.0.0
PyPI 1.1.0b1
Resource Management - Device Provisioning Services PyPI 1.1.0 docs GitHub 1.1.0
PyPI 1.2.0b2
Resource Management - Hardware Security Modules PyPI 1.0.0b2 docs GitHub 1.0.0b2
Resource Management - Health Data AI Services PyPI 1.0.0 docs GitHub 1.0.0
Resource Management - Hybrid Container Service PyPI 1.0.0 docs GitHub 1.0.0
Resource Management - Informatica Data Management PyPI 1.0.0 docs GitHub 1.0.0
Resource Management - IoT Firmware Defense PyPI 1.0.0 docs GitHub 1.0.0
Resource Management - Machine Learning Compute PyPI 1.0.0b2 docs GitHub 1.0.0b2
Resource Management - Machine Learning Services PyPI 1.0.0 docs GitHub 1.0.0
PyPI 2.0.0b2 GitHub 2.0.0b2
Resource Management - Managed Network Fabric PyPI 1.0.0 docs GitHub 1.0.0
Resource Management - Managed Service Identity PyPI 7.0.0 docs GitHub 7.0.0
PyPI 7.1.0b1 GitHub 7.1.0b1
Resource Management - Migration Discovery SAP PyPI 1.0.0b1 docs GitHub 1.0.0b1
Resource Management - MySQL Flexible Servers PyPI 1.0.0b3 docs GitHub 1.0.0b3
Resource Management - New Relic Observability PyPI 1.1.0 docs GitHub 1.1.0
Resource Management - Palo Alto Networks - Next PyPI 1.0.0 docs GitHub 1.0.0
Generation Firewall PyPI 2.0.0b1 GitHub 2.0.0b1
Resource Management - PostgreSQL Flexible Servers PyPI 1.1.0 docs GitHub 1.1.0
PyPI 1.2.0b1 GitHub 1.2.0b1
Resource Management - Recovery Services Backup PyPI 9.2.0 docs GitHub 9.2.0
Resource Management - Recovery Services Data PyPI 1.0.0b1 docs GitHub 1.0.0b1
Replication
Resource Management - Recovery Services Site Recovery PyPI 1.3.0 docs GitHub 1.3.0
Resource Management - Red Hat OpenShift PyPI 2.0.0 docs GitHub 2.0.0
Resource Management - Service Fabric Managed Clusters PyPI 2.0.0 docs GitHub 2.0.0
PyPI 2.1.0b2 GitHub 2.1.0b2
Resource Management - Spring App Discovery PyPI 1.0.0b1 docs GitHub 1.0.0b1
Resource Management - SQL Virtual Machine PyPI 1.0.0b6 docs GitHub 1.0.0b6
Resource Management - Time Series Insights PyPI 1.0.0 docs GitHub 1.0.0
PyPI 2.0.0b1 GitHub 2.0.0b1
Resource Management - Weights & Biases PyPI 1.0.0b1 docs GitHub 1.0.0b1
Resource Management - Workloads SAP Virtual Instance PyPI 1.0.0 docs GitHub 1.0.0
All libraries
ノ Expand table
Azure Blob Storage Checkpoint Store PyPI 1.2.0 docs GitHub 1.2.0
Azure Blob Storage Checkpoint Store AIO PyPI 1.2.0 docs GitHub 1.2.0
Resource Management - AKS Developer Hub PyPI 1.0.0b1 docs GitHub 1.0.0b1
Resource Management - App Compliance Automation PyPI 1.0.0 docs GitHub 1.0.0
Resource Management - Arize AI Observability Eval PyPI 1.0.0b1 docs GitHub 1.0.0b1
Resource Management - Azure Stack HCI PyPI 7.0.0 docs GitHub 7.0.0
PyPI 8.0.0b4 GitHub 8.0.0b4
Resource Management - Azure VMware Solution PyPI 9.0.0 docs GitHub 9.0.0
Resource Management - Container Orchestrator Runtime PyPI 1.0.0b1 docs GitHub 1.0.0b1
Resource Management - Container Service Fleet PyPI 3.1.0 docs GitHub 3.1.0
Resource Management - Content Delivery Network PyPI 13.1.1 docs GitHub 13.1.1
Resource Management - Cosmos DB for PostgreSQL PyPI 1.0.0 docs GitHub 1.0.0
PyPI 1.1.0b1 GitHub 1.1.0b1
Resource Management - Data Box Edge PyPI 2.0.0 docs GitHub 2.0.0
Name Package Docs Source
Resource Management - Data Lake Analytics PyPI 1.0.0b2 docs GitHub 1.0.0b2
Resource Management - Data Lake Store PyPI 1.0.0 docs GitHub 1.0.0
PyPI 1.1.0b1
Resource Management - Device Provisioning Services PyPI 1.1.0 docs GitHub 1.1.0
PyPI 1.2.0b2
Resource Management - Hardware Security Modules PyPI 1.0.0b2 docs GitHub 1.0.0b2
Resource Management - Health Data AI Services PyPI 1.0.0 docs GitHub 1.0.0
Resource Management - Hybrid Container Service PyPI 1.0.0 docs GitHub 1.0.0
Resource Management - Informatica Data Management PyPI 1.0.0 docs GitHub 1.0.0
Resource Management - IoT Firmware Defense PyPI 1.0.0 docs GitHub 1.0.0
Resource Management - Machine Learning Compute PyPI 1.0.0b2 docs GitHub 1.0.0b2
Resource Management - Machine Learning Services PyPI 1.0.0 docs GitHub 1.0.0
PyPI 2.0.0b2 GitHub 2.0.0b2
Resource Management - Managed Network Fabric PyPI 1.0.0 docs GitHub 1.0.0
Resource Management - Managed Service Identity PyPI 7.0.0 docs GitHub 7.0.0
PyPI 7.1.0b1 GitHub 7.1.0b1
Resource Management - Migration Discovery SAP PyPI 1.0.0b1 docs GitHub 1.0.0b1
Resource Management - MySQL Flexible Servers PyPI 1.0.0b3 docs GitHub 1.0.0b3
Name Package Docs Source
Resource Management - New Relic Observability PyPI 1.1.0 docs GitHub 1.1.0
Resource Management - Palo Alto Networks - Next PyPI 1.0.0 docs GitHub 1.0.0
Generation Firewall PyPI 2.0.0b1 GitHub 2.0.0b1
Resource Management - PostgreSQL Flexible Servers PyPI 1.1.0 docs GitHub 1.1.0
PyPI 1.2.0b1 GitHub 1.2.0b1
Resource Management - Recovery Services Backup PyPI 9.2.0 docs GitHub 9.2.0
Resource Management - Recovery Services Data PyPI 1.0.0b1 docs GitHub 1.0.0b1
Replication
Resource Management - Recovery Services Site Recovery PyPI 1.3.0 docs GitHub 1.3.0
Resource Management - Red Hat OpenShift PyPI 2.0.0 docs GitHub 2.0.0
Resource Management - Service Fabric Managed Clusters PyPI 2.0.0 docs GitHub 2.0.0
PyPI 2.1.0b2 GitHub 2.1.0b2
Resource Management - Spring App Discovery PyPI 1.0.0b1 docs GitHub 1.0.0b1
Resource Management - SQL Virtual Machine PyPI 1.0.0b6 docs GitHub 1.0.0b6
Resource Management - Time Series Insights PyPI 1.0.0 docs GitHub 1.0.0
PyPI 2.0.0b1 GitHub 2.0.0b1
Resource Management - Weights & Biases PyPI 1.0.0b1 docs GitHub 1.0.0b1
Resource Management - Workloads SAP Virtual Instance PyPI 1.0.0 docs GitHub 1.0.0
Reference
Services
Azure offers several options for hosting your application, each suited to different levels of
control and responsibility. For an overview of these options, see Hosting applications on
Azuree.
We recommend starting with Azure App Service, which provides a highly managed
environment with minimal administrative overhead. As your needs evolve, you can explore
other options that offer increased flexibility and control, such as Azure Container Apps, Azure
Kubernetes Service (AKS), or ultimately Azure Virtual Machines, which provide the greatest
control but also require the most maintenance.
The hosting options in this article are presented in order from more managed (less
responsibility on your part) to less managed (more control and responsibility).
Azure offers a wide range of fully managed database and storage solutions, including
relational, NoSQL, and in-memory databases, with support for both proprietary and open-
source technologies. You can also choose from object, block, and file storage services. The
following articles can help you get started using these options with Python on Azure.
Databases
PostgreSQL: Build scalable, secure, and fully managed enterprise apps using open-source
PostgreSQL. You can scale single-node PostgreSQL for high performance or migrate
existing PostgreSQL and Oracle workloads to the cloud.
Quickstart: Use Python to connect and query data in Azure Database for PostgreSQL -
Flexible Server
Quickstart: Use Python to connect and query data in Azure Database for PostgreSQL -
Single Server
Deploy a Python (Django or Flask) web app with PostgreSQL in Azure App Service
MySQL: Build scalable applications using a fully managed, intelligent MySQL database in
the cloud.
Quickstart: Use Python to connect and query data in Azure Database for MySQL -
Flexible Server
Quickstart: Use Python to connect and query data in Azure Database for MySQL
Azure SQL: Build scalable applications with a fully managed and intelligent SQL database
platform in the cloud.
Quickstart: Use Python to query a database in Azure SQL Database or Azure SQL
Managed Instance
Azure Data Lake Storage Gen2: Scalable, secure data lake optimized for high-
performance analytics.
Use Python to manage directories and files in Azure Data Lake Storage Gen2
Use Python to manage ACLs in Azure Data Lake Storage Gen2
File storage: Simple, secure, and serverless enterprise-grade cloud file shares.
Develop for Azure Files with Python
Redis Cache: Accelerate application performance with a scalable, in-memory data store
compatible with open source.
Quickstart: Use Azure Cache for Redis in Python
Azure Data Factory: A fully managed data integration service that lets you visually build,
orchestrate, and automate data movement and transformation across various data
sources.
Quickstart: Create a data factory and pipeline using Python
Transform data by running a Python activity in Azure Databricks
Azure Event Hubs: A fully managed, hyper-scale telemetry ingestion service designed to
collect, transform, and store millions of events per second from connected devices and
applications.
Send events to or receive events from event hubs by using Python
Capture Event Hubs data in Azure Storage and read it by using Python (azure-
eventhub)
HDInsight: A fully managed cloud service that runs popular open-source frameworks like
Hadoop and Spark, backed by a 99.9% SLA for enterprise-grade big data analytics.
Use Spark & Hive Tools for Visual Studio Code
Azure Databricks: A fully managed, fast, easy and collaborative Apache® Spark™ based
analytics platform optimized for big data and AI workloads on Azure.
Connect to Azure Databricks from Excel, Python, or R
Get Started with Azure Databricks
Tutorial: Azure Data Lake Storage Gen2, Azure Databricks & Spark
Azure Synapse Analytics: A fully managed analytics service that unifies data integration,
enterprise data warehousing, and big data analytics into a single platform.
Quickstart: Use Python to query a database in Azure SQL Database or Azure SQL
Managed Instance (includes Azure Synapse Analytics)
Identity and access management for
Python apps on Azure
06/05/2025
In Azure, identity and access management (IAM) for Python applications involves two key
concepts:
Azure provides multiple IAM options to fit your application's security requirements. This article
includes links to essential resources to help you get started.
Passwordless connections
Whenever possible, we recommend using managed identities to simplify identity management
and enhance security. Managed identities support passwordless authentication, eliminating the
need to embed sensitive credentials—such as passwords or client secrets—in code or
environment variables. Managed identities are available for Azure services like App Service,
Azure Functions, and Azure Container Apps. They allow your applications to authenticate to
Azure services without needing to manage credentials.
The following resources demonstrate how to use the Azure SDK for Python with passwordless
authentication via DefaultAzureCredential . DefaultAzureCredential is ideal for most
applications running in Azure, as it seamlessly supports both local development and
production environments by chaining multiple credential types in a secure and intelligent
order.
Authenticate Python Apps to Azure services using the Azure SDK for Python
Quickstart: Azure Blob Storage client library for Python with passwordless connections
Quickstart: Send messages to and receive message from Azure Service Bus queues with
passwordless connections
Create and deploy a Flask web app to Azure with a system-assigned managed identity
Create and deploy a Django web app to Azure with a user-assigned managed identity
Service Connector
Many Azure resources commonly used in Python applications support the Service Connector.
The Service Connector streamlines the process of configuring secure connections between
Azure services. It automates the setup of authentication, network access, and connection
strings between compute services (like App Service or Container Apps) and dependent services
(such as Azure Storage, Azure SQL, or Cosmos DB). This reduces manual steps, helps enforce
best practices (like using managed identities and private endpoints), and improves deployment
consistency and security.
Quickstart: Create a service connection in App Service from the Azure portal
Tutorial: Using Service Connector to build a Django app with Postgres on Azure App
Service
Key Vault
Using a key management solution such as Azure Key Vault offers greater control over your
secrets and credentials, though it comes with added management complexity.
Quickstart: Sign in users and call the Microsoft Graph API from a Python web app
The following articles help you get started with Azure Machine Learning. Azure Machine
Learning v2 REST APIs, Azure CLI extension, and Python SDK are designed to streamline the
entire machine learning lifecycle and accelerate production workflows. The links in this article
target v2, which is recommended if you're starting a new machine learning project.
Getting started
In Azure Machine Learning, the workspace is the main resource that organizes and manages
everything you create, such as datasets, models, and experiments.
Deploy models
Deploy models for low-latency, real-time machine learning predictions.
Data access
With Azure Machine Learning, you can import data from your local computer or connect to
existing cloud storage services.
Azure AI services are cloud-based artificial intelligence (AI) services that help developers build
cognitive intelligence into applications without having direct AI or data science skills or
knowledge. There are ready-made AI services for computer vision and image processing,
language analysis and translation, speech, decision-making, search, and Azure OpenAI that you
can use in your Python applications.
Because of the dynamic nature of Azure AI services, the best way to find getting started
material for Python is to begin on the Azure AI services hub page, and then find the specific
service you're looking for.
1. On the hub page, select a service to go its documentation landing page. For example, for
Azure AI Vision.
2. On the service's landing page, select a category of the service. For example, in Computer
Vision, select Image Analysis.
3. In the documentation, look for Quickstarts in the table of contents. For example, in the
Image Analysis documentation, under Quickstarts, there's a Version 4.0 quickstart
(preview).
4. In quickstart articles, choose the Python programming language if it exists or the REST
API.
If you don't see a quickstart, in the table of contents search box enter Python to find
Python-related articles.
Also, you can go to the Azure Cognitive Services modules for Python overview to learn about
the available Python SDK modules. (Azure Cognitive Services is the previous name of Azure AI
services. The documentation is currently being updated to reflect the change.)
The following articles help you get started with messaging, event ingestion and processing,
and Internet of Things (IoT) services in Azure.
Messaging
Azure messaging services let different components and apps communicate easily, no matter
what language they use or where they're hosted—whether in the same cloud, across multiple
clouds, or on-premises.
Notifications
How to use Notification Hubs from Python
Queues
Quickstart: Azure Queue Storage client library for Python
Quickstart: Send messages to and receive messages from Azure Service Bus queues
(Python)
Send messages to an Azure Service Bus topic and receive messages from subscriptions
to the topic (Python)
Events
Azure Event Hubs and Azure Event Grid are two key services for handling events in Azure. They
provide capabilities for ingesting, processing, and routing events across various applications
and services.
These services allow you to build event-driven architectures and process events in real time.
Event Hubs
Quickstart: Send events to or receive events from event hubs by using Python
Quickstart: Capture Event Hubs data in Azure Storage and read it by using Python
(azure-eventhub)
Event Grid
Quickstart: Route custom events to web endpoint with Azure CLI and Event Grid
Azure Event Grid Client Library Python Samples
IoT Hub
Quickstart: Send telemetry from an IoT Plug and Play device to Azure IoT Hub
Send cloud-to-device messages with IoT Hub
Upload files from your device to the cloud with IoT Hub
Schedule and broadcast jobs
Quickstart: Control a device connected to an IoT hub
Device provisioning
Quickstart: Provision an X.509 certificate simulated device
Tutorial: Provision devices using symmetric key enrollment groups
Tutorial: Provision multiple X.509 devices using enrollment groups
The services referenced in this article for Python are specialized, each designed to address a
specific set of problems. The term other services includes Azure offerings beyond the
foundational categories of compute, networking, storage, and databases. This article features
examples from areas like management and governance, media, genomics, and the Internet of
Things (IoT). For a full list of available services Azure products .
Media streaming:
Connect to Azure Media Services v3 API
Automation:
Tutorial: Create a Python runbook
DevOps:
Use CI/CD with GitHub Actions to deploy a Python web app to Azure App Service on
Linux
Build and deploy a Python cloud app with the Azure Developer CLI (azd) open-source
tool
Build, test, and deploy Python apps with Azure Pipelines
Resource management:
Quickstart: Run your first Resource Graph query using Python