qqmusic-api-python 0.4.0__tar.gz → 0.4.1__tar.gz
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.
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/PKG-INFO +2 -4
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/README.md +0 -1
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/pyproject.toml +26 -27
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/__init__.py +1 -1
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/network.py +57 -7
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/.gitignore +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/LICENSE +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/album.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/comment.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/exceptions/__init__.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/exceptions/api_exception.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/login.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/lyric.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/mv.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/recommend.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/search.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/singer.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/song.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/songlist.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/top.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/user.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/__init__.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/common.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/credential.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/device.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/mqtt.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/qimei.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/session.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/sign.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/tripledes.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_album.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_comment.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_login.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_lyric.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_mv.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_qimei.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_recommend.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_search.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_session.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_sign.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_singer.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_song.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_songlist.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_top.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_user.py +0 -0
- {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/web/README.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qqmusic-api-python
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: QQ音乐API封装库
|
|
5
5
|
Project-URL: homepage, https://luren-dc.github.io/QQMusicApi/
|
|
6
6
|
Project-URL: repository, https://github.com/luren-dc/QQMusicApi
|
|
@@ -21,8 +21,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
21
21
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
22
22
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
23
|
Requires-Python: >=3.10
|
|
24
|
-
Requires-Dist:
|
|
25
|
-
Requires-Dist: cryptography<45.0.6,>=45.0.5
|
|
24
|
+
Requires-Dist: cryptography>=46.0.3
|
|
26
25
|
Requires-Dist: httpx-ws>=0.8.2
|
|
27
26
|
Requires-Dist: httpx[http2]>=0.27.0
|
|
28
27
|
Requires-Dist: orjson>=3.10.15
|
|
@@ -72,7 +71,6 @@ Description-Content-Type: text/markdown
|
|
|
72
71
|
|
|
73
72
|
- Cryptography
|
|
74
73
|
- HTTPX
|
|
75
|
-
- aiocache
|
|
76
74
|
- orjson
|
|
77
75
|
|
|
78
76
|
## 快速上手
|
|
@@ -5,12 +5,11 @@ authors = [
|
|
|
5
5
|
{ name = "Luren", email = "68656403+luren-dc@users.noreply.github.com" },
|
|
6
6
|
]
|
|
7
7
|
dependencies = [
|
|
8
|
-
"cryptography>=45.0.5,<45.0.6",
|
|
9
8
|
"typing-extensions>=4.12.2",
|
|
10
9
|
"httpx[http2]>=0.27.0",
|
|
11
|
-
"aiocache>=0.12.3",
|
|
12
10
|
"orjson>=3.10.15",
|
|
13
11
|
"httpx-ws>=0.8.2",
|
|
12
|
+
"cryptography>=46.0.3",
|
|
14
13
|
]
|
|
15
14
|
requires-python = ">=3.10"
|
|
16
15
|
readme = "README.md"
|
|
@@ -38,32 +37,7 @@ homepage = "https://luren-dc.github.io/QQMusicApi/"
|
|
|
38
37
|
repository = "https://github.com/luren-dc/QQMusicApi"
|
|
39
38
|
documentation = "https://luren-dc.github.io/QQMusicApi/"
|
|
40
39
|
|
|
41
|
-
[build-system]
|
|
42
|
-
requires = ["hatchling"]
|
|
43
|
-
build-backend = "hatchling.build"
|
|
44
|
-
|
|
45
|
-
[tool.uv]
|
|
46
|
-
package = true
|
|
47
|
-
|
|
48
|
-
[[tool.uv.index]]
|
|
49
|
-
url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"
|
|
50
|
-
default = true
|
|
51
|
-
|
|
52
|
-
[tool.hatch.version]
|
|
53
|
-
path = "qqmusic_api/__init__.py"
|
|
54
|
-
|
|
55
|
-
[tool.hatch.build.targets.wheel]
|
|
56
|
-
packages = ["qqmusic_api"]
|
|
57
|
-
|
|
58
|
-
[tool.hatch.build.targets.sdist]
|
|
59
|
-
include = ["/qqmusic_api", "/tests", "LICENSE", "README.md"]
|
|
60
|
-
|
|
61
40
|
[dependency-groups]
|
|
62
|
-
testing = [
|
|
63
|
-
"pytest<9.0.0,>=8.2.0",
|
|
64
|
-
"pytest-asyncio<1.1.0,>=1.0.0",
|
|
65
|
-
"pytest-sugar<2.0.0,>=1.0.0",
|
|
66
|
-
]
|
|
67
41
|
docs = [
|
|
68
42
|
"mkdocs-material>=9.5.29",
|
|
69
43
|
"mkdocstrings-python>=1.10.5",
|
|
@@ -74,11 +48,36 @@ docs = [
|
|
|
74
48
|
"docstring-inheritance>=2.2.1",
|
|
75
49
|
"griffe-modernized-annotations>=1.0.8",
|
|
76
50
|
]
|
|
51
|
+
testing = [
|
|
52
|
+
"pytest>=9.0.2",
|
|
53
|
+
"pytest-asyncio>=1.3.0",
|
|
54
|
+
"pytest-sugar>=1.1.1",
|
|
55
|
+
]
|
|
77
56
|
web = [
|
|
78
57
|
"fastapi>=0.115.8",
|
|
79
58
|
"uvicorn>=0.34.0",
|
|
80
59
|
]
|
|
81
60
|
|
|
61
|
+
[build-system]
|
|
62
|
+
requires = ["hatchling"]
|
|
63
|
+
build-backend = "hatchling.build"
|
|
64
|
+
|
|
65
|
+
[tool.hatch.version]
|
|
66
|
+
path = "qqmusic_api/__init__.py"
|
|
67
|
+
|
|
68
|
+
[tool.hatch.build.targets.wheel]
|
|
69
|
+
packages = ["qqmusic_api"]
|
|
70
|
+
|
|
71
|
+
[tool.hatch.build.targets.sdist]
|
|
72
|
+
include = ["/qqmusic_api", "/tests", "LICENSE", "README.md"]
|
|
73
|
+
|
|
74
|
+
[tool.uv]
|
|
75
|
+
package = true
|
|
76
|
+
|
|
77
|
+
[[tool.uv.index]]
|
|
78
|
+
url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"
|
|
79
|
+
default = true
|
|
80
|
+
|
|
82
81
|
[tool.commitizen]
|
|
83
82
|
name = "cz_gitmoji"
|
|
84
83
|
|
|
@@ -6,7 +6,7 @@ from . import album, comment, login, lyric, mv, search, singer, song, songlist,
|
|
|
6
6
|
from .utils.credential import Credential
|
|
7
7
|
from .utils.session import Session, get_session, set_session
|
|
8
8
|
|
|
9
|
-
__version__ = "0.4.
|
|
9
|
+
__version__ = "0.4.1"
|
|
10
10
|
|
|
11
11
|
logger = logging.getLogger("qqmusicapi")
|
|
12
12
|
|
|
@@ -38,7 +38,21 @@ def api_request(
|
|
|
38
38
|
process_bool: bool = True,
|
|
39
39
|
catch_error_code: list[int] | None = None,
|
|
40
40
|
):
|
|
41
|
-
"""API
|
|
41
|
+
"""API请求装饰器.
|
|
42
|
+
|
|
43
|
+
用于将普通函数转换为 `ApiRequest` 实例的工厂函数.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
module: 模块名称 (e.g. `music.trackInfo.UniformRuleCtrl`).
|
|
47
|
+
method: 调用方法名称 (e.g. `CgiGetTrackInfo`).
|
|
48
|
+
verify: 是否验证凭证有效性.如果为 `True`,请求前会检查凭证是否过期,过期则抛出异常.
|
|
49
|
+
ignore_code: 是否忽略业务状态码检查.如果为 `True`,将跳过 `code != 0` 的验证.
|
|
50
|
+
process_bool: 是否转换布尔值.如果为 `True`,参数中的 `bool` 值会自动转换为 `int` (`0`/`1`).
|
|
51
|
+
catch_error_code: 视为成功的错误码列表.当响应 `code` 在此列表中时,不会抛出异常.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
一个装饰器,将函数转换为返回 `ApiRequest` 的可调用对象.
|
|
55
|
+
"""
|
|
42
56
|
|
|
43
57
|
def decorator(
|
|
44
58
|
api_func: Callable[_P, Coroutine[None, None, tuple[dict[Any, Any], Callable[[dict[str, Any]], _R]]]],
|
|
@@ -178,7 +192,10 @@ class BaseRequest(ABC):
|
|
|
178
192
|
|
|
179
193
|
|
|
180
194
|
class ApiRequest(BaseRequest, Generic[_P, _R]):
|
|
181
|
-
"""API
|
|
195
|
+
"""API 请求处理器.
|
|
196
|
+
|
|
197
|
+
封装单个 API 请求的构建、发送和处理逻辑.
|
|
198
|
+
"""
|
|
182
199
|
|
|
183
200
|
def __init__(
|
|
184
201
|
self,
|
|
@@ -195,12 +212,26 @@ class ApiRequest(BaseRequest, Generic[_P, _R]):
|
|
|
195
212
|
process_bool: bool = True,
|
|
196
213
|
catch_error_code: list[int] | None = None,
|
|
197
214
|
) -> None:
|
|
215
|
+
"""初始化 ApiRequest.
|
|
216
|
+
|
|
217
|
+
Args:
|
|
218
|
+
module: 模块名.
|
|
219
|
+
method: 方法名.
|
|
220
|
+
api_func: 被装饰的原始 API 函数
|
|
221
|
+
params: 请求参数字典.
|
|
222
|
+
common: 公共参数字典.
|
|
223
|
+
credential: 请求凭证.
|
|
224
|
+
verify: 是否验证凭证.
|
|
225
|
+
ignore_code: 是否忽略错误码.
|
|
226
|
+
process_bool: 是否处理布尔值.
|
|
227
|
+
catch_error_code: 捕获的错误码列表.
|
|
228
|
+
"""
|
|
198
229
|
super().__init__(common, credential, verify, ignore_code)
|
|
199
230
|
self.module = module
|
|
200
231
|
self.method = method
|
|
201
232
|
self.params = params or {}
|
|
202
233
|
self.api_func = api_func
|
|
203
|
-
self.
|
|
234
|
+
self.process_bool = process_bool
|
|
204
235
|
self.processor: Callable[[dict[str, Any]], Any] = NO_PROCESSOR
|
|
205
236
|
self.catch_error_code = catch_error_code or []
|
|
206
237
|
|
|
@@ -214,7 +245,7 @@ class ApiRequest(BaseRequest, Generic[_P, _R]):
|
|
|
214
245
|
@property
|
|
215
246
|
def data(self) -> dict[str, Any]:
|
|
216
247
|
"""API 请求数据"""
|
|
217
|
-
if self.
|
|
248
|
+
if self.process_bool:
|
|
218
249
|
params = {k: int(v) if isinstance(v, bool) else v for k, v in self.params.items()}
|
|
219
250
|
else:
|
|
220
251
|
params = self.params
|
|
@@ -301,8 +332,15 @@ class RequestGroup(BaseRequest):
|
|
|
301
332
|
self,
|
|
302
333
|
common: dict[str, Any] | None = None,
|
|
303
334
|
credential: Credential | None = None,
|
|
304
|
-
limit: int =
|
|
335
|
+
limit: int = 20,
|
|
305
336
|
):
|
|
337
|
+
"""初始化 RequestGroup.
|
|
338
|
+
|
|
339
|
+
Args:
|
|
340
|
+
common: 组级公共参数,将合并到每个子请求中.
|
|
341
|
+
credential: 组级凭证,将应用于所有子请求.
|
|
342
|
+
limit: 单次请求的最大子请求数量.超过此数量会自动分批发送.
|
|
343
|
+
"""
|
|
306
344
|
super().__init__(common, credential)
|
|
307
345
|
self._requests: list[RequestItem] = []
|
|
308
346
|
self.limit = limit
|
|
@@ -310,7 +348,13 @@ class RequestGroup(BaseRequest):
|
|
|
310
348
|
self._results = []
|
|
311
349
|
|
|
312
350
|
def add_request(self, request: ApiRequest[_P, _R], *args: _P.args, **kwargs: _P.kwargs) -> None:
|
|
313
|
-
"""
|
|
351
|
+
"""添加请求到组.
|
|
352
|
+
|
|
353
|
+
Args:
|
|
354
|
+
request: `ApiRequest` 实例或被 `@api_request` 装饰的函数.
|
|
355
|
+
*args: 传递给 API 函数的位置参数.
|
|
356
|
+
**kwargs: 传递给 API 函数的关键字参数.
|
|
357
|
+
"""
|
|
314
358
|
base_key = f"{request.module}.{request.method}"
|
|
315
359
|
self._key_counter[base_key] += 1
|
|
316
360
|
count = self._key_counter[base_key]
|
|
@@ -378,7 +422,13 @@ class RequestGroup(BaseRequest):
|
|
|
378
422
|
return self._results
|
|
379
423
|
|
|
380
424
|
async def execute(self) -> list[Any]:
|
|
381
|
-
"""
|
|
425
|
+
"""执行合并请求。
|
|
426
|
+
|
|
427
|
+
如果请求数量超过 `limit`,会自动分批执行并合并结果。
|
|
428
|
+
|
|
429
|
+
Returns:
|
|
430
|
+
list[Any]: 请求结果列表
|
|
431
|
+
"""
|
|
382
432
|
if not self._requests:
|
|
383
433
|
return []
|
|
384
434
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/exceptions/api_exception.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|