python-123-client


Namepython-123-client JSON
Version 0.0.4.0.1 PyPI version JSON
download
home_pagehttps://github.com/ChenyangGao/web-mount-packs/tree/main/python-123-client
SummaryPython wrapper for 123 webdisk.
upload_time2025-01-20 06:42:52
maintainerNone
docs_urlNone
authorChenyangGao
requires_python<4.0,>=3.12
licenseMIT
keywords 123 webdisk client
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Python 123 网盘客户端

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

## 安装

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

```console
pip install -U python-123-client
```

## 入门介绍

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

导入模块

```python
from p123 import P123Client
```

创建客户端对象,需要传入 JWT <kbd>token</kbd>

```python
token = "..."
client = P123Client(token=token)
```

你也可以用账户和密码登录

```python
passport = "..." # 手机号或者邮箱
password = "..." # 密码
client = P123Client(passport, password)
```

### 2. 接口调用

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

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

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

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

```python
url = "https://www.123pan.com/api/someapi"
response = client.request(url=url, json={...})
```

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

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

from p123 import P123Client

class MyCustom123Client(P123Client):

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

### 3. 检查响应

接口被调用后,如果返回的是 dict 类型的数据(说明原本是 JSON),则可以用 `p123.check_response` 执行检查。首先会查看其中名为 "code" 的键的对应值,如果为 0 或 200 或者不存在,则原样返回被检查的数据;否则,抛出一个 `p123.P123OSError` 的实例。

```python
from p123 import check_response

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

### 4. 辅助工具

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

```python
from p123 import tool
```

#### 1. 创建自定义 uri

```python
from p123 import P123Client
from p123.tool import make_uri

# TODO: 改成你自己的账户和密码
client = P123Client(passport="手机号或邮箱", password="登录密码")

# TODO: 请改成你要处理的文件 id
file_id = 15688945
print(make_uri(client, file_id))
```

#### 2. 由自定义 uri 转存文件到你的网盘

```python
from p123 import P123Client
from p123.tool import upload_uri

# TODO: 改成你自己的账户和密码
client = P123Client(passport="手机号或邮箱", password="登录密码")

uri = "123://torrentgalaxy.db|1976025090|582aa8bfb0ad8e6f512d9661f6243bdd"
print(upload_uri(client, uri, duplicate=1))
```

#### 3. 由自定义 uri 获取下载直链

```python
from p123 import P123Client
from p123.tool import get_downurl

# TODO: 改成你自己的账户和密码
client = P123Client(passport="手机号或邮箱", password="登录密码")

# 带 s3_key_flag
print(get_downurl(client, "123://torrentgalaxy.db|1976025090|582aa8bfb0ad8e6f512d9661f6243bdd?1812602326-0"))
# 不带 s3_key_flag(会转存)
print(get_downurl(client, "123://torrentgalaxy.db|1976025090|582aa8bfb0ad8e6f512d9661f6243bdd"))
```

#### 4. 直链服务

需要先安装 [fastapi](https://pypi.org/project/fastapi/)

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

然后启动如下服务,就可以访问以获取直链了

**带 s3_key_flag**

http://localhost:8123/torrentgalaxy.db|1976025090|582aa8bfb0ad8e6f512d9661f6243bdd?1812602326-0

**不带 s3_key_flag(会转存)**

http://localhost:8123/torrentgalaxy.db|1976025090|582aa8bfb0ad8e6f512d9661f6243bdd

```python
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse, RedirectResponse
from p123 import P123Client
from p123.tool import get_downurl

# TODO: 改成你自己的账户和密码
client = P123Client(passport="手机号或邮箱", password="登录密码")

app = FastAPI(debug=True)

@app.get("/{uri:path}")
@app.head("/{uri:path}")
async def index(request: Request, uri: str):
    try:
        payload = int(uri)
    except ValueError:
        if uri.count("|") < 2:
            return JSONResponse({"state": False, "message": f"bad uri: {uri!r}"}, 500)
        payload = uri
        if s3_key_flag := request.url.query:
            payload += "?" + s3_key_flag
    url = await get_downurl(client, payload, quoted=False, async_=True)
    return RedirectResponse(url, 302)

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

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

#### 5. 遍历文件列表

**遍历网盘中的文件列表**

```python
from p123 import P123Client
from p123.tool import iterdir

# TODO: 改成你自己的账户和密码
client = P123Client(passport="手机号或邮箱", password="登录密码")

for info in iterdir(client, parent_id=0, max_depth=-1, predicate=lambda a: not a["is_dir"]):
    print(info)
```

**遍历分享中的文件列表(无需登录)**

```python
from p123.tool import share_iterdir

# TODO: 分享码
share_key = "g0n0Vv-2sbI"
# TODO: 密码
share_pwd = ""

for info in share_iterdir(share_key, share_pwd, parent_id=0, max_depth=-1, predicate=lambda a: not a["is_dir"]):
    print(info)
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/ChenyangGao/web-mount-packs/tree/main/python-123-client",
    "name": "python-123-client",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.12",
    "maintainer_email": null,
    "keywords": "123, webdisk, client",
    "author": "ChenyangGao",
    "author_email": "wosiwujm@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/b4/ea/029445bbac5d4692d51db5843d4d3d2791e8feb7ab605f2e22f65a222511/python_123_client-0.0.4.0.1.tar.gz",
    "platform": null,
    "description": "# Python 123 \u7f51\u76d8\u5ba2\u6237\u7aef\n\n![PyPI - Python Version](https://img.shields.io/pypi/pyversions/python-123-client)\n![PyPI - Version](https://img.shields.io/pypi/v/python-123-client)\n![PyPI - Downloads](https://img.shields.io/pypi/dm/python-123-client)\n![PyPI - Format](https://img.shields.io/pypi/format/python-123-client)\n![PyPI - Status](https://img.shields.io/pypi/status/python-123-client)\n\n## \u5b89\u88c5\n\n\u4f60\u53ef\u4ee5\u4ece [pypi](https://pypi.org/project/python-123-client/) \u5b89\u88c5\u6700\u65b0\u7248\u672c\n\n```console\npip install -U python-123-client\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 p123 import P123Client\n```\n\n\u521b\u5efa\u5ba2\u6237\u7aef\u5bf9\u8c61\uff0c\u9700\u8981\u4f20\u5165 JWT <kbd>token</kbd>\n\n```python\ntoken = \"...\"\nclient = P123Client(token=token)\n```\n\n\u4f60\u4e5f\u53ef\u4ee5\u7528\u8d26\u6237\u548c\u5bc6\u7801\u767b\u5f55\n\n```python\npassport = \"...\" # \u624b\u673a\u53f7\u6216\u8005\u90ae\u7bb1\npassword = \"...\" # \u5bc6\u7801\nclient = P123Client(passport, password)\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\uff0c\u4e14\u9ed8\u8ba4\u662f\u91c7\u7528 POST \u53d1\u9001 JSON \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 `P123Client.request`\n\n```python\nurl = \"https://www.123pan.com/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 123 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 p123 import P123Client\n\nclass MyCustom123Client(P123Client):\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://www.123pan.com/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://www.123pan.com/api/bar\"\n        return self.request(\n            api, \n            method=\"POST\", \n            json=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 `p123.check_response` \u6267\u884c\u68c0\u67e5\u3002\u9996\u5148\u4f1a\u67e5\u770b\u5176\u4e2d\u540d\u4e3a \"code\" \u7684\u952e\u7684\u5bf9\u5e94\u503c\uff0c\u5982\u679c\u4e3a 0 \u6216 200 \u6216\u8005\u4e0d\u5b58\u5728\uff0c\u5219\u539f\u6837\u8fd4\u56de\u88ab\u68c0\u67e5\u7684\u6570\u636e\uff1b\u5426\u5219\uff0c\u629b\u51fa\u4e00\u4e2a `p123.P123OSError` \u7684\u5b9e\u4f8b\u3002\n\n```python\nfrom p123 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 p123 import tool\n```\n\n#### 1. \u521b\u5efa\u81ea\u5b9a\u4e49 uri\n\n```python\nfrom p123 import P123Client\nfrom p123.tool import make_uri\n\n# TODO: \u6539\u6210\u4f60\u81ea\u5df1\u7684\u8d26\u6237\u548c\u5bc6\u7801\nclient = P123Client(passport=\"\u624b\u673a\u53f7\u6216\u90ae\u7bb1\", password=\"\u767b\u5f55\u5bc6\u7801\")\n\n# TODO: \u8bf7\u6539\u6210\u4f60\u8981\u5904\u7406\u7684\u6587\u4ef6 id\nfile_id = 15688945\nprint(make_uri(client, file_id))\n```\n\n#### 2. \u7531\u81ea\u5b9a\u4e49 uri \u8f6c\u5b58\u6587\u4ef6\u5230\u4f60\u7684\u7f51\u76d8\n\n```python\nfrom p123 import P123Client\nfrom p123.tool import upload_uri\n\n# TODO: \u6539\u6210\u4f60\u81ea\u5df1\u7684\u8d26\u6237\u548c\u5bc6\u7801\nclient = P123Client(passport=\"\u624b\u673a\u53f7\u6216\u90ae\u7bb1\", password=\"\u767b\u5f55\u5bc6\u7801\")\n\nuri = \"123://torrentgalaxy.db|1976025090|582aa8bfb0ad8e6f512d9661f6243bdd\"\nprint(upload_uri(client, uri, duplicate=1))\n```\n\n#### 3. \u7531\u81ea\u5b9a\u4e49 uri \u83b7\u53d6\u4e0b\u8f7d\u76f4\u94fe\n\n```python\nfrom p123 import P123Client\nfrom p123.tool import get_downurl\n\n# TODO: \u6539\u6210\u4f60\u81ea\u5df1\u7684\u8d26\u6237\u548c\u5bc6\u7801\nclient = P123Client(passport=\"\u624b\u673a\u53f7\u6216\u90ae\u7bb1\", password=\"\u767b\u5f55\u5bc6\u7801\")\n\n# \u5e26 s3_key_flag\nprint(get_downurl(client, \"123://torrentgalaxy.db|1976025090|582aa8bfb0ad8e6f512d9661f6243bdd?1812602326-0\"))\n# \u4e0d\u5e26 s3_key_flag\uff08\u4f1a\u8f6c\u5b58\uff09\nprint(get_downurl(client, \"123://torrentgalaxy.db|1976025090|582aa8bfb0ad8e6f512d9661f6243bdd\"))\n```\n\n#### 4. \u76f4\u94fe\u670d\u52a1\n\n\u9700\u8981\u5148\u5b89\u88c5 [fastapi](https://pypi.org/project/fastapi/)\n\n```console\npip install 'fastapi[uvicorn]'\n```\n\n\u7136\u540e\u542f\u52a8\u5982\u4e0b\u670d\u52a1\uff0c\u5c31\u53ef\u4ee5\u8bbf\u95ee\u4ee5\u83b7\u53d6\u76f4\u94fe\u4e86\n\n**\u5e26 s3_key_flag**\n\nhttp://localhost:8123/torrentgalaxy.db|1976025090|582aa8bfb0ad8e6f512d9661f6243bdd?1812602326-0\n\n**\u4e0d\u5e26 s3_key_flag\uff08\u4f1a\u8f6c\u5b58\uff09**\n\nhttp://localhost:8123/torrentgalaxy.db|1976025090|582aa8bfb0ad8e6f512d9661f6243bdd\n\n```python\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import JSONResponse, RedirectResponse\nfrom p123 import P123Client\nfrom p123.tool import get_downurl\n\n# TODO: \u6539\u6210\u4f60\u81ea\u5df1\u7684\u8d26\u6237\u548c\u5bc6\u7801\nclient = P123Client(passport=\"\u624b\u673a\u53f7\u6216\u90ae\u7bb1\", password=\"\u767b\u5f55\u5bc6\u7801\")\n\napp = FastAPI(debug=True)\n\n@app.get(\"/{uri:path}\")\n@app.head(\"/{uri:path}\")\nasync def index(request: Request, uri: str):\n    try:\n        payload = int(uri)\n    except ValueError:\n        if uri.count(\"|\") < 2:\n            return JSONResponse({\"state\": False, \"message\": f\"bad uri: {uri!r}\"}, 500)\n        payload = uri\n        if s3_key_flag := request.url.query:\n            payload += \"?\" + s3_key_flag\n    url = await get_downurl(client, payload, quoted=False, async_=True)\n    return RedirectResponse(url, 302)\n\nif __name__ == \"__main__\":\n    from uvicorn import run\n\n    run(app, host=\"0.0.0.0\", port=8123)\n```\n\n#### 5. \u904d\u5386\u6587\u4ef6\u5217\u8868\n\n**\u904d\u5386\u7f51\u76d8\u4e2d\u7684\u6587\u4ef6\u5217\u8868**\n\n```python\nfrom p123 import P123Client\nfrom p123.tool import iterdir\n\n# TODO: \u6539\u6210\u4f60\u81ea\u5df1\u7684\u8d26\u6237\u548c\u5bc6\u7801\nclient = P123Client(passport=\"\u624b\u673a\u53f7\u6216\u90ae\u7bb1\", password=\"\u767b\u5f55\u5bc6\u7801\")\n\nfor info in iterdir(client, parent_id=0, max_depth=-1, predicate=lambda a: not a[\"is_dir\"]):\n    print(info)\n```\n\n**\u904d\u5386\u5206\u4eab\u4e2d\u7684\u6587\u4ef6\u5217\u8868\uff08\u65e0\u9700\u767b\u5f55\uff09**\n\n```python\nfrom p123.tool import share_iterdir\n\n# TODO: \u5206\u4eab\u7801\nshare_key = \"g0n0Vv-2sbI\"\n# TODO: \u5bc6\u7801\nshare_pwd = \"\"\n\nfor info in share_iterdir(share_key, share_pwd, parent_id=0, max_depth=-1, predicate=lambda a: not a[\"is_dir\"]):\n    print(info)\n```\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Python wrapper for 123 webdisk.",
    "version": "0.0.4.0.1",
    "project_urls": {
        "Homepage": "https://github.com/ChenyangGao/web-mount-packs/tree/main/python-123-client",
        "Repository": "https://github.com/ChenyangGao/web-mount-packs/tree/main/python-123-client"
    },
    "split_keywords": [
        "123",
        " webdisk",
        " client"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6f9a27a2ced944b797e411201b5ae9a430f64d41180622c3c1f1833a7472888e",
                "md5": "11c098f45ee9c78db0080d9077afcd7c",
                "sha256": "b6d2eb169208c0e35b3167df0b8891f0b6c95897c47b137173c4a06efbdcf7ce"
            },
            "downloads": -1,
            "filename": "python_123_client-0.0.4.0.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "11c098f45ee9c78db0080d9077afcd7c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.12",
            "size": 21628,
            "upload_time": "2025-01-20T06:42:50",
            "upload_time_iso_8601": "2025-01-20T06:42:50.172695Z",
            "url": "https://files.pythonhosted.org/packages/6f/9a/27a2ced944b797e411201b5ae9a430f64d41180622c3c1f1833a7472888e/python_123_client-0.0.4.0.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b4ea029445bbac5d4692d51db5843d4d3d2791e8feb7ab605f2e22f65a222511",
                "md5": "68e19729579422301bcadecf595e58fe",
                "sha256": "167e0e58b5c0b5fd1194eb80339b2535346706351c50a9f5e19c6f3b727722b3"
            },
            "downloads": -1,
            "filename": "python_123_client-0.0.4.0.1.tar.gz",
            "has_sig": false,
            "md5_digest": "68e19729579422301bcadecf595e58fe",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.12",
            "size": 19277,
            "upload_time": "2025-01-20T06:42:52",
            "upload_time_iso_8601": "2025-01-20T06:42:52.723920Z",
            "url": "https://files.pythonhosted.org/packages/b4/ea/029445bbac5d4692d51db5843d4d3d2791e8feb7ab605f2e22f65a222511/python_123_client-0.0.4.0.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-01-20 06:42:52",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ChenyangGao",
    "github_project": "web-mount-packs",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "python-123-client"
}
        
Elapsed time: 0.45987s