upload

上传

这个模块提供了一些和上传有关的函数

class p115client.tool.upload.P115MultipartUpload(url: str, path: str | PathLike | URL | SupportsGeturl, callback: dict, upload_id: str = '')[source]

Bases: object

待分块上传对象

Parameters:
  • url – HTTP 请求链接,包含存储桶和对象的名字

  • path – 待上传的文件路径

  • callback – 回调数据

  • upload_id – 上传任务 id

下面是一个上传的例子,会在命令行显示进度条

from pathlib import Path
from p115client import P115Client
from p115client.tool import P115MultipartUpload

client = P115Client(Path("~/115-cookies.txt").expanduser())

# NOTE: 待上传文件的路径(同样也支持 URL)
path = "/path/to/file"

uploader = P115MultipartUpload.from_path(path, user_id=client.user_id, user_key=client.user_key)
# NOTE: 返回字典说明秒传成功
if isinstance(uploader, dict):
    print(uploader)
else:
    from os.path import getsize
    # NOTE: 你可以随意指定其它各种进度条模块,或者自己写的函数
    from tqdm import tqdm

    # NOTE: 文件总大小需要你自己获取,`reporthook`只做增量推送
    with tqdm(total=getsize(path), unit="B", unit_scale=True, desc="Uploading") as t:
        # NOTE: `iter_upload` 支持其它请求模块,例如 urllib3
        #     from urllib3_request import request
        #     uploader.iter_upload(request=request)
        for _ in uploader.iter_upload(reporthook=t.update):
            pass
    print(uploader.complete())

你也可以自己写一个进度条

from collections import deque
from time import perf_counter

def make_reporthook(total: None | int = None):
    dq: deque[tuple[int, float]] = deque(maxlen=64)
    push = dq.append
    read_num = 0
    push((read_num, perf_counter()))
    while True:
        read_num += yield
        cur_t = perf_counter()
        speed = (read_num - dq[0][0]) / 1024 / 1024 / (cur_t - dq[0][1])
        if total:
            percentage = read_num / total * 100
            print(f"\r\x1b[K{read_num} / {total} | {speed:.2f} MB/s | {percentage:.2f} %", end="", flush=True)
        else:
            print(f"\r\x1b[K{read_num} | {speed:.2f} MB/s", end="", flush=True)
        push((read_num, cur_t))

然后像下面这样使用

for _ in uploader.iter_upload(reporthook=make_reporthook(getsize(path)).send):
    pass
complete(parts: None | list[dict] = None, *, async_: Literal[False] = False, **request_kwargs) dict[source]
complete(parts: None | list[dict] = None, *, async_: Literal[True], **request_kwargs) Coroutine[Any, Any, dict]

完成分块上传

Parameters:
  • parts – 分块信息列表

  • async – 是否异步

  • request_kwargs – 其它请求参数

Returns:

接口响应

property completed: bool

是否已完成

classmethod from_path(path: str | PathLike | URL | SupportsGeturl, pid: int | str = 0, filename: str = '', filesha1: str = '', filesize: int = -1, user_id: int | str = '', user_key: str = '', endpoint: str = 'http://oss-cn-shenzhen.aliyuncs.com', *, async_: Literal[False] = False, **request_kwargs) dict | P115MultipartUpload[source]
classmethod from_path(path: str | PathLike | URL | SupportsGeturl, pid: int | str = 0, filename: str = '', filesha1: str = '', filesize: int = -1, user_id: int | str = '', user_key: str = '', endpoint: str = 'http://oss-cn-shenzhen.aliyuncs.com', *, async_: Literal[True], **request_kwargs) Coroutine[Any, Any, dict | P115MultipartUpload]

准备上传,获取必要信息,可能秒传成功

Parameters:
  • path – 待上传的文件路径

  • pid – 上传文件到目录的 id 或 pickcode

  • filename – 文件名,若为空则自动确定

  • filesha1 – 文件的 sha1 哈希值,若为空则自动计算

  • filesize – 文件大小,若为负数则自动计算

  • user_id – 用户 id

  • user_key – 用户的 key

  • endpoint – 上传目的网址

  • async – 是否异步

  • request_kwargs – 其它请求参数

Returns:

秒传成功的响应或者待分块上传对象

iter_upload(partsize: int = 10485760, reporthook: None | Callable[[int], Any] = None, opener: None | Callable[[str, int], SupportsRead | Iterable[Buffer]] = None, *, async_: Literal[False] = False, **request_kwargs) Iterator[dict][source]
iter_upload(partsize: int = 10485760, reporthook: None | Callable[[int], Any] = None, opener: None | Callable[[str, int], SupportsRead | Awaitable[SupportsRead] | Iterable[Buffer] | AsyncIterable[Buffer]] = None, *, async_: Literal[True], **request_kwargs) AsyncIterator[dict]

逐个上传分块

Attention

上传完成后,并不会提交,请手动调用 .complete() 方法

Note

  • 可随意搭配请求模块: 指定 request 参数

  • 可随意搭配进度条: 指定 reporthook 参数

  • 可随意搭配文件打开器: 指定 opener 参数

Note

如果想把把上传过程外包出去,由其它任何工具完成,则调用 upload_url(part_number) 方法获得指定分块的上传链接和带签名请求头

或者调用 iter_upload_url(part_number_start) 创建一个迭代器,从某个分块编号开始,获得一系列的上传链接和带签名请求头

Parameters:
  • partsize – 分块大小

  • reporthook – 回调函数,可以用来统计已上传的数据量或者展示进度条

  • opener – 打开文件路径(本地路径或 URL)并从指定位置开始,如果为 None,则用默认方式

  • async – 是否异步

  • request_kwargs – 其它请求参数

Returns:

迭代器,产生各个刚上传完成的分块信息

iter_upload_url(part_number_start: int = 1, headers: None | dict[str, str] = None) Iterator[dict][source]

逐个获取上传链接和请求头

Caution

这个接口只用来获取上传链接和请求头,并不会做实际的上传,而且也不会判断总共有多少个分块,而是无限生成

Parameters:
  • part_number_start – 开始的分块编号,从 1 开始

  • headers – 默认的请求头,会被扩展

Returns:

迭代器,产生上传链接和请求头(带签名)

list_parts(async_: Literal[False] = False, **request_kwargs) list[dict][source]
list_parts(async_: Literal[True], **request_kwargs) Coroutine[Any, Any, list[dict]]

罗列已上传的分块信息

Parameters:
  • async – 是否异步

  • request_kwargs – 其它请求参数

Returns:

分块信息列表

property result: None | dict

完成后的结果

property succeeded: bool

结果是否成功

upload_url(part_number: int = 1, *, async_: Literal[False] = False, **request_kwargs) dict[source]
upload_url(part_number: int = 1, *, async_: Literal[True], **request_kwargs) Coroutine[Any, Any, dict]

获取分块上传的链接和请求头

Caution

这个接口只用来获取上传链接和请求头,并不会做实际的上传

Parameters:
  • part_number – 分块编号(从 1 开始)

  • async – 是否异步

  • request_kwargs – 其它请求参数

Returns:

上传链接 和 请求头 的 2 元组

p115client.tool.upload.iter_115_to_115(from_client: P115Client, to_client: P115Client, from_cid: int | str = 0, to_pid: int | str = 0, max_workers: int = 8, with_root: bool = True, use_iter_files: bool = False, *, async_: Literal[False] = False, **request_kwargs) Iterator[dict][source]
p115client.tool.upload.iter_115_to_115(from_client: P115Client, to_client: P115Client, from_cid: int | str = 0, to_pid: int | str = 0, max_workers: int = 8, with_root: bool = True, use_iter_files: bool = False, *, async_: Literal[True], **request_kwargs) AsyncIterator[dict]

从 115 传到 115

Parameters:
  • from_client – 来源 115 客户端对象

  • to_client – 去向 115 客户端对象

  • from_cid – 来源 115 的目录 id 或 pickcode

  • to_pid – 去向 115 的父目录 id 或 pickcode

  • max_workers – 最大并发数

  • with_root – 是否保留 from_cid 对应的目录名(如果为 False,则会少 1 级目录)

  • use_iter_files – 如果为 True,则调用 iter_files_with_path,否则调用 iter_download_files

  • async – 是否异步

  • request_kwargs – 其它请求参数

Returns:

迭代器,产生转移结果,有 3 种类型:”good”、”fail” 和 “skip”

p115client.tool.upload.iter_115_to_115_resume(from_client: P115Client, to_client: P115Client, from_cid: int | str = 0, to_pid: int | str = 0, max_workers: int = 8, with_root: bool = True, *, async_: Literal[False] = False, **request_kwargs) Iterator[dict][source]
p115client.tool.upload.iter_115_to_115_resume(from_client: P115Client, to_client: P115Client, from_cid: int | str = 0, to_pid: int | str = 0, max_workers: int = 8, with_root: bool = True, *, async_: Literal[True], **request_kwargs) AsyncIterator[dict]

从 115 传到 115(可以跳过已经存在的文件)

Parameters:
  • from_client – 来源 115 客户端对象

  • to_client – 去向 115 客户端对象

  • from_cid – 来源 115 的目录 id 或 pickcode(文件数最好控制在 100 万以内,太多的话,里面多个子文件夹分别传即可)

  • to_pid – 去向 115 的父目录 id 或 pickcode

  • max_workers – 最大并发数

  • with_root – 是否保留 from_cid 对应的目录名(如果为 False,则会少 1 级目录)

  • async – 是否异步

  • request_kwargs – 其它请求参数

Returns:

迭代器,产生转移结果,有 3 种类型:”good”、”fail” 和 “skip”

p115client.tool.upload.sha1_for_check_existence(client: str | PathLike | P115Client, sha1: str, *, async_: Literal[False] = False, **request_kwargs) bool[source]
p115client.tool.upload.sha1_for_check_existence(client: str | PathLike | P115Client, sha1: str, *, async_: Literal[True], **request_kwargs) Coroutine[Any, Any, bool]

判断某个文件(用 sha1 唯一确定)是否存在于 115 网盘上(但不一定在你自己的网盘中)

Parameters:
  • client – 115 客户端或 cookies

  • sha1 – 文件的 sha1 哈希值

  • async – 是否异步

  • request_kwargs – 其它请求参数

Returns:

是否存在文件

p115client.tool.upload.upload_for_check_existence(client: str | PathLike | P115Client | P115OpenClient, sha1: str, size: int, *, async_: Literal[False] = False, **request_kwargs) bool[source]
p115client.tool.upload.upload_for_check_existence(client: str | PathLike | P115Client | P115OpenClient, sha1: str, size: int, *, async_: Literal[True], **request_kwargs) Coroutine[Any, Any, bool]

通过秒传接口,判断某个文件(用 sha1size 唯一确定)是否存在于 115 网盘上(但不一定在你自己的网盘中)

Parameters:
  • client – 115 客户端或 cookies

  • sha1 – 文件的 sha1 哈希值

  • size – 文件大小

  • async – 是否异步

  • request_kwargs – 其它请求参数

Returns:

是否存在文件

p115client.tool.upload.upload_host_image(client: str | PathLike | P115Client, file: Buffer | str | PathLike | URL | SupportsGeturl | SupportsRead | Iterable[Buffer], base_url: bool | str = False, *, async_: Literal[False] = False, **request_kwargs) P115URL[source]
p115client.tool.upload.upload_host_image(client: str | PathLike | P115Client, file: Buffer | str | PathLike | URL | SupportsGeturl | SupportsRead | Iterable[Buffer] | AsyncIterable[Buffer], base_url: bool | str = False, *, async_: Literal[True], **request_kwargs) Coroutine[P115URL, Any, Any]

上传图片,然后可作为图床使用

Caution

115 网盘允许图片最大到 50 MB

Parameters:
  • client – 115 网盘客户端对象

  • file – 待上传的文件

  • base_url

    图片的基地址

    • 如果为 False,上传到 U_4_-1,获取一次性的图片链接,有效时间 1 小时

    • 如果为 True,上传到 U_4_-1,获取永久的图片链接

    • 如果为 str,上传到 U_12_0,视为 302 代理,会把 user_id、id、pickcode、sha1 和 size 作为查询参数拼接到其后

  • async – 是否异步

  • request_kwargs – 其余请求参数

Returns:

图片链接

p115client.tool.upload.upload_init(client: str | PathLike | P115Client | P115OpenClient, file: Buffer | str | PathLike | URL | SupportsGeturl | SupportsRead, pid: int | str = 0, filename: str = '', filesha1: str = '', filesize: int = -1, endpoint: str = 'http://oss-cn-shenzhen.aliyuncs.com', *, async_: Literal[False] = False, **request_kwargs) dict[source]
p115client.tool.upload.upload_init(client: str | PathLike | P115Client | P115OpenClient, file: Buffer | str | PathLike | URL | SupportsGeturl | SupportsRead, pid: int | str = 0, filename: str = '', filesha1: str = '', filesize: int = -1, endpoint: str = 'http://oss-cn-shenzhen.aliyuncs.com', *, async_: Literal[True], **request_kwargs) Coroutine[Any, Any, dict]

准备上传,获取必要信息,可能秒传成功

Parameters:
  • client – 115 客户端或 cookies

  • file – 待上传的文件或其路径

  • pid – 上传文件到目录的 id 或 pickcode

  • filename – 文件名,若为空则自动确定

  • filesha1 – 文件的 sha1 哈希值,若为空则自动计算

  • filesize – 文件大小,若为负数则自动计算

  • endpoint – 上传目的网址

  • async – 是否异步

  • request_kwargs – 其它请求参数

Returns:

响应信息,如果有字段 “reuse” 为 True,则说明秒传成功