如何在Python中生成Azure容器的完整内容下载URL
如何生成Azure Storage容器全部内容的下载URL
我在Azure Storage中有一个名为test的容器,文件结构如下:
test -> annotate # 目录 -> file1.txt -> file2.txt -> images # 目录 -> file1.jpg -> file2.jpg
我希望生成一个URL,访问时能下载该容器的全部内容(包括所有文件和子目录)。之前我只能通过以下代码生成单个Blob的下载URL:
account_name = "deeusblobstorage" container_name = "rperodct" blob_name = "face_1_7285.jpg" account_key = "hMlIRXCjAomfDRfied8Y5FPwTVnWEkEDuVsw//CQtkiOdcFD/y5wUcxH9Ou7Ni+DtDQFwe23YbZ3Qia9gw==" url = f"https://{account_name}.blob.core.windows.net/{container_name}/{blob_name}" sas_token = generate_blob_sas( account_name=account_name, account_key=account_key, container_name=container_name, blob_name=blob_name, permission=AccountSasPermissions(read=True), expiry=datetime.datetime.utcnow() + timedelta(hours=1) ) url_with_sas = f"{url}?{sas_token}" print(url_with_sas)
这段代码需要指定具体Blob才能生成下载链接,请问怎么生成能下载整个容器所有内容的URL?
解决方案
Azure Blob Storage本身没有提供直接一键下载整个容器的单URL,但可以通过两种方式实现需求:
1. 生成容器级SAS令牌,配合工具批量下载
生成容器级别的SAS令牌,而非单个Blob的。有了这个令牌,用户可以用Azure存储资源管理器、azcopy命令行或自定义脚本,通过容器URL加SAS令牌批量下载所有内容。
修改后的容器级SAS生成代码:
from azure.storage.blob import generate_container_sas, ContainerSasPermissions from datetime import datetime, timedelta account_name = "deeusblobstorage" container_name = "test" # 替换为你的目标容器名 account_key = "hMlIRXCjAomfDRfied8Y5FPwTVnWEkEDuVsw//CQtkiOdcFD/y5wUcxH9Ou7Ni+DtDQFwe23YbZ3Qia9gw==" # 生成容器级SAS,赋予读取权限 sas_token = generate_container_sas( account_name=account_name, account_key=account_key, container_name=container_name, permission=ContainerSasPermissions(read=True), expiry=datetime.utcnow() + timedelta(hours=1) ) # 拼接带SAS的容器URL container_url = f"https://{account_name}.blob.core.windows.net/{container_name}" container_url_with_sas = f"{container_url}?{sas_token}" print(container_url_with_sas)
拿到URL后的使用方式:
- Azure存储资源管理器:输入该URL建立连接,选中所有文件即可批量下载
- azcopy命令行:
azcopy copy "https://deeusblobstorage.blob.core.windows.net/test?{你的SAS令牌}" "本地目标路径" --recursive=true
2. 打包容器内容为ZIP,生成单个Blob下载URL
如果需要单URL直接下载压缩包,可以先将容器内所有文件打包成ZIP上传到Blob存储,再生成该ZIP的下载URL。可以通过本地脚本、Azure函数或逻辑应用实现自动打包:
本地打包上传示例代码:
import os import zipfile from azure.storage.blob import BlobServiceClient, generate_blob_sas, ContainerSasPermissions from datetime import datetime, timedelta account_name = "deeusblobstorage" account_key = "hMlIRXCjAomfDRfied8Y5FPwTVnWEkEDuVsw//CQtkiOdcFD/y5wUcxH9Ou7Ni+DtDQFwe23YbZ3Qia9gw==" container_name = "test" # 初始化Blob服务客户端 connection_string = f"DefaultEndpointsProtocol=https;AccountName={account_name};AccountKey={account_key};EndpointSuffix=core.windows.net" blob_service_client = BlobServiceClient.from_connection_string(connection_string) container_client = blob_service_client.get_container_client(container_name) # 本地临时ZIP文件路径 zip_file_path = "test_container.zip" # 打包容器内所有Blob到ZIP with zipfile.ZipFile(zip_file_path, 'w', zipfile.ZIP_DEFLATED) as zipf: for blob in container_client.list_blobs(): # 临时下载Blob到本地 temp_file = f"temp_{blob.name.replace('/', '_')}" with open(temp_file, "wb") as f: f.write(container_client.download_blob(blob.name).readall()) # 按原目录结构添加到ZIP zipf.write(temp_file, arcname=blob.name) # 删除临时文件 os.remove(temp_file) # 上传ZIP到容器 zip_blob_client = blob_service_client.get_blob_client(container=container_name, blob="test_container.zip") with open(zip_file_path, "rb") as data: zip_blob_client.upload_blob(data, overwrite=True) # 生成ZIP文件的下载URL sas_token = generate_blob_sas( account_name=account_name, account_key=account_key, container_name=container_name, blob_name="test_container.zip", permission=ContainerSasPermissions(read=True), expiry=datetime.utcnow() + timedelta(hours=1) ) zip_download_url = f"https://{account_name}.blob.core.windows.net/{container_name}/test_container.zip?{sas_token}" print(zip_download_url) # 删除本地ZIP文件 os.remove(zip_file_path)
注意:这种方法需要额外存储容量保存ZIP文件,若容器内容更新,需重新打包上传才能获取最新内容的下载URL。
内容的提问来源于stack exchange,提问作者S Andrew
相关产品推荐
相关产品推荐

