p115client


Namep115client JSON
Version 0.0.3.7.7.7 PyPI version JSON
download
home_pagehttps://github.com/ChenyangGao/p115client
SummaryPython 115 webdisk client.
upload_time2024-11-12 15:32:29
maintainerNone
docs_urlNone
authorChenyangGao
requires_python<4.0,>=3.11
licenseMIT
keywords 115 webdisk client
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Python 115 网盘客户端.

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

## 安装

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

```console
pip install -U p115client
```

## 入门介绍

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

导入模块

```python
from p115client import P115Client
```

创建客户端对象,需要传入 <kbd>cookies</kbd>,如果不传,则需要扫码登录

```python
cookies = "UID=...; CID=...; SEID=..."
client = P115Client(cookies)
```

如果你的 <kbd>cookies</kbd> 保存在 `~/115-cookies.txt`

```python
from pathlib import Path

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

如果想要在接口返回时自动捕获 405 HTTP 响应码,进行自动扫码,并把更新后的 <kbd>cookies</kbd> 写回文件,然后重试接口调用

```python
client = P115Client(Path("~/115-cookies.txt").expanduser(), check_for_relogin=True)
```

所以综上,推荐的初始化代码为

```python
from p115client import P115Client
from pathlib import Path

client = P115Client(Path("~/115-cookies.txt").expanduser(), check_for_relogin=True)
```

### 2. 接口调用

所有需要直接或间接执行 HTTP 请求的接口,都有同步和异步的调用方式

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

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

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

```python
url = "https://webapi.115.com/files"
response = client.request(url=url, params={"cid": 0, "show_dir": 1})
```

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

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

from p115client import P115Client

class MyCustom115Client(P115Client):

    @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://webapi.115.com/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://webapi.115.com/bar"
        return self.request(
            api, 
            method="POST", 
            data=payload, 
            async_=async_, 
            **request_kwargs, 
        )
```

### 3. 检查响应

接口被调用后,如果返回的是 dict 类型的数据(说明原本是 JSON),则可以用 `p115client.check_response` 执行检查。首先会查看其中名为 "state" 的键的对应值,如果为  True、1 或不存在,则原样返回被检查的数据;否则,"state" 的对应值大概是 False 或 0,说明有问题出现,会根据实际情况抛出一个异常,但都是 `p115client.P115OSError` 的实例。

```python
from p115client import check_response

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

### 4. 辅助工具

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

```python
from p115client import tool
```

## 其它资源

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

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

- 如果你想要一组更高级的封装,特别是一组文件系统的操作集合,可以使用

    [https://pypi.org/project/python-115/](https://pypi.org/project/python-115/)


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/ChenyangGao/p115client",
    "name": "p115client",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.11",
    "maintainer_email": null,
    "keywords": "115, webdisk, client",
    "author": "ChenyangGao",
    "author_email": "wosiwujm@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/c1/4b/461e7312f93e4b4ca3344c526b182005ca2c77d43e309104a6e8a1813644/p115client-0.0.3.7.7.7.tar.gz",
    "platform": null,
    "description": "# Python 115 \u7f51\u76d8\u5ba2\u6237\u7aef.\n\n![PyPI - Python Version](https://img.shields.io/pypi/pyversions/p115client)\n![PyPI - Version](https://img.shields.io/pypi/v/p115client)\n![PyPI - Downloads](https://img.shields.io/pypi/dm/p115client)\n![PyPI - Format](https://img.shields.io/pypi/format/p115client)\n![PyPI - Status](https://img.shields.io/pypi/status/p115client)\n\n## \u5b89\u88c5\n\n\u4f60\u53ef\u4ee5\u4ece [pypi](https://pypi.org/project/p115client/) \u5b89\u88c5\u6700\u65b0\u7248\u672c\n\n```console\npip install -U p115client\n```\n\n## \u5165\u95e8\u4ecb\u7ecd\n\n### 1. \u5bfc\u5165\u6a21\u5757\u548c\u521b\u5efa\u5b9e\u4f8b\n\n\u5bfc\u5165\u6a21\u5757\n\n```python\nfrom p115client import P115Client\n```\n\n\u521b\u5efa\u5ba2\u6237\u7aef\u5bf9\u8c61\uff0c\u9700\u8981\u4f20\u5165 <kbd>cookies</kbd>\uff0c\u5982\u679c\u4e0d\u4f20\uff0c\u5219\u9700\u8981\u626b\u7801\u767b\u5f55\n\n```python\ncookies = \"UID=...; CID=...; SEID=...\"\nclient = P115Client(cookies)\n```\n\n\u5982\u679c\u4f60\u7684 <kbd>cookies</kbd> \u4fdd\u5b58\u5728 `~/115-cookies.txt`\n\n```python\nfrom pathlib import Path\n\nclient = P115Client(Path(\"~/115-cookies.txt\").expanduser())\n```\n\n\u5982\u679c\u60f3\u8981\u5728\u63a5\u53e3\u8fd4\u56de\u65f6\u81ea\u52a8\u6355\u83b7 405 HTTP \u54cd\u5e94\u7801\uff0c\u8fdb\u884c\u81ea\u52a8\u626b\u7801\uff0c\u5e76\u628a\u66f4\u65b0\u540e\u7684 <kbd>cookies</kbd> \u5199\u56de\u6587\u4ef6\uff0c\u7136\u540e\u91cd\u8bd5\u63a5\u53e3\u8c03\u7528\n\n```python\nclient = P115Client(Path(\"~/115-cookies.txt\").expanduser(), check_for_relogin=True)\n```\n\n\u6240\u4ee5\u7efc\u4e0a\uff0c\u63a8\u8350\u7684\u521d\u59cb\u5316\u4ee3\u7801\u4e3a\n\n```python\nfrom p115client import P115Client\nfrom pathlib import Path\n\nclient = P115Client(Path(\"~/115-cookies.txt\").expanduser(), check_for_relogin=True)\n```\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\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 `P115Client.request`\n\n```python\nurl = \"https://webapi.115.com/files\"\nresponse = client.request(url=url, params={\"cid\": 0, \"show_dir\": 1})\n```\n\n\u5f53\u4f60\u9700\u8981\u6784\u5efa\u81ea\u5df1\u7684\u6269\u5c55\u6a21\u5757\uff0c\u4ee5\u589e\u52a0\u4e00\u4e9b\u65b0\u7684 115 web \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 p115client import P115Client\n\nclass MyCustom115Client(P115Client):\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://webapi.115.com/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://webapi.115.com/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 `p115client.check_response` \u6267\u884c\u68c0\u67e5\u3002\u9996\u5148\u4f1a\u67e5\u770b\u5176\u4e2d\u540d\u4e3a \"state\" \u7684\u952e\u7684\u5bf9\u5e94\u503c\uff0c\u5982\u679c\u4e3a  True\u30011 \u6216\u4e0d\u5b58\u5728\uff0c\u5219\u539f\u6837\u8fd4\u56de\u88ab\u68c0\u67e5\u7684\u6570\u636e\uff1b\u5426\u5219\uff0c\"state\" \u7684\u5bf9\u5e94\u503c\u5927\u6982\u662f False \u6216 0\uff0c\u8bf4\u660e\u6709\u95ee\u9898\u51fa\u73b0\uff0c\u4f1a\u6839\u636e\u5b9e\u9645\u60c5\u51b5\u629b\u51fa\u4e00\u4e2a\u5f02\u5e38\uff0c\u4f46\u90fd\u662f `p115client.P115OSError` \u7684\u5b9e\u4f8b\u3002\n\n```python\nfrom p115client 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 p115client import tool\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://p115client.readthedocs.io/en/latest/](https://p115client.readthedocs.io/en/latest/)\n\n- \u5982\u679c\u4f60\u60f3\u8981\u4e00\u7ec4\u66f4\u9ad8\u7ea7\u7684\u5c01\u88c5\uff0c\u7279\u522b\u662f\u4e00\u7ec4\u6587\u4ef6\u7cfb\u7edf\u7684\u64cd\u4f5c\u96c6\u5408\uff0c\u53ef\u4ee5\u4f7f\u7528\n\n    [https://pypi.org/project/python-115/](https://pypi.org/project/python-115/)\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Python 115 webdisk client.",
    "version": "0.0.3.7.7.7",
    "project_urls": {
        "Documentation": "https://p115client.readthedocs.io",
        "Homepage": "https://github.com/ChenyangGao/p115client",
        "Repository": "https://github.com/ChenyangGao/p115client"
    },
    "split_keywords": [
        "115",
        " webdisk",
        " client"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "07eea7f5ded134a340d82a02499514321c27232c961c78e2f2b34eb6395e9004",
                "md5": "5c9c0f9ccdf2f74e3828daab826380c0",
                "sha256": "c6d0243c7b6e7cb2a2d45524985d532a59fb42e549ac13a3c0ffe22009d11ccd"
            },
            "downloads": -1,
            "filename": "p115client-0.0.3.7.7.7-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "5c9c0f9ccdf2f74e3828daab826380c0",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.11",
            "size": 94443,
            "upload_time": "2024-11-12T15:32:27",
            "upload_time_iso_8601": "2024-11-12T15:32:27.667051Z",
            "url": "https://files.pythonhosted.org/packages/07/ee/a7f5ded134a340d82a02499514321c27232c961c78e2f2b34eb6395e9004/p115client-0.0.3.7.7.7-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c14b461e7312f93e4b4ca3344c526b182005ca2c77d43e309104a6e8a1813644",
                "md5": "a53c5a0b9cf8519a731702144052f722",
                "sha256": "43157faa34611112c7cf7f6c45de4b478ddb33ccabafc19563e476f3f827e9bf"
            },
            "downloads": -1,
            "filename": "p115client-0.0.3.7.7.7.tar.gz",
            "has_sig": false,
            "md5_digest": "a53c5a0b9cf8519a731702144052f722",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.11",
            "size": 85992,
            "upload_time": "2024-11-12T15:32:29",
            "upload_time_iso_8601": "2024-11-12T15:32:29.922716Z",
            "url": "https://files.pythonhosted.org/packages/c1/4b/461e7312f93e4b4ca3344c526b182005ca2c77d43e309104a6e8a1813644/p115client-0.0.3.7.7.7.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-11-12 15:32:29",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ChenyangGao",
    "github_project": "p115client",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "p115client"
}
        
Elapsed time: 0.45515s