p123client 0.0.6.9.4__py3-none-any.whl → 0.0.6.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- p123client/client.py +911 -325
- p123client/tool/__init__.py +4 -3
- {p123client-0.0.6.9.4.dist-info → p123client-0.0.6.10.dist-info}/METADATA +162 -27
- p123client-0.0.6.10.dist-info/RECORD +12 -0
- p123client-0.0.6.9.4.dist-info/RECORD +0 -12
- {p123client-0.0.6.9.4.dist-info → p123client-0.0.6.10.dist-info}/LICENSE +0 -0
- {p123client-0.0.6.9.4.dist-info → p123client-0.0.6.10.dist-info}/WHEEL +0 -0
p123client/client.py
CHANGED
@@ -5,13 +5,14 @@ from __future__ import annotations
|
|
5
5
|
|
6
6
|
__all__ = ["check_response", "P123OpenClient", "P123Client"]
|
7
7
|
|
8
|
-
|
8
|
+
import errno
|
9
|
+
|
10
|
+
from base64 import urlsafe_b64decode
|
9
11
|
from collections.abc import (
|
10
12
|
AsyncIterable, Awaitable, Buffer, Callable, Coroutine,
|
11
13
|
ItemsView, Iterable, Iterator, Mapping, MutableMapping,
|
12
14
|
)
|
13
15
|
from contextlib import contextmanager
|
14
|
-
from errno import EAUTH, EIO, EISDIR, ENOENT
|
15
16
|
from functools import partial
|
16
17
|
from hashlib import md5
|
17
18
|
from http.cookiejar import CookieJar
|
@@ -21,9 +22,11 @@ from os import fsdecode, fstat, isatty, PathLike
|
|
21
22
|
from os.path import basename
|
22
23
|
from pathlib import Path, PurePath
|
23
24
|
from re import compile as re_compile, MULTILINE
|
25
|
+
from string import digits, ascii_uppercase
|
24
26
|
from sys import _getframe
|
25
27
|
from tempfile import TemporaryFile
|
26
28
|
from typing import cast, overload, Any, Final, Literal, Self
|
29
|
+
from urllib.parse import parse_qsl, urlsplit
|
27
30
|
from uuid import uuid4
|
28
31
|
from warnings import warn
|
29
32
|
|
@@ -39,11 +42,14 @@ from http_request import (
|
|
39
42
|
encode_multipart_data, encode_multipart_data_async, SupportsGeturl,
|
40
43
|
)
|
41
44
|
from iterutils import run_gen_step
|
45
|
+
from orjson import loads
|
42
46
|
from property import locked_cacheproperty
|
43
47
|
from yarl import URL
|
44
48
|
|
45
49
|
from .const import CLIENT_API_METHODS_MAP, CLIENT_METHOD_API_MAP
|
46
|
-
from .exception import
|
50
|
+
from .exception import (
|
51
|
+
P123OSError, P123BrokenUpload, P123LoginError, P123AuthenticationError, P123FileNotFoundError,
|
52
|
+
)
|
47
53
|
|
48
54
|
|
49
55
|
# 默认使用的域名
|
@@ -66,7 +72,6 @@ def get_default_request():
|
|
66
72
|
|
67
73
|
|
68
74
|
def default_parse(_, content: Buffer, /):
|
69
|
-
from orjson import loads
|
70
75
|
if isinstance(content, (bytes, bytearray, memoryview)):
|
71
76
|
return loads(content)
|
72
77
|
else:
|
@@ -179,15 +184,23 @@ def check_response(resp: dict | Awaitable[dict], /) -> dict | Coroutine[Any, Any
|
|
179
184
|
"""
|
180
185
|
def check(resp, /) -> dict:
|
181
186
|
if not isinstance(resp, dict):
|
182
|
-
raise P123OSError(EIO, resp)
|
187
|
+
raise P123OSError(errno.EIO, resp)
|
183
188
|
code = resp.get("code", 0)
|
184
189
|
if code in (0, 200):
|
185
190
|
return resp
|
186
191
|
match code:
|
187
|
-
case
|
188
|
-
raise P123AuthenticationError(
|
192
|
+
case 1: # 内部错误
|
193
|
+
raise P123AuthenticationError(errno.EIO, resp)
|
194
|
+
case 401: # access_token 失效
|
195
|
+
raise P123AuthenticationError(errno.EAUTH, resp)
|
196
|
+
case 429: # 请求太频繁
|
197
|
+
raise P123OSError(errno.EBUSY, resp)
|
198
|
+
case 5066: # 文件不存在
|
199
|
+
raise P123FileNotFoundError(errno.ENOENT, resp)
|
200
|
+
case 5113: # 流量超限
|
201
|
+
raise P123OSError(errno.EIO, resp)
|
189
202
|
case _:
|
190
|
-
raise P123OSError(EIO, resp)
|
203
|
+
raise P123OSError(errno.EIO, resp)
|
191
204
|
if isawaitable(resp):
|
192
205
|
async def check_await() -> dict:
|
193
206
|
return check(await resp)
|
@@ -204,6 +217,9 @@ class P123OpenClient:
|
|
204
217
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced
|
205
218
|
"""
|
206
219
|
|
220
|
+
client_id: str = ""
|
221
|
+
client_secret: str = ""
|
222
|
+
refresh_token: str = ""
|
207
223
|
token_path: None | PurePath = None
|
208
224
|
|
209
225
|
def __init__(
|
@@ -211,14 +227,16 @@ class P123OpenClient:
|
|
211
227
|
client_id: str | PathLike = "",
|
212
228
|
client_secret: str = "",
|
213
229
|
token: None | str | PathLike = None,
|
230
|
+
refresh_token: str = "",
|
214
231
|
):
|
215
232
|
if isinstance(client_id, PathLike):
|
216
233
|
token = client_id
|
217
234
|
else:
|
218
235
|
self.client_id = client_id
|
219
|
-
|
236
|
+
self.client_secret = client_secret
|
237
|
+
self.refresh_token = refresh_token
|
220
238
|
if token is None:
|
221
|
-
if client_id and client_secret:
|
239
|
+
if client_id and client_secret or refresh_token:
|
222
240
|
self.login_open()
|
223
241
|
elif isinstance(token, str):
|
224
242
|
self.token = token.removeprefix("Bearer ")
|
@@ -228,7 +246,7 @@ class P123OpenClient:
|
|
228
246
|
else:
|
229
247
|
self.token_path = Path(fsdecode(token))
|
230
248
|
self._read_token()
|
231
|
-
if not self.token and client_id and client_secret:
|
249
|
+
if not self.token and (client_id and client_secret or refresh_token):
|
232
250
|
self.login_open()
|
233
251
|
|
234
252
|
def __del__(self, /):
|
@@ -322,8 +340,7 @@ class P123OpenClient:
|
|
322
340
|
|
323
341
|
@locked_cacheproperty
|
324
342
|
def token_user_info(self, /) -> dict:
|
325
|
-
|
326
|
-
return loads(b64decode(self.token.split(".", 2)[1] + "=="))
|
343
|
+
return loads(urlsafe_b64decode(self.token.split(".", 2)[1] + "=="))
|
327
344
|
|
328
345
|
@locked_cacheproperty
|
329
346
|
def user_id(self, /) -> dict:
|
@@ -403,7 +420,8 @@ class P123OpenClient:
|
|
403
420
|
/,
|
404
421
|
client_id: str = "",
|
405
422
|
client_secret: str = "",
|
406
|
-
|
423
|
+
refresh_token: str = "",
|
424
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
407
425
|
*,
|
408
426
|
async_: Literal[False] = False,
|
409
427
|
**request_kwargs,
|
@@ -415,7 +433,8 @@ class P123OpenClient:
|
|
415
433
|
/,
|
416
434
|
client_id: str = "",
|
417
435
|
client_secret: str = "",
|
418
|
-
|
436
|
+
refresh_token: str = "",
|
437
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
419
438
|
*,
|
420
439
|
async_: Literal[True],
|
421
440
|
**request_kwargs,
|
@@ -426,7 +445,8 @@ class P123OpenClient:
|
|
426
445
|
/,
|
427
446
|
client_id: str = "",
|
428
447
|
client_secret: str = "",
|
429
|
-
|
448
|
+
refresh_token: str = "",
|
449
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
430
450
|
*,
|
431
451
|
async_: Literal[False, True] = False,
|
432
452
|
**request_kwargs,
|
@@ -435,6 +455,7 @@ class P123OpenClient:
|
|
435
455
|
|
436
456
|
:param client_id: 应用标识,创建应用时分配的 appId
|
437
457
|
:param client_secret: 应用密钥,创建应用时分配的 secretId
|
458
|
+
:param refresh_token: 刷新令牌
|
438
459
|
:param base_url: 接口的基地址
|
439
460
|
:param async_: 是否异步
|
440
461
|
:param request_kwargs: 其它请求参数
|
@@ -445,222 +466,323 @@ class P123OpenClient:
|
|
445
466
|
self.client_id = client_id
|
446
467
|
else:
|
447
468
|
client_id = self.client_id
|
469
|
+
if client_secret:
|
470
|
+
self.client_secret = client_secret
|
471
|
+
else:
|
472
|
+
client_secret = self.client_secret
|
473
|
+
if refresh_token:
|
474
|
+
self.refresh_token = refresh_token
|
475
|
+
else:
|
476
|
+
refresh_token = self.refresh_token
|
477
|
+
def gen_step():
|
478
|
+
if refresh_token:
|
479
|
+
resp = yield self.login_with_refresh_token(
|
480
|
+
refresh_token,
|
481
|
+
base_url=base_url,
|
482
|
+
async_=async_,
|
483
|
+
**request_kwargs,
|
484
|
+
)
|
485
|
+
self.token = resp["access_token"]
|
486
|
+
self.refresh_token = resp["refresh_token"]
|
487
|
+
return resp
|
488
|
+
else:
|
489
|
+
resp = yield self.login_token_open( # type: ignore
|
490
|
+
{"clientID": client_id, "clientSecret": client_secret},
|
491
|
+
base_url=base_url,
|
492
|
+
async_=async_,
|
493
|
+
**request_kwargs,
|
494
|
+
)
|
495
|
+
check_response(resp)
|
496
|
+
self.token = resp["data"]["accessToken"]
|
497
|
+
return resp
|
498
|
+
return run_gen_step(gen_step, async_)
|
499
|
+
|
500
|
+
@overload
|
501
|
+
def login_another_oauth(
|
502
|
+
self,
|
503
|
+
/,
|
504
|
+
redirect_uri: str,
|
505
|
+
client_id: str = "",
|
506
|
+
client_secret: str = "",
|
507
|
+
replace: bool | Self = False,
|
508
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
509
|
+
*,
|
510
|
+
async_: Literal[False] = False,
|
511
|
+
**request_kwargs,
|
512
|
+
) -> Self:
|
513
|
+
...
|
514
|
+
@overload
|
515
|
+
def login_another_oauth(
|
516
|
+
self,
|
517
|
+
/,
|
518
|
+
redirect_uri: str,
|
519
|
+
client_id: str = "",
|
520
|
+
client_secret: str = "",
|
521
|
+
replace: bool | Self = False,
|
522
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
523
|
+
*,
|
524
|
+
async_: Literal[True],
|
525
|
+
**request_kwargs,
|
526
|
+
) -> Coroutine[Any, Any, Self]:
|
527
|
+
...
|
528
|
+
def login_another_oauth(
|
529
|
+
self,
|
530
|
+
/,
|
531
|
+
redirect_uri: str,
|
532
|
+
client_id: str = "",
|
533
|
+
client_secret: str = "",
|
534
|
+
replace: bool | Self = False,
|
535
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
536
|
+
*,
|
537
|
+
async_: Literal[False, True] = False,
|
538
|
+
**request_kwargs,
|
539
|
+
) -> Self | Coroutine[Any, Any, Self]:
|
540
|
+
"""第三方应用授权登录
|
541
|
+
|
542
|
+
:param redirect_uri: 回调链接
|
543
|
+
:param client_id: 应用标识,创建应用时分配的 appId
|
544
|
+
:param client_secret: 应用密钥,创建应用时分配的 secretId
|
545
|
+
:param replace: 替换某个 client 对象的 token
|
546
|
+
|
547
|
+
- 如果为 P123Client, 则更新到此对象
|
548
|
+
- 如果为 True,则更新到 `self``
|
549
|
+
- 如果为 False,否则返回新的 ``P123Client`` 对象
|
550
|
+
|
551
|
+
:param async_: 是否异步
|
552
|
+
:param request_kwargs: 其它请求参数
|
553
|
+
|
554
|
+
:return: 接口响应
|
555
|
+
"""
|
448
556
|
if client_id:
|
557
|
+
self.client_id = client_id
|
558
|
+
else:
|
559
|
+
client_id = self.client_id
|
560
|
+
if client_secret:
|
449
561
|
self.client_secret = client_secret
|
450
562
|
else:
|
451
563
|
client_secret = self.client_secret
|
452
564
|
def gen_step():
|
453
|
-
resp = yield self.
|
454
|
-
|
565
|
+
resp = yield self.login_with_oauth(
|
566
|
+
client_id,
|
567
|
+
client_secret,
|
568
|
+
redirect_uri=redirect_uri,
|
569
|
+
token=self.token,
|
455
570
|
base_url=base_url,
|
456
571
|
async_=async_,
|
457
572
|
**request_kwargs,
|
458
573
|
)
|
459
|
-
|
460
|
-
|
461
|
-
|
574
|
+
token = resp["access_token"]
|
575
|
+
refresh_token = resp["refresh_token"]
|
576
|
+
if replace is False:
|
577
|
+
return type(self)(
|
578
|
+
client_id=client_id,
|
579
|
+
client_secret=client_secret,
|
580
|
+
token=token,
|
581
|
+
refresh_token=refresh_token,
|
582
|
+
)
|
583
|
+
elif replace is True:
|
584
|
+
inst = self
|
585
|
+
else:
|
586
|
+
inst = replace
|
587
|
+
inst.token = token
|
588
|
+
inst.refresh_token = refresh_token
|
589
|
+
return inst
|
462
590
|
return run_gen_step(gen_step, async_)
|
463
591
|
|
464
592
|
@overload
|
465
|
-
|
466
|
-
|
467
|
-
payload: dict,
|
593
|
+
def login_another_refresh_token(
|
594
|
+
self,
|
468
595
|
/,
|
469
|
-
|
470
|
-
|
596
|
+
refresh_token: str = "",
|
597
|
+
replace: bool | Self = False,
|
598
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
471
599
|
*,
|
472
600
|
async_: Literal[False] = False,
|
473
601
|
**request_kwargs,
|
474
|
-
) ->
|
602
|
+
) -> Self:
|
475
603
|
...
|
476
604
|
@overload
|
477
|
-
|
478
|
-
|
479
|
-
payload: dict,
|
605
|
+
def login_another_refresh_token(
|
606
|
+
self,
|
480
607
|
/,
|
481
|
-
|
482
|
-
|
608
|
+
refresh_token: str = "",
|
609
|
+
replace: bool | Self = False,
|
610
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
483
611
|
*,
|
484
612
|
async_: Literal[True],
|
485
613
|
**request_kwargs,
|
486
|
-
) -> Coroutine[Any, Any,
|
614
|
+
) -> Coroutine[Any, Any, Self]:
|
487
615
|
...
|
488
|
-
|
489
|
-
|
490
|
-
payload: dict,
|
616
|
+
def login_another_refresh_token(
|
617
|
+
self,
|
491
618
|
/,
|
492
|
-
|
493
|
-
|
619
|
+
refresh_token: str = "",
|
620
|
+
replace: bool | Self = False,
|
621
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
494
622
|
*,
|
495
623
|
async_: Literal[False, True] = False,
|
496
624
|
**request_kwargs,
|
497
|
-
) ->
|
498
|
-
"""
|
499
|
-
|
500
|
-
POST https://open-api.123pan.com/api/v1/access_token
|
501
|
-
|
502
|
-
.. attention::
|
503
|
-
此接口有访问频率限制。请获取到 `access_token` 后本地保存使用,并在 `access_token `过期前及时重新获取。`access_token` 有效期根据返回的 "expiredAt" 字段判断。
|
504
|
-
|
505
|
-
.. note::
|
506
|
-
通过这种方式授权得到的 `access_token`,各个接口分别允许一个较低的 QPS
|
507
|
-
|
508
|
-
/接入指南/开发者接入/开发须知
|
625
|
+
) -> Self | Coroutine[Any, Any, Self]:
|
626
|
+
"""登录以获取 access_token
|
509
627
|
|
510
|
-
|
628
|
+
:param refresh_token: 刷新令牌
|
629
|
+
:param replace: 替换某个 client 对象的 token
|
511
630
|
|
512
|
-
|
513
|
-
|
631
|
+
- 如果为 P123Client, 则更新到此对象
|
632
|
+
- 如果为 True,则更新到 `self``
|
633
|
+
- 如果为 False,否则返回新的 ``P123Client`` 对象
|
514
634
|
|
515
|
-
|
635
|
+
:param base_url: 接口的基地址
|
636
|
+
:param async_: 是否异步
|
637
|
+
:param request_kwargs: 其它请求参数
|
516
638
|
|
517
|
-
:
|
518
|
-
- clientID: str 💡 应用标识,创建应用时分配的 appId
|
519
|
-
- clientSecret: str 💡 应用密钥,创建应用时分配的 secretId
|
639
|
+
:return: 接口的响应信息
|
520
640
|
"""
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
641
|
+
if refresh_token:
|
642
|
+
self.refresh_token = refresh_token
|
643
|
+
else:
|
644
|
+
refresh_token = self.refresh_token
|
645
|
+
def gen_step():
|
646
|
+
nonlocal refresh_token
|
647
|
+
resp = yield self.login_with_refresh_token(
|
648
|
+
refresh_token,
|
649
|
+
base_url=base_url,
|
650
|
+
async_=async_,
|
651
|
+
**request_kwargs,
|
652
|
+
)
|
653
|
+
token = resp["access_token"]
|
654
|
+
refresh_token = resp["refresh_token"]
|
655
|
+
if replace is False:
|
656
|
+
return type(self)(
|
657
|
+
token=token,
|
658
|
+
refresh_token=refresh_token,
|
659
|
+
)
|
660
|
+
elif replace is True:
|
661
|
+
inst = self
|
662
|
+
else:
|
663
|
+
inst = replace
|
664
|
+
inst.token = token
|
665
|
+
inst.refresh_token = refresh_token
|
666
|
+
return inst
|
667
|
+
return run_gen_step(gen_step, async_)
|
531
668
|
|
532
669
|
@overload
|
533
|
-
|
534
|
-
|
535
|
-
payload: dict,
|
670
|
+
def login_with_oauth(
|
671
|
+
cls,
|
536
672
|
/,
|
537
|
-
|
538
|
-
|
673
|
+
client_id: str,
|
674
|
+
client_secret: str,
|
675
|
+
redirect_uri: str,
|
676
|
+
token: str,
|
677
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
539
678
|
*,
|
540
679
|
async_: Literal[False] = False,
|
541
680
|
**request_kwargs,
|
542
681
|
) -> dict:
|
543
682
|
...
|
544
683
|
@overload
|
545
|
-
|
546
|
-
|
547
|
-
payload: dict,
|
684
|
+
def login_with_oauth(
|
685
|
+
cls,
|
548
686
|
/,
|
549
|
-
|
550
|
-
|
687
|
+
client_id: str,
|
688
|
+
client_secret: str,
|
689
|
+
redirect_uri: str,
|
690
|
+
token: str,
|
691
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
551
692
|
*,
|
552
693
|
async_: Literal[True],
|
553
694
|
**request_kwargs,
|
554
695
|
) -> Coroutine[Any, Any, dict]:
|
555
696
|
...
|
556
|
-
|
557
|
-
|
558
|
-
payload: dict,
|
697
|
+
def login_with_oauth(
|
698
|
+
cls,
|
559
699
|
/,
|
560
|
-
|
561
|
-
|
700
|
+
client_id: str,
|
701
|
+
client_secret: str,
|
702
|
+
redirect_uri: str,
|
703
|
+
token: str,
|
704
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
562
705
|
*,
|
563
706
|
async_: Literal[False, True] = False,
|
564
707
|
**request_kwargs,
|
565
708
|
) -> dict | Coroutine[Any, Any, dict]:
|
566
|
-
"""
|
567
|
-
|
568
|
-
GET https://www.123pan.com/auth
|
709
|
+
"""第三方应用授权登录
|
569
710
|
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
711
|
+
:param client_id: 应用标识,创建应用时分配的 appId
|
712
|
+
:param client_secret: 应用密钥,创建应用时分配的 secretId
|
713
|
+
:param redirect_uri: 回调链接
|
714
|
+
:param token: 访问令牌
|
715
|
+
:param async_: 是否异步
|
716
|
+
:param request_kwargs: 其它请求参数
|
574
717
|
|
575
|
-
:
|
576
|
-
- client_id: str 💡 应用标识,创建应用时分配的 appId
|
577
|
-
- redirect_uri: str 💡 应用注册的回调地址
|
578
|
-
- scope: str = "user:base,file:all:read,file:all:write" 💡 权限
|
579
|
-
- state: str = "" 💡 自定义参数,任意取值
|
718
|
+
:return: 接口响应
|
580
719
|
"""
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
720
|
+
def gen_step():
|
721
|
+
resp = yield cls.login_oauth_authorize(
|
722
|
+
{"accessToken": token, "client_id": client_id, "redirect_uri": redirect_uri},
|
723
|
+
base_url=base_url,
|
724
|
+
async_=async_,
|
725
|
+
**request_kwargs,
|
726
|
+
)
|
727
|
+
check_response(resp)
|
728
|
+
authorization_code = resp["data"]["code"]
|
729
|
+
return cls.login_oauth_token(
|
730
|
+
{
|
731
|
+
"client_id": client_id,
|
732
|
+
"client_secret": client_secret,
|
733
|
+
"code": authorization_code,
|
734
|
+
"grant_type": "authorization_code",
|
735
|
+
"redirect_uri": redirect_uri,
|
736
|
+
},
|
737
|
+
base_url=base_url,
|
738
|
+
async_=async_,
|
739
|
+
**request_kwargs,
|
740
|
+
)
|
741
|
+
return run_gen_step(gen_step, async_)
|
591
742
|
|
592
743
|
@overload
|
593
|
-
|
594
|
-
|
595
|
-
payload: dict,
|
744
|
+
def login_with_refresh_token(
|
745
|
+
cls,
|
596
746
|
/,
|
597
|
-
|
598
|
-
|
747
|
+
refresh_token: str,
|
748
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
599
749
|
*,
|
600
750
|
async_: Literal[False] = False,
|
601
751
|
**request_kwargs,
|
602
752
|
) -> dict:
|
603
753
|
...
|
604
754
|
@overload
|
605
|
-
|
606
|
-
|
607
|
-
payload: dict,
|
755
|
+
def login_with_refresh_token(
|
756
|
+
cls,
|
608
757
|
/,
|
609
|
-
|
610
|
-
|
758
|
+
refresh_token: str,
|
759
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
611
760
|
*,
|
612
761
|
async_: Literal[True],
|
613
762
|
**request_kwargs,
|
614
763
|
) -> Coroutine[Any, Any, dict]:
|
615
764
|
...
|
616
|
-
|
617
|
-
|
618
|
-
payload: dict,
|
765
|
+
def login_with_refresh_token(
|
766
|
+
cls,
|
619
767
|
/,
|
620
|
-
|
621
|
-
|
768
|
+
refresh_token: str,
|
769
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
622
770
|
*,
|
623
771
|
async_: Literal[False, True] = False,
|
624
772
|
**request_kwargs,
|
625
773
|
) -> dict | Coroutine[Any, Any, dict]:
|
626
|
-
"""
|
627
|
-
|
628
|
-
POST https://open-api.123pan.com/api/v1/oauth2/access_token
|
629
|
-
|
630
|
-
.. note::
|
631
|
-
通过这种方式授权得到的 `access_token`,各个接口分别允许更高的 QPS
|
632
|
-
|
633
|
-
/接入指南/第三方挂载应用接入/授权须知
|
634
|
-
|
635
|
-
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/kf05anzt1r0qnudd
|
774
|
+
"""通过刷新令牌登录
|
636
775
|
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/gammzlhe6k4qtwd9
|
776
|
+
:param refresh_token: 刷新令牌
|
777
|
+
:param async_: 是否异步
|
778
|
+
:param request_kwargs: 其它请求参数
|
641
779
|
|
642
|
-
:
|
643
|
-
- client_id: str 💡 应用标识,创建应用时分配的 appId
|
644
|
-
- client_secret: str 💡 应用密钥,创建应用时分配的 secretId
|
645
|
-
- code: str = <default> 💡 授权码
|
646
|
-
- grant_type: "authorization_code" | "refresh_token" = <default> 💡 身份类型
|
647
|
-
- redirect_uri: str = <default> 💡 应用注册的回调地址,`grant_type` 为 "authorization_code" 时必携带
|
648
|
-
- refresh_token: str = <default> 💡 刷新 token,单次请求有效
|
780
|
+
:return: 接口响应
|
649
781
|
"""
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
payload["grant_type"] = "refresh_token"
|
655
|
-
else:
|
656
|
-
payload["grant_type"] = "authorization_code"
|
657
|
-
if request is None:
|
658
|
-
request = get_default_request()
|
659
|
-
request_kwargs["async_"] = async_
|
660
|
-
return request(
|
661
|
-
url=complete_url("/api/v1/oauth2/access_token", base_url),
|
662
|
-
method="POST",
|
663
|
-
params=payload,
|
782
|
+
return cls.login_oauth_token(
|
783
|
+
{"grant_type": "refresh_token", "refresh_token": refresh_token},
|
784
|
+
base_url=base_url,
|
785
|
+
async_=async_,
|
664
786
|
**request_kwargs,
|
665
787
|
)
|
666
788
|
|
@@ -699,6 +821,7 @@ class P123OpenClient:
|
|
699
821
|
GET https://open-api.123pan.com/api/v1/developer/config/forbide-ip/list
|
700
822
|
|
701
823
|
.. admonition:: Reference
|
824
|
+
|
702
825
|
/API列表/直链/IP黑名单配置/ip黑名单列表
|
703
826
|
|
704
827
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/mxldrm9d5gpw5h2d
|
@@ -745,6 +868,7 @@ class P123OpenClient:
|
|
745
868
|
POST https://open-api.123pan.com/api/v1/developer/config/forbide-ip/switch
|
746
869
|
|
747
870
|
.. admonition:: Reference
|
871
|
+
|
748
872
|
/API列表/直链/IP黑名单配置/开启关闭ip黑名单
|
749
873
|
|
750
874
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/xwx77dbzrkxquuxm
|
@@ -796,6 +920,7 @@ class P123OpenClient:
|
|
796
920
|
POST https://open-api.123pan.com/api/v1/developer/config/forbide-ip/update
|
797
921
|
|
798
922
|
.. admonition:: Reference
|
923
|
+
|
799
924
|
/API列表/直链/IP黑名单配置/更新ip黑名单列表
|
800
925
|
|
801
926
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/tt3s54slh87q8wuh
|
@@ -851,6 +976,7 @@ class P123OpenClient:
|
|
851
976
|
POST https://open-api.123pan.com/api/v1/direct-link/disable
|
852
977
|
|
853
978
|
.. admonition:: Reference
|
979
|
+
|
854
980
|
/API列表/直链/禁用直链空间
|
855
981
|
|
856
982
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/ccgz6fwf25nd9psl
|
@@ -899,6 +1025,7 @@ class P123OpenClient:
|
|
899
1025
|
POST https://open-api.123pan.com/api/v1/direct-link/enable
|
900
1026
|
|
901
1027
|
.. admonition:: Reference
|
1028
|
+
|
902
1029
|
/API列表/直链/启用直链空间
|
903
1030
|
|
904
1031
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/cl3gvdmho288d376
|
@@ -947,6 +1074,7 @@ class P123OpenClient:
|
|
947
1074
|
GET https://open-api.123pan.com/api/v1/direct-link/log
|
948
1075
|
|
949
1076
|
.. admonition:: Reference
|
1077
|
+
|
950
1078
|
/API列表/直链/获取直链日志
|
951
1079
|
|
952
1080
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/agmqpmu0dm0iogc9
|
@@ -1011,18 +1139,18 @@ class P123OpenClient:
|
|
1011
1139
|
:return:
|
1012
1140
|
响应数据的 data 字段是一个字典,键值如下:
|
1013
1141
|
|
1014
|
-
|
1015
|
-
| 名称
|
1016
|
-
|
1017
|
-
| list | array | 必填 | 响应列表
|
1018
|
-
|
1019
|
-
| list[*].resolutions | string | 必填 | 分辨率
|
1020
|
-
|
1021
|
-
| list[*].address | string | 必填 | 播放地址。请将播放地址放入支持的 hls 协议的播放器中进行播放。|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
1142
|
+
+-------------------------+--------+----------+----------------------------------------------------------------+
|
1143
|
+
| 名称 | 类型 | 是否必填 | 说明 |
|
1144
|
+
+=========================+========+==========+================================================================+
|
1145
|
+
| ``list`` | array | 必填 | 响应列表 |
|
1146
|
+
+-------------------------+--------+----------+----------------------------------------------------------------+
|
1147
|
+
| ``list[*].resolutions`` | string | 必填 | 分辨率 |
|
1148
|
+
+-------------------------+--------+----------+----------------------------------------------------------------+
|
1149
|
+
| ``list[*].address`` | string | 必填 | | 播放地址。请将播放地址放入支持的 hls 协议的播放器中进行播放。|
|
1150
|
+
| | | | | 示例在线播放地址: https://m3u8-player.com/ |
|
1151
|
+
| | | | | 请注意:转码链接播放过程中将会消耗您的直链流量。 |
|
1152
|
+
| | | | | 如果您开启了直链鉴权,也需要将转码链接根据鉴权指引进行签名。 |
|
1153
|
+
+-------------------------+--------+----------+----------------------------------------------------------------+
|
1026
1154
|
"""
|
1027
1155
|
api = complete_url("/api/v1/direct-link/get/m3u8", base_url)
|
1028
1156
|
if not isinstance(payload, dict):
|
@@ -1065,6 +1193,7 @@ class P123OpenClient:
|
|
1065
1193
|
GET https://open-api.123pan.com/api/v1/direct-link/offline/logs
|
1066
1194
|
|
1067
1195
|
.. admonition:: Reference
|
1196
|
+
|
1068
1197
|
/API列表/直链/获取直链离线日志
|
1069
1198
|
|
1070
1199
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/yz4bdynw9yx5erqb
|
@@ -1229,6 +1358,7 @@ class P123OpenClient:
|
|
1229
1358
|
GET https://open-api.123pan.com/api/v1/direct-link/url
|
1230
1359
|
|
1231
1360
|
.. admonition:: Reference
|
1361
|
+
|
1232
1362
|
/API列表/直链/获取直链链接
|
1233
1363
|
|
1234
1364
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/tdxfsmtemp4gu4o2
|
@@ -1279,6 +1409,7 @@ class P123OpenClient:
|
|
1279
1409
|
GET https://open-api.123pan.com/api/v1/file/download_info
|
1280
1410
|
|
1281
1411
|
.. admonition:: Reference
|
1412
|
+
|
1282
1413
|
/API列表/文件管理/下载
|
1283
1414
|
|
1284
1415
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/fnf60phsushn8ip2
|
@@ -1333,6 +1464,7 @@ class P123OpenClient:
|
|
1333
1464
|
彻底删除文件前,文件必须要在回收站中,否则无法删除
|
1334
1465
|
|
1335
1466
|
.. admonition:: Reference
|
1467
|
+
|
1336
1468
|
/API列表/文件管理/删除/彻底删除文件
|
1337
1469
|
|
1338
1470
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/sg2gvfk5i3dwoxtg
|
@@ -1385,6 +1517,7 @@ class P123OpenClient:
|
|
1385
1517
|
GET https://open-api.123pan.com/api/v1/file/detail
|
1386
1518
|
|
1387
1519
|
.. admonition:: Reference
|
1520
|
+
|
1388
1521
|
/API列表/文件管理/文件详情/获取单个文件详情
|
1389
1522
|
|
1390
1523
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/owapsz373dzwiqbp
|
@@ -1436,6 +1569,7 @@ class P123OpenClient:
|
|
1436
1569
|
POST https://open-api.123pan.com/api/v1/file/infos
|
1437
1570
|
|
1438
1571
|
.. admonition:: Reference
|
1572
|
+
|
1439
1573
|
/API列表/文件管理/文件详情/获取多个文件详情
|
1440
1574
|
|
1441
1575
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/cqqayfuxybegrlru
|
@@ -1488,6 +1622,7 @@ class P123OpenClient:
|
|
1488
1622
|
GET https://open-api.123pan.com/api/v2/file/list
|
1489
1623
|
|
1490
1624
|
.. admonition:: Reference
|
1625
|
+
|
1491
1626
|
/API列表/文件管理/文件列表/获取文件列表(推荐)
|
1492
1627
|
|
1493
1628
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/zrip9b0ye81zimv4
|
@@ -1505,7 +1640,7 @@ class P123OpenClient:
|
|
1505
1640
|
其它则代表下一页开始的文件 id,携带到请求参数中,可查询下一页。
|
1506
1641
|
|
1507
1642
|
.. caution::
|
1508
|
-
此接口查询结果包含回收站的文件,需自行根据字段
|
1643
|
+
此接口查询结果包含回收站的文件,需自行根据字段 ``trashed`` 判断处理
|
1509
1644
|
|
1510
1645
|
:payload:
|
1511
1646
|
- businessType: int = <default> 💡 业务类型:2:转码空间
|
@@ -1513,7 +1648,7 @@ class P123OpenClient:
|
|
1513
1648
|
- lastFileId: int = <default> 💡 上一页的最后一条记录的 FileID,翻页查询时需要填写
|
1514
1649
|
- limit: int = 100 💡 分页大小,最多 100
|
1515
1650
|
- parentFileId: int | str = 0 💡 父目录 id,根目录是 0
|
1516
|
-
- searchData: str = <default> 💡 搜索关键字,将无视
|
1651
|
+
- searchData: str = <default> 💡 搜索关键字,将无视 ``parentFileId``,而进行全局查找
|
1517
1652
|
- searchMode: 0 | 1 = 0 💡 搜索模式
|
1518
1653
|
|
1519
1654
|
- 0: 模糊搜索(将会根据搜索项分词,查找出相似的匹配项)
|
@@ -1570,12 +1705,13 @@ class P123OpenClient:
|
|
1570
1705
|
GET https://open-api.123pan.com/api/v1/file/list
|
1571
1706
|
|
1572
1707
|
.. admonition:: Reference
|
1708
|
+
|
1573
1709
|
/API列表/文件管理/文件列表/获取文件列表(旧)
|
1574
1710
|
|
1575
1711
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/hosdqqax0knovnm2
|
1576
1712
|
|
1577
1713
|
.. note::
|
1578
|
-
是否有下一页需要自行判断。如果返回的列表大小 <
|
1714
|
+
是否有下一页需要自行判断。如果返回的列表大小 < ``limit``,或者根据返回值里的 "total",如果 = ``page * limit``,都说明没有下一页
|
1579
1715
|
|
1580
1716
|
:payload:
|
1581
1717
|
- limit: int = 100 💡 分页大小,最多 100
|
@@ -1597,7 +1733,7 @@ class P123OpenClient:
|
|
1597
1733
|
- page: int = 1 💡 第几页,从 1 开始(可传 0 或不传,视为 1)
|
1598
1734
|
- parentFileId: int | str = 0 💡 父目录 id,根目录是 0
|
1599
1735
|
- trashed: "false" | "true" = "false" 💡 是否查看回收站的文件
|
1600
|
-
- searchData: str = <default> 💡 搜索关键字(将无视
|
1736
|
+
- searchData: str = <default> 💡 搜索关键字(将无视 ``parentFileId`` 参数)
|
1601
1737
|
"""
|
1602
1738
|
api = complete_url("/api/v1/file/list", base_url)
|
1603
1739
|
if isinstance(payload, (int, str)):
|
@@ -1651,6 +1787,7 @@ class P123OpenClient:
|
|
1651
1787
|
POST https://open-api.123pan.com/upload/v1/file/mkdir
|
1652
1788
|
|
1653
1789
|
.. admonition:: Reference
|
1790
|
+
|
1654
1791
|
/API列表/文件管理/上传/创建目录
|
1655
1792
|
|
1656
1793
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/ouyvcxqg3185zzk4
|
@@ -1704,6 +1841,7 @@ class P123OpenClient:
|
|
1704
1841
|
POST https://open-api.123pan.com/api/v1/file/move
|
1705
1842
|
|
1706
1843
|
.. admonition:: Reference
|
1844
|
+
|
1707
1845
|
/API列表/文件管理/移动
|
1708
1846
|
|
1709
1847
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/rsyfsn1gnpgo4m4f
|
@@ -1758,6 +1896,7 @@ class P123OpenClient:
|
|
1758
1896
|
POST https://open-api.123pan.com/api/v1/file/recover
|
1759
1897
|
|
1760
1898
|
.. admonition:: Reference
|
1899
|
+
|
1761
1900
|
/API列表/文件管理/删除/从回收站恢复文件
|
1762
1901
|
|
1763
1902
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/kx9f8b6wk6g55uwy
|
@@ -1775,164 +1914,470 @@ class P123OpenClient:
|
|
1775
1914
|
return self.request(api, "POST", json=payload, async_=async_, **request_kwargs)
|
1776
1915
|
|
1777
1916
|
@overload
|
1778
|
-
def fs_rename(
|
1779
|
-
self,
|
1780
|
-
payload: dict | str | tuple[int | str, str] | Iterable[str | tuple[int | str, str]],
|
1917
|
+
def fs_rename(
|
1918
|
+
self,
|
1919
|
+
payload: dict | str | tuple[int | str, str] | Iterable[str | tuple[int | str, str]],
|
1920
|
+
/,
|
1921
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
1922
|
+
*,
|
1923
|
+
async_: Literal[False] = False,
|
1924
|
+
**request_kwargs,
|
1925
|
+
) -> dict:
|
1926
|
+
...
|
1927
|
+
@overload
|
1928
|
+
def fs_rename(
|
1929
|
+
self,
|
1930
|
+
payload: dict | str | tuple[int | str, str] | Iterable[str | tuple[int | str, str]],
|
1931
|
+
/,
|
1932
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
1933
|
+
*,
|
1934
|
+
async_: Literal[True],
|
1935
|
+
**request_kwargs,
|
1936
|
+
) -> Coroutine[Any, Any, dict]:
|
1937
|
+
...
|
1938
|
+
def fs_rename(
|
1939
|
+
self,
|
1940
|
+
payload: dict | str | tuple[int | str, str] | Iterable[str | tuple[int | str, str]],
|
1941
|
+
/,
|
1942
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
1943
|
+
*,
|
1944
|
+
async_: Literal[False, True] = False,
|
1945
|
+
**request_kwargs,
|
1946
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
1947
|
+
"""批量文件重命名
|
1948
|
+
|
1949
|
+
POST https://open-api.123pan.com/api/v1/file/rename
|
1950
|
+
|
1951
|
+
.. admonition:: Reference
|
1952
|
+
|
1953
|
+
/API列表/文件管理/重命名/批量文件重命名
|
1954
|
+
|
1955
|
+
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/imhguepnr727aquk
|
1956
|
+
|
1957
|
+
:payload:
|
1958
|
+
- renameList: list[str] 💡 列表,每个成员的格式为 f"{fileId}|{fileName}",最多 30 个
|
1959
|
+
"""
|
1960
|
+
api = complete_url("/api/v1/file/rename", base_url)
|
1961
|
+
if not isinstance(payload, dict):
|
1962
|
+
if isinstance(payload, str):
|
1963
|
+
payload = [payload]
|
1964
|
+
elif isinstance(payload, tuple):
|
1965
|
+
payload = ["%s|%s" % payload]
|
1966
|
+
else:
|
1967
|
+
payload = [s if isinstance(s, str) else "%s|%s" % s for s in payload]
|
1968
|
+
payload = {"renameList": payload}
|
1969
|
+
return self.request(api, "POST", json=payload, async_=async_, **request_kwargs)
|
1970
|
+
|
1971
|
+
@overload
|
1972
|
+
def fs_rename_one(
|
1973
|
+
self,
|
1974
|
+
payload: dict | str | tuple[int | str, str],
|
1975
|
+
/,
|
1976
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
1977
|
+
*,
|
1978
|
+
async_: Literal[False] = False,
|
1979
|
+
**request_kwargs,
|
1980
|
+
) -> dict:
|
1981
|
+
...
|
1982
|
+
@overload
|
1983
|
+
def fs_rename_one(
|
1984
|
+
self,
|
1985
|
+
payload: dict | str | tuple[int | str, str],
|
1986
|
+
/,
|
1987
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
1988
|
+
*,
|
1989
|
+
async_: Literal[True],
|
1990
|
+
**request_kwargs,
|
1991
|
+
) -> Coroutine[Any, Any, dict]:
|
1992
|
+
...
|
1993
|
+
def fs_rename_one(
|
1994
|
+
self,
|
1995
|
+
payload: dict | str | tuple[int | str, str],
|
1996
|
+
/,
|
1997
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
1998
|
+
*,
|
1999
|
+
async_: Literal[False, True] = False,
|
2000
|
+
**request_kwargs,
|
2001
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
2002
|
+
"""单个文件重命名
|
2003
|
+
|
2004
|
+
PUT https://open-api.123pan.com/api/v1/file/name
|
2005
|
+
|
2006
|
+
.. admonition:: Reference
|
2007
|
+
|
2008
|
+
/API列表/文件管理/重命名/单个文件重命名
|
2009
|
+
|
2010
|
+
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/ha6mfe9tteht5skc
|
2011
|
+
|
2012
|
+
:payload:
|
2013
|
+
- fileId: int 💡 文件 id
|
2014
|
+
- fileName: str 💡 文件名
|
2015
|
+
"""
|
2016
|
+
api = complete_url("/api/v1/file/name", base_url)
|
2017
|
+
if not isinstance(payload, dict):
|
2018
|
+
fid: int | str
|
2019
|
+
if isinstance(payload, str):
|
2020
|
+
fid, name = payload.split("|", 1)
|
2021
|
+
else:
|
2022
|
+
fid, name = payload
|
2023
|
+
payload = {"fileId": fid, "fileName": name}
|
2024
|
+
return self.request(api, "PUT", json=payload, async_=async_, **request_kwargs)
|
2025
|
+
|
2026
|
+
@overload
|
2027
|
+
def fs_trash(
|
2028
|
+
self,
|
2029
|
+
payload: dict | int | str | Iterable[int | str],
|
2030
|
+
/,
|
2031
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
2032
|
+
*,
|
2033
|
+
async_: Literal[False] = False,
|
2034
|
+
**request_kwargs,
|
2035
|
+
) -> dict:
|
2036
|
+
...
|
2037
|
+
@overload
|
2038
|
+
def fs_trash(
|
2039
|
+
self,
|
2040
|
+
payload: dict | int | str | Iterable[int | str],
|
2041
|
+
/,
|
2042
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
2043
|
+
*,
|
2044
|
+
async_: Literal[True],
|
2045
|
+
**request_kwargs,
|
2046
|
+
) -> Coroutine[Any, Any, dict]:
|
2047
|
+
...
|
2048
|
+
def fs_trash(
|
2049
|
+
self,
|
2050
|
+
payload: dict | int | str | Iterable[int | str],
|
2051
|
+
/,
|
2052
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
2053
|
+
*,
|
2054
|
+
async_: Literal[False, True] = False,
|
2055
|
+
**request_kwargs,
|
2056
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
2057
|
+
"""删除文件至回收站
|
2058
|
+
|
2059
|
+
POST https://open-api.123pan.com/api/v1/file/trash
|
2060
|
+
|
2061
|
+
.. admonition:: Reference
|
2062
|
+
|
2063
|
+
/API列表/文件管理/删除/删除文件至回收站
|
2064
|
+
|
2065
|
+
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/en07662k2kki4bo6
|
2066
|
+
|
2067
|
+
:payload:
|
2068
|
+
- fileIDs: list[int] 💡 文件 id 列表,最多 100 个
|
2069
|
+
"""
|
2070
|
+
api = complete_url("/api/v1/file/trash", base_url)
|
2071
|
+
if not isinstance(payload, dict):
|
2072
|
+
if isinstance(payload, (int, str)):
|
2073
|
+
payload = [payload]
|
2074
|
+
elif not isinstance(payload, (tuple, list)):
|
2075
|
+
payload = list(payload)
|
2076
|
+
payload = {"fileIDs": payload}
|
2077
|
+
return self.request(api, "POST", json=payload, async_=async_, **request_kwargs)
|
2078
|
+
|
2079
|
+
########## Login API ##########
|
2080
|
+
|
2081
|
+
@overload
|
2082
|
+
@staticmethod
|
2083
|
+
def login_token(
|
2084
|
+
payload: dict,
|
2085
|
+
/,
|
2086
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
2087
|
+
request: None | Callable = None,
|
2088
|
+
*,
|
2089
|
+
async_: Literal[False] = False,
|
2090
|
+
**request_kwargs,
|
2091
|
+
) -> dict:
|
2092
|
+
...
|
2093
|
+
@overload
|
2094
|
+
@staticmethod
|
2095
|
+
def login_token(
|
2096
|
+
payload: dict,
|
2097
|
+
/,
|
2098
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
2099
|
+
request: None | Callable = None,
|
2100
|
+
*,
|
2101
|
+
async_: Literal[True],
|
2102
|
+
**request_kwargs,
|
2103
|
+
) -> Coroutine[Any, Any, dict]:
|
2104
|
+
...
|
2105
|
+
@staticmethod
|
2106
|
+
def login_token(
|
2107
|
+
payload: dict,
|
2108
|
+
/,
|
2109
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
2110
|
+
request: None | Callable = None,
|
2111
|
+
*,
|
2112
|
+
async_: Literal[False, True] = False,
|
2113
|
+
**request_kwargs,
|
2114
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
2115
|
+
"""获取access_token
|
2116
|
+
|
2117
|
+
POST https://open-api.123pan.com/api/v1/access_token
|
2118
|
+
|
2119
|
+
.. attention::
|
2120
|
+
此接口有访问频率限制。请获取到 ``access_token`` 后本地保存使用,并在 `access_token `过期前及时重新获取。``access_token`` 有效期根据返回的 "expiredAt" 字段判断。
|
2121
|
+
|
2122
|
+
.. note::
|
2123
|
+
通过这种方式授权得到的 ``access_token``,各个接口分别允许一个较低的 QPS
|
2124
|
+
|
2125
|
+
/接入指南/开发者接入/开发须知
|
2126
|
+
|
2127
|
+
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/txgcvbfgh0gtuad5
|
2128
|
+
|
2129
|
+
.. admonition:: Reference
|
2130
|
+
|
2131
|
+
/接入指南/开发者接入/获取access_token
|
2132
|
+
|
2133
|
+
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/gn1nai4x0v0ry9ki
|
2134
|
+
|
2135
|
+
:payload:
|
2136
|
+
- clientID: str 💡 应用标识,创建应用时分配的 appId
|
2137
|
+
- clientSecret: str 💡 应用密钥,创建应用时分配的 secretId
|
2138
|
+
"""
|
2139
|
+
request_kwargs.setdefault("parse", default_parse)
|
2140
|
+
if request is None:
|
2141
|
+
if headers := request_kwargs.get("headers"):
|
2142
|
+
headers = dict(headers, platform="open_platform")
|
2143
|
+
else:
|
2144
|
+
headers = {"platform": "open_platform"}
|
2145
|
+
request_kwargs["headers"] = headers
|
2146
|
+
request = get_default_request()
|
2147
|
+
request_kwargs["async_"] = async_
|
2148
|
+
return request(
|
2149
|
+
url=complete_url("/api/v1/access_token", base_url),
|
2150
|
+
method="POST",
|
2151
|
+
json=payload,
|
2152
|
+
**request_kwargs,
|
2153
|
+
)
|
2154
|
+
|
2155
|
+
@overload
|
2156
|
+
@staticmethod
|
2157
|
+
def login_oauth_authorize(
|
2158
|
+
payload: dict,
|
1781
2159
|
/,
|
1782
2160
|
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
2161
|
+
request: None | Callable = None,
|
1783
2162
|
*,
|
1784
2163
|
async_: Literal[False] = False,
|
1785
2164
|
**request_kwargs,
|
1786
2165
|
) -> dict:
|
1787
2166
|
...
|
1788
2167
|
@overload
|
1789
|
-
|
1790
|
-
|
1791
|
-
payload: dict
|
2168
|
+
@staticmethod
|
2169
|
+
def login_oauth_authorize(
|
2170
|
+
payload: dict,
|
1792
2171
|
/,
|
1793
2172
|
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
2173
|
+
request: None | Callable = None,
|
1794
2174
|
*,
|
1795
2175
|
async_: Literal[True],
|
1796
2176
|
**request_kwargs,
|
1797
2177
|
) -> Coroutine[Any, Any, dict]:
|
1798
2178
|
...
|
1799
|
-
|
1800
|
-
|
1801
|
-
payload: dict
|
2179
|
+
@staticmethod
|
2180
|
+
def login_oauth_authorize(
|
2181
|
+
payload: dict,
|
1802
2182
|
/,
|
1803
2183
|
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
2184
|
+
request: None | Callable = None,
|
1804
2185
|
*,
|
1805
2186
|
async_: Literal[False, True] = False,
|
1806
2187
|
**request_kwargs,
|
1807
2188
|
) -> dict | Coroutine[Any, Any, dict]:
|
1808
|
-
"""
|
2189
|
+
"""授权以获取和 ``accessToken`` 绑定的 ``code``
|
1809
2190
|
|
1810
|
-
|
2191
|
+
GET https://open-api.123pan.com/api/v1/oauth2/user/authorize
|
1811
2192
|
|
1812
2193
|
.. admonition:: Reference
|
1813
|
-
/API列表/文件管理/重命名/批量文件重命名
|
1814
2194
|
|
1815
|
-
|
2195
|
+
/接入指南/第三方挂载应用接入/授权地址
|
2196
|
+
|
2197
|
+
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/gr7ggimkcysm18ap
|
1816
2198
|
|
1817
2199
|
:payload:
|
1818
|
-
-
|
1819
|
-
|
1820
|
-
|
1821
|
-
|
1822
|
-
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
2200
|
+
- accessToken: str 💡 访问令牌
|
2201
|
+
- client_id: str 💡 应用标识,创建应用时分配的 appId
|
2202
|
+
- redirect_uri: str 💡 回调链接
|
2203
|
+
- scope: str = "user:base,file:all:read,file:all:write" 💡 权限
|
2204
|
+
- response_type: str = "code"
|
2205
|
+
- state: str = <default>
|
2206
|
+
"""
|
2207
|
+
def parse(resp, _, /):
|
2208
|
+
url = resp.headers["location"]
|
2209
|
+
data = dict(parse_qsl(urlsplit(url).query))
|
2210
|
+
if "code" in data:
|
2211
|
+
code = 0
|
2212
|
+
message = "ok"
|
1826
2213
|
else:
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
2214
|
+
code = 1
|
2215
|
+
message = data.get("error_description") or "error"
|
2216
|
+
return {
|
2217
|
+
"code": code,
|
2218
|
+
"message": message,
|
2219
|
+
"url": url,
|
2220
|
+
"data": data,
|
2221
|
+
"headers": dict(resp.headers),
|
2222
|
+
}
|
2223
|
+
request_kwargs.setdefault("parse", parse)
|
2224
|
+
for key in ("allow_redirects", "follow_redirects", "redirect"):
|
2225
|
+
request_kwargs[key] = False
|
2226
|
+
payload = dict_to_lower_merge(
|
2227
|
+
payload,
|
2228
|
+
response_type="code",
|
2229
|
+
scope="user:base,file:all:read,file:all:write",
|
2230
|
+
)
|
2231
|
+
if request is None:
|
2232
|
+
request = get_default_request()
|
2233
|
+
request_kwargs["async_"] = async_
|
2234
|
+
return request(
|
2235
|
+
url=complete_url("/api/v1/oauth2/user/authorize", base_url),
|
2236
|
+
params=payload,
|
2237
|
+
**request_kwargs,
|
2238
|
+
)
|
1830
2239
|
|
1831
2240
|
@overload
|
1832
|
-
|
1833
|
-
|
1834
|
-
payload: dict
|
2241
|
+
@staticmethod
|
2242
|
+
def login_oauth_token(
|
2243
|
+
payload: dict,
|
1835
2244
|
/,
|
1836
2245
|
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
2246
|
+
request: None | Callable = None,
|
1837
2247
|
*,
|
1838
2248
|
async_: Literal[False] = False,
|
1839
2249
|
**request_kwargs,
|
1840
2250
|
) -> dict:
|
1841
2251
|
...
|
1842
2252
|
@overload
|
1843
|
-
|
1844
|
-
|
1845
|
-
payload: dict
|
2253
|
+
@staticmethod
|
2254
|
+
def login_oauth_token(
|
2255
|
+
payload: dict,
|
1846
2256
|
/,
|
1847
2257
|
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
2258
|
+
request: None | Callable = None,
|
1848
2259
|
*,
|
1849
2260
|
async_: Literal[True],
|
1850
2261
|
**request_kwargs,
|
1851
2262
|
) -> Coroutine[Any, Any, dict]:
|
1852
2263
|
...
|
1853
|
-
|
1854
|
-
|
1855
|
-
payload: dict
|
2264
|
+
@staticmethod
|
2265
|
+
def login_oauth_token(
|
2266
|
+
payload: dict,
|
1856
2267
|
/,
|
1857
2268
|
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
2269
|
+
request: None | Callable = None,
|
1858
2270
|
*,
|
1859
2271
|
async_: Literal[False, True] = False,
|
1860
2272
|
**request_kwargs,
|
1861
2273
|
) -> dict | Coroutine[Any, Any, dict]:
|
1862
|
-
"""
|
2274
|
+
"""通过 ``authorization_code`` 或 ``refresh_token`` 获取新的 ``access_token`` 和 ``refresh_token``
|
1863
2275
|
|
1864
|
-
|
2276
|
+
POST https://open-api.123pan.com/api/v1/oauth2/access_token
|
2277
|
+
|
2278
|
+
.. note::
|
2279
|
+
通过这种方式授权得到的 ``access_token``,各个接口分别允许更高的 QPS
|
2280
|
+
|
2281
|
+
/接入指南/第三方挂载应用接入/授权须知
|
2282
|
+
|
2283
|
+
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/kf05anzt1r0qnudd
|
1865
2284
|
|
1866
2285
|
.. admonition:: Reference
|
1867
|
-
/API列表/文件管理/重命名/单个文件重命名
|
1868
2286
|
|
1869
|
-
|
2287
|
+
/接入指南/第三方挂载应用接入/授权code获取access_token
|
2288
|
+
|
2289
|
+
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/gammzlhe6k4qtwd9
|
1870
2290
|
|
1871
2291
|
:payload:
|
1872
|
-
-
|
1873
|
-
-
|
2292
|
+
- client_id: str 💡 应用标识,创建应用时分配的 appId
|
2293
|
+
- client_secret: str 💡 应用密钥,创建应用时分配的 secretId
|
2294
|
+
- code: str = <default> 💡 授权码
|
2295
|
+
- grant_type: "authorization_code" | "refresh_token" = <default> 💡 身份类型
|
2296
|
+
- redirect_uri: str = <default> 💡 应用注册的回调地址,``grant_type`` 为 "authorization_code" 时必携带
|
2297
|
+
- refresh_token: str = <default> 💡 刷新 token,单次请求有效
|
1874
2298
|
"""
|
1875
|
-
|
1876
|
-
|
1877
|
-
|
1878
|
-
if
|
1879
|
-
|
2299
|
+
request_kwargs.setdefault("parse", default_parse)
|
2300
|
+
payload = dict_to_lower(payload)
|
2301
|
+
if not payload.get("grant_type"):
|
2302
|
+
if payload.get("refresh_token"):
|
2303
|
+
payload["grant_type"] = "refresh_token"
|
1880
2304
|
else:
|
1881
|
-
|
1882
|
-
|
1883
|
-
|
2305
|
+
payload["grant_type"] = "authorization_code"
|
2306
|
+
if request is None:
|
2307
|
+
if headers := request_kwargs.get("headers"):
|
2308
|
+
headers = dict(headers, platform="open_platform")
|
2309
|
+
else:
|
2310
|
+
headers = {"platform": "open_platform"}
|
2311
|
+
request_kwargs["headers"] = headers
|
2312
|
+
request = get_default_request()
|
2313
|
+
request_kwargs["async_"] = async_
|
2314
|
+
return request(
|
2315
|
+
url=complete_url("/api/v1/oauth2/access_token", base_url),
|
2316
|
+
method="POST",
|
2317
|
+
params=payload,
|
2318
|
+
**request_kwargs,
|
2319
|
+
)
|
1884
2320
|
|
1885
2321
|
@overload
|
1886
|
-
|
1887
|
-
|
1888
|
-
payload: dict
|
2322
|
+
@staticmethod
|
2323
|
+
def login_oauth_verify(
|
2324
|
+
payload: dict,
|
1889
2325
|
/,
|
1890
2326
|
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
2327
|
+
request: None | Callable = None,
|
1891
2328
|
*,
|
1892
2329
|
async_: Literal[False] = False,
|
1893
2330
|
**request_kwargs,
|
1894
2331
|
) -> dict:
|
1895
2332
|
...
|
1896
2333
|
@overload
|
1897
|
-
|
1898
|
-
|
1899
|
-
payload: dict
|
2334
|
+
@staticmethod
|
2335
|
+
def login_oauth_verify(
|
2336
|
+
payload: dict,
|
1900
2337
|
/,
|
1901
2338
|
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
2339
|
+
request: None | Callable = None,
|
1902
2340
|
*,
|
1903
2341
|
async_: Literal[True],
|
1904
2342
|
**request_kwargs,
|
1905
2343
|
) -> Coroutine[Any, Any, dict]:
|
1906
2344
|
...
|
1907
|
-
|
1908
|
-
|
1909
|
-
payload: dict
|
2345
|
+
@staticmethod
|
2346
|
+
def login_oauth_verify(
|
2347
|
+
payload: dict,
|
1910
2348
|
/,
|
1911
2349
|
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
2350
|
+
request: None | Callable = None,
|
1912
2351
|
*,
|
1913
2352
|
async_: Literal[False, True] = False,
|
1914
2353
|
**request_kwargs,
|
1915
2354
|
) -> dict | Coroutine[Any, Any, dict]:
|
1916
|
-
"""
|
2355
|
+
"""检查 ``appId`` 对应的 ``redirectUri`` 是否可用
|
1917
2356
|
|
1918
|
-
POST https://open-api.123pan.com/api/v1/
|
2357
|
+
POST https://open-api.123pan.com/api/v1/oauth2/app/verify
|
1919
2358
|
|
1920
2359
|
.. admonition:: Reference
|
1921
|
-
/API列表/文件管理/删除/删除文件至回收站
|
1922
2360
|
|
1923
|
-
|
2361
|
+
/接入指南/第三方挂载应用接入/授权地址
|
2362
|
+
|
2363
|
+
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/gr7ggimkcysm18ap
|
1924
2364
|
|
1925
2365
|
:payload:
|
1926
|
-
-
|
2366
|
+
- appId: str 💡 应用标识,创建应用时分配的 appId
|
2367
|
+
- redirectUri: str 💡 回调链接
|
2368
|
+
- scope: str = "user:base,file:all:read,file:all:write" 💡 权限
|
1927
2369
|
"""
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
|
1934
|
-
|
1935
|
-
|
2370
|
+
request_kwargs.setdefault("parse", default_parse)
|
2371
|
+
payload = dict_to_lower_merge(payload, scope="user:base,file:all:read,file:all:write")
|
2372
|
+
if request is None:
|
2373
|
+
request = get_default_request()
|
2374
|
+
request_kwargs["async_"] = async_
|
2375
|
+
return request(
|
2376
|
+
url=complete_url("/api/v1/oauth2/app/verify", base_url),
|
2377
|
+
method="POST",
|
2378
|
+
json=payload,
|
2379
|
+
**request_kwargs,
|
2380
|
+
)
|
1936
2381
|
|
1937
2382
|
########## Offline Download API ##########
|
1938
2383
|
|
@@ -1972,6 +2417,7 @@ class P123OpenClient:
|
|
1972
2417
|
POST https://open-api.123pan.com/api/v1/offline/download
|
1973
2418
|
|
1974
2419
|
.. admonition:: Reference
|
2420
|
+
|
1975
2421
|
/API列表/离线下载/创建离线下载任务
|
1976
2422
|
|
1977
2423
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/he47hsq2o1xvgado
|
@@ -2033,6 +2479,7 @@ class P123OpenClient:
|
|
2033
2479
|
GET https://open-api.123pan.com/api/v1/offline/download/process
|
2034
2480
|
|
2035
2481
|
.. admonition:: Reference
|
2482
|
+
|
2036
2483
|
/API列表/离线下载/获取离线下载进度
|
2037
2484
|
|
2038
2485
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/sclficr3t655pii5
|
@@ -2086,11 +2533,14 @@ class P123OpenClient:
|
|
2086
2533
|
POST https://open-api.123pan.com/api/v1/oss/source/copy
|
2087
2534
|
|
2088
2535
|
.. note::
|
2089
|
-
|
2090
|
-
|
2091
|
-
|
2536
|
+
图床复制任务创建(可创建的任务数:3,fileIDs 长度限制:100,当前一个任务处理完后将会继续处理下个任务)。
|
2537
|
+
|
2538
|
+
该接口将会复制云盘里的文件或目录对应的图片到对应图床目录,每次任务包含的图片总数限制 1000 张,图片格式:png, gif, jpeg, tiff, webp,jpg,tif,svg,bmp,图片大小限制:100M,文件夹层级限制:15层。
|
2539
|
+
|
2540
|
+
如果图床目录下存在相同 etag、size 的图片将会视为同一张图片,将覆盖原图片
|
2092
2541
|
|
2093
2542
|
.. admonition:: Reference
|
2543
|
+
|
2094
2544
|
/API列表/图床/复制云盘图片/创建复制任务
|
2095
2545
|
|
2096
2546
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/trahy3lmds4o0i3r
|
@@ -2151,6 +2601,7 @@ class P123OpenClient:
|
|
2151
2601
|
GET https://open-api.123pan.com/api/v1/oss/source/copy/process
|
2152
2602
|
|
2153
2603
|
.. admonition:: Reference
|
2604
|
+
|
2154
2605
|
/API列表/图床/复制云盘图片/获取复制任务详情
|
2155
2606
|
|
2156
2607
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/rissl4ewklaui4th
|
@@ -2199,6 +2650,7 @@ class P123OpenClient:
|
|
2199
2650
|
GET https://open-api.123pan.com/api/v1/oss/source/copy/fail
|
2200
2651
|
|
2201
2652
|
.. admonition:: Reference
|
2653
|
+
|
2202
2654
|
/API列表/图床/复制云盘图片/获取复制失败文件列表
|
2203
2655
|
|
2204
2656
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/tlug9od3xlw2w23v
|
@@ -2253,6 +2705,7 @@ class P123OpenClient:
|
|
2253
2705
|
彻底删除文件前,文件必须要在回收站中,否则无法删除
|
2254
2706
|
|
2255
2707
|
.. admonition:: Reference
|
2708
|
+
|
2256
2709
|
/API列表/图床/删除图片
|
2257
2710
|
|
2258
2711
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/ef8yluqdzm2yttdn
|
@@ -2305,6 +2758,7 @@ class P123OpenClient:
|
|
2305
2758
|
GET https://open-api.123pan.com/api/v1/oss/file/detail
|
2306
2759
|
|
2307
2760
|
.. admonition:: Reference
|
2761
|
+
|
2308
2762
|
/API列表/图床/获取图片信息/获取图片详情
|
2309
2763
|
|
2310
2764
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/rgf2ndfaxc2gugp8
|
@@ -2357,6 +2811,7 @@ class P123OpenClient:
|
|
2357
2811
|
其它则代表下一页开始的文件 id,携带到请求参数中,可查询下一页
|
2358
2812
|
|
2359
2813
|
.. admonition:: Reference
|
2814
|
+
|
2360
2815
|
/API列表/图床/获取图片信息/获取图片列表
|
2361
2816
|
|
2362
2817
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/zayr72q8xd7gg4f8
|
@@ -2414,6 +2869,7 @@ class P123OpenClient:
|
|
2414
2869
|
POST https://open-api.123pan.com/upload/v1/oss/file/mkdir
|
2415
2870
|
|
2416
2871
|
.. admonition:: Reference
|
2872
|
+
|
2417
2873
|
/API列表/图床/上传图片/创建目录
|
2418
2874
|
|
2419
2875
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/tpqqm04ocqwvonrk
|
@@ -2468,6 +2924,7 @@ class P123OpenClient:
|
|
2468
2924
|
POST https://open-api.123pan.com/api/v1/oss/file/move
|
2469
2925
|
|
2470
2926
|
.. admonition:: Reference
|
2927
|
+
|
2471
2928
|
/API列表/图床/移动图片
|
2472
2929
|
|
2473
2930
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/eqeargimuvycddna
|
@@ -2522,6 +2979,7 @@ class P123OpenClient:
|
|
2522
2979
|
POST https://open-api.123pan.com/api/v1/oss/offline/download
|
2523
2980
|
|
2524
2981
|
.. admonition:: Reference
|
2982
|
+
|
2525
2983
|
/API列表/图床/图床离线迁移/创建离线迁移任务
|
2526
2984
|
|
2527
2985
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/ctigc3a08lqzsfnq
|
@@ -2585,6 +3043,7 @@ class P123OpenClient:
|
|
2585
3043
|
GET https://open-api.123pan.com/api/v1/oss/offline/download/process
|
2586
3044
|
|
2587
3045
|
.. admonition:: Reference
|
3046
|
+
|
2588
3047
|
/API列表/图床/图床离线迁移/获取离线迁移任务
|
2589
3048
|
|
2590
3049
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/svo92desugbyhrgq
|
@@ -2633,11 +3092,12 @@ class P123OpenClient:
|
|
2633
3092
|
POST https://open-api.123pan.com/upload/v1/oss/file/create
|
2634
3093
|
|
2635
3094
|
.. note::
|
2636
|
-
- 文件名要小于 256
|
3095
|
+
- 文件名要小于 256 个字符且不能包含以下字符:``"\\/:*?|><``
|
2637
3096
|
- 文件名不能全部是空格
|
2638
3097
|
- 不会重名
|
2639
3098
|
|
2640
3099
|
.. admonition:: Reference
|
3100
|
+
|
2641
3101
|
/API列表/图床/上传图片/创建文件
|
2642
3102
|
|
2643
3103
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/xwfka5kt6vtmgs8r
|
@@ -2656,10 +3116,10 @@ class P123OpenClient:
|
|
2656
3116
|
.. code:: python
|
2657
3117
|
|
2658
3118
|
{
|
2659
|
-
"fileID": str, # 上传后的文件 id。当已有相同
|
2660
|
-
"preuploadID": str, # 预上传 id。当
|
3119
|
+
"fileID": str, # 上传后的文件 id。当已有相同 ``size`` 和 ``etag`` 的文件时,会发生秒传
|
3120
|
+
"preuploadID": str, # 预上传 id。当 ``reuse`` 为 "true" 时,该字段不存在
|
2661
3121
|
"reuse": bool, # 是否秒传,返回 "true" 时表示文件已上传成功
|
2662
|
-
"sliceSize": int, # 分片大小,必须按此大小生成文件分片再上传。当
|
3122
|
+
"sliceSize": int, # 分片大小,必须按此大小生成文件分片再上传。当 ``reuse`` 为 "true" 时,该字段不存在
|
2663
3123
|
}
|
2664
3124
|
"""
|
2665
3125
|
api = complete_url("/upload/v1/oss/file/create", base_url)
|
@@ -2707,6 +3167,7 @@ class P123OpenClient:
|
|
2707
3167
|
有多个分片时,轮流分别根据序号获取下载链接,然后 PUT 方法上传分片。由于上传链接会过期,所以没必要提前获取一大批
|
2708
3168
|
|
2709
3169
|
.. admonition:: Reference
|
3170
|
+
|
2710
3171
|
/API列表/图床/上传图片/获取上传地址&上传分片
|
2711
3172
|
|
2712
3173
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/pyfo3a39q6ac0ocd
|
@@ -2800,6 +3261,7 @@ class P123OpenClient:
|
|
2800
3261
|
POST https://open-api.123pan.com/upload/v1/oss/file/upload_complete
|
2801
3262
|
|
2802
3263
|
.. admonition:: Reference
|
3264
|
+
|
2803
3265
|
/API列表/图床/上传图片/上传完毕
|
2804
3266
|
|
2805
3267
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/yhgo0kt3nkngi8r2
|
@@ -2859,6 +3321,7 @@ class P123OpenClient:
|
|
2859
3321
|
POST https://open-api.123pan.com/upload/v1/oss/file/upload_async_result
|
2860
3322
|
|
2861
3323
|
.. admonition:: Reference
|
3324
|
+
|
2862
3325
|
/API列表/图床/上传图片/异步轮询获取上传结果
|
2863
3326
|
|
2864
3327
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/lbdq2cbyzfzayipu
|
@@ -2939,27 +3402,28 @@ class P123OpenClient:
|
|
2939
3402
|
"""上传文件
|
2940
3403
|
|
2941
3404
|
.. note::
|
2942
|
-
如果文件名中包含字符 "
|
3405
|
+
如果文件名中包含字符 ``"\\/:*?|><``,则转换为对应的全角字符
|
2943
3406
|
|
2944
3407
|
.. admonition:: Reference
|
3408
|
+
|
2945
3409
|
/API列表/图床/上传图片/💡上传流程说明
|
2946
3410
|
|
2947
3411
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/di0url3qn13tk28t
|
2948
3412
|
|
2949
3413
|
:param file: 待上传的文件
|
2950
3414
|
|
2951
|
-
- 如果为
|
2952
|
-
- 如果为
|
2953
|
-
- 如果为
|
2954
|
-
- 如果为
|
2955
|
-
- 如果为
|
3415
|
+
- 如果为 ``collections.abc.Buffer``,则作为二进制数据上传
|
3416
|
+
- 如果为 ``filewrap.SupportsRead``,则作为可读的二进制文件上传
|
3417
|
+
- 如果为 ``str`` 或 ``os.PathLike``,则视为路径,打开后作为文件上传
|
3418
|
+
- 如果为 ``yarl.URL`` 或 ``http_request.SupportsGeturl`` (``pip install python-http_request``),则视为超链接,打开后作为文件上传
|
3419
|
+
- 如果为 ``collections.abc.Iterable[collections.abc.Buffer]`` 或 ``collections.abc.AsyncIterable[collections.abc.Buffer]``,则迭代以获取二进制数据,逐步上传
|
2956
3420
|
|
2957
3421
|
:param file_md5: 文件的 MD5 散列值
|
2958
3422
|
:param file_name: 文件名
|
2959
3423
|
:param file_size: 文件大小
|
2960
3424
|
:param parent_id: 要上传的目标目录,默认为根目录
|
2961
3425
|
:param duplicate: 处理同名:0: 提示/忽略 1: 保留两者 2: 替换
|
2962
|
-
:param preupload_id: 预上传 id,用于断点续传,提供此参数,则会忽略
|
3426
|
+
:param preupload_id: 预上传 id,用于断点续传,提供此参数,则会忽略 ``file_md5``、``file_name``、``file_size``、``parent_id`` 和 ``duplicate``
|
2963
3427
|
:param slice_size: 分块大小,断点续传时,如果只上传过少于 2 个分块时,会被使用
|
2964
3428
|
:param async_: 是否异步
|
2965
3429
|
:param request_kwargs: 其它请求参数
|
@@ -3223,6 +3687,7 @@ class P123OpenClient:
|
|
3223
3687
|
POST https://open-api.123pan.com/api/v1/share/create
|
3224
3688
|
|
3225
3689
|
.. admonition:: Reference
|
3690
|
+
|
3226
3691
|
/API列表/分享管理/创建分享链接
|
3227
3692
|
|
3228
3693
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/dwd2ss0qnpab5i5s
|
@@ -3230,7 +3695,7 @@ class P123OpenClient:
|
|
3230
3695
|
:payload:
|
3231
3696
|
- fileIDList: str 💡 分享文件 id 列表,最多 100 个,用逗号,分隔连接
|
3232
3697
|
- shareExpire: 0 | 1 | 7 | 30 = 0 💡 分享链接有效期天数,0 为永久
|
3233
|
-
- shareName: str 💡 分享链接名称,须小于 35 个字符且不能包含特殊字符 "
|
3698
|
+
- shareName: str 💡 分享链接名称,须小于 35 个字符且不能包含特殊字符 ``"\\/:*?|><``
|
3234
3699
|
- sharePwd: str = "" 💡 设置分享链接提取码
|
3235
3700
|
- trafficLimit: int = <default> 💡 免登陆限制流量,单位:字节
|
3236
3701
|
- trafficLimitSwitch: 1 | 2 = <default> 💡 免登录流量限制开关:1:关闭 2:打开
|
@@ -3276,6 +3741,7 @@ class P123OpenClient:
|
|
3276
3741
|
POST https://open-api.123pan.com/api/v1/share/content-payment/create
|
3277
3742
|
|
3278
3743
|
.. admonition:: Reference
|
3744
|
+
|
3279
3745
|
/API列表/分享管理/创建付费分享链接
|
3280
3746
|
|
3281
3747
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/qz30c5k2npe8l98r
|
@@ -3285,7 +3751,7 @@ class P123OpenClient:
|
|
3285
3751
|
- isReward: 0 | 1 = 0 💡 是否开启打赏
|
3286
3752
|
- payAmount: int = 1 💡 金额,从 1 到 99,单位:元
|
3287
3753
|
- resourceDesc: str = "" 💡 资源描述
|
3288
|
-
- shareName: str 💡 分享链接名称,须小于 35 个字符且不能包含特殊字符 "
|
3754
|
+
- shareName: str 💡 分享链接名称,须小于 35 个字符且不能包含特殊字符 ``"\\/:*?|><``
|
3289
3755
|
"""
|
3290
3756
|
api = complete_url("/api/v1/share/content-payment/create", base_url)
|
3291
3757
|
payload = dict_to_lower_merge(payload, {"payAmount": 1, "isReward": 0, "resourceDesc": ""})
|
@@ -3327,6 +3793,7 @@ class P123OpenClient:
|
|
3327
3793
|
PUT https://open-api.123pan.com/api/v1/share/list/info
|
3328
3794
|
|
3329
3795
|
.. admonition:: Reference
|
3796
|
+
|
3330
3797
|
/API列表/分享管理/修改分享链接
|
3331
3798
|
|
3332
3799
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/ga6hhca1u8v9yqx0
|
@@ -3382,6 +3849,7 @@ class P123OpenClient:
|
|
3382
3849
|
GET https://open-api.123pan.com/api/v1/share/list
|
3383
3850
|
|
3384
3851
|
.. admonition:: Reference
|
3852
|
+
|
3385
3853
|
/API列表/分享管理/获取分享链接列表
|
3386
3854
|
|
3387
3855
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/ixg0arldi61fe7av
|
@@ -3433,6 +3901,7 @@ class P123OpenClient:
|
|
3433
3901
|
POST https://open-api.123pan.com/api/v1/transcode/delete
|
3434
3902
|
|
3435
3903
|
.. admonition:: Reference
|
3904
|
+
|
3436
3905
|
/API列表/视频转码/删除视频/删除转码视频
|
3437
3906
|
|
3438
3907
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/tg2xgotkgmgpulrp
|
@@ -3484,6 +3953,7 @@ class P123OpenClient:
|
|
3484
3953
|
POST https://open-api.123pan.com/api/v1/transcode/file/download
|
3485
3954
|
|
3486
3955
|
.. admonition:: Reference
|
3956
|
+
|
3487
3957
|
/API列表/视频转码/视频文件下载/原文件下载
|
3488
3958
|
|
3489
3959
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/mlltlx57sty6g9gf
|
@@ -3535,6 +4005,7 @@ class P123OpenClient:
|
|
3535
4005
|
该接口需要轮询去查询结果,建议 10s 一次
|
3536
4006
|
|
3537
4007
|
.. admonition:: Reference
|
4008
|
+
|
3538
4009
|
/API列表/视频转码/视频文件下载/某个视频全部转码文件下载
|
3539
4010
|
|
3540
4011
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/yb7hrb0x2gym7xic
|
@@ -3585,6 +4056,7 @@ class P123OpenClient:
|
|
3585
4056
|
POST https://open-api.123pan.com/api/v1/transcode/m3u8_ts/download
|
3586
4057
|
|
3587
4058
|
.. admonition:: Reference
|
4059
|
+
|
3588
4060
|
/API列表/视频转码/视频文件下载/单个转码文件下载(m3u8或ts)
|
3589
4061
|
|
3590
4062
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/yf97p60yyzb8mzbr
|
@@ -3631,6 +4103,7 @@ class P123OpenClient:
|
|
3631
4103
|
POST https://open-api.123pan.com/api/v1/transcode/folder/info
|
3632
4104
|
|
3633
4105
|
.. admonition:: Reference
|
4106
|
+
|
3634
4107
|
/API列表/视频转码/获取视频信息/获取转码空间文件夹信息
|
3635
4108
|
|
3636
4109
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/kaalgke88r9y7nlt
|
@@ -3674,9 +4147,10 @@ class P123OpenClient:
|
|
3674
4147
|
GET https://open-api.123pan.com/api/v1/video/transcode/list
|
3675
4148
|
|
3676
4149
|
.. attention::
|
3677
|
-
此接口仅限授权
|
4150
|
+
此接口仅限授权 ``access_token`` 调用
|
3678
4151
|
|
3679
4152
|
.. admonition:: Reference
|
4153
|
+
|
3680
4154
|
/API列表/视频转码/获取视频信息/视频转码列表(三方挂载应用授权使用)
|
3681
4155
|
|
3682
4156
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/tgg6g84gdrmyess5
|
@@ -3725,6 +4199,7 @@ class P123OpenClient:
|
|
3725
4199
|
POST https://open-api.123pan.com/api/v1/transcode/video/record
|
3726
4200
|
|
3727
4201
|
.. admonition:: Reference
|
4202
|
+
|
3728
4203
|
/API列表/视频转码/查询转码信息/查询某个视频的转码记录
|
3729
4204
|
|
3730
4205
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/ost1m82sa9chh0mc
|
@@ -3776,6 +4251,7 @@ class P123OpenClient:
|
|
3776
4251
|
POST https://open-api.123pan.com/api/v1/transcode/video/resolutions
|
3777
4252
|
|
3778
4253
|
.. admonition:: Reference
|
4254
|
+
|
3779
4255
|
/API列表/视频转码/获取视频信息/获取视频文件可转码的分辨率
|
3780
4256
|
|
3781
4257
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/apzlsgyoggmqwl36
|
@@ -3824,6 +4300,7 @@ class P123OpenClient:
|
|
3824
4300
|
POST https://open-api.123pan.com/api/v1/transcode/video/result
|
3825
4301
|
|
3826
4302
|
.. admonition:: Reference
|
4303
|
+
|
3827
4304
|
/API列表/视频转码/查询转码信息/查询某个视频的转码结果
|
3828
4305
|
|
3829
4306
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/iucbqgge0dgfc8sv
|
@@ -3872,6 +4349,7 @@ class P123OpenClient:
|
|
3872
4349
|
POST https://open-api.123pan.com/api/v1/transcode/upload/from_cloud_disk
|
3873
4350
|
|
3874
4351
|
.. admonition:: Reference
|
4352
|
+
|
3875
4353
|
/API列表/视频转码/上传视频/云盘上传/从云盘空间上传
|
3876
4354
|
|
3877
4355
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/tqy2xatoo4qmdbz7
|
@@ -3930,6 +4408,7 @@ class P123OpenClient:
|
|
3930
4408
|
POST https://open-api.123pan.com/api/v1/transcode/video
|
3931
4409
|
|
3932
4410
|
.. admonition:: Reference
|
4411
|
+
|
3933
4412
|
/API列表/视频转码/视频转码/视频转码操作
|
3934
4413
|
|
3935
4414
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/xy42nv2x8wav9n5l
|
@@ -3981,19 +4460,20 @@ class P123OpenClient:
|
|
3981
4460
|
POST https://open-api.123pan.com/upload/v1/file/create
|
3982
4461
|
|
3983
4462
|
.. note::
|
3984
|
-
- 文件名要小于 256
|
4463
|
+
- 文件名要小于 256 个字符且不能包含以下字符:``"\\/:*?|><``
|
3985
4464
|
- 文件名不能全部是空格
|
3986
4465
|
- 开发者上传单文件大小限制 10 GB
|
3987
4466
|
- 不会重名
|
3988
4467
|
|
3989
4468
|
.. admonition:: Reference
|
4469
|
+
|
3990
4470
|
/API列表/文件管理/上传/V1/创建文件
|
3991
4471
|
|
3992
4472
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/lrfuu3qe7q1ul8ig
|
3993
4473
|
|
3994
4474
|
:payload:
|
3995
4475
|
- containDir: "false" | "true" = "false" 💡 上传文件是否包含路径
|
3996
|
-
- filename: str 💡 文件名,但
|
4476
|
+
- filename: str 💡 文件名,但 ``containDir`` 为 "true" 时,视为路径
|
3997
4477
|
- duplicate: 0 | 1 | 2 = 0 💡 处理同名:0: 跳过/报错 1: 保留/后缀编号 2: 替换/覆盖
|
3998
4478
|
- etag: str 💡 文件 md5
|
3999
4479
|
- parentFileID: int = 0 💡 父目录 id,根目录是 0
|
@@ -4005,10 +4485,10 @@ class P123OpenClient:
|
|
4005
4485
|
.. code:: python
|
4006
4486
|
|
4007
4487
|
{
|
4008
|
-
"fileID": str, # 上传后的文件 id。当已有相同
|
4009
|
-
"preuploadID": str, # 预上传 id。当
|
4488
|
+
"fileID": str, # 上传后的文件 id。当已有相同 ``size`` 和 ``etag`` 的文件时,会发生秒传
|
4489
|
+
"preuploadID": str, # 预上传 id。当 ``reuse`` 为 "true" 时,该字段不存在
|
4010
4490
|
"reuse": bool, # 是否秒传,返回 "true" 时表示文件已上传成功
|
4011
|
-
"sliceSize": int, # 分片大小,必须按此大小生成文件分片再上传。当
|
4491
|
+
"sliceSize": int, # 分片大小,必须按此大小生成文件分片再上传。当 ``reuse`` 为 "true" 时,该字段不存在
|
4012
4492
|
}
|
4013
4493
|
"""
|
4014
4494
|
api = complete_url("/upload/v1/file/create", base_url)
|
@@ -4059,6 +4539,7 @@ class P123OpenClient:
|
|
4059
4539
|
有多个分片时,轮流分别根据序号获取下载链接,然后 PUT 方法上传分片。由于上传链接会过期,所以没必要提前获取一大批
|
4060
4540
|
|
4061
4541
|
.. admonition:: Reference
|
4542
|
+
|
4062
4543
|
/API列表/文件管理/上传/V1/获取上传地址&上传分片
|
4063
4544
|
|
4064
4545
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/sonz9n085gnz0n3m
|
@@ -4109,6 +4590,7 @@ class P123OpenClient:
|
|
4109
4590
|
此接口用于罗列已经上传的分片信息,以供比对
|
4110
4591
|
|
4111
4592
|
.. admonition:: Reference
|
4593
|
+
|
4112
4594
|
/API列表/文件管理/上传/V1/列举已上传分片(非必需)
|
4113
4595
|
|
4114
4596
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/dd28ws4bfn644cny
|
@@ -4157,6 +4639,7 @@ class P123OpenClient:
|
|
4157
4639
|
POST https://open-api.123pan.com/upload/v1/file/upload_complete
|
4158
4640
|
|
4159
4641
|
.. admonition:: Reference
|
4642
|
+
|
4160
4643
|
/API列表/文件管理/上传/V1/上传完毕
|
4161
4644
|
|
4162
4645
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/hkdmcmvg437rfu6x
|
@@ -4216,6 +4699,7 @@ class P123OpenClient:
|
|
4216
4699
|
POST https://open-api.123pan.com/upload/v1/file/upload_async_result
|
4217
4700
|
|
4218
4701
|
.. admonition:: Reference
|
4702
|
+
|
4219
4703
|
/API列表/文件管理/上传/V1/异步轮询获取上传结果
|
4220
4704
|
|
4221
4705
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/qgcosr6adkmm51h7
|
@@ -4297,9 +4781,10 @@ class P123OpenClient:
|
|
4297
4781
|
"""上传文件
|
4298
4782
|
|
4299
4783
|
.. note::
|
4300
|
-
如果文件名中包含字符 "
|
4784
|
+
如果文件名中包含字符 ``"\\/:*?|><``,则转换为对应的全角字符
|
4301
4785
|
|
4302
4786
|
.. admonition:: Reference
|
4787
|
+
|
4303
4788
|
/API列表/文件管理/上传/v1/💡上传流程说明
|
4304
4789
|
|
4305
4790
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/il16qi0opiel4889
|
@@ -4310,18 +4795,18 @@ class P123OpenClient:
|
|
4310
4795
|
|
4311
4796
|
:param file: 待上传的文件
|
4312
4797
|
|
4313
|
-
- 如果为
|
4314
|
-
- 如果为
|
4315
|
-
- 如果为
|
4316
|
-
- 如果为
|
4317
|
-
- 如果为
|
4798
|
+
- 如果为 ``collections.abc.Buffer``,则作为二进制数据上传
|
4799
|
+
- 如果为 ``filewrap.SupportsRead``,则作为可读的二进制文件上传
|
4800
|
+
- 如果为 ``str`` 或 ``os.PathLike``,则视为路径,打开后作为文件上传
|
4801
|
+
- 如果为 ``yarl.URL`` 或 ``http_request.SupportsGeturl`` (``pip install python-http_request``),则视为超链接,打开后作为文件上传
|
4802
|
+
- 如果为 ``collections.abc.Iterable[collections.abc.Buffer]`` 或 ``collections.abc.AsyncIterable[collections.abc.Buffer]``,则迭代以获取二进制数据,逐步上传
|
4318
4803
|
|
4319
4804
|
:param file_md5: 文件的 MD5 散列值
|
4320
4805
|
:param file_name: 文件名
|
4321
4806
|
:param file_size: 文件大小
|
4322
4807
|
:param parent_id: 要上传的目标目录
|
4323
4808
|
:param duplicate: 处理同名:0: 提示/忽略 1: 保留两者 2: 替换
|
4324
|
-
:param preupload_id: 预上传 id,用于断点续传,提供此参数,则会忽略
|
4809
|
+
:param preupload_id: 预上传 id,用于断点续传,提供此参数,则会忽略 ``file_md5``、``file_name``、``file_size``、``parent_id`` 和 ``duplicate``
|
4325
4810
|
:param slice_size: 分块大小,断点续传时,如果只上传过少于 2 个分块时,会被使用
|
4326
4811
|
:param async_: 是否异步
|
4327
4812
|
:param request_kwargs: 其它请求参数
|
@@ -4582,6 +5067,7 @@ class P123OpenClient:
|
|
4582
5067
|
GET https://open-api.123pan.com/api/v1/user/info
|
4583
5068
|
|
4584
5069
|
.. admonition:: Reference
|
5070
|
+
|
4585
5071
|
/API列表/用户管理/获取用户信息
|
4586
5072
|
|
4587
5073
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/fa2w0rosunui2v4m
|
@@ -4606,9 +5092,6 @@ class P123OpenClient:
|
|
4606
5092
|
########## API Aliases ##########
|
4607
5093
|
|
4608
5094
|
login_open = login
|
4609
|
-
login_access_token_open = login_access_token
|
4610
|
-
login_auth_open = login_auth
|
4611
|
-
login_refresh_token_open = login_refresh_token
|
4612
5095
|
dlink_disable_open = dlink_disable
|
4613
5096
|
dlink_enable_open = dlink_enable
|
4614
5097
|
dlink_log_open = dlink_log
|
@@ -4629,6 +5112,10 @@ class P123OpenClient:
|
|
4629
5112
|
fs_rename_open = fs_rename
|
4630
5113
|
fs_rename_one_open = fs_rename_one
|
4631
5114
|
fs_trash_open = fs_trash
|
5115
|
+
login_token_open = login_token
|
5116
|
+
login_oauth_authorize_open = login_oauth_authorize
|
5117
|
+
login_oauth_token_open = login_oauth_token
|
5118
|
+
login_oauth_verify_open = login_oauth_verify
|
4632
5119
|
offline_download_open = offline_download
|
4633
5120
|
offline_process_open = offline_process
|
4634
5121
|
oss_copy_open = oss_copy
|
@@ -4674,22 +5161,62 @@ class P123OpenClient:
|
|
4674
5161
|
class P123Client(P123OpenClient):
|
4675
5162
|
"""123 的客户端对象
|
4676
5163
|
|
5164
|
+
.. caution::
|
5165
|
+
优先级为:token > passport+password > refresh_token > client_id+client_secret > 扫码
|
5166
|
+
|
5167
|
+
使用 refresh_token(或者说 oauth 登录),只允许访问 open 接口
|
5168
|
+
|
4677
5169
|
:param passport: 手机号或邮箱
|
4678
5170
|
:param password: 密码
|
4679
5171
|
:param token: 123 的访问令牌
|
5172
|
+
:param client_id: 应用标识,创建应用时分配的 appId
|
5173
|
+
:param client_secret: 应用密钥,创建应用时分配的 secretId
|
5174
|
+
:param refresh_token: 刷新令牌
|
4680
5175
|
"""
|
5176
|
+
passport: int | str = ""
|
5177
|
+
password: str = ""
|
5178
|
+
|
4681
5179
|
def __init__(
|
4682
5180
|
self,
|
4683
5181
|
/,
|
4684
5182
|
passport: int | str | PathLike = "",
|
4685
5183
|
password: str = "",
|
4686
5184
|
token: None | str | PathLike = None,
|
5185
|
+
client_id: str = "",
|
5186
|
+
client_secret: str = "",
|
5187
|
+
refresh_token: str = "",
|
4687
5188
|
):
|
4688
|
-
if isinstance(passport, PathLike)
|
5189
|
+
if (isinstance(passport, PathLike) or
|
5190
|
+
not token and
|
5191
|
+
isinstance(passport, str) and
|
5192
|
+
len(passport) >= 128
|
5193
|
+
):
|
4689
5194
|
token = passport
|
5195
|
+
elif (not refresh_token and
|
5196
|
+
isinstance(passport, str) and
|
5197
|
+
len(passport) >= 48 and
|
5198
|
+
not passport.strip(digits+ascii_uppercase)
|
5199
|
+
):
|
5200
|
+
refresh_token = passport
|
5201
|
+
elif (not client_id and
|
5202
|
+
isinstance(passport, str) and
|
5203
|
+
len(passport) >= 32 and
|
5204
|
+
not passport.strip(digits+"abcdef")
|
5205
|
+
):
|
5206
|
+
client_id = passport
|
4690
5207
|
else:
|
4691
5208
|
self.passport = passport
|
5209
|
+
if (not client_secret and
|
5210
|
+
isinstance(password, str)
|
5211
|
+
and len(password) >= 32 and
|
5212
|
+
not password.strip(digits+"abcdef")
|
5213
|
+
):
|
5214
|
+
client_secret = password
|
5215
|
+
else:
|
4692
5216
|
self.password = password
|
5217
|
+
self.client_id = client_id
|
5218
|
+
self.client_secret = client_secret
|
5219
|
+
self.refresh_token = refresh_token
|
4693
5220
|
if token is None:
|
4694
5221
|
self.login()
|
4695
5222
|
elif isinstance(token, str):
|
@@ -4702,6 +5229,8 @@ class P123Client(P123OpenClient):
|
|
4702
5229
|
self._read_token()
|
4703
5230
|
if not self.token:
|
4704
5231
|
self.login()
|
5232
|
+
if not self.passport:
|
5233
|
+
self.passport = self.token_user_info["username"]
|
4705
5234
|
|
4706
5235
|
@overload # type: ignore
|
4707
5236
|
def login(
|
@@ -4709,7 +5238,11 @@ class P123Client(P123OpenClient):
|
|
4709
5238
|
/,
|
4710
5239
|
passport: int | str = "",
|
4711
5240
|
password: str = "",
|
5241
|
+
client_id: str = "",
|
5242
|
+
client_secret: str = "",
|
5243
|
+
refresh_token: str = "",
|
4712
5244
|
remember: bool = True,
|
5245
|
+
platform: int = 0,
|
4713
5246
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4714
5247
|
*,
|
4715
5248
|
async_: Literal[False] = False,
|
@@ -4722,7 +5255,11 @@ class P123Client(P123OpenClient):
|
|
4722
5255
|
/,
|
4723
5256
|
passport: int | str = "",
|
4724
5257
|
password: str = "",
|
5258
|
+
client_id: str = "",
|
5259
|
+
client_secret: str = "",
|
5260
|
+
refresh_token: str = "",
|
4725
5261
|
remember: bool = True,
|
5262
|
+
platform: int = 0,
|
4726
5263
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4727
5264
|
*,
|
4728
5265
|
async_: Literal[True],
|
@@ -4734,7 +5271,11 @@ class P123Client(P123OpenClient):
|
|
4734
5271
|
/,
|
4735
5272
|
passport: int | str = "",
|
4736
5273
|
password: str = "",
|
5274
|
+
client_id: str = "",
|
5275
|
+
client_secret: str = "",
|
5276
|
+
refresh_token: str = "",
|
4737
5277
|
remember: bool = True,
|
5278
|
+
platform: int = 0,
|
4738
5279
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4739
5280
|
*,
|
4740
5281
|
async_: Literal[False, True] = False,
|
@@ -4745,6 +5286,7 @@ class P123Client(P123OpenClient):
|
|
4745
5286
|
:param passport: 账号
|
4746
5287
|
:param password: 密码
|
4747
5288
|
:param remember: 是否记住密码(不用管)
|
5289
|
+
:param platform: 用哪个设备平台扫码
|
4748
5290
|
:param base_url: 接口的基地址
|
4749
5291
|
:param async_: 是否异步
|
4750
5292
|
:param request_kwargs: 其它请求参数
|
@@ -4759,6 +5301,18 @@ class P123Client(P123OpenClient):
|
|
4759
5301
|
self.password = password
|
4760
5302
|
else:
|
4761
5303
|
password = self.password
|
5304
|
+
if client_id:
|
5305
|
+
self.client_id = client_id
|
5306
|
+
else:
|
5307
|
+
client_id = self.client_id
|
5308
|
+
if client_secret:
|
5309
|
+
self.client_secret = client_secret
|
5310
|
+
else:
|
5311
|
+
client_secret = self.client_secret
|
5312
|
+
if refresh_token:
|
5313
|
+
self.refresh_token = refresh_token
|
5314
|
+
else:
|
5315
|
+
refresh_token = self.refresh_token
|
4762
5316
|
def gen_step():
|
4763
5317
|
if passport and password:
|
4764
5318
|
resp = yield self.login_passport(
|
@@ -4770,8 +5324,17 @@ class P123Client(P123OpenClient):
|
|
4770
5324
|
check_response(resp)
|
4771
5325
|
self.token = resp["data"]["token"]
|
4772
5326
|
return resp
|
5327
|
+
elif client_id and client_secret or refresh_token:
|
5328
|
+
return self.login_open(
|
5329
|
+
client_id,
|
5330
|
+
client_secret,
|
5331
|
+
refresh_token,
|
5332
|
+
async_=async_,
|
5333
|
+
**request_kwargs,
|
5334
|
+
)
|
4773
5335
|
else:
|
4774
5336
|
resp = yield self.login_with_qrcode(
|
5337
|
+
platform=platform,
|
4775
5338
|
base_url=base_url,
|
4776
5339
|
async_=async_,
|
4777
5340
|
**request_kwargs,
|
@@ -4785,6 +5348,7 @@ class P123Client(P123OpenClient):
|
|
4785
5348
|
self,
|
4786
5349
|
/,
|
4787
5350
|
replace: bool | Self = False,
|
5351
|
+
platform: int = 0,
|
4788
5352
|
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4789
5353
|
*,
|
4790
5354
|
async_: Literal[False] = False,
|
@@ -4796,6 +5360,7 @@ class P123Client(P123OpenClient):
|
|
4796
5360
|
self,
|
4797
5361
|
/,
|
4798
5362
|
replace: bool | Self = False,
|
5363
|
+
platform: int = 0,
|
4799
5364
|
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4800
5365
|
*,
|
4801
5366
|
async_: Literal[True],
|
@@ -4806,6 +5371,7 @@ class P123Client(P123OpenClient):
|
|
4806
5371
|
self,
|
4807
5372
|
/,
|
4808
5373
|
replace: bool | Self = False,
|
5374
|
+
platform: int = 0,
|
4809
5375
|
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4810
5376
|
*,
|
4811
5377
|
async_: Literal[False, True] = False,
|
@@ -4816,9 +5382,10 @@ class P123Client(P123OpenClient):
|
|
4816
5382
|
:param replace: 替换某个 client 对象的 token
|
4817
5383
|
|
4818
5384
|
- 如果为 P123Client, 则更新到此对象
|
4819
|
-
- 如果为 True,则更新到 `self
|
4820
|
-
- 如果为 False,否则返回新的
|
5385
|
+
- 如果为 True,则更新到 `self``
|
5386
|
+
- 如果为 False,否则返回新的 ``P123Client`` 对象
|
4821
5387
|
|
5388
|
+
:param platform: 用哪个设备平台扫码
|
4822
5389
|
:param base_url: 接口的基地址
|
4823
5390
|
:param async_: 是否异步
|
4824
5391
|
:param request_kwargs: 其它请求参数
|
@@ -4827,13 +5394,13 @@ class P123Client(P123OpenClient):
|
|
4827
5394
|
"""
|
4828
5395
|
def gen_step():
|
4829
5396
|
resp = yield self.login_qrcode_auto(
|
5397
|
+
platform=platform,
|
4830
5398
|
base_url=base_url,
|
4831
5399
|
async_=async_,
|
4832
5400
|
**request_kwargs,
|
4833
5401
|
)
|
4834
|
-
check_response(resp)
|
4835
5402
|
if resp["code"] != 200:
|
4836
|
-
raise P123LoginError(EAUTH, resp)
|
5403
|
+
raise P123LoginError(errno.EAUTH, resp)
|
4837
5404
|
token = resp["data"]["token"]
|
4838
5405
|
if replace is False:
|
4839
5406
|
return type(self)(passport=self.passport, password=self.password, token=token)
|
@@ -4849,6 +5416,7 @@ class P123Client(P123OpenClient):
|
|
4849
5416
|
def login_qrcode_auto(
|
4850
5417
|
self,
|
4851
5418
|
/,
|
5419
|
+
platform: int = 0,
|
4852
5420
|
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4853
5421
|
*,
|
4854
5422
|
async_: Literal[False] = False,
|
@@ -4859,6 +5427,7 @@ class P123Client(P123OpenClient):
|
|
4859
5427
|
def login_qrcode_auto(
|
4860
5428
|
self,
|
4861
5429
|
/,
|
5430
|
+
platform: int = 0,
|
4862
5431
|
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4863
5432
|
*,
|
4864
5433
|
async_: Literal[True],
|
@@ -4868,13 +5437,18 @@ class P123Client(P123OpenClient):
|
|
4868
5437
|
def login_qrcode_auto(
|
4869
5438
|
self,
|
4870
5439
|
/,
|
5440
|
+
platform: int = 0,
|
4871
5441
|
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4872
5442
|
*,
|
4873
5443
|
async_: Literal[False, True] = False,
|
4874
5444
|
**request_kwargs,
|
4875
5445
|
) -> dict | Coroutine[Any, Any, dict]:
|
4876
|
-
"""执行一次自动扫码,但并不因此更新
|
5446
|
+
"""执行一次自动扫码,但并不因此更新 ``self.token``
|
4877
5447
|
|
5448
|
+
.. caution::
|
5449
|
+
非会员目前只支持同时在线 3 台登录设备
|
5450
|
+
|
5451
|
+
:param platform: 用哪个设备平台扫码
|
4878
5452
|
:param base_url: 接口的基地址
|
4879
5453
|
:param async_: 是否异步
|
4880
5454
|
:param request_kwargs: 其它请求参数
|
@@ -4889,6 +5463,14 @@ class P123Client(P123OpenClient):
|
|
4889
5463
|
)
|
4890
5464
|
check_response(resp)
|
4891
5465
|
uniID = resp["data"]["uniID"]
|
5466
|
+
if platform:
|
5467
|
+
resp = yield self.login_qrcode_scan(
|
5468
|
+
{"uniID": uniID, "scanPlatform": platform},
|
5469
|
+
base_url=base_url,
|
5470
|
+
async_=async_,
|
5471
|
+
**request_kwargs,
|
5472
|
+
)
|
5473
|
+
check_response(resp)
|
4892
5474
|
resp = yield self.login_qrcode_confirm(
|
4893
5475
|
uniID,
|
4894
5476
|
base_url=base_url,
|
@@ -4902,7 +5484,9 @@ class P123Client(P123OpenClient):
|
|
4902
5484
|
async_=async_,
|
4903
5485
|
**request_kwargs,
|
4904
5486
|
)
|
4905
|
-
|
5487
|
+
check_response(resp)
|
5488
|
+
if resp["code"] == 200 or resp["data"]["loginStatus"] not in (0, 1, 3):
|
5489
|
+
return resp
|
4906
5490
|
return run_gen_step(gen_step, async_)
|
4907
5491
|
|
4908
5492
|
@overload
|
@@ -4974,14 +5558,14 @@ class P123Client(P123OpenClient):
|
|
4974
5558
|
print("\r\033[1K[loginStatus=1] qrcode: scanned", end="")
|
4975
5559
|
case 2:
|
4976
5560
|
print("\r\033[1K[loginStatus=2] qrcode: cancelled", end="")
|
4977
|
-
raise P123LoginError(EAUTH, f"qrcode: cancelled with {resp!r}")
|
5561
|
+
raise P123LoginError(errno.EAUTH, f"qrcode: cancelled with {resp!r}")
|
4978
5562
|
case 3:
|
4979
5563
|
print("\r\033[1K[loginStatus=3] qrcode: login", end="")
|
4980
5564
|
case 4:
|
4981
5565
|
print("\r\033[1K[loginStatus=4] qrcode: expired", end="")
|
4982
|
-
raise P123LoginError(EAUTH, f"qrcode: expired with {resp!r}")
|
5566
|
+
raise P123LoginError(errno.EAUTH, f"qrcode: expired with {resp!r}")
|
4983
5567
|
case _:
|
4984
|
-
raise P123LoginError(EAUTH, f"qrcode: aborted with {resp!r}")
|
5568
|
+
raise P123LoginError(errno.EAUTH, f"qrcode: aborted with {resp!r}")
|
4985
5569
|
return run_gen_step(gen_step, async_)
|
4986
5570
|
|
4987
5571
|
########## App API ##########
|
@@ -5395,7 +5979,7 @@ class P123Client(P123OpenClient):
|
|
5395
5979
|
"Etag": "...", # 必填,文件的 MD5
|
5396
5980
|
"FileID": 0, # 可以随便填
|
5397
5981
|
"FileName": "a", # 随便填一个名字
|
5398
|
-
"S3KeyFlag": str # 必填,格式为 f"{UID}-0",UID 就是上传此文件的用户的 UID,如果此文件是由你上传的,则可从
|
5982
|
+
"S3KeyFlag": str # 必填,格式为 f"{UID}-0",UID 就是上传此文件的用户的 UID,如果此文件是由你上传的,则可从 ``P123Client.user_info`` 的响应中获取
|
5399
5983
|
"Size": 0, # 可以随便填,填了可能搜索更准确
|
5400
5984
|
}
|
5401
5985
|
|
@@ -5425,10 +6009,10 @@ class P123Client(P123OpenClient):
|
|
5425
6009
|
resp["payload"] = payload
|
5426
6010
|
check_response(resp)
|
5427
6011
|
if not (info_list := resp["data"]["infoList"]):
|
5428
|
-
raise FileNotFoundError(ENOENT, resp)
|
6012
|
+
raise FileNotFoundError(errno.ENOENT, resp)
|
5429
6013
|
payload = cast(dict, info_list[0])
|
5430
6014
|
if payload["Type"]:
|
5431
|
-
raise IsADirectoryError(EISDIR, resp)
|
6015
|
+
raise IsADirectoryError(errno.EISDIR, resp)
|
5432
6016
|
payload = dict_to_lower_merge(
|
5433
6017
|
payload, {"driveId": 0, "Type": 0, "FileID": 0})
|
5434
6018
|
if "filename" not in payload:
|
@@ -5479,7 +6063,7 @@ class P123Client(P123OpenClient):
|
|
5479
6063
|
POST https://www.123pan.com/api/file/batch_download_info
|
5480
6064
|
|
5481
6065
|
.. warning::
|
5482
|
-
会把一些文件或目录以 zip 包的形式下载,但非会员有流量限制,所以还是推荐用
|
6066
|
+
会把一些文件或目录以 zip 包的形式下载,但非会员有流量限制,所以还是推荐用 ``P123Client.download_info`` 逐个获取下载链接并下载
|
5483
6067
|
|
5484
6068
|
:payload:
|
5485
6069
|
- fileIdList: list[FileID]
|
@@ -5534,15 +6118,15 @@ class P123Client(P123OpenClient):
|
|
5534
6118
|
"""获取下载链接
|
5535
6119
|
|
5536
6120
|
.. note::
|
5537
|
-
|
6121
|
+
``payload`` 支持多种格式的输入,按下面的规则按顺序进行判断:
|
5538
6122
|
|
5539
|
-
1. 如果是
|
5540
|
-
2. 如果是
|
5541
|
-
3. 如果是
|
5542
|
-
4. 如果是
|
6123
|
+
1. 如果是 ``int`` 或 ``str``,则视为文件 id,必须在你的网盘中存在此文件
|
6124
|
+
2. 如果是 ``dict`` (不区分大小写),有 "S3KeyFlag", "Etag" 和 "Size" 的值,则直接获取链接,文件不必在你网盘中
|
6125
|
+
3. 如果是 ``dict`` (不区分大小写),有 "Etag" 和 "Size" 的值,则会先秒传(临时文件路径为 /.tempfile)再获取链接,文件不必在你网盘中
|
6126
|
+
4. 如果是 ``dict`` (不区分大小写),有 "FileID",则会先获取信息,再获取链接,必须在你的网盘中存在此文件
|
5543
6127
|
5. 否则会报错 ValueError
|
5544
6128
|
|
5545
|
-
:
|
6129
|
+
:param payload: 文件 id 或者文件信息,文件信息必须包含的信息如下:
|
5546
6130
|
|
5547
6131
|
- FileID: int | str 💡 下载链接
|
5548
6132
|
- S3KeyFlag: str 💡 s3 存储名
|
@@ -5550,8 +6134,8 @@ class P123Client(P123OpenClient):
|
|
5550
6134
|
- Size: int 💡 文件大小
|
5551
6135
|
- FileName: str 💡 默认用 Etag(即 MD5)作为文件名,可以省略
|
5552
6136
|
|
5553
|
-
:
|
5554
|
-
:
|
6137
|
+
:param async_: 是否异步
|
6138
|
+
:param request_kwargs: 其它请求参数
|
5555
6139
|
|
5556
6140
|
:return: 下载链接
|
5557
6141
|
"""
|
@@ -5564,10 +6148,10 @@ class P123Client(P123OpenClient):
|
|
5564
6148
|
resp = yield self.fs_info(fileid, async_=async_, **request_kwargs)
|
5565
6149
|
check_response(resp)
|
5566
6150
|
if not (info_list := resp["data"]["infoList"]):
|
5567
|
-
raise P123OSError(ENOENT, resp)
|
6151
|
+
raise P123OSError(errno.ENOENT, resp)
|
5568
6152
|
info = info_list[0]
|
5569
6153
|
if info["Type"]:
|
5570
|
-
raise IsADirectoryError(EISDIR, resp)
|
6154
|
+
raise IsADirectoryError(errno.EISDIR, resp)
|
5571
6155
|
payload = dict_to_lower_merge(payload, info)
|
5572
6156
|
else:
|
5573
6157
|
raise ValueError("`Size` and `Etag` must be provided")
|
@@ -5585,7 +6169,7 @@ class P123Client(P123OpenClient):
|
|
5585
6169
|
)
|
5586
6170
|
check_response(resp)
|
5587
6171
|
if not resp["data"]["Reuse"]:
|
5588
|
-
raise P123OSError(ENOENT, resp)
|
6172
|
+
raise P123OSError(errno.ENOENT, resp)
|
5589
6173
|
payload["s3keyflag"] = resp["data"]["Info"]["S3KeyFlag"]
|
5590
6174
|
resp = yield self.download_info(
|
5591
6175
|
payload,
|
@@ -5684,7 +6268,7 @@ class P123Client(P123OpenClient):
|
|
5684
6268
|
POST https://www.123pan.com/api/restful/goapi/v1/file/copy/async
|
5685
6269
|
|
5686
6270
|
:payload:
|
5687
|
-
- fileList: list[File] 💡 信息可以取自
|
6271
|
+
- fileList: list[File] 💡 信息可以取自 ``P123Client.fs_info`` 接口
|
5688
6272
|
|
5689
6273
|
.. code:: python
|
5690
6274
|
|
@@ -5708,7 +6292,7 @@ class P123Client(P123OpenClient):
|
|
5708
6292
|
check_response(resp)
|
5709
6293
|
info_list = resp["data"]["infoList"]
|
5710
6294
|
if not info_list:
|
5711
|
-
raise FileNotFoundError(ENOENT, resp)
|
6295
|
+
raise FileNotFoundError(errno.ENOENT, resp)
|
5712
6296
|
payload = {"fileList": info_list}
|
5713
6297
|
payload = dict_to_lower_merge(payload, targetFileId=parent_id)
|
5714
6298
|
return self.request(
|
@@ -6006,7 +6590,7 @@ class P123Client(P123OpenClient):
|
|
6006
6590
|
- "syncFileList": 同步空间
|
6007
6591
|
|
6008
6592
|
- operateType: int | str = <default> 💡 操作类型,如果在同步空间,则需要指定为 "SyncSpacePage"
|
6009
|
-
- SearchData: str = <default> 💡 搜索关键字(将无视
|
6593
|
+
- SearchData: str = <default> 💡 搜索关键字(将无视 ``parentFileId`` 参数)
|
6010
6594
|
- OnlyLookAbnormalFile: int = <default>
|
6011
6595
|
"""
|
6012
6596
|
if isinstance(payload, (int, str)):
|
@@ -6117,9 +6701,9 @@ class P123Client(P123OpenClient):
|
|
6117
6701
|
- operateType: int | str = <default> 💡 操作类型,如果在同步空间,则需要指定为 "SyncSpacePage"
|
6118
6702
|
|
6119
6703
|
.. note::
|
6120
|
-
这个值似乎不影响结果,所以可以忽略。我在浏览器中,看到罗列根目录为 1,搜索(指定
|
6704
|
+
这个值似乎不影响结果,所以可以忽略。我在浏览器中,看到罗列根目录为 1,搜索(指定 ``SearchData``)为 2,同步空间的根目录为 3,罗列其它目录大多为 4,偶尔为 8,也可能是其它值
|
6121
6705
|
|
6122
|
-
- SearchData: str = <default> 💡 搜索关键字(将无视
|
6706
|
+
- SearchData: str = <default> 💡 搜索关键字(将无视 ``parentFileId`` 参数)
|
6123
6707
|
- OnlyLookAbnormalFile: int = 0 💡 大概可传入 0 或 1
|
6124
6708
|
"""
|
6125
6709
|
if not isinstance(payload, dict):
|
@@ -6222,9 +6806,9 @@ class P123Client(P123OpenClient):
|
|
6222
6806
|
- operateType: int | str = <default> 💡 操作类型,如果在同步空间,则需要指定为 "SyncSpacePage"
|
6223
6807
|
|
6224
6808
|
.. note::
|
6225
|
-
这个值似乎不影响结果,所以可以忽略。我在浏览器中,看到罗列根目录为 1,搜索(指定
|
6809
|
+
这个值似乎不影响结果,所以可以忽略。我在浏览器中,看到罗列根目录为 1,搜索(指定 ``SearchData``)为 2,同步空间的根目录为 3,罗列其它目录大多为 4,偶尔为 8,也可能是其它值
|
6226
6810
|
|
6227
|
-
- SearchData: str = <default> 💡 搜索关键字(将无视
|
6811
|
+
- SearchData: str = <default> 💡 搜索关键字(将无视 ``parentFileId`` 参数)
|
6228
6812
|
- OnlyLookAbnormalFile: int = 0 💡 大概可传入 0 或 1
|
6229
6813
|
- RequestSource: int = <default> 💡 浏览器中,在同步空间中为 1
|
6230
6814
|
"""
|
@@ -6605,9 +7189,9 @@ class P123Client(P123OpenClient):
|
|
6605
7189
|
- operateType: int | str = <default> 💡 操作类型,如果在同步空间,则需要指定为 "SyncSpacePage"
|
6606
7190
|
|
6607
7191
|
.. note::
|
6608
|
-
这个值似乎不影响结果,所以可以忽略。我在浏览器中,看到罗列根目录为 1,搜索(指定
|
7192
|
+
这个值似乎不影响结果,所以可以忽略。我在浏览器中,看到罗列根目录为 1,搜索(指定 ``SearchData``)为 2,同步空间的根目录为 3,罗列其它目录大多为 4,偶尔为 8,也可能是其它值
|
6609
7193
|
|
6610
|
-
- SearchData: str = <default> 💡 搜索关键字(将无视
|
7194
|
+
- SearchData: str = <default> 💡 搜索关键字(将无视 ``parentFileId`` 参数)
|
6611
7195
|
- OnlyLookAbnormalFile: int = 0 💡 大概可传入 0 或 1
|
6612
7196
|
"""
|
6613
7197
|
if not isinstance(payload, dict):
|
@@ -6727,7 +7311,7 @@ class P123Client(P123OpenClient):
|
|
6727
7311
|
POST https://www.123pan.com/api/file/trash
|
6728
7312
|
|
6729
7313
|
:payload:
|
6730
|
-
- fileTrashInfoList: list[File] 💡 信息可以取自
|
7314
|
+
- fileTrashInfoList: list[File] 💡 信息可以取自 ``P123Client.fs_info`` 接口
|
6731
7315
|
|
6732
7316
|
.. code:: python
|
6733
7317
|
|
@@ -7261,11 +7845,11 @@ class P123Client(P123OpenClient):
|
|
7261
7845
|
|
7262
7846
|
:payload:
|
7263
7847
|
- uniID: str 💡 二维码 id
|
7264
|
-
- scanPlatform: int =
|
7848
|
+
- scanPlatform: int = 0 💡 扫码的平台代码,部分已知:4:微信 7:android
|
7265
7849
|
"""
|
7266
7850
|
if not isinstance(payload, dict):
|
7267
7851
|
payload = {"uniID": payload}
|
7268
|
-
payload.setdefault("scanPlatform",
|
7852
|
+
payload.setdefault("scanPlatform", 0)
|
7269
7853
|
request_kwargs.setdefault("parse", default_parse)
|
7270
7854
|
if request is None:
|
7271
7855
|
request = get_default_request()
|
@@ -7462,7 +8046,7 @@ class P123Client(P123OpenClient):
|
|
7462
8046
|
POST https://www.123pan.com/api/offline_download/task/resolve
|
7463
8047
|
|
7464
8048
|
:payload:
|
7465
|
-
- urls: str = <default> 💡 下载链接,多个用 "
|
8049
|
+
- urls: str = <default> 💡 下载链接,多个用 "\\n" 隔开(用于新建链接下载任务)
|
7466
8050
|
- info_hash: str = <default> 💡 种子文件的 info_hash(用于新建BT任务)
|
7467
8051
|
"""
|
7468
8052
|
if isinstance(payload, str):
|
@@ -7621,7 +8205,7 @@ class P123Client(P123OpenClient):
|
|
7621
8205
|
POST https://www.123pan.com/api/share/delete
|
7622
8206
|
|
7623
8207
|
:payload:
|
7624
|
-
- shareInfoList: list[ShareID] 💡 信息可以取自
|
8208
|
+
- shareInfoList: list[ShareID] 💡 信息可以取自 ``P123Client.fs_info`` 接口
|
7625
8209
|
|
7626
8210
|
.. code:: python
|
7627
8211
|
|
@@ -7821,7 +8405,7 @@ class P123Client(P123OpenClient):
|
|
7821
8405
|
|
7822
8406
|
如果文件在 100MB 以内,下载时是不需要登录的;如果超过 100 MB,但分享者设置的免登录流量包未告罄,下载时也不需要登录
|
7823
8407
|
|
7824
|
-
你也可以使用
|
8408
|
+
你也可以使用 ``P123Client.download_info`` 来获取下载链接,则不需要提供 "ShareKey" 和 "SharePwd"
|
7825
8409
|
|
7826
8410
|
:payload:
|
7827
8411
|
- ShareKey: str 💡 分享码
|
@@ -8164,7 +8748,7 @@ class P123Client(P123OpenClient):
|
|
8164
8748
|
- Page: int = <default> 💡 第几页,从 1 开始,可以是 0
|
8165
8749
|
- event: str = "shareListFile"
|
8166
8750
|
- operateType: int | str = <default>
|
8167
|
-
- SearchData: str = <default> 💡 搜索关键字(将无视
|
8751
|
+
- SearchData: str = <default> 💡 搜索关键字(将无视 ``parentFileId`` 参数)
|
8168
8752
|
"""
|
8169
8753
|
if isinstance(payload, int):
|
8170
8754
|
payload = {"Page": payload}
|
@@ -8234,7 +8818,7 @@ class P123Client(P123OpenClient):
|
|
8234
8818
|
- Page: int = <default> 💡 第几页,从 1 开始,可以是 0
|
8235
8819
|
- event: str = "shareListFile"
|
8236
8820
|
- operateType: int | str = <default>
|
8237
|
-
- SearchData: str = <default> 💡 搜索关键字(将无视
|
8821
|
+
- SearchData: str = <default> 💡 搜索关键字(将无视 ``parentFileId`` 参数)
|
8238
8822
|
"""
|
8239
8823
|
if isinstance(payload, int):
|
8240
8824
|
payload = {"Page": payload}
|
@@ -8627,7 +9211,7 @@ class P123Client(P123OpenClient):
|
|
8627
9211
|
- parentFileId: int | str = 0 💡 父目录 id
|
8628
9212
|
- size: int = 0 💡 文件大小,单位:字节
|
8629
9213
|
- type: 0 | 1 = 1 💡 类型,如果是目录则是 1,如果是文件则是 0
|
8630
|
-
- NotReuse: bool = False 💡 不要重用(仅在 `type=1` 时有效,如果为 False,当有重名时,立即返回,此时
|
9214
|
+
- NotReuse: bool = False 💡 不要重用(仅在 `type=1` 时有效,如果为 False,当有重名时,立即返回,此时 ``duplicate`` 字段无效)
|
8631
9215
|
- ...
|
8632
9216
|
"""
|
8633
9217
|
if isinstance(payload, str):
|
@@ -8706,15 +9290,15 @@ class P123Client(P123OpenClient):
|
|
8706
9290
|
"""上传文件
|
8707
9291
|
|
8708
9292
|
.. note::
|
8709
|
-
如果文件名中包含字符 "
|
9293
|
+
如果文件名中包含字符 ``"\\/:*?|><``,则转换为对应的全角字符
|
8710
9294
|
|
8711
9295
|
:param file: 待上传的文件
|
8712
9296
|
|
8713
|
-
- 如果为
|
8714
|
-
- 如果为
|
8715
|
-
- 如果为
|
8716
|
-
- 如果为
|
8717
|
-
- 如果为
|
9297
|
+
- 如果为 ``collections.abc.Buffer``,则作为二进制数据上传
|
9298
|
+
- 如果为 ``filewrap.SupportsRead``,则作为可读的二进制文件上传
|
9299
|
+
- 如果为 ``str`` 或 ``os.PathLike``,则视为路径,打开后作为文件上传
|
9300
|
+
- 如果为 ``yarl.URL`` 或 ``http_request.SupportsGeturl`` (``pip install python-http_request``),则视为超链接,打开后作为文件上传
|
9301
|
+
- 如果为 ``collections.abc.Iterable[collections.abc.Buffer]`` 或 ``collections.abc.AsyncIterable[collections.abc.Buffer]``,则迭代以获取二进制数据,逐步上传
|
8718
9302
|
|
8719
9303
|
:param file_md5: 文件的 MD5 散列值
|
8720
9304
|
:param file_name: 文件名
|
@@ -8978,11 +9562,11 @@ class P123Client(P123OpenClient):
|
|
8978
9562
|
|
8979
9563
|
:param file: 待上传的文件
|
8980
9564
|
|
8981
|
-
- 如果为
|
8982
|
-
- 如果为
|
8983
|
-
- 如果为
|
8984
|
-
- 如果为
|
8985
|
-
- 如果为
|
9565
|
+
- 如果为 ``collections.abc.Buffer``,则作为二进制数据上传
|
9566
|
+
- 如果为 ``filewrap.SupportsRead``,则作为可读的二进制文件上传
|
9567
|
+
- 如果为 ``str`` 或 ``os.PathLike``,则视为路径,打开后作为文件上传
|
9568
|
+
- 如果为 ``yarl.URL`` 或 ``http_request.SupportsGeturl`` (``pip install python-http_request``),则视为超链接,打开后作为文件上传
|
9569
|
+
- 如果为 ``collections.abc.Iterable[collections.abc.Buffer]`` 或 ``collections.abc.AsyncIterable[collections.abc.Buffer]``,则迭代以获取二进制数据,逐步上传
|
8986
9570
|
|
8987
9571
|
:param file_md5: 文件的 MD5 散列值
|
8988
9572
|
:param file_name: 文件名
|
@@ -9320,6 +9904,8 @@ with temp_globals():
|
|
9320
9904
|
CLIENT_API_METHODS_MAP[api] = [name]
|
9321
9905
|
|
9322
9906
|
|
9907
|
+
# TODO: 只有在使用密码登录的情况下,即使 token 失效,也可以重新登录(在有账号和密码的情况下,遇到 401 报错,会自动重新登录(需要加锁))
|
9908
|
+
# TODO: 新的上传方法需要封装:https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/xogi45g7okqk7svr
|
9323
9909
|
# TODO: 对于某些工具的接口封装,例如 重复文件清理
|
9324
9910
|
# TODO: 同步空间
|
9325
9911
|
# TODO: 直链空间
|