Python 操作 Azure Blob Storage

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 操作 Azure Blob Storage相关的知识,希望对你有一定的参考价值。

笔者在《Azure 基础:Blob Storage》一文中介绍了 Azure Blob Storage 的基本概念,并通过 C# 代码展示了如何进行基本的操作。最近笔者需要在 Linux 系统中做类似的事情,于是决定使用 Azure 提供的 Azure Storage SDK for Python 来操作 Blob Storage。这样今后无论在 Windows 上还是 Linux上,都用 Python 就可以了。对 Azure Blob Storage 概念还不太熟悉的同学请先参考前文

安装 Azure Storage SDK for Python

最简单的方式是在安装了 python 和 pip 的机器上直接执行下面的命令:

pip install azure-storage

安装完成后通过 pip freeze 命令查看安装的版本:

技术分享

由于 Azure Storage SDK for Python 是一个开源项目,所以你也可以通过源代码安装它,请参考官方文档

创建 Blob Container

由于任何一个 Blob 都必须包含在一个 Blob Container 中,所以我们的第一个任务是创建 Blob Container。
SDK 为我们提供了一个名为 BlockBlobService 的对象。通过这个对象我们可以创建并操作 Blob Container。下面的代码创建一个名为"nickcon" 的 Container:

技术分享

代码本身很简单,其中的 account_name 和 account_key 是你的 storage 账号及其访问 key。我们使用 GUI 工具 Microsoft Azure Storage Explorer 查看代码操作的结果:

技术分享

名为 nickcon 的 Blob Container 已经被成功的创建了。

上传文件

接下来我们要把本地的文件上传到刚才创建的 Blob Container 中。Azure SDK 为我们提供了下面四个方法:

create_blob_from_path #上传指定路径的文件。
create_blob_from_stream #把一个数据流中的内容上传。
create_blob_from_bytes #上传一个 bype 数组。
create_blob_from_text #使用特定的编码格式上传字符串。

是的,你没有看错,所有方法的名字中都没有 upload 字眼,而是使用了 create。这也说明上传文件的本质是在云端创建一个 Blob 对象。

from azure.storage.blob import BlockBlobService
from azure.storage.blob import ContentSettings

mystoragename = "xxxx"
mystoragekey = "yyyy"
blob_service = BlockBlobService(account_name=mystoragename, account_key=mystoragekey)

blob_service.create_blob_from_path(
    nickcon,
    myblobcortana.jpg,
    cortana-wallpaper.jpg,
    content_settings=ContentSettings(content_type=image/jpg))

这次我们引入了类型 ContentSettings,主要是指定文件的类型。注意 create_blob_from_path 方法的第二个参数,我们需要为新的 blob 对象指定一个名字。第一个参数是目标 Container, 第三个参数是要上传的本地文件路径。执行上面的脚本,会把本地的一张壁纸 cortana-wallpaper.jpg 上传到 Azure Blob Container 中:

技术分享

在 Container 中创建的 Blob 对象的名称已经不是源文件的名称了,而是我们指定的 myblobcortana.jpg。

控制访问权限

存放在 Blob Container 中的文件都有对应的 URL,这是 Azure Blob Storage 的默认策略。为的是我们可以从任何地方通过 URL 来访问这些文件。比如 myblobcortana.jpg 文件的 URL 为:

https://nickpsdk.blob.core.windows.net/nickcon/myblobcortana.jpg
直接把这个地址粘贴到浏览器的地址栏里:

技术分享

啊哦,尴尬了,收到了一个无情的 error!

认真想一下,收到这样的错误是合理的。否则任何人都能看到我保存的文件内容,隐私何在?还会有人为 Azure Blob Storage 付费吗?事情的真相是这样的,默认情况下我们创建的 Blob Container 和 Blob 对象都是私有的,也就是必须通过账号和 access key 才能访问。如果你要想让内容变成大家都能访问的公共资源,可以在创建时指定为 PublicAccess。也可以在创建完成后修改它的属性为 PublicAccess。下面我们把 nickcon Container 设置为 PublicAccess:

from azure.storage.blob import BlockBlobService
from azure.storage.blob import PublicAccess

mystoragename = "xxxx"
mystoragekey = "yyyy"
blob_service = BlockBlobService(account_name=mystoragename, account_key=mystoragekey)

blob_service.set_container_acl(nickcon, public_access=PublicAccess.Container)

此处 import 了 PublicAccess 类型,并调用 set_container_acl 方法来修改 Container 的访问权限。试试重新刷新一下网页:

技术分享

此时就不要再往你的 Blob Container 中放隐私照了哦!

列出 Blob Container 中的所有文件

检查 Container 中都有哪些文件是很重要的操作,当然我们可以轻松的完成:

generator = blob_service.list_blobs(nickcon)
for blob in generator:
print(blob.name)

使用 list_blobs 方法可以获得 Container 中的所有 Blob 对象。上面的代码打印了所有 Blob 对象的名称。

下载 Blob 对象

和创建 Blob 对象一样,也有四个方法可以下载 Blob 对象。简单期间我们只演示 get_blob_to_path 方法,其它的用法类似:

blob_service.get_blob_to_path(nickcon, myblobcortana.jpg, newimage.png)

其中第二个参数为 Container 中 Blob 对象的名称,第三个参数为保存到本地文件的路径。

删除 Blob 对象

有创建自然有删除,代码很简单,不再啰嗦:

blob_service.delete_blob(nickcon, myblobcortana.jpg)

备份 Blob Container 中的文件

是的,你没听错!
我们相信云存储的安全性,但把重要的数据备份到其它的存储上也是需要的。下面的代码会把一个 Azure Storage Account 中的所有 Blob Container 中的内容备份到本地磁盘上:

from azure.storage.blob import BlockBlobService
import os

mystoragename = "xxxx"
mystoragekey = "yyyy"
blob_service = BlockBlobService(account_name=mystoragename, account_key=mystoragekey)

# 下载一个 Blob Container 中的所有文件
def downloadFilesInContainer(blobContainName):
    generator = blob_service.list_blobs(blobContainName)
    for blob in generator:
        # 获得 Blob 文件的目录路径
        blobDirName =  os.path.dirname(blob.name)
        # 把 Blob Container 的名称也添加为一级目录
        newBlobDirName = os.path.join(blobContainName, blobDirName)
        # 检查文件目录是否存在,不存在就创建
        if not os.path.exists(newBlobDirName):
            os.makedirs(newBlobDirName)
        localFileName = os.path.join(blobContainName, blob.name)
        blob_service.get_blob_to_path(blobContainName, blob.name, localFileName)

# 获得用户所有的 Blob Container
containerGenerator = blob_service.list_containers()
for con in containerGenerator:
    downloadFilesInContainer(con.name)

此处需要注意一点,blob.name 包含了文件在 container 中的目录。比如一个文件在 Blob Container 中的路径为 abc/test.txt,那么它的 blog.name 就是 abc/test.txt。要保持文件在 Blob Container 的名称及路径就要在本地创建对应的目录结构。

总结

最后的 demo 可以简单的实现备份所有 Blob 文件的功能。由于微软把相关接口封装的很清晰,所以代码非常的简短。使用 Python 的好处是可以在不同的平台上运行相同的代码。当你需要在不同的操作系统中做同样的事情时,这可太棒了!




以上是关于Python 操作 Azure Blob Storage的主要内容,如果未能解决你的问题,请参考以下文章

Python 操作 Azure Blob Storage

如何从 Azure blob 数据存储中获取 Python pathlib 路径?

Azure 存储:Blob:Python:获取指示符是不是存在 Blob

Azure Functions - Python(Blob 触发器和绑定)

使用 Blob 服务客户端查找 azure 帐户密钥失败(azure python sdk)

如何在 Python 中生成 Azure blob SAS URL?