跳转至

File类

文件类

v1版本, 不含上传文件等操作, 因为v2版本已经支持上传文件等操作

File

123 文件上传 V1 接口封装类

Source code in src/cpan123/File.py
class File:
    """123 文件上传 V1 接口封装类"""

    def __init__(self, auth: Auth, userinfo: UserInfoModel | None = None) -> None:
        """初始化 File 客户端

        Args:
            auth (Auth): 已授权的 Auth 实例
        """
        self.auth = auth
        self.userinfo = userinfo

    @validate_call
    def mkdir(self, name: str, parentID: int, verbose: bool = True) -> dict:
        """创建目录
        Args:
            name (str): 目录名称
            parentID (int): 父目录ID
        """
        data = {
            "name": name,
            "parentID": parentID,
        }
        return self.auth.request_json("POST", API.FilePath.MKDIR, json=data, verbose=verbose)

    @validate_call
    def name(
        self,
        fileId: int,
        fileName: str,
    ) -> dict:
        """单个文件重命名

        Args:
            fileId (int): 文件ID
            fileName (str): 新文件名

        """
        data = {
            "fileID": fileId,
            "fileName": fileName,
        }
        return self.auth.request_json("PUT", API.FilePath.NAME, json=data)

    @validate_call
    def rename(
        self,
        renameList: list[str],
    ) -> dict:
        """批量重命名文件,最多支持同时30个文件重命名

        Args:
            renameList (list): 重命名列表,格式为 [14705301|测试文件重命名","14705306|测试文件重命名.mp4"]

        """
        if len(renameList) > 30:
            log.error("renameList 参数长度最大不超过 30,请修改后重试")
            sys.exit(1)
        # 检查格式
        for item in renameList:
            if "|" not in item or len(item.split("|")) != 2:
                log.error(f"renameList 参数格式错误: {item}, 正确格式为 fileID|新文件名,请修改后重试")
                sys.exit(1)
        return self.auth.request_json("POST", API.FilePath.RENAME, json={"renameList": renameList})

    @validate_call
    def trash(
        self,
        fileIDs: list[int],
    ) -> dict:
        """删除的文件,会放入回收站中

        Args:
            fileIDs (list[int]): 文件id数组,一次性最大不能超过 100 个文件

        """
        if len(fileIDs) > 100:
            log.error("fileIDs 参数长度最大不超过 100,请修改后重试")
            sys.exit(1)
        return self.auth.request_json("POST", API.FilePath.TRASH, json={"fileIDs": fileIDs})

    @validate_call
    def delete(
        self,
        fileIDs: list[int],
    ) -> dict:
        """彻底删除文件前,文件必须要在回收站中,否则无法删除

        Args:
            fileIDs (list): 文件id数组,参数长度最大不超过 100

        """
        if len(fileIDs) > 100:
            log.error("fileIDs 参数长度最大不超过 100,请修改后重试")
            sys.exit(1)
        return self.auth.request_json("POST", API.FilePath.DELETE, json={"fileIDs": fileIDs})

    @validate_call
    def recover(
        self,
        fileIDs: list[int],
    ) -> dict:
        """将回收站的文件恢复至删除前的位置

        Args:
            fileIDs (list): 文件id数组,一次性最大不能超过 100 个文件

        """
        if len(fileIDs) > 100:
            log.error("fileIDs 参数长度最大不超过 100,请修改后重试")
            sys.exit(1)
        data = {
            "fileIDs": fileIDs,
        }
        return self.auth.request_json("POST", API.FilePath.RECOVER, json=data)

    @validate_call
    def recover_by_path(
        self,
        fileIDs: list[int],
        parentFileID: int = 0,
    ) -> dict:
        """将回收站的文件恢复至删除前的位置

        Args:
            fileIDs (list): 文件id数组,一次性最大不能超过 100 个文件

        """
        if len(fileIDs) > 100:
            log.error("fileIDs 参数长度最大不超过 100,请修改后重试")
            sys.exit(1)
        data = {
            "fileIDs": fileIDs,
            "parentFileID": parentFileID,
        }
        return self.auth.request_json("POST", API.FilePath.RECOVER_BY_PATH, json=data)

    @validate_call
    def detail(
        self,
        fileID: int,
    ) -> dict:
        """获取单个文件详情

        Args:
            fileID (int): 文件ID

        """
        return self.auth.request_json("GET", API.FilePath.DETAIL, params={"fileID": fileID})

    @validate_call
    def infos(
        self,
        fileIds: list[int],
    ) -> dict:
        """获取多个文件详情

        Args:
            fileIds (list): 文件ID列表

        """
        return self.auth.request_json("POST", API.FilePath.INFOS, json={"fileIds": fileIds})

    @validate_call
    def list_v2(
        self,
        parentFileId: int,
        limit: int = 100,
        searchData: Optional[str] = None,
        searchMode: Optional[int] = 0,
        lastFileId: Optional[int] = None,
        isTrashed: bool = True,
    ) -> dict:
        """获取文件列表(V2版本, v1弃用)

        此接口查询结果包含回收站的文件,需自行根据字段trashed判断处理

        Args:
            parentFileId (int): 文件夹ID,根目录传 0
            limit (int): 每页文件数量,最大不超过100
            searchData (str, optional):搜索关键字将无视文件夹ID参数. 将会进行全局查找
            searchMode (int, optional): 搜索模式,0:模糊搜索,1:精确搜索,默认为0
            lastFileId (int, optional): 翻页查询时需要填写
            isTrashed (bool): 是否包含回收站文件,默认包含 (官方是包含的), 保持与官网一致

        """
        # 如果要对参数进行校验,需要 Field 等参数校验方法
        # 默认已开启函数参数校验
        # 也可以在函数体中进行参数校验了, 不能参与计算
        # print(self.list_v2.__name__)
        # print(self.list_v2.__doc__)
        if limit > 100 and limit < 0:
            log.error("limit 参数最大值为 100,请修改后重试")
            sys.exit(1)
        params = {
            "parentFileId": parentFileId,
            "limit": limit,
            "searchData": searchData,
            "searchMode": searchMode,
            "lastFileId": lastFileId,
        }
        resp = self.auth.request_json("GET", API.FilePath.LIST_V2, params=params)
        # 不能要回收站的文件
        if isTrashed:
            return resp
        # 前提 fileList 存在
        try:
            if (
                resp
                and isinstance(resp, dict)
                and "data" in resp
                and isinstance(resp["data"], dict)
                and "fileList" in resp["data"]
                and isinstance(resp["data"]["fileList"], list)
            ):
                resp["data"]["fileList"] = [file for file in resp["data"]["fileList"] if file.get("trashed") == 0]
            return resp
        except Exception as e:
            log.error(f"过滤回收站文件时出错: {e}")
            return resp

    @validate_call
    def list_v1(
        self,
        parentFileId: int = 0,
        page: int = 1,
        limit: int = Field(default=100, gt=0, le=100),
        orderBy: str = "file_id",
        orderDirection: str = "asc",
        trashed: Optional[bool] = True,
        searchData: Optional[str] = "",
    ) -> dict:
        """获取文件列表(V1版本, v2弃用)

        具体参考 list_v2的用法,这个只是一个别名, 因为list和python中的list冲突了(为了尽力保证和url的末端一致性)

        Args:
            parentFileId (int): 文件夹ID,根目录传 0
            page (int): 页码,从 1 开始
            limit (int): 每页文件数量,最大不超过100
            orderBy (str): 排序字段,file_id(默认),filename,size,created_at,updated_at
            orderDirection (str): 排序方式,asc(默认),desc
            trashed (bool, optional): 是否包含回收站文件,默认包含
            searchData (str, optional): 搜索关键字将无视文件夹ID参数. 将会进行全局查找

        """
        if limit > 100 and limit < 0:
            log.error("limit 参数最大值为 100,请修改后重试")
            sys.exit(1)
        params = {
            "parentFileId": parentFileId,
            "page": page,
            "limit": limit,
            "orderBy": orderBy,
            "orderDirection": orderDirection,
            "trashed": trashed,
            "searchData": searchData,
        }
        return self.auth.request_json("GET", API.FilePath.LIST, params=params)

    @validate_call
    def move(
        self,
        fileIDs: list[int],
        toParentFileID: int = 0,
    ) -> dict:
        """批量移动文件,单级最多支持100个

        Args:
            fileIDs: 文件id数组
            toParentFileID: 要移动到的目标文件夹id,移动到根目录时填写 0

        """
        if len(fileIDs) > 100:
            log.error("fileIDs 参数长度最大不超过 100,请修改后重试")
            sys.exit(1)
        data = {
            "fileIDs": fileIDs,
            "toParentFileID": toParentFileID,
        }
        return self.auth.request_json("POST", API.FilePath.MOVE, json=data)

    @validate_call
    def download_info(
        self,
        fileId: int,
    ) -> dict:
        """获取文件下载地址

        Args:
            fileId (int): 文件ID

        """
        return self.auth.request_json("GET", API.FilePath.DOWNLOAD_INFO, params={"fileId": fileId})

__init__

__init__(
    auth: Auth, userinfo: UserInfoModel | None = None
) -> None

初始化 File 客户端

Parameters:

Name Type Description Default
auth Auth

已授权的 Auth 实例

required
Source code in src/cpan123/File.py
def __init__(self, auth: Auth, userinfo: UserInfoModel | None = None) -> None:
    """初始化 File 客户端

    Args:
        auth (Auth): 已授权的 Auth 实例
    """
    self.auth = auth
    self.userinfo = userinfo

mkdir

mkdir(
    name: str, parentID: int, verbose: bool = True
) -> dict

创建目录 Args: name (str): 目录名称 parentID (int): 父目录ID

Source code in src/cpan123/File.py
@validate_call
def mkdir(self, name: str, parentID: int, verbose: bool = True) -> dict:
    """创建目录
    Args:
        name (str): 目录名称
        parentID (int): 父目录ID
    """
    data = {
        "name": name,
        "parentID": parentID,
    }
    return self.auth.request_json("POST", API.FilePath.MKDIR, json=data, verbose=verbose)

name

name(fileId: int, fileName: str) -> dict

单个文件重命名

Parameters:

Name Type Description Default
fileId int

文件ID

required
fileName str

新文件名

required
Source code in src/cpan123/File.py
@validate_call
def name(
    self,
    fileId: int,
    fileName: str,
) -> dict:
    """单个文件重命名

    Args:
        fileId (int): 文件ID
        fileName (str): 新文件名

    """
    data = {
        "fileID": fileId,
        "fileName": fileName,
    }
    return self.auth.request_json("PUT", API.FilePath.NAME, json=data)

rename

rename(renameList: list[str]) -> dict

批量重命名文件,最多支持同时30个文件重命名

Parameters:

Name Type Description Default
renameList list

重命名列表,格式为 [14705301|测试文件重命名","14705306|测试文件重命名.mp4"]

required
Source code in src/cpan123/File.py
@validate_call
def rename(
    self,
    renameList: list[str],
) -> dict:
    """批量重命名文件,最多支持同时30个文件重命名

    Args:
        renameList (list): 重命名列表,格式为 [14705301|测试文件重命名","14705306|测试文件重命名.mp4"]

    """
    if len(renameList) > 30:
        log.error("renameList 参数长度最大不超过 30,请修改后重试")
        sys.exit(1)
    # 检查格式
    for item in renameList:
        if "|" not in item or len(item.split("|")) != 2:
            log.error(f"renameList 参数格式错误: {item}, 正确格式为 fileID|新文件名,请修改后重试")
            sys.exit(1)
    return self.auth.request_json("POST", API.FilePath.RENAME, json={"renameList": renameList})

trash

trash(fileIDs: list[int]) -> dict

删除的文件,会放入回收站中

Parameters:

Name Type Description Default
fileIDs list[int]

文件id数组,一次性最大不能超过 100 个文件

required
Source code in src/cpan123/File.py
@validate_call
def trash(
    self,
    fileIDs: list[int],
) -> dict:
    """删除的文件,会放入回收站中

    Args:
        fileIDs (list[int]): 文件id数组,一次性最大不能超过 100 个文件

    """
    if len(fileIDs) > 100:
        log.error("fileIDs 参数长度最大不超过 100,请修改后重试")
        sys.exit(1)
    return self.auth.request_json("POST", API.FilePath.TRASH, json={"fileIDs": fileIDs})

delete

delete(fileIDs: list[int]) -> dict

彻底删除文件前,文件必须要在回收站中,否则无法删除

Parameters:

Name Type Description Default
fileIDs list

文件id数组,参数长度最大不超过 100

required
Source code in src/cpan123/File.py
@validate_call
def delete(
    self,
    fileIDs: list[int],
) -> dict:
    """彻底删除文件前,文件必须要在回收站中,否则无法删除

    Args:
        fileIDs (list): 文件id数组,参数长度最大不超过 100

    """
    if len(fileIDs) > 100:
        log.error("fileIDs 参数长度最大不超过 100,请修改后重试")
        sys.exit(1)
    return self.auth.request_json("POST", API.FilePath.DELETE, json={"fileIDs": fileIDs})

recover

recover(fileIDs: list[int]) -> dict

将回收站的文件恢复至删除前的位置

Parameters:

Name Type Description Default
fileIDs list

文件id数组,一次性最大不能超过 100 个文件

required
Source code in src/cpan123/File.py
@validate_call
def recover(
    self,
    fileIDs: list[int],
) -> dict:
    """将回收站的文件恢复至删除前的位置

    Args:
        fileIDs (list): 文件id数组,一次性最大不能超过 100 个文件

    """
    if len(fileIDs) > 100:
        log.error("fileIDs 参数长度最大不超过 100,请修改后重试")
        sys.exit(1)
    data = {
        "fileIDs": fileIDs,
    }
    return self.auth.request_json("POST", API.FilePath.RECOVER, json=data)

recover_by_path

recover_by_path(
    fileIDs: list[int], parentFileID: int = 0
) -> dict

将回收站的文件恢复至删除前的位置

Parameters:

Name Type Description Default
fileIDs list

文件id数组,一次性最大不能超过 100 个文件

required
Source code in src/cpan123/File.py
@validate_call
def recover_by_path(
    self,
    fileIDs: list[int],
    parentFileID: int = 0,
) -> dict:
    """将回收站的文件恢复至删除前的位置

    Args:
        fileIDs (list): 文件id数组,一次性最大不能超过 100 个文件

    """
    if len(fileIDs) > 100:
        log.error("fileIDs 参数长度最大不超过 100,请修改后重试")
        sys.exit(1)
    data = {
        "fileIDs": fileIDs,
        "parentFileID": parentFileID,
    }
    return self.auth.request_json("POST", API.FilePath.RECOVER_BY_PATH, json=data)

detail

detail(fileID: int) -> dict

获取单个文件详情

Parameters:

Name Type Description Default
fileID int

文件ID

required
Source code in src/cpan123/File.py
@validate_call
def detail(
    self,
    fileID: int,
) -> dict:
    """获取单个文件详情

    Args:
        fileID (int): 文件ID

    """
    return self.auth.request_json("GET", API.FilePath.DETAIL, params={"fileID": fileID})

infos

infos(fileIds: list[int]) -> dict

获取多个文件详情

Parameters:

Name Type Description Default
fileIds list

文件ID列表

required
Source code in src/cpan123/File.py
@validate_call
def infos(
    self,
    fileIds: list[int],
) -> dict:
    """获取多个文件详情

    Args:
        fileIds (list): 文件ID列表

    """
    return self.auth.request_json("POST", API.FilePath.INFOS, json={"fileIds": fileIds})

list_v2

list_v2(
    parentFileId: int,
    limit: int = 100,
    searchData: Optional[str] = None,
    searchMode: Optional[int] = 0,
    lastFileId: Optional[int] = None,
    isTrashed: bool = True,
) -> dict

获取文件列表(V2版本, v1弃用)

此接口查询结果包含回收站的文件,需自行根据字段trashed判断处理

Parameters:

Name Type Description Default
parentFileId int

文件夹ID,根目录传 0

required
limit int

每页文件数量,最大不超过100

100
searchData str

搜索关键字将无视文件夹ID参数. 将会进行全局查找

None
searchMode int

搜索模式,0:模糊搜索,1:精确搜索,默认为0

0
lastFileId int

翻页查询时需要填写

None
isTrashed bool

是否包含回收站文件,默认包含 (官方是包含的), 保持与官网一致

True
Source code in src/cpan123/File.py
@validate_call
def list_v2(
    self,
    parentFileId: int,
    limit: int = 100,
    searchData: Optional[str] = None,
    searchMode: Optional[int] = 0,
    lastFileId: Optional[int] = None,
    isTrashed: bool = True,
) -> dict:
    """获取文件列表(V2版本, v1弃用)

    此接口查询结果包含回收站的文件,需自行根据字段trashed判断处理

    Args:
        parentFileId (int): 文件夹ID,根目录传 0
        limit (int): 每页文件数量,最大不超过100
        searchData (str, optional):搜索关键字将无视文件夹ID参数. 将会进行全局查找
        searchMode (int, optional): 搜索模式,0:模糊搜索,1:精确搜索,默认为0
        lastFileId (int, optional): 翻页查询时需要填写
        isTrashed (bool): 是否包含回收站文件,默认包含 (官方是包含的), 保持与官网一致

    """
    # 如果要对参数进行校验,需要 Field 等参数校验方法
    # 默认已开启函数参数校验
    # 也可以在函数体中进行参数校验了, 不能参与计算
    # print(self.list_v2.__name__)
    # print(self.list_v2.__doc__)
    if limit > 100 and limit < 0:
        log.error("limit 参数最大值为 100,请修改后重试")
        sys.exit(1)
    params = {
        "parentFileId": parentFileId,
        "limit": limit,
        "searchData": searchData,
        "searchMode": searchMode,
        "lastFileId": lastFileId,
    }
    resp = self.auth.request_json("GET", API.FilePath.LIST_V2, params=params)
    # 不能要回收站的文件
    if isTrashed:
        return resp
    # 前提 fileList 存在
    try:
        if (
            resp
            and isinstance(resp, dict)
            and "data" in resp
            and isinstance(resp["data"], dict)
            and "fileList" in resp["data"]
            and isinstance(resp["data"]["fileList"], list)
        ):
            resp["data"]["fileList"] = [file for file in resp["data"]["fileList"] if file.get("trashed") == 0]
        return resp
    except Exception as e:
        log.error(f"过滤回收站文件时出错: {e}")
        return resp

list_v1

list_v1(
    parentFileId: int = 0,
    page: int = 1,
    limit: int = Field(default=100, gt=0, le=100),
    orderBy: str = "file_id",
    orderDirection: str = "asc",
    trashed: Optional[bool] = True,
    searchData: Optional[str] = "",
) -> dict

获取文件列表(V1版本, v2弃用)

具体参考 list_v2的用法,这个只是一个别名, 因为list和python中的list冲突了(为了尽力保证和url的末端一致性)

Parameters:

Name Type Description Default
parentFileId int

文件夹ID,根目录传 0

0
page int

页码,从 1 开始

1
limit int

每页文件数量,最大不超过100

Field(default=100, gt=0, le=100)
orderBy str

排序字段,file_id(默认),filename,size,created_at,updated_at

'file_id'
orderDirection str

排序方式,asc(默认),desc

'asc'
trashed bool

是否包含回收站文件,默认包含

True
searchData str

搜索关键字将无视文件夹ID参数. 将会进行全局查找

''
Source code in src/cpan123/File.py
@validate_call
def list_v1(
    self,
    parentFileId: int = 0,
    page: int = 1,
    limit: int = Field(default=100, gt=0, le=100),
    orderBy: str = "file_id",
    orderDirection: str = "asc",
    trashed: Optional[bool] = True,
    searchData: Optional[str] = "",
) -> dict:
    """获取文件列表(V1版本, v2弃用)

    具体参考 list_v2的用法,这个只是一个别名, 因为list和python中的list冲突了(为了尽力保证和url的末端一致性)

    Args:
        parentFileId (int): 文件夹ID,根目录传 0
        page (int): 页码,从 1 开始
        limit (int): 每页文件数量,最大不超过100
        orderBy (str): 排序字段,file_id(默认),filename,size,created_at,updated_at
        orderDirection (str): 排序方式,asc(默认),desc
        trashed (bool, optional): 是否包含回收站文件,默认包含
        searchData (str, optional): 搜索关键字将无视文件夹ID参数. 将会进行全局查找

    """
    if limit > 100 and limit < 0:
        log.error("limit 参数最大值为 100,请修改后重试")
        sys.exit(1)
    params = {
        "parentFileId": parentFileId,
        "page": page,
        "limit": limit,
        "orderBy": orderBy,
        "orderDirection": orderDirection,
        "trashed": trashed,
        "searchData": searchData,
    }
    return self.auth.request_json("GET", API.FilePath.LIST, params=params)

move

move(fileIDs: list[int], toParentFileID: int = 0) -> dict

批量移动文件,单级最多支持100个

Parameters:

Name Type Description Default
fileIDs list[int]

文件id数组

required
toParentFileID int

要移动到的目标文件夹id,移动到根目录时填写 0

0
Source code in src/cpan123/File.py
@validate_call
def move(
    self,
    fileIDs: list[int],
    toParentFileID: int = 0,
) -> dict:
    """批量移动文件,单级最多支持100个

    Args:
        fileIDs: 文件id数组
        toParentFileID: 要移动到的目标文件夹id,移动到根目录时填写 0

    """
    if len(fileIDs) > 100:
        log.error("fileIDs 参数长度最大不超过 100,请修改后重试")
        sys.exit(1)
    data = {
        "fileIDs": fileIDs,
        "toParentFileID": toParentFileID,
    }
    return self.auth.request_json("POST", API.FilePath.MOVE, json=data)

download_info

download_info(fileId: int) -> dict

获取文件下载地址

Parameters:

Name Type Description Default
fileId int

文件ID

required
Source code in src/cpan123/File.py
@validate_call
def download_info(
    self,
    fileId: int,
) -> dict:
    """获取文件下载地址

    Args:
        fileId (int): 文件ID

    """
    return self.auth.request_json("GET", API.FilePath.DOWNLOAD_INFO, params={"fileId": fileId})

文件上传类(V2)

File2

123 文件上传 V2 接口封装类

Source code in src/cpan123/File2.py
class File2:
    """123 文件上传 V2 接口封装类"""

    def __init__(self, auth: Auth, userinfo: UserInfoModel | None = None) -> None:
        """初始化

        Args:
            auth (Auth): 已授权的 Auth 实例
        """
        self.auth = auth
        self.userinfo = userinfo

    @validate_call
    def create(
        self,
        parentFileID: int,
        filename: str,
        etag: str = Field(default="", max_length=32),
        size: int = Field(default=0, gt=0),
        *,
        duplicate: int = 1,
        containDir: bool = False,
    ) -> dict:
        """
        创建文件上传任务.

        - 文件名不能全部是空格
        - 开发者上传单文件大小限制10GB
        - 文件名要小于256个字符且不能包含以下任何字符: `"\\/:*?|><`

        Args:
            parentFileID: 父目录id,上传到根目录时填写 0
            filename: 文件名要小于255个字符且不能包含一些特殊字符(不建议重名)
            etag: 文件的md5值, 如果不传入,则自动计算
            size: 文件大小, 单位字节
            duplicate: 当有相同文件名时,文件处理策略(1保留两者,新文件名将自动添加后缀,2覆盖原文件)
            containDir: 上传文件是否包含路径,默认false

        Returns:
            创建上传任务的响应数据
        """
        data = {
            "parentFileID": parentFileID,
            "filename": filename,
            "etag": etag,
            "size": size,
            "duplicate": duplicate,
            "containDir": containDir,
        }
        return self.auth.request_json("POST", API.File2Path.CREATE, json=data)

    @validate_call
    def sha1_reuse(self, parentFileID: int, filename: str, sha1: str, size: int, *, duplicate: int = 1) -> dict:
        """秒传文件.

        Args:
            parentFileID: 父目录id,上传到根目录时填写 0
            filename: 文件名要小于255个字符且不能包含一些特殊字符(不建议重名)
            sha1: 文件的sha1值
            size: 文件大小, 单位字节
            duplicate: 当有相同文件名时,文件处理策略(1保留两者,新文件名将自动添加后缀,2覆盖原文件)

        Returns:
            秒传文件的响应数据
        """
        data = {
            "parentFileID": parentFileID,
            "filename": filename,
            "sha1": sha1,
            "size": size,
            "duplicate": duplicate,
        }
        return self.auth.request_json("POST", API.File2Path.SHA1_REUSE, json=data)

    @validate_call
    def slice(
        self,
        preuploadID: Union[int, str],
        sliceNo: int,
        sliceMD5: str,
        slice: bytes,
        upload_server: str,
    ) -> dict:
        """上传文件分片.

        Args:
            preuploadID:  预上传ID(可以是字符串或整数)
            sliceNo: 分片序号,从1开始自增
            sliceMD5: 当前分片md5
            slice: 分片二进制流
            upload_server: 上传服务器地址(从创建文件接口返回的 servers 中获取)

        Returns:
            上传分片的响应数据
        """
        data = {
            "preuploadID": str(preuploadID),  # 确保转换为字符串
            "sliceNo": sliceNo,
            "sliceMD5": sliceMD5,
        }

        files = {
            "slice": ("slice", slice, "application/octet-stream"),
        }

        url = f"{upload_server}/upload/v2/file/slice"
        return self.auth.request_json("POST", url, data=data, files=files)

    @validate_call
    def upload_complete(self, preuploadID: Union[int, str]) -> dict:
        """完成文件上传.

        Args:
            preuploadID: 预上传ID(可以是字符串或整数)
        """
        data = {
            "preuploadID": str(preuploadID),  # 确保转换为字符串
        }
        return self.auth.request_json("POST", API.File2Path.UPLOAD_COMPLETE, json=data)

    @validate_call
    def domain(self) -> dict:
        """获取上传域名."""
        return self.auth.request_json("GET", API.File2Path.DOMAIN)

    @validate_call
    def single_create(
        self,
        parentFileID: int,
        filename: str,
        upload_server: str,
        etag: str = Field(default="", max_length=32),
        size: int = Field(default=0, gt=0),
        file: bytes = Field(default=b""),
        duplicate: int = 1,
        containDir: bool = False,
    ) -> dict:  # type: ignore
        """单步上传

        - 文件名要小于256个字符且不能包含以下任何字符
        - 文件名不能全部是空格
        - 此接口限制开发者上传单文件大小为1GB
        - 上传域名是获取上传域名接口响应中的域名
        - 此接口用于实现小文件单步上传一次HTTP请求交互即可完成上传

        Args:
            parentFileID: 父目录id,上传到根目录时填写 0
            filename: 文件名要小于255个字符且不能包含一些特殊字符(不建议重名)
            etag: 文件的md5值, 如果不传入,则自动计算
            size: 文件大小, 单位字节
            file: 文件二进制流
            duplicate: 当有相同文件名时,文件处理策略(1保留两者,新文件名将自动添加后缀,2覆盖原文件)
            containDir: 上传文件是否包含路径,默认false
            upload_server: 上传服务器地址(从获取上传域名接口返回)

        Returns:
            单步上传的响应数据

        """
        data = {
            "parentFileID": parentFileID,
            "filename": filename,
            "etag": etag,
            "size": size,
            "duplicate": duplicate,
            "containDir": containDir,
        }

        files = {
            "file": (filename, file, "application/octet-stream"),
        }

        # 如果提供了上传服务器地址,使用完整URL;否则使用默认路径
        url = f"{upload_server}/upload/v2/file/single/create"
        return self.auth.request_json("POST", url, data=data, files=files)

__init__

__init__(
    auth: Auth, userinfo: UserInfoModel | None = None
) -> None

初始化

Parameters:

Name Type Description Default
auth Auth

已授权的 Auth 实例

required
Source code in src/cpan123/File2.py
def __init__(self, auth: Auth, userinfo: UserInfoModel | None = None) -> None:
    """初始化

    Args:
        auth (Auth): 已授权的 Auth 实例
    """
    self.auth = auth
    self.userinfo = userinfo

create

create(
    parentFileID: int,
    filename: str,
    etag: str = Field(default="", max_length=32),
    size: int = Field(default=0, gt=0),
    *,
    duplicate: int = 1,
    containDir: bool = False
) -> dict

创建文件上传任务.

  • 文件名不能全部是空格
  • 开发者上传单文件大小限制10GB
  • 文件名要小于256个字符且不能包含以下任何字符: "\/:*?|><

Parameters:

Name Type Description Default
parentFileID int

父目录id,上传到根目录时填写 0

required
filename str

文件名要小于255个字符且不能包含一些特殊字符(不建议重名)

required
etag str

文件的md5值, 如果不传入,则自动计算

Field(default='', max_length=32)
size int

文件大小, 单位字节

Field(default=0, gt=0)
duplicate int

当有相同文件名时,文件处理策略(1保留两者,新文件名将自动添加后缀,2覆盖原文件)

1
containDir bool

上传文件是否包含路径,默认false

False

Returns:

Type Description
dict

创建上传任务的响应数据

Source code in src/cpan123/File2.py
@validate_call
def create(
    self,
    parentFileID: int,
    filename: str,
    etag: str = Field(default="", max_length=32),
    size: int = Field(default=0, gt=0),
    *,
    duplicate: int = 1,
    containDir: bool = False,
) -> dict:
    """
    创建文件上传任务.

    - 文件名不能全部是空格
    - 开发者上传单文件大小限制10GB
    - 文件名要小于256个字符且不能包含以下任何字符: `"\\/:*?|><`

    Args:
        parentFileID: 父目录id,上传到根目录时填写 0
        filename: 文件名要小于255个字符且不能包含一些特殊字符(不建议重名)
        etag: 文件的md5值, 如果不传入,则自动计算
        size: 文件大小, 单位字节
        duplicate: 当有相同文件名时,文件处理策略(1保留两者,新文件名将自动添加后缀,2覆盖原文件)
        containDir: 上传文件是否包含路径,默认false

    Returns:
        创建上传任务的响应数据
    """
    data = {
        "parentFileID": parentFileID,
        "filename": filename,
        "etag": etag,
        "size": size,
        "duplicate": duplicate,
        "containDir": containDir,
    }
    return self.auth.request_json("POST", API.File2Path.CREATE, json=data)

sha1_reuse

sha1_reuse(
    parentFileID: int,
    filename: str,
    sha1: str,
    size: int,
    *,
    duplicate: int = 1
) -> dict

秒传文件.

Parameters:

Name Type Description Default
parentFileID int

父目录id,上传到根目录时填写 0

required
filename str

文件名要小于255个字符且不能包含一些特殊字符(不建议重名)

required
sha1 str

文件的sha1值

required
size int

文件大小, 单位字节

required
duplicate int

当有相同文件名时,文件处理策略(1保留两者,新文件名将自动添加后缀,2覆盖原文件)

1

Returns:

Type Description
dict

秒传文件的响应数据

Source code in src/cpan123/File2.py
@validate_call
def sha1_reuse(self, parentFileID: int, filename: str, sha1: str, size: int, *, duplicate: int = 1) -> dict:
    """秒传文件.

    Args:
        parentFileID: 父目录id,上传到根目录时填写 0
        filename: 文件名要小于255个字符且不能包含一些特殊字符(不建议重名)
        sha1: 文件的sha1值
        size: 文件大小, 单位字节
        duplicate: 当有相同文件名时,文件处理策略(1保留两者,新文件名将自动添加后缀,2覆盖原文件)

    Returns:
        秒传文件的响应数据
    """
    data = {
        "parentFileID": parentFileID,
        "filename": filename,
        "sha1": sha1,
        "size": size,
        "duplicate": duplicate,
    }
    return self.auth.request_json("POST", API.File2Path.SHA1_REUSE, json=data)

slice

slice(
    preuploadID: Union[int, str],
    sliceNo: int,
    sliceMD5: str,
    slice: bytes,
    upload_server: str,
) -> dict

上传文件分片.

Parameters:

Name Type Description Default
preuploadID Union[int, str]

预上传ID(可以是字符串或整数)

required
sliceNo int

分片序号,从1开始自增

required
sliceMD5 str

当前分片md5

required
slice bytes

分片二进制流

required
upload_server str

上传服务器地址(从创建文件接口返回的 servers 中获取)

required

Returns:

Type Description
dict

上传分片的响应数据

Source code in src/cpan123/File2.py
@validate_call
def slice(
    self,
    preuploadID: Union[int, str],
    sliceNo: int,
    sliceMD5: str,
    slice: bytes,
    upload_server: str,
) -> dict:
    """上传文件分片.

    Args:
        preuploadID:  预上传ID(可以是字符串或整数)
        sliceNo: 分片序号,从1开始自增
        sliceMD5: 当前分片md5
        slice: 分片二进制流
        upload_server: 上传服务器地址(从创建文件接口返回的 servers 中获取)

    Returns:
        上传分片的响应数据
    """
    data = {
        "preuploadID": str(preuploadID),  # 确保转换为字符串
        "sliceNo": sliceNo,
        "sliceMD5": sliceMD5,
    }

    files = {
        "slice": ("slice", slice, "application/octet-stream"),
    }

    url = f"{upload_server}/upload/v2/file/slice"
    return self.auth.request_json("POST", url, data=data, files=files)

upload_complete

upload_complete(preuploadID: Union[int, str]) -> dict

完成文件上传.

Parameters:

Name Type Description Default
preuploadID Union[int, str]

预上传ID(可以是字符串或整数)

required
Source code in src/cpan123/File2.py
@validate_call
def upload_complete(self, preuploadID: Union[int, str]) -> dict:
    """完成文件上传.

    Args:
        preuploadID: 预上传ID(可以是字符串或整数)
    """
    data = {
        "preuploadID": str(preuploadID),  # 确保转换为字符串
    }
    return self.auth.request_json("POST", API.File2Path.UPLOAD_COMPLETE, json=data)

domain

domain() -> dict

获取上传域名.

Source code in src/cpan123/File2.py
@validate_call
def domain(self) -> dict:
    """获取上传域名."""
    return self.auth.request_json("GET", API.File2Path.DOMAIN)

single_create

single_create(
    parentFileID: int,
    filename: str,
    upload_server: str,
    etag: str = Field(default="", max_length=32),
    size: int = Field(default=0, gt=0),
    file: bytes = Field(default=b""),
    duplicate: int = 1,
    containDir: bool = False,
) -> dict

单步上传

  • 文件名要小于256个字符且不能包含以下任何字符
  • 文件名不能全部是空格
  • 此接口限制开发者上传单文件大小为1GB
  • 上传域名是获取上传域名接口响应中的域名
  • 此接口用于实现小文件单步上传一次HTTP请求交互即可完成上传

Parameters:

Name Type Description Default
parentFileID int

父目录id,上传到根目录时填写 0

required
filename str

文件名要小于255个字符且不能包含一些特殊字符(不建议重名)

required
etag str

文件的md5值, 如果不传入,则自动计算

Field(default='', max_length=32)
size int

文件大小, 单位字节

Field(default=0, gt=0)
file bytes

文件二进制流

Field(default=b'')
duplicate int

当有相同文件名时,文件处理策略(1保留两者,新文件名将自动添加后缀,2覆盖原文件)

1
containDir bool

上传文件是否包含路径,默认false

False
upload_server str

上传服务器地址(从获取上传域名接口返回)

required

Returns:

Type Description
dict

单步上传的响应数据

Source code in src/cpan123/File2.py
@validate_call
def single_create(
    self,
    parentFileID: int,
    filename: str,
    upload_server: str,
    etag: str = Field(default="", max_length=32),
    size: int = Field(default=0, gt=0),
    file: bytes = Field(default=b""),
    duplicate: int = 1,
    containDir: bool = False,
) -> dict:  # type: ignore
    """单步上传

    - 文件名要小于256个字符且不能包含以下任何字符
    - 文件名不能全部是空格
    - 此接口限制开发者上传单文件大小为1GB
    - 上传域名是获取上传域名接口响应中的域名
    - 此接口用于实现小文件单步上传一次HTTP请求交互即可完成上传

    Args:
        parentFileID: 父目录id,上传到根目录时填写 0
        filename: 文件名要小于255个字符且不能包含一些特殊字符(不建议重名)
        etag: 文件的md5值, 如果不传入,则自动计算
        size: 文件大小, 单位字节
        file: 文件二进制流
        duplicate: 当有相同文件名时,文件处理策略(1保留两者,新文件名将自动添加后缀,2覆盖原文件)
        containDir: 上传文件是否包含路径,默认false
        upload_server: 上传服务器地址(从获取上传域名接口返回)

    Returns:
        单步上传的响应数据

    """
    data = {
        "parentFileID": parentFileID,
        "filename": filename,
        "etag": etag,
        "size": size,
        "duplicate": duplicate,
        "containDir": containDir,
    }

    files = {
        "file": (filename, file, "application/octet-stream"),
    }

    # 如果提供了上传服务器地址,使用完整URL;否则使用默认路径
    url = f"{upload_server}/upload/v2/file/single/create"
    return self.auth.request_json("POST", url, data=data, files=files)