示例:使用用于 Python 的 Azure 库访问Azure 存储
本文介绍如何使用 Python 应用程序代码中的 Azure 客户端库将文件上传到 Azure Blob 存储容器。 本文假定已创建示例:创建Azure 存储中显示的资源。
除非另行说明,否则本文中的所有资源在 Linux/macOS bash 和 Windows 命令行界面上的工作方式相同。
1:设置本地开发环境
如果尚未安装,请设置可以运行此代码的环境。 提供以下选择:
配置 Python 虚拟环境。 可以在本地或 Azure Cloud Shell 中创建虚拟环境,并在其中运行代码。 请务必激活虚拟环境以开始使用它。
在 Visual Studio Code 或 GitHub Codespaces 中使用开发容器。
2:安装库包
在requirements.txt文件中,为要使用的客户端库包添加行并保存该文件。
azure-storage-blob
azure-identity
然后,在终端或命令提示符下,安装要求。
pip install -r requirements.txt
3:创建要上传的文件
创建名为sample-source.txt的源文件。 此文件名是代码所需的内容。
Hello there, Azure Storage. I'm a friendly file ready to be stored in a blob.
4:使用应用代码中的 Blob 存储
以下两个部分演示了访问通过示例创建的 Blob 容器的两种方法:创建Azure 存储。
第 一种方法(使用身份验证)DefaultAzureCredential
使用服务主体在本地开发期间使用 Python 应用对 Azure 服务进行身份验证。 使用此方法,必须先将适当的权限分配给应用标识,这是建议的做法。
第二种方法(带有连接字符串)使用连接字符串直接访问存储帐户。 尽管此方法看起来更简单,但它有两个重大缺点:
连接字符串在本质上使用存储帐户(而不是该帐户中的单个资源)来验证连接代理。 因此,连接字符串授予比可能需要更广泛的授权。
连接字符串以纯文本形式包含访问信息,因此,如果未正确构造或保护它,则会出现潜在的漏洞。 如果公开此类连接字符串,则可用于访问存储帐户中的各种资源。
出于这些原因,建议在生产代码中使用该身份验证方法。
4a:将 Blob 存储与身份验证配合使用
使用以下代码创建一个名为“use_blob_auth py”的文件。 注释对步骤进行了说明。
import os import uuid 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://<your-storage-account-name>.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=f"sample-blob-{str(uuid.uuid4())[0:5]}.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) print(f"Uploaded sample-source.txt to {blob_client.url}")
参考链接:
创建名为
AZURE_STORAGE_BLOB_URL
的环境变量:将“pythonazurestorage12345”替换为存储帐户的名称。
该
AZURE_STORAGE_BLOB_URL
环境变量仅由此示例使用。 Azure 库不使用它。使用 az ad sp create-for-rbac 命令为应用创建新的服务主体。 该命令同时为应用创建应用注册。 为服务主体指定所选名称。
az ad sp create-for-rbac --name {service-principal-name}
此命令的输出如下所示。 记下这些值或使此窗口保持打开状态,因为下一步需要这些值,并且无法再次查看密码(客户端密码)值。 但是,以后可以添加新密码,而无需根据需要使服务主体或现有密码失效。
{ "appId": "00000000-0000-0000-0000-000000000000", "displayName": "{service-principal-name}", "password": "abcdefghijklmnopqrstuvwxyz", "tenant": "11111111-1111-1111-1111-111111111111" }
可以在 Azure Cloud Shell 中或装有 Azure CLI 的工作站上运行 Azure CLI 命令。
为应用程序服务主体创建环境变量:
使用上一命令输出中的值创建以下环境变量。 这些变量指示
DefaultAzureCredential
使用应用程序服务主体。AZURE_CLIENT_ID
→ 应用 ID 值。AZURE_TENANT_ID
→ 租户 ID 值。AZURE_CLIENT_SECRET
→ 为应用生成的密码/凭据。
尝试运行代码(有意失败):
python use_blob_auth.py
请注意错误“此请求无权使用此权限执行此操作”。由于正在使用的本地服务主体尚无权访问 Blob 容器,因此会出现此错误。
使用 az role assignment create Azure CLI 命令向服务主体授予对 blob 容器参与者权限:
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"
该
--assignee
参数标识服务主体。 将AZURE_CLIENT_ID>占位符替换为<服务主体的应用 ID。--scope
参数标识此角色分配适用的位置。 在此示例中,将“存储 Blob 数据参与者”角色授予名为“blob-container-01”的容器的服务主体。替换
PythonAzureExample-Storage-rg
并pythonazurestorage12345
替换为包含存储帐户的资源组和存储帐户的确切名称。 此外,如有必要,请调整 Blob 容器的名称。 如果使用错误名称,会发现错误“无法对嵌套资源执行请求的操作。 找不到父资源‘pythonazurestorage12345’”。将 <AZURE_SUBSCRIPTION_ID> 位置持有者替换为 Azure 订阅 ID。 (可以运行 az account show 命令并从输出中的属性获取订阅 ID
id
。
提示
如果使用 bash shell 时角色分配命令返回错误“找不到连接适配器”,请尝试设置
export MSYS_NO_PATHCONV=1
以避免路径转换。 有关详细信息,请参阅此问题。花一两分钟时间等待权限传播,然后再次运行该代码,验证它现在是否正常工作。 如果再次看到权限错误,请等待更长的时间,然后重试代码。
有关角色分配的详细信息,请参阅如何使用 Azure CLI 分配角色权限。
4b:将 blob 存储与连接字符串配合使用
创建包含以下代码的名为“use_blob_conn_string.py”的 Python 文件。 注释对步骤进行了说明。
import os import uuid # 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=f"sample-blob-{str(uuid.uuid4())[0:5]}.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) print(f"Uploaded sample-source.txt to {blob_client.url}")
创建一个名为
AZURE_STORAGE_CONNECTION_STRING
的环境变量,其值是存储帐户的完整连接字符串。 (此环境变量也由各种 Azure CLI 注释使用。可以通过运行 az storage account show-connection-string 命令来获取存储帐户的连接字符串。az storage account show-connection-string --resource-group PythonAzureExample-Storage-rg --name pythonazurestorage12345
替换
PythonAzureExample-Storage-rg
并pythonazurestorage12345
替换为包含存储帐户的资源组和存储帐户的确切名称。设置环境变量时,请使用输出中属性的
connectionString
整个值,包括引号。运行代码:
python use_blob_conn_string.py
同样,虽然此方法很简单,但连接字符串会授权存储帐户中的所有操作。 使用生产代码时,最好使用上一节中所述的特定权限。
5.验证 Blob 创建
运行任一方法的代码后,转到Azure 门户,导航到 blob 容器,验证是否存在名为 sample-blob-{random}的新 blob .txt,其内容与sample-source.txt文件相同:
如果创建了名为“环境变量AZURE_STORAGE_CONNECTION_STRING
”的环境变量,还可以使用 Azure CLI 通过 az storage blob list 命令验证 blob 是否存在:
az storage blob list --container-name blob-container-01
如果按照说明使用具有身份验证的 Blob 存储,则可以使用存储帐户的连接字符串将参数添加到--connection-string
上述命令。 若要了解如何获取连接字符串,请参阅 4b 中的说明:将 blob 存储与连接字符串配合使用。 使用包括引号在内的整个连接字符串。
6:清理资源
如果不需要保留此示例中使用的资源组和存储资源,请运行 az group delete 命令。 资源组不会在订阅中产生任何持续费用,但资源组中的资源(如存储帐户)可能会产生费用。 最好清理未主动使用的任何组。 --no-wait
参数允许命令立即返回,而不是等到操作完成再返回。
az group delete -n PythonAzureExample-Storage-rg --no-wait
你还可以使用 ResourceManagementClient.resource_groups.begin_delete
方法从代码中删除资源组。 示例中的 代码:创建资源组 演示用法。
如果按照说明使用 Blob 存储进行身份验证,最好删除创建的应用程序服务主体。 可以使用 az ad app delete 命令。 将 <AZURE_CLIENT_ID> 占位符替换为服务主体的应用 ID。
az ad app delete --id <AZURE_CLIENT_ID>
另请参阅
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈