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.
Files changed (46) hide show
  1. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/PKG-INFO +2 -4
  2. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/README.md +0 -1
  3. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/pyproject.toml +26 -27
  4. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/__init__.py +1 -1
  5. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/network.py +57 -7
  6. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/.gitignore +0 -0
  7. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/LICENSE +0 -0
  8. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/album.py +0 -0
  9. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/comment.py +0 -0
  10. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/exceptions/__init__.py +0 -0
  11. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/exceptions/api_exception.py +0 -0
  12. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/login.py +0 -0
  13. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/lyric.py +0 -0
  14. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/mv.py +0 -0
  15. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/recommend.py +0 -0
  16. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/search.py +0 -0
  17. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/singer.py +0 -0
  18. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/song.py +0 -0
  19. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/songlist.py +0 -0
  20. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/top.py +0 -0
  21. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/user.py +0 -0
  22. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/__init__.py +0 -0
  23. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/common.py +0 -0
  24. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/credential.py +0 -0
  25. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/device.py +0 -0
  26. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/mqtt.py +0 -0
  27. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/qimei.py +0 -0
  28. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/session.py +0 -0
  29. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/sign.py +0 -0
  30. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/qqmusic_api/utils/tripledes.py +0 -0
  31. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_album.py +0 -0
  32. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_comment.py +0 -0
  33. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_login.py +0 -0
  34. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_lyric.py +0 -0
  35. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_mv.py +0 -0
  36. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_qimei.py +0 -0
  37. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_recommend.py +0 -0
  38. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_search.py +0 -0
  39. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_session.py +0 -0
  40. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_sign.py +0 -0
  41. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_singer.py +0 -0
  42. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_song.py +0 -0
  43. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_songlist.py +0 -0
  44. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_top.py +0 -0
  45. {qqmusic_api_python-0.4.0 → qqmusic_api_python-0.4.1}/tests/test_user.py +0 -0
  46. {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.0
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: aiocache>=0.12.3
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
  ## 快速上手
@@ -41,7 +41,6 @@
41
41
 
42
42
  - Cryptography
43
43
  - HTTPX
44
- - aiocache
45
44
  - orjson
46
45
 
47
46
  ## 快速上手
@@ -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.0"
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.proceduce_bool = process_bool
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.proceduce_bool:
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 = 30,
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