DigitalOcean Spaces 拥有高达 250G 的云存储容量,并且支持单向(出站)高达1TB的月流量,入站流量不限制。特别适合个人用于文件存储及备份。
为了提高文件的上传效率,方便管理,学会使用 Python 上传文件到 DigitalOcean 空间绝对是个不错的选择。今天我们就来谈谈如何通过 Python 上传文件到 DigitalOcean 云存储空间的具体方法。在本文中,我们将通过 Pyhon 工具 Boto3 来达成此目标。
首先,我们打开终端通过以下命令安装 Boto3 库:
pip install boto3
上传本地文件到 DigitalOcean Spaces
安装完 Boto3 后,我们便可以使用其中的 upload_file
方法来最终完成文件上传功能。另外,我们将使用 mimetypes
来完成文件格式的转换。
新建一个名为 digitalocean.py
的 Pyhon 文件,代码如下:
import boto3
import mimetypes
def get_spaces_client(**kwargs):
"""
:param kwargs:
:return:
"""
region_name = kwargs.get("region_name")
endpoint_url = kwargs.get("endpoint_url")
key_id = kwargs.get("key_id")
secret_access_key = kwargs.get("secret_access_key")
session = boto3.session.Session()
return session.client(
's3',
region_name=region_name,
endpoint_url=endpoint_url,
aws_access_key_id=key_id,
aws_secret_access_key=secret_access_key
)
def upload_file_to_space(spaces_client, space_name, file_src, save_as, **kwargs):
"""
:param spaces_client: Your DigitalOcean Spaces client from get_spaces_client()
:param space_name: Unique name of your space. Can be found at your digitalocean panel
:param file_src: File location on your disk
:param save_as: Where to save your file in the space
:param kwargs
:return:
"""
is_public = kwargs.get("is_public", False)
content_type = kwargs.get("content_type")
meta = kwargs.get("meta")
if not content_type:
file_type_guess = mimetypes.guess_type(file_src)
if not file_type_guess[0]:
raise Exception("We can't identify content type. Please specify directly via content_type arg.")
content_type = file_type_guess[0]
extra_args = {
'ACL': "public-read" if is_public else "private",
'ContentType': content_type
}
if isinstance(meta, dict):
extra_args["Metadata"] = meta
return spaces_client.upload_file(
file_src,
space_name,
save_as,
# boto3.s3.transfer.S3Transfer.ALLOWED_UPLOAD_ARGS
ExtraArgs=extra_args
)
现在,您可以随时在任何 Python 模块中引用上述文件来上传本地文件到 DigitalOcean 云存储空间。
您可以这么做:
import digitalocean
client = digitalocean.get_spaces_client(
region_name="nyc3",
endpoint_url="https://nyc3.digitaloceanspaces.com",
key_id="my-spaces-key",
secret_access_key="my-spaces-secret-access-key"
)
digitalocean.upload_file_to_space(client, "space-name", "local/my_photo.jpg", "place/here/my_photo.jpg")
注意:请使用您自己的 “Spaces access keys” 来替换上述代码中 key_id
、secret_access_key
的值。您可以在 “DigitalOcean Spaces” 控制面板 “API” 菜单中的 “Spaces access keys” 来查询或者生成访问密钥。
如何设置 DigitalOcean 云存储空间文件权限为公开?
上传到 DigitalOcean Spaces 的文件默认权限为私有,只有您自己可以查看。如果您想通过 URL 将文件分享给其它人,必须设置文件权限为公开。我们可以通过设置 is_public=True
来做到这点。
虽然 Boto3
支持完整的 ACL 权限设置,但 DigitalOcean 云存储只支持 public-read
和 private
两种权限。所以,我们只需要简单的通过设置 is_public=True
来完成权限的设置。
digitalocean.upload_file_to_space(
client,
"space-name",
"local/my_photo.jpg",
"place/here/my_photo.jpg",
is_public=True
)
与文件格式 “binary/octet-stream” 有关的错误
如果您曾使用过 Boto3
,一定遇到过一个 mime-type
错误。事实上,无论是 Amazon S3 还是 DigitalOcean 云存储都存在使用 binary/octet-stream
或 octet/binary
相关的 mime-type
错误。在这里,我们通过 mimetypes.guess_type
解决了这个问题。当然,也可以通过 content_type
参数直接完成。
digitalocean.upload_file_to_space(
client,
"space-name",
"local/my_styles.css",
"place/my_styles.css",
content_type="text/css"
)
设置文件元数据(Metadata)
digitalocean.upload_file_to_space(
client,
"space-name",
"local/my_styles.css",
"space/path/my_styles.css",
meta={
"x-amz-meta-my-key": "your-value"
}
)
使用 “put_object” 上传字节数组文件
首先,添加以下函数到 digitalocean.py
模块:
def upload_bytes_array_to_space(spaces_client, space_name, file_body, save_as, **kwargs):
"""
:param spaces_client: Your DigitalOcean Spaces client from get_spaces_client()
:param space_name: Unique name of your space. Can be found at your digitalocean panel
:param file_body: Byte Array File
:param save_as: Where to save your file in the space
:param kwargs:
:return:
"""
is_public = kwargs.get("is_public", False)
content_type = kwargs.get("content_type")
meta = kwargs.get("meta")
args = {
"Bucket": space_name,
"Body": file_body,
"Key": save_as,
"ACL": "public-read" if is_public else "private"
}
if content_type:
args["ContentType"] = content_type
if isinstance(meta, dict):
args["Metadata"] = meta
return spaces_client.put_object(**args)
接下来,您就可以通过此函数通过二进制模式上传文件到 DigitalOcean 云存储空间。
with open("scripts/test/test.jpg", "rb") as my_file:
digitalocean.upload_bytes_array_to_space(
client,
"space-name",
my_file,
"space/path/test6.jpg",
is_public=True
)
当然,您也可以根据需要在上述代码中指定 content_type
。
设置文件元数据
与之前一样,您可以通过指定 meta
参数来为文件添加额外的 “metadata” 元数据信息。
with open("scripts/test/test.jpg", "rb") as my_file:
digitalocean.upload_bytes_array_to_space(
client,
"space-name",
my_file,
"space/path/test6.jpg",
is_public=True,
meta={
"x-amz-meta-my-key": "your-value"
}
)
总结
目前 DigitalOcean Spaces 正在推行免费试用2个月的优惠活动,您可以随时取消试用,并且如果试用期额度没有用完,还可以再次启用。试用期结束后,您需要支付5美元一个月的费用。
DigitalOcean 云存储空间兼容 AWS S3 存储标准,所以 DigitalOcean Spaces 的扩展应用很丰富。除了本文提供的方法,您还可以使用 Cyberduck 等客户端工具将数据同步备份到DigitalOcean 云存储空间。
最后,位于中国的用户需要注意,DigitalOcean 云存储空间纽约区网速要高于新加坡。