qqmusic-api-python 0.5.3__tar.gz → 0.6.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 (192) hide show
  1. qqmusic_api_python-0.6.1/.dockerignore +26 -0
  2. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/.gitignore +0 -1
  3. qqmusic_api_python-0.6.1/CLAUDE.md +1 -0
  4. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/PKG-INFO +4 -5
  5. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/coding.md +15 -54
  6. qqmusic_api_python-0.6.1/docs/reference/core/exception.md +3 -0
  7. qqmusic_api_python-0.6.1/docs/reference/modules/private_message.md +3 -0
  8. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/release-notes.md +45 -0
  9. qqmusic_api_python-0.6.1/docs/tutorial/client.md +96 -0
  10. qqmusic_api_python-0.6.1/docs/tutorial/web.md +79 -0
  11. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/examples/phone_login.py +1 -1
  12. qqmusic_api_python-0.6.1/examples/private_message.py +74 -0
  13. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/examples/qrcode_login.py +1 -1
  14. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/pyproject.toml +18 -19
  15. qqmusic_api_python-0.6.1/qqmusic_api/__init__.py +40 -0
  16. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/algorithms/__init__.py +0 -2
  17. qqmusic_api_python-0.6.1/qqmusic_api/core/__init__.py +40 -0
  18. qqmusic_api_python-0.6.1/qqmusic_api/core/client.py +556 -0
  19. qqmusic_api_python-0.6.1/qqmusic_api/core/exceptions.py +136 -0
  20. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/core/pagination.py +5 -2
  21. qqmusic_api_python-0.6.1/qqmusic_api/core/request.py +142 -0
  22. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/core/versioning.py +2 -14
  23. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/models/comment.py +20 -0
  24. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/models/login.py +5 -4
  25. qqmusic_api_python-0.6.1/qqmusic_api/models/private_message.py +350 -0
  26. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/models/request.py +2 -1
  27. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/models/song.py +1 -3
  28. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/modules/__init__.py +2 -0
  29. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/modules/_base.py +17 -64
  30. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/modules/album.py +6 -6
  31. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/modules/comment.py +60 -1
  32. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/modules/login.py +204 -316
  33. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/modules/login_utils.py +8 -12
  34. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/modules/lyric.py +3 -3
  35. qqmusic_api_python-0.6.1/qqmusic_api/modules/private_message.py +518 -0
  36. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/modules/search.py +2 -2
  37. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/modules/song.py +24 -9
  38. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/modules/songlist.py +3 -4
  39. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/utils/__init__.py +2 -2
  40. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/utils/common.py +26 -13
  41. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/utils/device.py +60 -57
  42. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/utils/qimei.py +82 -56
  43. qqmusic_api_python-0.6.1/tests/conftest.py +125 -0
  44. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/tests/test_login.py +30 -21
  45. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/tests/test_login_utils.py +43 -4
  46. qqmusic_api_python-0.6.1/tests/test_private_message.py +38 -0
  47. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/tests/test_search.py +17 -4
  48. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/tests/test_songlist.py +13 -7
  49. qqmusic_api_python-0.6.1/uv.lock +2062 -0
  50. qqmusic_api_python-0.6.1/web/.gitignore +5 -0
  51. qqmusic_api_python-0.6.1/web/Dockerfile +20 -0
  52. qqmusic_api_python-0.6.1/web/README.md +101 -0
  53. qqmusic_api_python-0.6.1/web/accounts.example.toml +40 -0
  54. qqmusic_api_python-0.6.1/web/config.example.toml +96 -0
  55. qqmusic_api_python-0.6.1/web/docker-compose.yml +14 -0
  56. qqmusic_api_python-0.6.1/web/run.py +95 -0
  57. qqmusic_api_python-0.6.1/web/src/app.py +263 -0
  58. qqmusic_api_python-0.6.1/web/src/core/__init__.py +1 -0
  59. qqmusic_api_python-0.6.1/web/src/core/auth.py +212 -0
  60. qqmusic_api_python-0.6.1/web/src/core/cache.py +153 -0
  61. qqmusic_api_python-0.6.1/web/src/core/config.py +210 -0
  62. qqmusic_api_python-0.6.1/web/src/core/credential_store.py +234 -0
  63. qqmusic_api_python-0.6.1/web/src/core/deps.py +66 -0
  64. qqmusic_api_python-0.6.1/web/src/core/response.py +40 -0
  65. qqmusic_api_python-0.6.1/web/src/core/security.py +286 -0
  66. qqmusic_api_python-0.6.1/web/src/modules/__init__.py +1 -0
  67. qqmusic_api_python-0.6.1/web/src/modules/login.py +218 -0
  68. qqmusic_api_python-0.6.1/web/src/modules/mv.py +13 -0
  69. qqmusic_api_python-0.6.1/web/src/modules/singer.py +8 -0
  70. qqmusic_api_python-0.6.1/web/src/modules/song.py +165 -0
  71. qqmusic_api_python-0.6.1/web/src/modules/songlist.py +33 -0
  72. qqmusic_api_python-0.6.1/web/src/routes/__init__.py +32 -0
  73. qqmusic_api_python-0.6.1/web/src/routes/_helpers.py +137 -0
  74. qqmusic_api_python-0.6.1/web/src/routes/album.py +18 -0
  75. qqmusic_api_python-0.6.1/web/src/routes/comment.py +49 -0
  76. qqmusic_api_python-0.6.1/web/src/routes/login.py +80 -0
  77. qqmusic_api_python-0.6.1/web/src/routes/lyric.py +10 -0
  78. qqmusic_api_python-0.6.1/web/src/routes/mv.py +34 -0
  79. qqmusic_api_python-0.6.1/web/src/routes/recommend.py +39 -0
  80. qqmusic_api_python-0.6.1/web/src/routes/search.py +40 -0
  81. qqmusic_api_python-0.6.1/web/src/routes/singer.py +95 -0
  82. qqmusic_api_python-0.6.1/web/src/routes/song.py +122 -0
  83. qqmusic_api_python-0.6.1/web/src/routes/songlist.py +63 -0
  84. qqmusic_api_python-0.6.1/web/src/routes/top.py +18 -0
  85. qqmusic_api_python-0.6.1/web/src/routes/user.py +109 -0
  86. qqmusic_api_python-0.6.1/web/src/routing/__init__.py +1 -0
  87. qqmusic_api_python-0.6.1/web/src/routing/docstrings.py +164 -0
  88. qqmusic_api_python-0.6.1/web/src/routing/executor.py +153 -0
  89. qqmusic_api_python-0.6.1/web/src/routing/params.py +259 -0
  90. qqmusic_api_python-0.6.1/web/src/routing/route_types.py +174 -0
  91. qqmusic_api_python-0.6.1/web/src/routing/router_factory.py +392 -0
  92. qqmusic_api_python-0.6.1/web/tests/test_web_docstrings.py +55 -0
  93. qqmusic_api_python-0.6.1/web/tests/test_web_enums.py +113 -0
  94. qqmusic_api_python-0.6.1/web/tests/test_web_route_validation.py +85 -0
  95. qqmusic_api_python-0.6.1/web/tests/test_web_routes.py +155 -0
  96. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/zensical.toml +2 -0
  97. qqmusic_api_python-0.5.3/docs/reference/core/exception.md +0 -21
  98. qqmusic_api_python-0.5.3/docs/tutorial/client.md +0 -68
  99. qqmusic_api_python-0.5.3/qqmusic_api/__init__.py +0 -52
  100. qqmusic_api_python-0.5.3/qqmusic_api/algorithms/sign.py +0 -58
  101. qqmusic_api_python-0.5.3/qqmusic_api/core/__init__.py +0 -67
  102. qqmusic_api_python-0.5.3/qqmusic_api/core/client.py +0 -807
  103. qqmusic_api_python-0.5.3/qqmusic_api/core/exceptions.py +0 -365
  104. qqmusic_api_python-0.5.3/qqmusic_api/core/request.py +0 -402
  105. qqmusic_api_python-0.5.3/tests/conftest.py +0 -96
  106. qqmusic_api_python-0.5.3/uv.lock +0 -1502
  107. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/.agents/skills/pydantic/SKILL.md +0 -0
  108. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/.agents/skills/python-standards/SKILL.md +0 -0
  109. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/.agents/skills/tarsio/SKILL.md +0 -0
  110. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/.agents/skills/tarsio/references/api-reference.md +0 -0
  111. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/.agents/skills/uv-package-manager/SKILL.md +0 -0
  112. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/.github/ISSUE_TEMPLATE/bug.yml +0 -0
  113. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  114. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/.github/ISSUE_TEMPLATE/feature.yml +0 -0
  115. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  116. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/.github/renovate.json +0 -0
  117. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/.github/workflows/checking.yaml +0 -0
  118. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/.github/workflows/docs.yml +0 -0
  119. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/.github/workflows/release.yml +0 -0
  120. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/.github/workflows/testing.yml +0 -0
  121. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/.markdownlint-cli2.yaml +0 -0
  122. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/AGENTS.md +0 -0
  123. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/LICENSE +0 -0
  124. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/README.md +0 -0
  125. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/assets/qq-music.svg +0 -0
  126. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/cliff.toml +0 -0
  127. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/contributing.md +0 -0
  128. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/index.md +0 -0
  129. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/core/client.md +0 -0
  130. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/core/pagination.md +0 -0
  131. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/core/request.md +0 -0
  132. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/core/versioning.md +0 -0
  133. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/model/album.md +0 -0
  134. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/model/base.md +0 -0
  135. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/model/comment.md +0 -0
  136. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/model/login.md +0 -0
  137. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/model/lyric.md +0 -0
  138. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/model/mv.md +0 -0
  139. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/model/recommend.md +0 -0
  140. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/model/request.md +0 -0
  141. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/model/search.md +0 -0
  142. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/model/singer.md +0 -0
  143. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/model/song.md +0 -0
  144. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/model/songlist.md +0 -0
  145. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/model/top.md +0 -0
  146. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/model/user.md +0 -0
  147. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/modules/album.md +0 -0
  148. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/modules/comment.md +0 -0
  149. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/modules/login.md +0 -0
  150. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/modules/login_utils.md +0 -0
  151. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/modules/lyric.md +0 -0
  152. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/modules/mv.md +0 -0
  153. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/modules/recommend.md +0 -0
  154. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/modules/search.md +0 -0
  155. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/modules/singer.md +0 -0
  156. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/modules/song.md +0 -0
  157. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/modules/songlist.md +0 -0
  158. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/modules/top.md +0 -0
  159. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/reference/modules/user.md +0 -0
  160. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/tutorial/credential.md +0 -0
  161. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/tutorial/pagination.md +0 -0
  162. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/docs/tutorial/start.md +0 -0
  163. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/examples/download_song.py +0 -0
  164. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/prek.toml +0 -0
  165. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/algorithms/tripledes.py +0 -0
  166. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/models/__init__.py +0 -0
  167. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/models/album.py +0 -0
  168. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/models/base.py +0 -0
  169. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/models/lyric.py +0 -0
  170. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/models/mv.py +0 -0
  171. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/models/recommend.py +0 -0
  172. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/models/search.py +0 -0
  173. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/models/singer.py +0 -0
  174. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/models/songlist.py +0 -0
  175. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/models/top.py +0 -0
  176. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/models/user.py +0 -0
  177. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/modules/mv.py +0 -0
  178. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/modules/recommend.py +0 -0
  179. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/modules/singer.py +0 -0
  180. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/modules/top.py +0 -0
  181. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/modules/user.py +0 -0
  182. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/qqmusic_api/utils/mqtt.py +0 -0
  183. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/scripts/ag-1.py +0 -0
  184. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/tests/test_album.py +0 -0
  185. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/tests/test_comment.py +0 -0
  186. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/tests/test_lyric.py +0 -0
  187. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/tests/test_mv.py +0 -0
  188. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/tests/test_recommend.py +0 -0
  189. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/tests/test_singer.py +0 -0
  190. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/tests/test_song.py +0 -0
  191. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/tests/test_top.py +0 -0
  192. {qqmusic_api_python-0.5.3 → qqmusic_api_python-0.6.1}/tests/test_user.py +0 -0
@@ -0,0 +1,26 @@
1
+ __pycache__
2
+ *.pyc
3
+ *.pyo
4
+ .venv
5
+ .conda
6
+ .git
7
+ .gitignore
8
+ .gitattributes
9
+ .github
10
+ .claude
11
+ docs
12
+ tests
13
+ web/tests
14
+ *.md
15
+ !README.md
16
+ .DS_Store
17
+ *.egg-info
18
+ dist
19
+ .ruff_cache
20
+ .mypy_cache
21
+ .pytest_cache
22
+ .prek_cache
23
+ *.toml
24
+ !pyproject.toml
25
+ !web/config.toml
26
+ !web/accounts.toml
@@ -7,7 +7,6 @@ __pycache__/
7
7
  *.py[cod]
8
8
  *$py.class
9
9
  device.json
10
-
11
10
  # C extensions
12
11
  *.so
13
12
 
@@ -0,0 +1 @@
1
+ AGENTS.md
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qqmusic-api-python
3
- Version: 0.5.3
3
+ Version: 0.6.1
4
4
  Summary: QQ音乐API封装库
5
5
  Project-URL: documentation, https://l-1124.github.io/QQMusicApi/
6
6
  Project-URL: homepage, https://l-1124.github.io/QQMusicApi/
@@ -29,13 +29,12 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
29
29
  Classifier: Typing :: Typed
30
30
  Requires-Python: >=3.10
31
31
  Requires-Dist: anyio>=4.12.1
32
- Requires-Dist: cryptography>=46.0.3
33
- Requires-Dist: httpx-retries>=0.4.6
34
- Requires-Dist: httpx[http2]>=0.27.0
32
+ Requires-Dist: cryptography>=47.0.0
35
33
  Requires-Dist: jsonpath-ng>=1.8.0
34
+ Requires-Dist: niquests[speedups]>=3.18.7
36
35
  Requires-Dist: orjson>=3.10.15
37
36
  Requires-Dist: paho-mqtt>=2.1.0
38
- Requires-Dist: pydantic>=2.0.0
37
+ Requires-Dist: pydantic>=2.13.3
39
38
  Requires-Dist: tarsio>=0.5.1
40
39
  Requires-Dist: typing-extensions>=4.12.2
41
40
  Description-Content-Type: text/markdown
@@ -2,9 +2,8 @@
2
2
 
3
3
  `qqmusic_api` 采用 `Client + ApiModule + Request` 的结构:
4
4
 
5
- * `Client` 负责网络发送、平台信息、凭证和批量调度。
5
+ * `Client` 负责网络发送、平台信息和凭证。
6
6
  * `ApiModule` 负责声明接口参数,并返回可 `await` 的 `Request`。
7
- * `RequestGroup` 用于批量执行多个 `Request`。
8
7
 
9
8
  ## 调用流程图
10
9
 
@@ -16,31 +15,28 @@
16
15
  -> Request
17
16
  -> await request
18
17
  -> Client.execute(request)
19
- -> 根据 request.is_jce 分发:
20
- -> Client.request_jce(...)
21
- -> 或 Client.request_musicu(...)
18
+ -> Client.request_api(...) (根据 request.is_jce 分发改用 JCE 或 JSON 协议)
22
19
  -> Client._build_result(...)
23
20
  -> 返回原始 dict / TarsDict 或 Pydantic 模型
24
21
  ```
25
22
 
26
- ### 批量请求
23
+ ### 批量并发请求
27
24
 
28
25
  ```text
29
26
  多个模块方法
30
- -> 多个 Request
31
- -> Client.request_group()
32
- -> RequestGroup.add(...) / extend(...)
33
- -> 按 is_jce / platform / comm / credential 分组
34
- -> batch_size 分批
35
- -> 并发发送批次
36
- -> 两种消费方式:
37
- -> execute_iter():
38
- 返回无序流式 RequestGroupResult
39
- 字段包括 index / success / data / error
40
- -> execute():
41
- 返回按添加顺序回填的 list[Any | Exception]
27
+ -> self._build_request(...)
28
+ -> Request 列表
29
+ -> Client.gather(requests)
30
+ -> 按协议、平台、公共参数和凭证分组
31
+ -> 每组按 batch_size 拆分为批量请求
32
+ -> 依次调用 Client.request_api(..., lazy=True) 生成响应任务
33
+ -> 使用客户端内部的 multiplexed AsyncSession 并发执行这些任务(self._session.gather)
34
+ -> 按 req_n 解析每个响应项
35
+ -> 按输入顺序返回结果
42
36
  ```
43
37
 
38
+ `gather` 的分组边界由 `Request._group_key` 决定。只有协议类型、显式平台、公共参数和凭证相同的请求才会合并到同一个批量请求中。
39
+
44
40
  ## 编写新的 API
45
41
 
46
42
  API 按功能拆分在 `qqmusic_api/modules/` 下,添加新的 API 只需在对应的模块中添加请求方法即可。
@@ -76,7 +72,7 @@ class SearchApi(ApiModule):
76
72
  Returns:
77
73
  dict[str, Any]: 搜索结果字典.
78
74
  """
79
- resp = await self._client.fetch(
75
+ resp = await self._client.request(
80
76
  "GET",
81
77
  "https://c.y.qq.com/splcloud/fcgi-bin/smartbox_new.fcg",
82
78
  params={"key": keyword},
@@ -344,38 +340,3 @@ class Client:
344
340
 
345
341
  return MyApi(self)
346
342
  ```
347
-
348
- ## 批量请求 `RequestGroup`
349
-
350
- 使用 `Client.request_group()` 可以批量提交请求。`RequestGroup` 会自动按 `platform`、`credential`、`comm` 和 `is_jce` 分组,并按 `batch_size` 分批发送。
351
-
352
- `execute()` 会返回与添加顺序一致的完整结果列表:
353
-
354
- ```python
355
- from qqmusic_api import Client
356
-
357
-
358
- async def batch_query(song_ids: list[int]):
359
- async with Client() as client:
360
- group = client.request_group()
361
- for song_id in song_ids:
362
- group.add(client.song.get_detail(song_id))
363
-
364
- return await group.execute()
365
- ```
366
-
367
- `execute_iter()` 会按完成顺序流式返回 [`RequestGroupResult`][core.request.RequestGroupResult],不保证与添加顺序一致:
368
-
369
- ```python
370
- from qqmusic_api import Client
371
-
372
-
373
- async def batch_query_stream(song_ids: list[int]):
374
- async with Client() as client:
375
- group = client.request_group(batch_size=1, max_inflight_batches=4)
376
- for song_id in song_ids:
377
- group.add(client.song.get_detail(song_id))
378
-
379
- async for result in group.execute_iter():
380
- print(result.index, result.module, result.method, result.success)
381
- ```
@@ -0,0 +1,3 @@
1
+ # Exception API
2
+
3
+ ::: qqmusic_api.core.exceptions
@@ -0,0 +1,3 @@
1
+ # PrivateMessageApi
2
+
3
+ ::: modules.private_message.PrivateMessageApi
@@ -1,4 +1,49 @@
1
1
 
2
+ ## [[0.6.0](https://github.com/L-1124/QQMusicApi/compare/v0.5.3..v0.6.0)] - 2026-05-09
3
+
4
+ ### Bug 修复
5
+
6
+ * **(login)** 修改手机验证码鉴权参数类型为字符串 ([5cfebc6](https://github.com/L-1124/QQMusicApi/commit/5cfebc67cc816e0ca1930f76386fc599215496af)) by [@L-1124](https://github.com/L-1124)
7
+
8
+ ### 功能更新
9
+
10
+ * **(client)** 添加连接重试机制参数 ([38134a7](https://github.com/L-1124/QQMusicApi/commit/38134a74cfe9d3b623c46d74136687d9a2731848)) by [@L-1124](https://github.com/L-1124)
11
+ * **(core)** [**breaking**] 移除 `RequestGroup`,支持 `Client.gather` 批量并发请求,重构请求速率限制参数 ([632b6a8](https://github.com/L-1124/QQMusicApi/commit/632b6a85fe509bbbab7bbe6e7ae702e34ef49440)) by [@L-1124](https://github.com/L-1124)
12
+ * **(web)** 添加 Docker 支持 ([b6f4dfc](https://github.com/L-1124/QQMusicApi/commit/b6f4dfc824c45cdba784904fd937495ab15065cc)) by [@L-1124](https://github.com/L-1124)
13
+ * **(web)** 添加 Web 服务路由 ([154d714](https://github.com/L-1124/QQMusicApi/commit/154d714f4bd918ab6b23814f841b154e5b388c94)) by [@L-1124](https://github.com/L-1124) in [#247](https://github.com/L-1124/QQMusicApi/pull/247)
14
+ * [**breaking**] 不再支持配置 `Client` 部分参数并且修改并且初始化参数名 ([c4a7001](https://github.com/L-1124/QQMusicApi/commit/c4a7001a007128eba76b89004504b58be60c6f84)) by [@L-1124](https://github.com/L-1124)
15
+
16
+ ### 功能重构
17
+
18
+ * **(algorithms)** [**breaking**] 移除 Web 端请求签名模块 ([21b3179](https://github.com/L-1124/QQMusicApi/commit/21b31794d89efebbf58505a4310dc95ecd9ba7f0)) by [@L-1124](https://github.com/L-1124)
19
+ * **(core)** 重构 API 客户端, 迁移 httpx → niquests ([fc4f1b7](https://github.com/L-1124/QQMusicApi/commit/fc4f1b77f2f001331f38a178a2a16e84279a4549)) by [@L-1124](https://github.com/L-1124)
20
+ * **(exception)** [**breaking**] 重构异常体系 ([3f7ef32](https://github.com/L-1124/QQMusicApi/commit/3f7ef3239f90cbcf3bf8ba64ab1561e89683df52)) by [@L-1124](https://github.com/L-1124)
21
+
22
+ ### 贡献者
23
+
24
+ * @L-1124
25
+ * @github-actions[bot]
26
+
27
+ ## [[0.5.3](https://github.com/L-1124/QQMusicApi/compare/v0.5.2..v0.5.3)] - 2026-05-01
28
+
29
+ ### Bug 修复
30
+
31
+ * **(song)** 传递歌曲链接请求凭证 ([8667e8c](https://github.com/L-1124/QQMusicApi/commit/8667e8c16a071d5b2e96e91e90441db724d71169)) by [@L-1124](https://github.com/L-1124)
32
+ * 模型字段类型出现`int | str` ([ed2e450](https://github.com/L-1124/QQMusicApi/commit/ed2e4503fab162ebdabae7368ffd408584f1e91a)) by [@L-1124](https://github.com/L-1124)
33
+ * 手机登录没有正常返回验证链接 ([3f69c5d](https://github.com/L-1124/QQMusicApi/commit/3f69c5d3f51353c73ab1c9f5a6637e29dc0aebe4)) by [@L-1124](https://github.com/L-1124)
34
+ * [**breaking**] 拼写错误及其他问题 ([6bd129e](https://github.com/L-1124/QQMusicApi/commit/6bd129eed7d9d8bd1b76fbd6389840ee295d6802)) by [@Copilot](https://github.com/Copilot) in [#242](https://github.com/L-1124/QQMusicApi/pull/242)
35
+
36
+ ### 功能更新
37
+
38
+ * **(api)** 统一分页参数,暴露搜索一致性参数 ([a3d3a5d](https://github.com/L-1124/QQMusicApi/commit/a3d3a5d36b0b1ee85628d4bafde17551ae76e5fe)) by [@L-1124](https://github.com/L-1124)
39
+ * **(login)** 细化登录异常体系并修正请求参数 ([fb9d2e6](https://github.com/L-1124/QQMusicApi/commit/fb9d2e6ed180b7188cc059b3a98ce67ec4760c0d)) by [@L-1124](https://github.com/L-1124) in [#245](https://github.com/L-1124/QQMusicApi/pull/245)
40
+
41
+ ### 贡献者
42
+
43
+ * @L-1124
44
+ * @Copilot [#242](https://github.com/L-1124/QQMusicApi/pull/242)
45
+ * @github-actions[bot]
46
+
2
47
  ## [[0.5.2](https://github.com/L-1124/QQMusicApi/compare/v0.5.1..v0.5.2)] - 2026-04-18
3
48
 
4
49
  ### Bug 修复
@@ -0,0 +1,96 @@
1
+ # Client
2
+
3
+ `Client` 用于统一管理连接、凭证、设备信息与请求配置,是调用 API 的入口。
4
+
5
+ ## 用法
6
+
7
+ ```python
8
+ import asyncio
9
+
10
+ from qqmusic_api import Client
11
+
12
+
13
+ async def main() -> None:
14
+ async with Client() as client:
15
+ result = await client.search.quick_search("周杰伦")
16
+ print(result)
17
+
18
+
19
+ asyncio.run(main())
20
+ ```
21
+
22
+ ## 批量并发请求
23
+
24
+ `Client.gather()` 可以一次执行多个 `Request`,并按传入顺序返回解析后的结果。适合同时请求多个互不依赖的 API。
25
+
26
+ ```python
27
+ import asyncio
28
+
29
+ from qqmusic_api import Client
30
+ from qqmusic_api.modules.search import SearchType
31
+
32
+
33
+ async def main() -> None:
34
+ async with Client() as client:
35
+ results = await client.gather(
36
+ [
37
+ client.search.search_by_type("周杰伦", SearchType.SONG, num=1),
38
+ client.search.search_by_type("林俊杰", SearchType.SONG, num=1),
39
+ ]
40
+ )
41
+ print(results[0].song)
42
+ print(results[1].song)
43
+
44
+
45
+ asyncio.run(main())
46
+ ```
47
+
48
+ `gather()` 的返回值顺序始终与传入的请求顺序一致。
49
+
50
+ 如果希望单个请求失败时不立即抛出异常,可以启用 `return_exceptions`:
51
+
52
+ ```python
53
+ results = await client.gather(
54
+ [
55
+ client.search.search_by_type("周杰伦", SearchType.SONG, num=1),
56
+ client.search.search_by_type("林俊杰", SearchType.SONG, num=1),
57
+ ],
58
+ return_exceptions=True,
59
+ )
60
+ ```
61
+
62
+ 此时失败项会以异常对象的形式出现在对应位置,成功项仍返回正常的响应模型。
63
+
64
+ ## 全局凭证
65
+
66
+ 如果你的场景需要登录,可以在初始化 `Client` 时直接注入 `Credential`:
67
+
68
+ ```python
69
+ from qqmusic_api import Client, Credential
70
+
71
+ credential = Credential(musicid=123456, musickey="Q_H_L_xxx")
72
+ client = Client(credential=credential)
73
+ ```
74
+
75
+ ## 请求平台
76
+
77
+ 默认的请求平台是 `android`,如果需要可以在初始化时覆盖:
78
+
79
+ !!! note
80
+
81
+ 部分 API 的请求平台是固定的,无法覆盖。
82
+
83
+ ```python
84
+ import asyncio
85
+
86
+ from qqmusic_api import Client, Platform
87
+
88
+
89
+ async def main():
90
+ async with Client(platform=Platform.DESKTOP) as client:
91
+ ...
92
+
93
+
94
+ asyncio.run(_main())
95
+
96
+ ```
@@ -0,0 +1,79 @@
1
+ # Web 服务
2
+
3
+ Web 服务将 QQMusicApi 暴露为 HTTP API。
4
+
5
+ ## 1. 安装
6
+
7
+ ```bash
8
+ git clone https://github.com/luren-dc/QQMusicApi
9
+ cd QQMusicApi
10
+ uv sync --group web
11
+ ```
12
+
13
+ 可使用环境变量或者编辑`web/config.toml` 来配置服务参数
14
+
15
+ ## 2. 启动服务
16
+
17
+ ```bash
18
+ uv run python web/run.py
19
+ ```
20
+
21
+ ## 3. 查看 API 文档
22
+
23
+ 打开 [http://localhost:8000/docs](http://localhost:8000/docs) 可以查看所有可用接口。
24
+
25
+ ## 4. 认证方式
26
+
27
+ 需要登录凭证的接口通过 **Cookie** 传递 QQ 音乐登录信息:
28
+
29
+ | Cookie 字段 | 说明 | 是否必须 |
30
+ | --- | --- | --- |
31
+ | `musicid` | QQ 音乐用户 ID | ✅ 必须 |
32
+ | `musickey` | QQ 音乐密钥 | ✅ 必须 |
33
+ | `openid` | QQ 音乐 OpenID | 可选 |
34
+ | `refresh_token` | Refresh Token | 可选 |
35
+ | `access_token` | Access Token | 可选 |
36
+ | `expired_at` | 登录态过期时间戳 | 可选 |
37
+ | `unionid` | UnionID | 可选 |
38
+ | `str_musicid` | 字符串形式的用户 ID | 可选 |
39
+ | `refresh_key` | Refresh Key | 可选 |
40
+
41
+ `musicid` 与 `musickey` 必须同时提供;如果未携带任何 Cookie,接口将以未登录状态调用。
42
+
43
+ ## 5. 响应格式
44
+
45
+ 所有接口均返回统一的 JSON 结构:
46
+
47
+ ```json
48
+ {
49
+ "code": 0,
50
+ "msg": "ok",
51
+ "data": { ... }
52
+ }
53
+ ```
54
+
55
+ | 字段 | 说明 |
56
+ | --- | --- |
57
+ | `code` | 状态码。成功为 `0`,失败为 `-1`。 |
58
+ | `msg` | 面向调用方的状态说明。 |
59
+ | `data` | 业务数据,失败时可能包含错误详情。 |
60
+
61
+ ## 6. 请求示例
62
+
63
+ ### 搜索歌曲
64
+
65
+ ```bash
66
+ curl "http://localhost:8000/search/search_by_type?keyword=周杰伦&search_type=song&num=5"
67
+ ```
68
+
69
+ ### 获取歌曲详情
70
+
71
+ ```bash
72
+ curl "http://localhost:8000/song/123456/detail"
73
+ ```
74
+
75
+ ### 获取歌词(需要歌曲 ID 或 MID)
76
+
77
+ ```bash
78
+ curl "http://localhost:8000/song/123456/lyric?trans=true"
79
+ ```
@@ -27,7 +27,7 @@ async def phone_login_example() -> None:
27
27
  print("验证码已发送")
28
28
 
29
29
  auth_code = (await asyncio.to_thread(input, "请输入验证码: ")).strip()
30
- credential = await session.authorize(int(auth_code))
30
+ credential = await session.authorize(auth_code)
31
31
  print(f"登录成功! MusicID: {credential.musicid}")
32
32
 
33
33
  except LoginError as e:
@@ -0,0 +1,74 @@
1
+ """私信只读接口示例."""
2
+
3
+ import asyncio
4
+
5
+ from qqmusic_api import Client, Credential
6
+ from qqmusic_api.models.private_message import PrivateMessageSession
7
+
8
+ MUSICID = 0
9
+ MUSICKEY = ""
10
+
11
+ credential = Credential(musicid=MUSICID, musickey=MUSICKEY)
12
+
13
+
14
+ def format_session_preview(index: int, session: PrivateMessageSession) -> str:
15
+ """格式化私信会话预览."""
16
+ user = session.user
17
+ latest_message = session.new_msg
18
+ metadata = latest_message.meta_data if latest_message else None
19
+ latest_text = metadata.content if metadata and metadata.content else latest_message.tips if latest_message else ""
20
+ return (
21
+ f"{index}. session_id={session.session_id}, "
22
+ f"uin={user.uin if user else ''}, "
23
+ f"nick={user.nick if user else ''}, "
24
+ f"unread={session.new_msg_cnt}, "
25
+ f"last={latest_text or '<无文本预览>'}"
26
+ )
27
+
28
+
29
+ async def main() -> None:
30
+ """运行私信只读接口示例."""
31
+ async with Client(credential) as client:
32
+ session_result = await client.private_message.get_sessions(size=10)
33
+ print(f"会话列表: has_more={session_result.has_more}, count={len(session_result.sessions)}")
34
+
35
+ if not session_result.sessions:
36
+ print("当前账号没有可展示的私信会话。")
37
+ return
38
+
39
+ print("可用会话:")
40
+ for index, session in enumerate(session_result.sessions, start=1):
41
+ print(format_session_preview(index, session))
42
+
43
+ first_session = session_result.sessions[0]
44
+ target_user = first_session.user
45
+ message_result = await client.private_message.get_messages(
46
+ session_id=first_session.session_id,
47
+ user_id=target_user.uin if target_user else "",
48
+ size=20,
49
+ )
50
+ print(f"首个会话消息: has_more={message_result.has_more}, count={len(message_result.messages)}")
51
+
52
+ entries_result = await client.private_message.get_chat_entries(
53
+ [1, 2],
54
+ from_user_type=0,
55
+ user_id=target_user.uin if target_user else None,
56
+ )
57
+ entry_count = sum(len(entries) for entries in entries_result.entries.values())
58
+ print(f"聊天入口: ret_code={entries_result.ret_code}, entry_count={entry_count}")
59
+
60
+ media_msg_ids = [
61
+ message.id for message in message_result.messages if message.id and message.msg_type in {2, 3, 5, 6}
62
+ ]
63
+ if not media_msg_ids:
64
+ print("当前会话没有可用于预览详情查询的图片或视频消息。")
65
+ return
66
+
67
+ detail_result = await client.private_message.get_media_message_details(
68
+ first_session.session_id,
69
+ media_msg_ids[:5],
70
+ )
71
+ print(f"媒体消息详情: count={len(detail_result.msg_ids)}")
72
+
73
+
74
+ asyncio.run(main())
@@ -23,7 +23,7 @@ def show_qrcode(qr: QR) -> None:
23
23
  async def qrcode_login_example(login_type: QRLoginType) -> None:
24
24
  """二维码登录示例."""
25
25
  try:
26
- async with Client(verify=False) as client:
26
+ async with Client() as client:
27
27
  print(f"正在获取 {login_type.name} 二维码...")
28
28
  session = QRCodeLoginSession(
29
29
  client.login,
@@ -33,13 +33,12 @@ classifiers = [
33
33
  ]
34
34
  dependencies = [
35
35
  "anyio>=4.12.1",
36
- "cryptography>=46.0.3",
37
- "httpx-retries>=0.4.6",
38
- "httpx[http2]>=0.27.0",
36
+ "cryptography>=47.0.0",
39
37
  "jsonpath-ng>=1.8.0",
38
+ "niquests[speedups]>=3.18.7",
40
39
  "orjson>=3.10.15",
41
40
  "paho-mqtt>=2.1.0",
42
- "pydantic>=2.0.0",
41
+ "pydantic>=2.13.3",
43
42
  "tarsio>=0.5.1",
44
43
  "typing-extensions>=4.12.2",
45
44
  ]
@@ -72,9 +71,16 @@ linting = [
72
71
  "ruff>=0.15.6",
73
72
  ]
74
73
  testing = [
75
- "pytest>=9.0.2",
76
- "pytest-asyncio>=1.3.0",
77
- "pytest-sugar>=1.1.1",
74
+ "pytest>=9.0.2",
75
+ "pytest-asyncio>=1.3.0",
76
+ "pytest-sugar>=1.1.1",
77
+ ]
78
+ web = [
79
+ "fastapi>=0.136.1",
80
+ "griffe>=2.0.2",
81
+ "pydantic-settings[toml]>=2.14.0",
82
+ "loguru>=0.7.3",
83
+ "uvicorn>=0.46.0",
78
84
  ]
79
85
 
80
86
  [build-system]
@@ -93,6 +99,10 @@ path = "qqmusic_api/__init__.py"
93
99
  [tool.pyrefly]
94
100
  python-version = "3.10"
95
101
 
102
+ [tool.pyright]
103
+ venv = ".venv"
104
+ typeCheckingMode = "basic"
105
+
96
106
  [tool.pytest]
97
107
  addopts = ["-rxXs"]
98
108
  pythonpath = ["."]
@@ -103,9 +113,6 @@ asyncio_mode = "auto"
103
113
  line-length = 120
104
114
  extend-exclude = ["docs"]
105
115
 
106
- [tool.pyright]
107
- typeCheckingMode = "basic"
108
-
109
116
  [tool.ruff.lint]
110
117
  extend-select = [
111
118
  "A",
@@ -132,15 +139,7 @@ extend-select = [
132
139
  "TRY",
133
140
  "UP",
134
141
  ]
135
- ignore = [
136
- "TRY003",
137
- "BLE001",
138
- "TRY300",
139
- "TRY301",
140
- "TID252",
141
- "C901",
142
- "COM81"
143
- ]
142
+ ignore = ["TRY003", "BLE001", "TRY300", "TRY301", "TID252", "C901", "COM81"]
144
143
  extend-per-file-ignores = { "qqmusic_api/core/exceptions.py" = ["D107"] }
145
144
  pydocstyle = { convention = "google" }
146
145
 
@@ -0,0 +1,40 @@
1
+ """QQMusic API 公开入口."""
2
+
3
+ from .core.client import Client
4
+ from .core.exceptions import (
5
+ ApiDataError,
6
+ ApiException,
7
+ BaseApiException,
8
+ CgiApiException,
9
+ CredentialExpiredError,
10
+ CredentialInvalidError,
11
+ CredentialRefreshError,
12
+ GlobalApiError,
13
+ HTTPError,
14
+ LoginError,
15
+ NetworkError,
16
+ RatelimitedError,
17
+ )
18
+ from .core.versioning import Platform
19
+ from .models.request import Credential
20
+
21
+ __version__ = "0.6.1"
22
+
23
+ __all__ = [
24
+ "ApiDataError",
25
+ "ApiException",
26
+ "BaseApiException",
27
+ "CgiApiException",
28
+ "Client",
29
+ "Credential",
30
+ "CredentialExpiredError",
31
+ "CredentialInvalidError",
32
+ "CredentialRefreshError",
33
+ "GlobalApiError",
34
+ "HTTPError",
35
+ "LoginError",
36
+ "NetworkError",
37
+ "Platform",
38
+ "RatelimitedError",
39
+ "__version__",
40
+ ]
@@ -2,7 +2,6 @@
2
2
 
3
3
  import zlib
4
4
 
5
- from .sign import sign_request
6
5
  from .tripledes import DECRYPT, tripledes_crypt, tripledes_key_setup
7
6
 
8
7
  _QRC_3DES_KEY = b"!@#)(*$%123ZXC!@!@#)(NHL"
@@ -44,5 +43,4 @@ def qrc_decrypt(encrypted_qrc: str | bytearray | bytes) -> str:
44
43
 
45
44
  __all__ = [
46
45
  "qrc_decrypt",
47
- "sign_request",
48
46
  ]
@@ -0,0 +1,40 @@
1
+ """core 模块."""
2
+
3
+ from .client import Client
4
+ from .exceptions import (
5
+ ApiDataError,
6
+ ApiException,
7
+ BaseApiException,
8
+ CgiApiException,
9
+ CredentialExpiredError,
10
+ CredentialInvalidError,
11
+ CredentialRefreshError,
12
+ GlobalApiError,
13
+ HTTPError,
14
+ LoginError,
15
+ NetworkError,
16
+ RatelimitedError,
17
+ )
18
+ from .request import Request
19
+ from .versioning import DEFAULT_VERSION_POLICY, Platform, VersionPolicy, VersionProfile
20
+
21
+ __all__ = [
22
+ "DEFAULT_VERSION_POLICY",
23
+ "ApiDataError",
24
+ "ApiException",
25
+ "BaseApiException",
26
+ "CgiApiException",
27
+ "Client",
28
+ "CredentialExpiredError",
29
+ "CredentialInvalidError",
30
+ "CredentialRefreshError",
31
+ "GlobalApiError",
32
+ "HTTPError",
33
+ "LoginError",
34
+ "NetworkError",
35
+ "Platform",
36
+ "RatelimitedError",
37
+ "Request",
38
+ "VersionPolicy",
39
+ "VersionProfile",
40
+ ]