前言:

Orchestra Python API (下文简称 API) 提供 upload_attachment 方法上传文件到对象存储服务器(OSS),并为新存储对象创建附件(Attachment)。

又提供 download_file 方法下载存储对象到本地文件。

OSS 采用签名机制保障数据安全可靠,依托云存储的优势,用户无论在哪里都可以安全访问数据。

我司不仅提供先进的云存储服务,也支持该服务的本地部署,欢迎咨询。

正文:

上传文件

upload_attachment 方法会先上传文件到 OSS,然后为新存储对象创建 Attachment 实体。

upload_attachment 方法的返回值是新创建的 Attachment 实体。

upload_attachment 方法包含一个位置参数,三个默认参数:

def upload_attachment(self, path, url=None, project=None, entity=None):

参数说明如下:

参数 说明
path 指本地文件路径。需要注意上传文件大小不能超过 1GB。
url 指新存储对象的路径,相当于 S3 接口的 object_name。
该参数要求开发者自定义存储路径。
需要注意的是,url 的根目录不能是 /media 或者 /static,请避免使用这两个目录。
url 中的文件名建议由 uuid 生成。
project 不为空时将传递给新 Attachment 实体的 project 字段。
project 是实体型字段,支持 Project 实体。
entity 不为空时将传递给新 Attachment 实体的 attachment_links 字段。
attachment_links 是实体列表型字段,支持的实体类型请参考 schema。

API 在上传文件时会先向服务端申请临时授权,临时授权有效期一个小时,过期会在方法中重新申请。

下面是一个上传本地文件的案例:

import os
import uuid

path = "/a/b/c/sample.png"
uuid_obj = uuid.uuid1()
basename = os.path.basename(path)
_, ext = os.path.splitext(basename)
url = "upload/image/%s%s" % (str(uuid_obj), ext)
attachment = client.upload_attachment(path, url)

开发者可以通过 Attachment.this_file 属性获取传入的 url 参数。

开发者可以通过 Attachment.attachment_type 属性值判断文件的存储方式。

Attachment.attachment_type 字段支持以下三种类型,分别对应三种存储方式:

存储类型 说明
local 表示 this_file 是本地路径。
link 表示 this_file 仅仅是 web 链接。
cloud 表示文件存储在 OSS 上。

下载文件

download_file 方法用于下载存储对象到本地。

download_file 方法兼容 OSS 存储对象和服务端媒体文件。

download_file 方法包含 object_name、 byte_array 两个参数:

def download_file(self, object_name, byte_array):

参数说明如下:

参数 说明
object_name 存储对象在 OSS 上的路径。
byte_array 既可以是 bytearray 类型也可以是列表类型,下载的二进制数据会被追加到 byte_array 对象尾部。

考虑到本地会话权限的不确定性,download_file 并不会把存储对象直接保存在本地文件中,而是保存 bytearray 对象中。

以下是两个下载存储对象并保存到本地文件中的案例。

在 PySide 环境中:

import os
from PySide6 import QtCore

path = "/a/b/c/sample.png"
object_name = "/upload/image/uuid.png"

if os.path.exists(path) and not os.access(path, os.W_OK | os.X_OK):
    raise IOError(
        "%s is not writable." % path)

byte_array = QtCore.QByteArray()
session.download_file(object_name, byte_array)

f = QtCore.QFile(path)
f.open(QtCore.QIODevice.WriteOnly)
f.write(byte_array)
f.close()

在 Python 环境中:

import os

path = "/a/b/c/sample.png"
object_name = "/upload/image/uuid.png"

if os.path.exists(path) and not os.access(path, os.W_OK | os.X_OK):
    raise IOError(
        "%s is not writable." % path)
        
with open(path, "wb") as f:
    byte_array = bytearray()
    session.download_file(object_name, byte_array)
    f.write(byte_array)

有了 upload_attachment 和 download_file 两大方法加持,文件上云再也不费劲辣。