p189client


Namep189client JSON
Version 0.0.2.3 PyPI version JSON
download
home_pagehttps://github.com/ChenyangGao/p189client
SummaryPython 189 webdisk client.
upload_time2025-08-05 07:53:18
maintainerNone
docs_urlNone
authorChenyangGao
requires_python<4.0,>=3.12
licenseMIT
keywords 189 webdisk client
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Python 天翼网盘客户端

![PyPI - Python Version](https://img.shields.io/pypi/pyversions/p189client)
![PyPI - Version](https://img.shields.io/pypi/v/p189client)
![PyPI - Downloads](https://img.shields.io/pypi/dm/p189client)
![PyPI - Format](https://img.shields.io/pypi/format/p189client)
![PyPI - Status](https://img.shields.io/pypi/status/p189client)

## 0. 安装

你可以从 [pypi](https://pypi.org/project/p189client/) 安装最新版本

```console
pip install -U p189client
```

## 1. 导入模块和创建实例

导入模块

```python
from p189client import P189Client, P189APIClient
```

`P189Client` 支持 2 种请求方式:

1. 请求头用 "Cookie",不需要签名
2. 请求头用 "AccessToken",需要签名

`P189APIClient` 支持 2 种请求方式

1. 请求头用 "SessionKey",需要签名
2. 请求头用 "AccessToken",需要签名

**温馨提示** `P189APIClient` 还在开发当中,接口补全,暂时不要使用

### 1. 人工扫码登录

什么都不传时,会输出一个二维码,要求你人工扫码登录

```python
client = P189Client()
api_client = P189APIClient()
```

### 2. 使用账号和密码登录

账号可以是邮箱或手机号,另外需要关闭设备锁。请在网页端登录天翼账号后,进行相关操作:

https://e.dlife.cn/user/index.do

```python
# TODO: 写下自己的账号和密码
username = "your_username"
password = "your_password"

client = P189Client(username, password)
api_client = P189APIClient(username, password)
```

### 3. 直接加载 `cookies`

`P189Client` 支持直接加载 `cookies`

```python
cookies = "..."

client = P189Client(cookies=cookies)
```

支持加载文件路径,这样当更新时,也会写入此文件中

```python
from pathlib import Path

client = P189Client(cookies=Path("~/189-cookies.txt").expanduser())
```

### 4. 直接加载 `session_data`

`P189APIClient` 支持直接加载 `session_data`

```python
session_data = {...}

api_client = P189APIClient(session_data=session_data)
```

支持加载文件路径,这样当更新时,也会写入此文件中

```python
from pathlib import Path

api_client = P189APIClient(session_data=Path("~/189-session-data.json").expanduser())
```

### 5. 使用 `session_key` 登录

`P189Client` 支持直接利用 `session_key` 来获取 `cookies`

```python
session_key = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

client = P189Client(session_key=session_key)
```

### 6. 使用 `token` 登录

`P189APIClient` 支持直接利用 `token` (`session_data` 中的 `accessToken`)来获取 `session_data`(除了 `refreshToken`)

```python
# 32 位小写的 16 进制,其实就是一个 UUID 的 16 进制表示
token = "..."

api_client = P189APIClient(token)
```

如果你存有一个 `refreshToken`,则需要先获取 `accessToken`,再获取 `session_data`

```python
# 32 位小写的 16 进制,其实也是一个 UUID 的 16 进制表示
refresh_token = "..."

api_client = P189APIClient(P189APIClient.login_with_refresh_token(refresh_token))
```

再结合上面的第 5 条,还可以用 `refresh_token` 来获取 cookies

```python
resp   = P189Client.login_with_refresh_token(refresh_token)
client = P189Client(resp["sessionKey"])
# 或者
client = P189Client(resp["familySessionKey"])
```

### 7. 使用 `SSO Cookie` 登录

有个 `Cookie` 字段是 "SSON",往往在扫码登录或账号密码登录后获得,有效期不长,但是也可以用来获取 `session_data`,从而也能间接获得 `cookies`

```python
sso_cookie = "..."

api_client = P189APIClient(P189APIClient.login_with_sso_cookie(sso_cookie))
```

并且

```python
resp   = P189Client.login_with_sso_cookie(sso_cookie)
client = P189Client(resp["sessionKey"])
# 或者
client = P189Client(resp["familySessionKey"])
```

### 8 使用 `cookies` 扫码授权登录

除了用 `SSO Cookie`,理论上也能用普通的 `cookies` 授权登录,只需要模拟扫码点击确认即可,但目前我暂未实现这条

**TODO** 实现模拟扫码登录

## 2. 接口调用

所有需要直接或间接执行 HTTP 请求的接口,都有同步和异步的调用方式,且默认是采用 GET 发送请求数据

```python
# 同步调用
client.method(payload)
client.method(payload, async_=False)

# 异步调用
await client.method(payload, async_=True)
```

从根本上讲,除了几个 `staticmethod`,它们都会调用 `P189Client.request`

```python
url = "https://cloud.189.cn/api/someapi"
response = client.request(url=url, json={...})
```

当你需要构建自己的扩展模块,以增加一些新的天翼网盘的接口时,就需要用到此方法了

```python
from collections.abc import Coroutine
from typing import overload, Any, Literal

from p189client import P189Client

class MyCustom189Client(P189Client):

    @overload
    def foo(
        self, 
        payload: dict, 
        /, 
        async_: Literal[False] = False, 
        **request_kwargs, 
    ) -> dict:
        ...
    @overload
    def foo(
        self, 
        payload: dict, 
        /, 
        async_: Literal[True], 
        **request_kwargs, 
    ) -> Coroutine[Any, Any, dict]:
        ...
    def foo(
        self, 
        payload: dict, 
        /, 
        async_: bool = False, 
        **request_kwargs, 
    ) -> dict | Coroutine[Any, Any, dict]:
        api = "https://cloud.189.cn/api/foo"
        return self.request(
            api, 
            method="GET", 
            params=payload, 
            async_=async_, 
            **request_kwargs, 
        )

    @overload
    def bar(
        self, 
        payload: dict, 
        /, 
        async_: Literal[False] = False, 
        **request_kwargs, 
    ) -> dict:
        ...
    @overload
    def bar(
        self, 
        payload: dict, 
        /, 
        async_: Literal[True], 
        **request_kwargs, 
    ) -> Coroutine[Any, Any, dict]:
        ...
    def bar(
        self, 
        payload: dict, 
        /, 
        async_: bool = False, 
        **request_kwargs, 
    ) -> dict | Coroutine[Any, Any, dict]:
        api = "https://cloud.189.cn/api/bar"
        return self.request(
            api, 
            method="POST", 
            data=payload, 
            async_=async_, 
            **request_kwargs, 
        )
```

## 3. 检查响应

接口被调用后,如果返回的是 dict 类型的数据(说明原本是 JSON),则可以用 `p189client.check_response` 执行检查。如果检测为正常,则原样返回数据;否则,抛出一个 `p189client.P189OSError` 的实例。

```python
from p189client import check_response

# 检查同步调用
data = check_response(client.method(payload))
# 检查异步调用
data = check_response(await client.method(payload, async_=True))
```

## 4. 辅助工具

一些简单的封装工具可能是必要的,特别是那种实现起来代码量比较少,可以封装成单个函数的。我把平常使用过程中,积累的一些经验具体化为一组工具函数。这些工具函数分别有着不同的功能,如果组合起来使用,或许能解决很多问题。

```python
from p189client import tool
```

## 5. 学习案例

### 1. 直链服务

需要先安装 [blacksheep](https://www.neoteroi.dev/blacksheep/)

```console
pip install 'blacksheep[uvicorn]'
```

```python
from blacksheep import json, redirect, Application, Request
from p189client import P189Client

# TODO: 改成你自己的账户和密码,不写就是扫码登录
client = P189Client(username="", password="")
# 或者可以写死某个特定的 access_token
# client = P189Client(cookies="")
# client.access_token = ""

app = Application(show_error_details=__debug__)

@app.router.route("/{path:path}", methods=["GET", "HEAD"])
async def index(request: Request, path: str, id: int, family_id: int = 0):
    if family_id:
        payload = {"fileId": id, "familyId": family_id}
    else:
        payload = {"fileId": id}
    url = await client.download_url(payload, use_access_token=True, async_=True)
    return redirect(url)

if __name__ == "__main__":
    from uvicorn import run

    run(app, host="0.0.0.0", port=8189)
```

### 2. 签到和抽奖

```python
from p189client import P189Client

# TODO: 改成你自己的账户和密码,不写就是扫码登录
client = P189Client(username="", password="")

# 签到
print("签到", client.user_sign())

# 抽奖
from time import sleep
print("\n抽奖")
for i, task_id in enumerate(["TASK_SIGNIN", "TASK_SIGNIN_PHOTOS", "TASK_2022_FLDFS_KJ"]):
    if i:
        # NOTE: 休息 5 秒,防止被说过于频繁
        sleep(5)
    print(task_id, client.user_draw(task_id))
```

## 其它资源

- 如果你需要更详细的文档,特别是关于各种接口的信息,可以阅读

    [https://p189client.readthedocs.io/en/latest/](https://p189client.readthedocs.io/en/latest/)

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/ChenyangGao/p189client",
    "name": "p189client",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.12",
    "maintainer_email": null,
    "keywords": "189, webdisk, client",
    "author": "ChenyangGao",
    "author_email": "wosiwujm@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/a0/03/1bd7e82a692df30fa5d2d8d106678d9c4a667537e8c7596add3bb0a4fcd4/p189client-0.0.2.3.tar.gz",
    "platform": null,
    "description": "# Python \u5929\u7ffc\u7f51\u76d8\u5ba2\u6237\u7aef\n\n![PyPI - Python Version](https://img.shields.io/pypi/pyversions/p189client)\n![PyPI - Version](https://img.shields.io/pypi/v/p189client)\n![PyPI - Downloads](https://img.shields.io/pypi/dm/p189client)\n![PyPI - Format](https://img.shields.io/pypi/format/p189client)\n![PyPI - Status](https://img.shields.io/pypi/status/p189client)\n\n## 0. \u5b89\u88c5\n\n\u4f60\u53ef\u4ee5\u4ece [pypi](https://pypi.org/project/p189client/) \u5b89\u88c5\u6700\u65b0\u7248\u672c\n\n```console\npip install -U p189client\n```\n\n## 1. \u5bfc\u5165\u6a21\u5757\u548c\u521b\u5efa\u5b9e\u4f8b\n\n\u5bfc\u5165\u6a21\u5757\n\n```python\nfrom p189client import P189Client, P189APIClient\n```\n\n`P189Client` \u652f\u6301 2 \u79cd\u8bf7\u6c42\u65b9\u5f0f\uff1a\n\n1. \u8bf7\u6c42\u5934\u7528 \"Cookie\"\uff0c\u4e0d\u9700\u8981\u7b7e\u540d\n2. \u8bf7\u6c42\u5934\u7528 \"AccessToken\"\uff0c\u9700\u8981\u7b7e\u540d\n\n`P189APIClient` \u652f\u6301 2 \u79cd\u8bf7\u6c42\u65b9\u5f0f\n\n1. \u8bf7\u6c42\u5934\u7528 \"SessionKey\"\uff0c\u9700\u8981\u7b7e\u540d\n2. \u8bf7\u6c42\u5934\u7528 \"AccessToken\"\uff0c\u9700\u8981\u7b7e\u540d\n\n**\u6e29\u99a8\u63d0\u793a** `P189APIClient` \u8fd8\u5728\u5f00\u53d1\u5f53\u4e2d\uff0c\u63a5\u53e3\u8865\u5168\uff0c\u6682\u65f6\u4e0d\u8981\u4f7f\u7528\n\n### 1. \u4eba\u5de5\u626b\u7801\u767b\u5f55\n\n\u4ec0\u4e48\u90fd\u4e0d\u4f20\u65f6\uff0c\u4f1a\u8f93\u51fa\u4e00\u4e2a\u4e8c\u7ef4\u7801\uff0c\u8981\u6c42\u4f60\u4eba\u5de5\u626b\u7801\u767b\u5f55\n\n```python\nclient = P189Client()\napi_client = P189APIClient()\n```\n\n### 2. \u4f7f\u7528\u8d26\u53f7\u548c\u5bc6\u7801\u767b\u5f55\n\n\u8d26\u53f7\u53ef\u4ee5\u662f\u90ae\u7bb1\u6216\u624b\u673a\u53f7\uff0c\u53e6\u5916\u9700\u8981\u5173\u95ed\u8bbe\u5907\u9501\u3002\u8bf7\u5728\u7f51\u9875\u7aef\u767b\u5f55\u5929\u7ffc\u8d26\u53f7\u540e\uff0c\u8fdb\u884c\u76f8\u5173\u64cd\u4f5c\uff1a\n\nhttps://e.dlife.cn/user/index.do\n\n```python\n# TODO: \u5199\u4e0b\u81ea\u5df1\u7684\u8d26\u53f7\u548c\u5bc6\u7801\nusername = \"your_username\"\npassword = \"your_password\"\n\nclient = P189Client(username, password)\napi_client = P189APIClient(username, password)\n```\n\n### 3. \u76f4\u63a5\u52a0\u8f7d `cookies`\n\n`P189Client` \u652f\u6301\u76f4\u63a5\u52a0\u8f7d `cookies`\n\n```python\ncookies = \"...\"\n\nclient = P189Client(cookies=cookies)\n```\n\n\u652f\u6301\u52a0\u8f7d\u6587\u4ef6\u8def\u5f84\uff0c\u8fd9\u6837\u5f53\u66f4\u65b0\u65f6\uff0c\u4e5f\u4f1a\u5199\u5165\u6b64\u6587\u4ef6\u4e2d\n\n```python\nfrom pathlib import Path\n\nclient = P189Client(cookies=Path(\"~/189-cookies.txt\").expanduser())\n```\n\n### 4. \u76f4\u63a5\u52a0\u8f7d `session_data`\n\n`P189APIClient` \u652f\u6301\u76f4\u63a5\u52a0\u8f7d `session_data`\n\n```python\nsession_data = {...}\n\napi_client = P189APIClient(session_data=session_data)\n```\n\n\u652f\u6301\u52a0\u8f7d\u6587\u4ef6\u8def\u5f84\uff0c\u8fd9\u6837\u5f53\u66f4\u65b0\u65f6\uff0c\u4e5f\u4f1a\u5199\u5165\u6b64\u6587\u4ef6\u4e2d\n\n```python\nfrom pathlib import Path\n\napi_client = P189APIClient(session_data=Path(\"~/189-session-data.json\").expanduser())\n```\n\n### 5. \u4f7f\u7528 `session_key` \u767b\u5f55\n\n`P189Client` \u652f\u6301\u76f4\u63a5\u5229\u7528 `session_key` \u6765\u83b7\u53d6 `cookies`\n\n```python\nsession_key = \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\n\nclient = P189Client(session_key=session_key)\n```\n\n### 6. \u4f7f\u7528 `token` \u767b\u5f55\n\n`P189APIClient` \u652f\u6301\u76f4\u63a5\u5229\u7528 `token` \uff08`session_data` \u4e2d\u7684 `accessToken`\uff09\u6765\u83b7\u53d6 `session_data`\uff08\u9664\u4e86 `refreshToken`\uff09\n\n```python\n# 32 \u4f4d\u5c0f\u5199\u7684 16 \u8fdb\u5236\uff0c\u5176\u5b9e\u5c31\u662f\u4e00\u4e2a UUID \u7684 16 \u8fdb\u5236\u8868\u793a\ntoken = \"...\"\n\napi_client = P189APIClient(token)\n```\n\n\u5982\u679c\u4f60\u5b58\u6709\u4e00\u4e2a `refreshToken`\uff0c\u5219\u9700\u8981\u5148\u83b7\u53d6 `accessToken`\uff0c\u518d\u83b7\u53d6 `session_data`\n\n```python\n# 32 \u4f4d\u5c0f\u5199\u7684 16 \u8fdb\u5236\uff0c\u5176\u5b9e\u4e5f\u662f\u4e00\u4e2a UUID \u7684 16 \u8fdb\u5236\u8868\u793a\nrefresh_token = \"...\"\n\napi_client = P189APIClient(P189APIClient.login_with_refresh_token(refresh_token))\n```\n\n\u518d\u7ed3\u5408\u4e0a\u9762\u7684\u7b2c 5 \u6761\uff0c\u8fd8\u53ef\u4ee5\u7528 `refresh_token` \u6765\u83b7\u53d6 cookies\n\n```python\nresp   = P189Client.login_with_refresh_token(refresh_token)\nclient = P189Client(resp[\"sessionKey\"])\n# \u6216\u8005\nclient = P189Client(resp[\"familySessionKey\"])\n```\n\n### 7. \u4f7f\u7528 `SSO Cookie` \u767b\u5f55\n\n\u6709\u4e2a `Cookie` \u5b57\u6bb5\u662f \"SSON\"\uff0c\u5f80\u5f80\u5728\u626b\u7801\u767b\u5f55\u6216\u8d26\u53f7\u5bc6\u7801\u767b\u5f55\u540e\u83b7\u5f97\uff0c\u6709\u6548\u671f\u4e0d\u957f\uff0c\u4f46\u662f\u4e5f\u53ef\u4ee5\u7528\u6765\u83b7\u53d6 `session_data`\uff0c\u4ece\u800c\u4e5f\u80fd\u95f4\u63a5\u83b7\u5f97 `cookies`\n\n```python\nsso_cookie = \"...\"\n\napi_client = P189APIClient(P189APIClient.login_with_sso_cookie(sso_cookie))\n```\n\n\u5e76\u4e14\n\n```python\nresp   = P189Client.login_with_sso_cookie(sso_cookie)\nclient = P189Client(resp[\"sessionKey\"])\n# \u6216\u8005\nclient = P189Client(resp[\"familySessionKey\"])\n```\n\n### 8 \u4f7f\u7528 `cookies` \u626b\u7801\u6388\u6743\u767b\u5f55\n\n\u9664\u4e86\u7528 `SSO Cookie`\uff0c\u7406\u8bba\u4e0a\u4e5f\u80fd\u7528\u666e\u901a\u7684 `cookies` \u6388\u6743\u767b\u5f55\uff0c\u53ea\u9700\u8981\u6a21\u62df\u626b\u7801\u70b9\u51fb\u786e\u8ba4\u5373\u53ef\uff0c\u4f46\u76ee\u524d\u6211\u6682\u672a\u5b9e\u73b0\u8fd9\u6761\n\n**TODO** \u5b9e\u73b0\u6a21\u62df\u626b\u7801\u767b\u5f55\n\n## 2. \u63a5\u53e3\u8c03\u7528\n\n\u6240\u6709\u9700\u8981\u76f4\u63a5\u6216\u95f4\u63a5\u6267\u884c HTTP \u8bf7\u6c42\u7684\u63a5\u53e3\uff0c\u90fd\u6709\u540c\u6b65\u548c\u5f02\u6b65\u7684\u8c03\u7528\u65b9\u5f0f\uff0c\u4e14\u9ed8\u8ba4\u662f\u91c7\u7528 GET \u53d1\u9001\u8bf7\u6c42\u6570\u636e\n\n```python\n# \u540c\u6b65\u8c03\u7528\nclient.method(payload)\nclient.method(payload, async_=False)\n\n# \u5f02\u6b65\u8c03\u7528\nawait client.method(payload, async_=True)\n```\n\n\u4ece\u6839\u672c\u4e0a\u8bb2\uff0c\u9664\u4e86\u51e0\u4e2a `staticmethod`\uff0c\u5b83\u4eec\u90fd\u4f1a\u8c03\u7528 `P189Client.request`\n\n```python\nurl = \"https://cloud.189.cn/api/someapi\"\nresponse = client.request(url=url, json={...})\n```\n\n\u5f53\u4f60\u9700\u8981\u6784\u5efa\u81ea\u5df1\u7684\u6269\u5c55\u6a21\u5757\uff0c\u4ee5\u589e\u52a0\u4e00\u4e9b\u65b0\u7684\u5929\u7ffc\u7f51\u76d8\u7684\u63a5\u53e3\u65f6\uff0c\u5c31\u9700\u8981\u7528\u5230\u6b64\u65b9\u6cd5\u4e86\n\n```python\nfrom collections.abc import Coroutine\nfrom typing import overload, Any, Literal\n\nfrom p189client import P189Client\n\nclass MyCustom189Client(P189Client):\n\n    @overload\n    def foo(\n        self, \n        payload: dict, \n        /, \n        async_: Literal[False] = False, \n        **request_kwargs, \n    ) -> dict:\n        ...\n    @overload\n    def foo(\n        self, \n        payload: dict, \n        /, \n        async_: Literal[True], \n        **request_kwargs, \n    ) -> Coroutine[Any, Any, dict]:\n        ...\n    def foo(\n        self, \n        payload: dict, \n        /, \n        async_: bool = False, \n        **request_kwargs, \n    ) -> dict | Coroutine[Any, Any, dict]:\n        api = \"https://cloud.189.cn/api/foo\"\n        return self.request(\n            api, \n            method=\"GET\", \n            params=payload, \n            async_=async_, \n            **request_kwargs, \n        )\n\n    @overload\n    def bar(\n        self, \n        payload: dict, \n        /, \n        async_: Literal[False] = False, \n        **request_kwargs, \n    ) -> dict:\n        ...\n    @overload\n    def bar(\n        self, \n        payload: dict, \n        /, \n        async_: Literal[True], \n        **request_kwargs, \n    ) -> Coroutine[Any, Any, dict]:\n        ...\n    def bar(\n        self, \n        payload: dict, \n        /, \n        async_: bool = False, \n        **request_kwargs, \n    ) -> dict | Coroutine[Any, Any, dict]:\n        api = \"https://cloud.189.cn/api/bar\"\n        return self.request(\n            api, \n            method=\"POST\", \n            data=payload, \n            async_=async_, \n            **request_kwargs, \n        )\n```\n\n## 3. \u68c0\u67e5\u54cd\u5e94\n\n\u63a5\u53e3\u88ab\u8c03\u7528\u540e\uff0c\u5982\u679c\u8fd4\u56de\u7684\u662f dict \u7c7b\u578b\u7684\u6570\u636e\uff08\u8bf4\u660e\u539f\u672c\u662f JSON\uff09\uff0c\u5219\u53ef\u4ee5\u7528 `p189client.check_response` \u6267\u884c\u68c0\u67e5\u3002\u5982\u679c\u68c0\u6d4b\u4e3a\u6b63\u5e38\uff0c\u5219\u539f\u6837\u8fd4\u56de\u6570\u636e\uff1b\u5426\u5219\uff0c\u629b\u51fa\u4e00\u4e2a `p189client.P189OSError` \u7684\u5b9e\u4f8b\u3002\n\n```python\nfrom p189client import check_response\n\n# \u68c0\u67e5\u540c\u6b65\u8c03\u7528\ndata = check_response(client.method(payload))\n# \u68c0\u67e5\u5f02\u6b65\u8c03\u7528\ndata = check_response(await client.method(payload, async_=True))\n```\n\n## 4. \u8f85\u52a9\u5de5\u5177\n\n\u4e00\u4e9b\u7b80\u5355\u7684\u5c01\u88c5\u5de5\u5177\u53ef\u80fd\u662f\u5fc5\u8981\u7684\uff0c\u7279\u522b\u662f\u90a3\u79cd\u5b9e\u73b0\u8d77\u6765\u4ee3\u7801\u91cf\u6bd4\u8f83\u5c11\uff0c\u53ef\u4ee5\u5c01\u88c5\u6210\u5355\u4e2a\u51fd\u6570\u7684\u3002\u6211\u628a\u5e73\u5e38\u4f7f\u7528\u8fc7\u7a0b\u4e2d\uff0c\u79ef\u7d2f\u7684\u4e00\u4e9b\u7ecf\u9a8c\u5177\u4f53\u5316\u4e3a\u4e00\u7ec4\u5de5\u5177\u51fd\u6570\u3002\u8fd9\u4e9b\u5de5\u5177\u51fd\u6570\u5206\u522b\u6709\u7740\u4e0d\u540c\u7684\u529f\u80fd\uff0c\u5982\u679c\u7ec4\u5408\u8d77\u6765\u4f7f\u7528\uff0c\u6216\u8bb8\u80fd\u89e3\u51b3\u5f88\u591a\u95ee\u9898\u3002\n\n```python\nfrom p189client import tool\n```\n\n## 5. \u5b66\u4e60\u6848\u4f8b\n\n### 1. \u76f4\u94fe\u670d\u52a1\n\n\u9700\u8981\u5148\u5b89\u88c5 [blacksheep](https://www.neoteroi.dev/blacksheep/)\n\n```console\npip install 'blacksheep[uvicorn]'\n```\n\n```python\nfrom blacksheep import json, redirect, Application, Request\nfrom p189client import P189Client\n\n# TODO: \u6539\u6210\u4f60\u81ea\u5df1\u7684\u8d26\u6237\u548c\u5bc6\u7801\uff0c\u4e0d\u5199\u5c31\u662f\u626b\u7801\u767b\u5f55\nclient = P189Client(username=\"\", password=\"\")\n# \u6216\u8005\u53ef\u4ee5\u5199\u6b7b\u67d0\u4e2a\u7279\u5b9a\u7684 access_token\n# client = P189Client(cookies=\"\")\n# client.access_token = \"\"\n\napp = Application(show_error_details=__debug__)\n\n@app.router.route(\"/{path:path}\", methods=[\"GET\", \"HEAD\"])\nasync def index(request: Request, path: str, id: int, family_id: int = 0):\n    if family_id:\n        payload = {\"fileId\": id, \"familyId\": family_id}\n    else:\n        payload = {\"fileId\": id}\n    url = await client.download_url(payload, use_access_token=True, async_=True)\n    return redirect(url)\n\nif __name__ == \"__main__\":\n    from uvicorn import run\n\n    run(app, host=\"0.0.0.0\", port=8189)\n```\n\n### 2. \u7b7e\u5230\u548c\u62bd\u5956\n\n```python\nfrom p189client import P189Client\n\n# TODO: \u6539\u6210\u4f60\u81ea\u5df1\u7684\u8d26\u6237\u548c\u5bc6\u7801\uff0c\u4e0d\u5199\u5c31\u662f\u626b\u7801\u767b\u5f55\nclient = P189Client(username=\"\", password=\"\")\n\n# \u7b7e\u5230\nprint(\"\u7b7e\u5230\", client.user_sign())\n\n# \u62bd\u5956\nfrom time import sleep\nprint(\"\\n\u62bd\u5956\")\nfor i, task_id in enumerate([\"TASK_SIGNIN\", \"TASK_SIGNIN_PHOTOS\", \"TASK_2022_FLDFS_KJ\"]):\n    if i:\n        # NOTE: \u4f11\u606f 5 \u79d2\uff0c\u9632\u6b62\u88ab\u8bf4\u8fc7\u4e8e\u9891\u7e41\n        sleep(5)\n    print(task_id, client.user_draw(task_id))\n```\n\n## \u5176\u5b83\u8d44\u6e90\n\n- \u5982\u679c\u4f60\u9700\u8981\u66f4\u8be6\u7ec6\u7684\u6587\u6863\uff0c\u7279\u522b\u662f\u5173\u4e8e\u5404\u79cd\u63a5\u53e3\u7684\u4fe1\u606f\uff0c\u53ef\u4ee5\u9605\u8bfb\n\n    [https://p189client.readthedocs.io/en/latest/](https://p189client.readthedocs.io/en/latest/)\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Python 189 webdisk client.",
    "version": "0.0.2.3",
    "project_urls": {
        "Homepage": "https://github.com/ChenyangGao/p189client",
        "Repository": "https://github.com/ChenyangGao/p189client"
    },
    "split_keywords": [
        "189",
        " webdisk",
        " client"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5f54022b4cb8190d9798f4ba11e620aa581d68996febd032c1b22b0d5eee091a",
                "md5": "c08c93e7156c20e530ec06714e5e5d6b",
                "sha256": "eba53e9dba63161547c3f51bb8246ada2a487ff07ff083a063ef29cfe2204ef5"
            },
            "downloads": -1,
            "filename": "p189client-0.0.2.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "c08c93e7156c20e530ec06714e5e5d6b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.12",
            "size": 44159,
            "upload_time": "2025-08-05T07:53:17",
            "upload_time_iso_8601": "2025-08-05T07:53:17.303428Z",
            "url": "https://files.pythonhosted.org/packages/5f/54/022b4cb8190d9798f4ba11e620aa581d68996febd032c1b22b0d5eee091a/p189client-0.0.2.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a0031bd7e82a692df30fa5d2d8d106678d9c4a667537e8c7596add3bb0a4fcd4",
                "md5": "d844f5828879c0c82e8e220cffc4cf7d",
                "sha256": "9519341532c7b573629cc7ac5104734514082d61275f423dc0ec439ec89d3c21"
            },
            "downloads": -1,
            "filename": "p189client-0.0.2.3.tar.gz",
            "has_sig": false,
            "md5_digest": "d844f5828879c0c82e8e220cffc4cf7d",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.12",
            "size": 41531,
            "upload_time": "2025-08-05T07:53:18",
            "upload_time_iso_8601": "2025-08-05T07:53:18.848262Z",
            "url": "https://files.pythonhosted.org/packages/a0/03/1bd7e82a692df30fa5d2d8d106678d9c4a667537e8c7596add3bb0a4fcd4/p189client-0.0.2.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-05 07:53:18",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ChenyangGao",
    "github_project": "p189client",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "p189client"
}
        
Elapsed time: 0.43480s