Backblaze B2 是眼下性价比最高的对象存储,结合 restic 加密备份工具,就可以非常低成本的实现数据安全冗余。

只是 B2 存储的 API 真是不够实在,除了常规的文件查看、上传和下载等基本操作以外,没有提供任何消费查询和用量统计的接口。

不提供就不提供吧,只要有列出文件的接口,并且能返回每个文件的尺寸信息就够了,起码可以自己累加计算。只是这样要多次发送请求才能得到最终的结果,真不节能。

import requests
import base64
import json


def b2_auth():
    # 身份认证,获取认证 Token。属于 Class C 请求。
    # 密钥格式 "keyId:applicationKey".
    id_and_key = "applicationKeyId:Application_Keys".encode('utf-8')
    # 基础认证字符串需编码为 byte 类型
    basic_auth_string = 'Basic '.encode('utf-8') + base64.b64encode(id_and_key)
    headers = {'Authorization': basic_auth_string}
    url = 'https://api.backblazeb2.com/b2api/v1/b2_authorize_account'

    r = requests.get(url, headers=headers)

    return r.json()


def b2_list_files(startFileName=None):
    # 获取 Bucket 中的文件列表,每次最多返回 10000 个文件,1000 个文件记为一个 Class C 请求,
    # 如果设置为一次获取 10000 个文件的列表,实际存储的文件为 3400 个,请求数记为 4 次 Class C。
    b2 = b2_auth()
    headers = {
        'Authorization': b2['authorizationToken']
    }
    data = {
        'bucketId': 'your_bucket_id',
        'maxFileCount': 10000,
        'startFileName': startFileName,
    }
    apiUrl = b2['apiUrl']

    r = requests.post('{}/b2api/v1/b2_list_file_names'.format(apiUrl), json=data, headers=headers)

    return r.json()


def b2_bucket_size():
    # 循环迭代文件列表,累加计算文件数量和已使用的容量。
    startFileName = None
    count = 0
    size = 0
    while True:
        data = b2_list_files(startFileName=startFileName)

        for f in data['files']:
            count += 1
            the_size = f['contentLength']
            size += the_size

        startFileName = data['nextFileName']

        if not startFileName:
            break

    print('文件数:' + str(count))
    print('容量:' + str(round(size/1000/1000/1000, 2)) + ' GB')

# 运行函数
b2_bucket_size()

特别注意:id_and_keybasic_auth_string 必须进行 encode 编码处理

返回结果示例:

文件数:14899
容量:74.4 GB