Example: Access Azure Storage using the Azure libraries for Python
This example demonstrated how to use the Azure client libraries in Python application code to upload a file to that Blob storage container. The example assumes you have provisioned the resources shown in Example: Provision Azure Storage.
All the commands in this article work the same in Linux/macOS bash and Windows command shells unless noted.
1: Set up your local development environment
If you haven't already, follow all the instructions on Configure your local Python dev environment for Azure.
Be sure to create a service principal for local development, set environment variables for the service principal (see below), and create and activate a virtual environment for this project.
2: Install library packages
In your requirements.txt file, add line for the needed client library package and save the file:
In your terminal or command prompt, reinstall requirements:
pip install -r requirements.txt
3: Create a file to upload
Create a source file named sample-source.txt (as the code expects), with contents like the following:
Hello there, Azure Storage. I'm a friendly file ready to be stored in a blob.
4: Use blob storage from app code
The following sections (numbered 4a and 4b) demonstrate two means to access the blob container provisioned through Example: Provision Azure Storage.
The first method (section 4a below) authenticates the app with
DefaultAzureCredential as described in Authenticate Azure hosted applications with DefaultAzureCredential. With this method you must first assign the appropriate permissions to the app identity, which is the recommended practice.
The second method (section 4b below) uses a connection string to access the storage account directly. Although this method seems simpler, it has two significant drawbacks:
A connection string inherently authenticates the connecting agent with the Storage account rather than with individual resources within that account. As a result, a connection string provides grants broader authorization than may be required.
A connection string contains an access key in plain text and therefore presents potential vulnerabilities if it's improperly constructed or improperly secured. If such a connection string is exposed it can be used to access a wide range of resources within the Storage account.
For these reasons, we recommend using the authentication method in production code.
4a: Use blob storage with authentication
Create an environment variable named
Replace "pythonazurestorage12345" with the name of your specific storage account.
STORAGE_BLOB_URLenvironment variable is used only by this example and it not used by the Azure libraries.
Create a file named use_blob_auth.py with the following code. The comments explain the steps.
import os from azure.identity import DefaultAzureCredential # Import the client object from the SDK library from azure.storage.blob import BlobClient credential = DefaultAzureCredential() # Retrieve the storage blob service URL, which is of the form # https://pythonsdkstorage12345.blob.core.windows.net/ storage_url = os.environ["AZURE_STORAGE_BLOB_URL"] # Create the client object using the storage URL and the credential blob_client = BlobClient(storage_url, container_name="blob-container-01", blob_name="sample-blob.txt", credential=credential) # Open a local file and upload its contents to Blob Storage with open("./sample-source.txt", "rb") as data: blob_client.upload_blob(data)
Attempt to run the code (which fails intentionally):
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 does not yet have permission to access the blob container.
Grant container permissions to the service principal using the Azure CLI command az role assignment create (it's a long one!):
az role assignment create --assignee %AZURE_CLIENT_ID% ^ --role "Storage Blob Data Contributor" ^ --scope "/subscriptions/%AZURE_SUBSCRIPTION_ID%/resourceGroups/PythonAzureExample-Storage-rg/providers/Microsoft.Storage/storageAccounts/pythonazurestorage12345/blobServices/default/containers/blob-container-01"
--scopeargument identifies where this role assignment applies. In this example, you grant the "Storage Blob Data Contributor" role to the specific container named "blob-container-01".
pythonazurestorage12345with the exact name of your storage account. You can also adjust the name of the resource group and blob container, if necessary. If you use the wrong name, you see the error, "Can not perform requested operation on nested resource. Parent resource 'pythonazurestorage12345' not found."
If needed, also replace
PythonAzureExample-Storage-rgwith the name of the resource group that contains your storage account. The resource group shown here is what's used in Example: Provision Azure Storage.
--scopeargument in this command also uses the AZURE_CLIENT_ID and AZURE_SUBSCRIPTION_ID environment variables, which you should already have set in your local environment for your service principal by following Configure your local Python dev environment for Azure.
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.
4b: Use blob storage with a connection string
Create an environment variable named
AZURE_STORAGE_CONNECTION_STRING, the value of which is the full connection string for the storage account. (This environment variable is also used by various Azure CLI comments.)
Create a Python file named use_blob_conn_string.py with the following code. The comments explain the steps.
import os # Import the client object from the SDK library from azure.storage.blob import BlobClient # Retrieve the connection string from an environment variable. Note that a connection # string grants all permissions to the caller, making it less secure than obtaining a # BlobClient object using credentials. conn_string = os.environ["AZURE_STORAGE_CONNECTION_STRING"] # Create the client object for the resource identified by the connection string, # indicating also the blob container and the name of the specific blob we want. blob_client = BlobClient.from_connection_string(conn_string, container_name="blob-container-01", blob_name="sample-blob.txt") # Open a local file and upload its contents to Blob Storage with open("./sample-source.txt", "rb") as data: blob_client.upload_blob(data)
Run the code:
Again, although this method is simple, a connection string authorizes all operations in a storage account. With production code it's better to use specific permissions as described in the previous section.
5. Verify blob creation
After running the code of either method, go to the Azure portal, navigate into the blob container to verify that a new blob exists named sample-blob.txt with the same contents as the sample-source.txt file:
6: Clean up resources
az group delete -n PythonAzureExample-Storage-rg --no-wait
Run this command if you don't need to keep the resources provisioned in this example and would like to avoid ongoing charges in your subscription.
You can also use the
ResourceManagementClient.resource_groups.begin_delete method to delete a resource group from code. The code in Example: Provision a resource group demonstrates usage.
- Example: Provision a resource group
- Example: List resource groups in a subscription
- Example: Provision a web app and deploy code
- Example: Provision Azure Storage
- 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