maxapi-python 2.1.3__tar.gz → 2.2.0__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 (244) hide show
  1. maxapi_python-2.2.0/.github/workflows/tests.yml +66 -0
  2. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/PKG-INFO +3 -11
  3. maxapi_python-2.2.0/docs/api/client-client.rst +18 -0
  4. maxapi_python-2.2.0/docs/api/client-config.rst +14 -0
  5. maxapi_python-2.2.0/docs/api/client-web.rst +17 -0
  6. maxapi_python-2.2.0/docs/api/client.rst +25 -0
  7. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/auth.rst +53 -1
  8. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/client.rst +71 -2
  9. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/index.rst +1 -0
  10. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/messages.rst +60 -1
  11. maxapi_python-2.2.0/docs/release-2-2-0.rst +57 -0
  12. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/router.rst +12 -0
  13. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/index.rst +4 -0
  14. maxapi_python-2.2.0/docs/types/message_read_event.rst +6 -0
  15. maxapi_python-2.2.0/docs/types/presence_event.rst +6 -0
  16. maxapi_python-2.2.0/docs/types/reaction_update_event.rst +6 -0
  17. maxapi_python-2.2.0/docs/types/typing_event.rst +6 -0
  18. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/pyproject.toml +10 -19
  19. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/__init__.py +18 -3
  20. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/auth/payloads.py +7 -0
  21. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/auth/service.py +33 -30
  22. maxapi_python-2.2.0/src/pymax/api/binding.py +57 -0
  23. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/chats/service.py +34 -47
  24. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/messages/enums.py +1 -0
  25. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/messages/payloads.py +16 -1
  26. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/messages/service.py +85 -33
  27. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/models.py +4 -6
  28. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/response.py +2 -2
  29. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/self/service.py +17 -26
  30. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/session/payloads.py +2 -9
  31. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/session/service.py +1 -3
  32. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/uploads/payloads.py +3 -9
  33. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/uploads/service.py +33 -99
  34. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/users/service.py +8 -16
  35. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/app.py +2 -0
  36. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/auth/qr.py +3 -9
  37. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/auth/sms.py +23 -11
  38. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/base.py +38 -1
  39. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/client.py +2 -1
  40. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/client_web.py +1 -2
  41. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/config.py +42 -3
  42. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/connection/connection.py +2 -0
  43. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/connection/readers/tcp.py +1 -3
  44. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/dispatch/dispatcher.py +36 -18
  45. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/dispatch/enums.py +4 -0
  46. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/dispatch/mapping.py +34 -11
  47. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/dispatch/resolvers.py +18 -0
  48. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/dispatch/router.py +34 -0
  49. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/formatting/markdown.py +22 -13
  50. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/infra/chat.py +12 -0
  51. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/infra/message.py +74 -3
  52. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/logging.py +2 -0
  53. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/protocol/tcp/compression.py +1 -3
  54. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/protocol/tcp/framing.py +1 -3
  55. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/protocol/ws/protocol.py +3 -9
  56. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/session/protocol.py +2 -6
  57. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/session/store.py +8 -24
  58. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/telemetry/navigation.py +1 -3
  59. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/telemetry/service.py +5 -17
  60. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/transport/tcp.py +1 -3
  61. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/unknown.py +1 -3
  62. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/auth.py +24 -2
  63. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/chat.py +38 -1
  64. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/message.py +31 -1
  65. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/presence.py +3 -3
  66. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/sync.py +5 -21
  67. maxapi_python-2.2.0/src/pymax/types/events/__init__.py +7 -0
  68. maxapi_python-2.2.0/src/pymax/types/events/mark.py +23 -0
  69. maxapi_python-2.2.0/src/pymax/types/events/message.py +89 -0
  70. maxapi_python-2.2.0/src/pymax/types/events/presence.py +15 -0
  71. maxapi_python-2.2.0/src/pymax/types/events/reaction.py +21 -0
  72. maxapi_python-2.2.0/src/pymax/types/events/typing.py +14 -0
  73. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/tests/api/test_auth_service.py +60 -13
  74. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/tests/api/test_chat_user_self_session_services.py +46 -59
  75. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/tests/api/test_message_service.py +171 -9
  76. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/tests/api/test_upload_service.py +10 -31
  77. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/tests/app/test_app_runtime.py +5 -15
  78. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/tests/auth/test_auth_flows.py +73 -6
  79. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/tests/conftest.py +7 -21
  80. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/tests/connection/test_connection.py +9 -27
  81. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/tests/connection/test_readers_and_transports.py +3 -9
  82. maxapi_python-2.2.0/tests/dispatch/test_dispatcher.py +328 -0
  83. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/tests/domain/test_bound_models.py +49 -19
  84. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/tests/files/test_files_and_formatting.py +1 -3
  85. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/tests/protocol/test_protocols.py +1 -3
  86. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/uv.lock +1 -51
  87. maxapi_python-2.1.3/docs/api/client.rst +0 -17
  88. maxapi_python-2.1.3/src/pymax/types/events/__init__.py +0 -3
  89. maxapi_python-2.1.3/src/pymax/types/events/message.py +0 -37
  90. maxapi_python-2.1.3/tests/dispatch/test_dispatcher.py +0 -102
  91. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  92. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  93. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/.github/ISSUE_TEMPLATE/refactor.md +0 -0
  94. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/.github/pull_request_template.md +0 -0
  95. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/.github/workflows/publish.yml +0 -0
  96. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/.gitignore +0 -0
  97. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/.pre-commit-config.yaml +0 -0
  98. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/LICENSE +0 -0
  99. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/README.md +0 -0
  100. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/_static/.gitkeep +0 -0
  101. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/account.rst +0 -0
  102. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/api/auth.rst +0 -0
  103. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/api/files.rst +0 -0
  104. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/api/router.rst +0 -0
  105. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/chats.rst +0 -0
  106. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/conf.py +0 -0
  107. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/examples.rst +0 -0
  108. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/faq.rst +0 -0
  109. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/files.rst +0 -0
  110. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/formatting.rst +0 -0
  111. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/getting-started.rst +0 -0
  112. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/release-2-1-0.rst +0 -0
  113. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/release-2-1-1.rst +0 -0
  114. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/release-2-1-2.rst +0 -0
  115. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/release-2-1-3.rst +0 -0
  116. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/troubleshooting.rst +0 -0
  117. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/audio_attachment.rst +0 -0
  118. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/call_attachment.rst +0 -0
  119. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/chat.rst +0 -0
  120. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/contact_attachment.rst +0 -0
  121. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/control_attachment.rst +0 -0
  122. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/element.rst +0 -0
  123. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/enums.rst +0 -0
  124. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/file_attachment.rst +0 -0
  125. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/folder.rst +0 -0
  126. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/folder_list.rst +0 -0
  127. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/folder_update.rst +0 -0
  128. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/inline_keyboard_attachment.rst +0 -0
  129. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/message.rst +0 -0
  130. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/message_delete_event.rst +0 -0
  131. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/name.rst +0 -0
  132. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/photo_attachment.rst +0 -0
  133. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/profile.rst +0 -0
  134. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/reaction_counter.rst +0 -0
  135. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/reaction_info.rst +0 -0
  136. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/read_state.rst +0 -0
  137. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/session.rst +0 -0
  138. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/share_attachment.rst +0 -0
  139. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/sticker_attachment.rst +0 -0
  140. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/sync_overrides.rst +0 -0
  141. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/sync_state.rst +0 -0
  142. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/user.rst +0 -0
  143. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/types/video_attachment.rst +0 -0
  144. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/docs/users.rst +0 -0
  145. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/__init__.py +0 -0
  146. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/auth/__init__.py +0 -0
  147. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/auth/enums.py +0 -0
  148. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/auth/types.py +0 -0
  149. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/bots/__init__.py +0 -0
  150. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/bots/payloads.py +0 -0
  151. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/bots/service.py +0 -0
  152. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/chats/__init__.py +0 -0
  153. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/chats/enums.py +0 -0
  154. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/chats/payloads.py +0 -0
  155. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/facade.py +0 -0
  156. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/messages/__init__.py +0 -0
  157. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/self/__init__.py +0 -0
  158. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/self/enums.py +0 -0
  159. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/self/payloads.py +0 -0
  160. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/session/__init__.py +0 -0
  161. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/session/enums.py +0 -0
  162. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/uploads/__init__.py +0 -0
  163. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/uploads/models.py +0 -0
  164. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/users/__init__.py +0 -0
  165. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/users/enums.py +0 -0
  166. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/api/users/payloads.py +0 -0
  167. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/auth/__init__.py +0 -0
  168. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/auth/base.py +0 -0
  169. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/auth/email.py +0 -0
  170. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/auth/models.py +0 -0
  171. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/auth/providers.py +0 -0
  172. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/auth/service.py +0 -0
  173. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/connection/__init__.py +0 -0
  174. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/connection/pending.py +0 -0
  175. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/connection/readers/__init__.py +0 -0
  176. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/connection/readers/base.py +0 -0
  177. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/connection/readers/ws.py +0 -0
  178. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/dispatch/__init__.py +0 -0
  179. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/exceptions.py +0 -0
  180. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/files/__init__.py +0 -0
  181. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/files/base.py +0 -0
  182. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/files/file.py +0 -0
  183. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/files/photo.py +0 -0
  184. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/files/static.py +0 -0
  185. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/files/video.py +0 -0
  186. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/formatting/__init__.py +0 -0
  187. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/infra/__init__.py +0 -0
  188. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/infra/auth.py +0 -0
  189. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/infra/base.py +0 -0
  190. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/infra/bots.py +0 -0
  191. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/infra/protocol.py +0 -0
  192. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/infra/self.py +0 -0
  193. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/infra/user.py +0 -0
  194. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/protocol/__init__.py +0 -0
  195. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/protocol/base.py +0 -0
  196. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/protocol/enums.py +0 -0
  197. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/protocol/models.py +0 -0
  198. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/protocol/tcp/__init__.py +0 -0
  199. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/protocol/tcp/payload.py +0 -0
  200. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/protocol/tcp/protocol.py +0 -0
  201. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/protocol/ws/__init__.py +0 -0
  202. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/py.typed +0 -0
  203. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/routers.py +0 -0
  204. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/session/__init__.py +0 -0
  205. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/session/models.py +0 -0
  206. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/telemetry/__init__.py +0 -0
  207. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/telemetry/payloads.py +0 -0
  208. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/transport/__init__.py +0 -0
  209. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/transport/base.py +0 -0
  210. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/transport/websocket.py +0 -0
  211. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/__init__.py +0 -0
  212. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/__init__.py +0 -0
  213. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/__init__.py +0 -0
  214. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/audio.py +0 -0
  215. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/call.py +0 -0
  216. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/contact.py +0 -0
  217. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/control.py +0 -0
  218. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/enums.py +0 -0
  219. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/file.py +0 -0
  220. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/keyboards/__init__.py +0 -0
  221. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/keyboards/inline.py +0 -0
  222. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/photo.py +0 -0
  223. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/share.py +0 -0
  224. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/sticker.py +0 -0
  225. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/video.py +0 -0
  226. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/base.py +0 -0
  227. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/bots.py +0 -0
  228. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/element.py +0 -0
  229. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/enums.py +0 -0
  230. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/error.py +0 -0
  231. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/folder.py +0 -0
  232. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/login.py +0 -0
  233. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/member.py +0 -0
  234. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/name.py +0 -0
  235. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/profile.py +0 -0
  236. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/session.py +0 -0
  237. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/domain/user.py +0 -0
  238. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/events/file.py +0 -0
  239. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/src/pymax/types/events/video.py +0 -0
  240. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/tests/__init__.py +0 -0
  241. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/tests/domain/test_message_models.py +0 -0
  242. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/tests/session/test_store.py +0 -0
  243. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/tests/telemetry/test_telemetry.py +0 -0
  244. {maxapi_python-2.1.3 → maxapi_python-2.2.0}/tests/test_logging.py +0 -0
@@ -0,0 +1,66 @@
1
+ name: Tests
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [main, "dev/**"]
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ concurrency:
13
+ group: checks-${{ github.workflow }}-${{ github.ref }}
14
+ cancel-in-progress: true
15
+
16
+ jobs:
17
+ lint:
18
+ name: Lint
19
+ runs-on: ubuntu-latest
20
+
21
+ steps:
22
+ - name: Checkout repository
23
+ uses: actions/checkout@v6
24
+
25
+ - name: Install uv
26
+ uses: astral-sh/setup-uv@v8.1.0
27
+ with:
28
+ enable-cache: true
29
+
30
+ - name: Install development dependencies
31
+ run: uv sync --group dev
32
+
33
+ - name: Check code formatting
34
+ run: uv run ruff format --check .
35
+
36
+ - name: Run Ruff linting
37
+ run: uv run ruff check .
38
+
39
+ tests:
40
+ name: Tests / Python ${{ matrix.python-version }}
41
+ runs-on: ubuntu-latest
42
+
43
+ strategy:
44
+ fail-fast: false
45
+ matrix:
46
+ python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
47
+
48
+ steps:
49
+ - name: Checkout repository
50
+ uses: actions/checkout@v6
51
+
52
+ - name: Install uv
53
+ uses: astral-sh/setup-uv@v8.1.0
54
+ with:
55
+ python-version: ${{ matrix.python-version }}
56
+ enable-cache: true
57
+
58
+ - name: Install development dependencies
59
+ run: uv sync --group dev
60
+
61
+ - name: Run tests with coverage
62
+ run: |
63
+ uv run pytest \
64
+ --cov=src/pymax \
65
+ --cov-report=term-missing:skip-covered \
66
+ --cov-report=markdown-append:$GITHUB_STEP_SUMMARY
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maxapi-python
3
- Version: 2.1.3
3
+ Version: 2.2.0
4
4
  Summary: Python wrapper для API мессенджера Max
5
5
  Project-URL: Homepage, https://github.com/MaxApiTeam/PyMax
6
6
  Project-URL: Repository, https://github.com/MaxApiTeam/PyMax
7
7
  Project-URL: Issues, https://github.com/MaxApiTeam/PyMax/issues
8
- Project-URL: Documentation, https://maxapiteam.github.io/PyMax/
8
+ Project-URL: Documentation, https://docs.pymax.org
9
9
  Author-email: ink <inkdev@proton.me>
10
10
  License-Expression: MIT
11
11
  License-File: LICENSE
@@ -20,6 +20,7 @@ Classifier: Programming Language :: Python :: 3.10
20
20
  Classifier: Programming Language :: Python :: 3.11
21
21
  Classifier: Programming Language :: Python :: 3.12
22
22
  Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Programming Language :: Python :: 3.14
23
24
  Classifier: Typing :: Typed
24
25
  Requires-Python: >=3.10
25
26
  Requires-Dist: aiofiles>=25.1.0
@@ -30,15 +31,6 @@ Requires-Dist: pydantic>=2.10.0
30
31
  Requires-Dist: python-socks[asyncio]>=2.8.1
31
32
  Requires-Dist: qrcode>=8.2
32
33
  Requires-Dist: websockets>=16.0
33
- Provides-Extra: docs
34
- Requires-Dist: furo>=2025.12.19; extra == 'docs'
35
- Requires-Dist: sphinx-copybutton>=0.5.2; extra == 'docs'
36
- Requires-Dist: sphinx>=8.1.3; extra == 'docs'
37
- Provides-Extra: test
38
- Requires-Dist: pytest-asyncio>=0.24.0; extra == 'test'
39
- Requires-Dist: pytest-cov>=5.0.0; extra == 'test'
40
- Requires-Dist: pytest-timeout>=2.1.0; extra == 'test'
41
- Requires-Dist: pytest>=8.0.0; extra == 'test'
42
34
  Description-Content-Type: text/markdown
43
35
 
44
36
  # PyMax
@@ -0,0 +1,18 @@
1
+ Client
2
+ ======
3
+
4
+ .. currentmodule:: pymax
5
+
6
+ TCP-клиент с SMS-авторизацией. Это основной клиент для long-running
7
+ подключения, обработчиков событий и mobile API Max.
8
+
9
+ .. note::
10
+
11
+ ``Client`` поддерживает ``ExtraConfig.device_type`` со значениями
12
+ ``ANDROID``, ``IOS`` и ``DESKTOP``. Для :meth:`Client.authorize_qr_login`
13
+ используйте ``ANDROID`` или ``IOS``: с ``DESKTOP`` подтверждение QR-входа
14
+ не работает.
15
+
16
+ .. autoclass:: Client
17
+ :members:
18
+ :inherited-members:
@@ -0,0 +1,14 @@
1
+ Client Config
2
+ =============
3
+
4
+ .. currentmodule:: pymax
5
+
6
+ Настройки, которые используются ``Client`` и ``WebClient``.
7
+
8
+ .. autoclass:: ExtraConfig
9
+ :members:
10
+
11
+ .. autoclass:: RegistrationConfig
12
+ :members:
13
+
14
+ .. autofunction:: configure_logging
@@ -0,0 +1,17 @@
1
+ WebClient
2
+ =========
3
+
4
+ .. currentmodule:: pymax
5
+
6
+ WebSocket-клиент с QR-авторизацией. Он подходит, когда нужно подключаться как
7
+ web-клиент Max.
8
+
9
+ .. note::
10
+
11
+ В штатной конфигурации ``WebClient`` использует только ``DeviceType.WEB``.
12
+ Параметр ``ExtraConfig.device_type`` предназначен для ``Client`` и не
13
+ меняет тип устройства ``WebClient``.
14
+
15
+ .. autoclass:: WebClient
16
+ :members:
17
+ :inherited-members:
@@ -0,0 +1,25 @@
1
+ Clients API
2
+ ===========
3
+
4
+ .. currentmodule:: pymax
5
+
6
+ ``Client`` и ``WebClient`` используют общий набор высокоуровневых методов,
7
+ но отличаются транспортом и способом авторизации:
8
+
9
+ ``Client``
10
+ TCP-клиент с SMS-авторизацией. Поддерживает mobile ``device_type``:
11
+ ``ANDROID``, ``IOS`` и ``DESKTOP``. Для подтверждения QR-входа через
12
+ :meth:`Client.authorize_qr_login` используйте ``ANDROID`` или ``IOS``:
13
+ с ``DESKTOP`` этот метод не работает.
14
+
15
+ ``WebClient``
16
+ WebSocket-клиент с QR-авторизацией. В штатной конфигурации всегда
17
+ использует ``DeviceType.WEB``; ``ExtraConfig.device_type`` на него не
18
+ влияет.
19
+
20
+ .. toctree::
21
+ :maxdepth: 1
22
+
23
+ client-client
24
+ client-web
25
+ client-config
@@ -91,7 +91,7 @@ Provider нужен, когда код приходит не из консоли
91
91
  Кастомный QR handler
92
92
  --------------------
93
93
 
94
- ``QrHandler`` не должен подтверждать QR сам. Его задача - показать ссылку
94
+ Обычно ``QrHandler`` не подтверждает QR сам. Его задача - показать ссылку
95
95
  пользователю: вывести в терминал, отправить в web UI или положить в лог.
96
96
 
97
97
  .. code-block:: python
@@ -110,6 +110,33 @@ Provider нужен, когда код приходит не из консоли
110
110
  qr_provider=PrintQrUrl(),
111
111
  )
112
112
 
113
+ Если у вас уже есть запущенный и авторизованный ``Client``, QR-ссылку можно
114
+ подтвердить программно через ``authorize_qr_login()``. Это удобно, когда
115
+ ``WebClient`` получает QR, а основной mobile-клиент должен разрешить вход:
116
+
117
+ .. code-block:: python
118
+
119
+ from pymax import Client, WebClient
120
+
121
+
122
+ class ConfirmQrWithClient:
123
+ def __init__(self, client: Client) -> None:
124
+ self.client = client
125
+
126
+ async def show_qr(self, qr_url: str) -> None:
127
+ await self.client.authorize_qr_login(qr_url)
128
+
129
+
130
+ mobile_client = Client(phone="+79990000000", work_dir="cache")
131
+ # mobile_client должен уже пройти start/login в вашей программе.
132
+ web_client = WebClient(qr_provider=ConfirmQrWithClient(mobile_client))
133
+
134
+ ``mobile_client`` должен быть уже авторизован к моменту вызова
135
+ ``show_qr()``. Для такого подтверждения используйте ``Client`` с
136
+ ``device_type`` ``ANDROID`` или ``IOS``; при ``DESKTOP`` метод
137
+ ``authorize_qr_login()`` не работает. ``WebClient`` в штатной конфигурации
138
+ всегда использует ``WEB``.
139
+
113
140
  Полный кастомный AuthFlow
114
141
  -------------------------
115
142
 
@@ -146,6 +173,31 @@ Flow должен иметь async-метод ``authenticate(app)`` и верн
146
173
  Если вам нужно только передать готовый token, проще использовать
147
174
  ``ExtraConfig(token="TOKEN")``. Тогда custom flow не нужен.
148
175
 
176
+ Регистрация нового аккаунта
177
+ ---------------------------
178
+
179
+ Если номер ещё не зарегистрирован в Max, после SMS-кода сервер возвращает
180
+ токен регистрации. Чтобы стандартный ``SmsAuthFlow`` завершил создание
181
+ аккаунта, передайте имя через ``RegistrationConfig``:
182
+
183
+ .. code-block:: python
184
+
185
+ from pymax import Client, ExtraConfig, RegistrationConfig
186
+
187
+ client = Client(
188
+ phone="+79990000000",
189
+ extra_config=ExtraConfig(
190
+ registration_config=RegistrationConfig(
191
+ first_name="Max",
192
+ last_name="User",
193
+ )
194
+ ),
195
+ )
196
+
197
+ Для уже существующего аккаунта эта настройка не используется. Если Max
198
+ вернул токен регистрации, а ``registration_config`` не задан, авторизация
199
+ завершится с ``RuntimeError``.
200
+
149
201
  Управление 2FA
150
202
  --------------
151
203
 
@@ -16,9 +16,11 @@ Client
16
16
 
17
17
  ``Client``
18
18
  TCP-клиент с авторизацией по телефону и SMS-коду. Это основной вариант.
19
+ Поддерживает ``device_type`` ``ANDROID``, ``IOS`` и ``DESKTOP``.
19
20
 
20
21
  ``WebClient``
21
- WebSocket-клиент с QR-авторизацией.
22
+ WebSocket-клиент с QR-авторизацией. В штатной конфигурации работает как
23
+ ``WEB``-устройство.
22
24
 
23
25
  Жизненный цикл
24
26
  --------------
@@ -85,6 +87,32 @@ Client
85
87
  ``extra_config``
86
88
  Настройки соединения, логов, reconnect, token, device/user-agent и sync.
87
89
 
90
+ Тип устройства
91
+ ---------------
92
+
93
+ ``Client`` по умолчанию использует ``DeviceType.ANDROID``. Если нужно
94
+ поменять тип устройства, передайте ``device_type`` через ``ExtraConfig``:
95
+
96
+ .. code-block:: python
97
+
98
+ from pymax import Client, ExtraConfig
99
+ from pymax.api.session.enums import DeviceType
100
+
101
+ client = Client(
102
+ phone="+79990000000",
103
+ work_dir="cache",
104
+ extra_config=ExtraConfig(device_type=DeviceType.IOS),
105
+ )
106
+
107
+ Для ``Client`` доступны ``ANDROID``, ``IOS`` и ``DESKTOP``. Практический
108
+ нюанс: ``authorize_qr_login()`` подтверждает QR-вход только из mobile-режима,
109
+ поэтому для него используйте ``ANDROID`` или ``IOS``. С ``DESKTOP`` этот метод
110
+ не работает.
111
+
112
+ ``WebClient`` сам использует ``DeviceType.WEB``. Параметр
113
+ ``ExtraConfig.device_type`` относится к ``Client`` и не меняет тип устройства
114
+ ``WebClient``.
115
+
88
116
  Авторизация
89
117
  -----------
90
118
 
@@ -119,6 +147,47 @@ Client
119
147
  extra_config=ExtraConfig(token="TOKEN"),
120
148
  )
121
149
 
150
+ Подтверждение QR-входа
151
+ ----------------------
152
+
153
+ ``Client`` может подтверждать QR-вход по ссылке через
154
+ ``authorize_qr_login()``. Это полезно, когда QR-ссылку показал другой клиент
155
+ или ваш UI получил ее от ``WebClient``:
156
+
157
+ .. code-block:: python
158
+
159
+ async def confirm_qr(client: Client, qr_link: str) -> None:
160
+ ok = await client.authorize_qr_login(qr_link)
161
+ print("QR подтвержден:", ok)
162
+
163
+ ``Client`` для такого подтверждения должен быть уже авторизован. Также
164
+ проверьте ``device_type``: используйте ``ANDROID`` или ``IOS``, не
165
+ ``DESKTOP``.
166
+
167
+ Если QR создает ``WebClient``, ссылку можно перехватить в своем
168
+ ``QrHandler`` и подтвердить ее уже запущенным ``Client``:
169
+
170
+ .. code-block:: python
171
+
172
+ from pymax import Client, WebClient
173
+
174
+
175
+ class ConfirmQrWithClient:
176
+ def __init__(self, client: Client) -> None:
177
+ self.client = client
178
+
179
+ async def show_qr(self, qr_url: str) -> None:
180
+ await self.client.authorize_qr_login(qr_url)
181
+
182
+
183
+ mobile_client = Client(phone="+79990000000", work_dir="cache")
184
+ # mobile_client должен уже пройти start/login в вашей программе.
185
+ web_client = WebClient(
186
+ work_dir="cache",
187
+ session_name="web.db",
188
+ qr_provider=ConfirmQrWithClient(mobile_client),
189
+ )
190
+
122
191
  Сессия и sync-state
123
192
  -------------------
124
193
 
@@ -226,7 +295,7 @@ Debug-логи показывают handshake, login, входящие собы
226
295
  ``close_all_sessions()``. Подробнее: :doc:`account`.
227
296
 
228
297
  Auth
229
- ``set_2fa()`` и ``remove_2fa()`` для управления паролем 2FA. Подробнее:
298
+ ``set_2fa()``, ``remove_2fa()`` и ``authorize_qr_login()``. Подробнее:
230
299
  :doc:`auth`.
231
300
 
232
301
  Частые ошибки
@@ -22,6 +22,7 @@ PyMax - асинхронная Python-библиотека для Max API. Он
22
22
  :maxdepth: 1
23
23
  :caption: Новости
24
24
 
25
+ release-2-2-0
25
26
  release-2-1-3
26
27
  release-2-1-2
27
28
  release-2-1-1
@@ -30,7 +30,27 @@ Messages
30
30
 
31
31
  @client.on_message_delete()
32
32
  async def on_delete(event: MessageDeleteEvent, client: Client) -> None:
33
- print("deleted in chat:", event.chat.id)
33
+ print("deleted in chat:", event.chat_id)
34
+
35
+ Получать и редактировать сообщения
36
+ ----------------------------------
37
+
38
+ .. code-block:: python
39
+
40
+ message = await client.get_message(
41
+ chat_id=123456,
42
+ message_id=987654,
43
+ )
44
+ messages = await client.get_messages(
45
+ chat_id=123456,
46
+ message_ids=[987654, 987655],
47
+ )
48
+
49
+ if message is not None:
50
+ await message.edit("Обновленный текст")
51
+
52
+ Через клиент то же редактирование доступно как
53
+ ``client.edit_message(chat_id, message_id, text, ...)``.
34
54
 
35
55
  Отправлять сообщения
36
56
  --------------------
@@ -69,6 +89,45 @@ Messages
69
89
  elif message.text == "/delete":
70
90
  await message.delete(for_me=False)
71
91
 
92
+ .. note::
93
+
94
+ У низкоуровневого ``client.read_message(...)`` есть особенность Max:
95
+ для отметки прочтения TCP-клиент ожидает ``message_id`` как ``int``, а
96
+ WebSocket-клиент - как ``str``. Если вызываете метод напрямую, выбирайте
97
+ тип по клиенту.
98
+
99
+ Служебные события
100
+ -----------------
101
+
102
+ В ``2.2.0`` доступны отдельные обработчики набора текста, присутствия,
103
+ прочтения и реакций:
104
+
105
+ .. code-block:: python
106
+
107
+ from pymax import (
108
+ Client,
109
+ MessageReadEvent,
110
+ PresenceEvent,
111
+ ReactionUpdateEvent,
112
+ TypingEvent,
113
+ )
114
+
115
+ @client.on_typing()
116
+ async def typing(event: TypingEvent, client: Client) -> None:
117
+ print(event.chat_id, event.user_id)
118
+
119
+ @client.on_presence()
120
+ async def presence(event: PresenceEvent, client: Client) -> None:
121
+ print(event.user_id, event.presence.status)
122
+
123
+ @client.on_message_read()
124
+ async def read(event: MessageReadEvent, client: Client) -> None:
125
+ print(event.chat_id, event.mark)
126
+
127
+ @client.on_reaction_update()
128
+ async def reactions(event: ReactionUpdateEvent, client: Client) -> None:
129
+ print(event.message_id, event.total_count)
130
+
72
131
  История сообщений
73
132
  -----------------
74
133
 
@@ -0,0 +1,57 @@
1
+ PyMax 2.2.0
2
+ ===========
3
+
4
+ Изменения относительно ``2.1.3``.
5
+
6
+ Добавлено
7
+ ---------
8
+
9
+ * Получение сообщений по ID через ``get_message()`` и ``get_messages()``.
10
+ Те же операции доступны на bound-объекте ``Chat``.
11
+ * Редактирование сообщений через ``edit_message()`` и ``Message.edit()`` с
12
+ поддержкой markdown, фото, видео и файлов.
13
+ * События ``TypingEvent``, ``PresenceEvent``, ``MessageReadEvent`` и
14
+ ``ReactionUpdateEvent`` с обработчиками ``on_typing()``, ``on_presence()``,
15
+ ``on_message_read()`` и ``on_reaction_update()``.
16
+ * ``join_channel()`` для вступления в канал по полной ссылке или join-токену.
17
+ * Автоматическое завершение SMS-регистрации нового аккаунта через
18
+ ``RegistrationConfig`` в ``ExtraConfig.registration_config``.
19
+ * Поддержка Python 3.14 в метаданных пакета и CI-матрице.
20
+
21
+ Исправлено
22
+ ----------
23
+
24
+ * Позиции markdown-элементов теперь корректно считаются в UTF-16 для emoji и
25
+ других символов вне BMP.
26
+ * Удаление сообщения в ``WebClient`` распознается из события
27
+ ``NOTIF_MESSAGE`` со статусом ``REMOVED``.
28
+ * ``MessageDeleteEvent`` принимает обе формы payload-а Max и не требует поле
29
+ ``ttl``.
30
+ * ``PresenceEvent`` принимает частичные обновления, в которых Max присылает
31
+ ``seen`` без ``status``.
32
+ * ``read_message()`` сохраняет тип ``message_id``: ``int`` для ``Client`` и
33
+ ``str`` для ``WebClient``.
34
+ * Вложенные ``Message``, ``Chat`` и ``User`` из API-ответов и событий
35
+ привязываются к сервисам клиента, поэтому их bound-методы работают
36
+ последовательно.
37
+
38
+ Изменилось
39
+ ----------
40
+
41
+ * ``MessageDeleteEvent`` всегда содержит ``chat_id``. Поля ``chat`` и
42
+ ``message`` зависят от формы события и могут быть ``None``.
43
+ * Проверка типов ``pyright`` ограничена релизным пакетом ``src`` и снова
44
+ проходит без ошибок.
45
+ * Документация клиента разделена на отдельные API-страницы для ``Client``,
46
+ ``WebClient`` и конфигурации.
47
+
48
+ Миграция
49
+ --------
50
+
51
+ * В обработчике удаления используйте ``event.chat_id`` вместо
52
+ ``event.chat.id``: ``event.chat`` может отсутствовать в ``WebClient``.
53
+ * При прямом вызове ``read_message()`` передавайте ``int`` в ``Client`` и
54
+ ``str`` в ``WebClient``.
55
+ * Для регистрации нового номера задайте
56
+ ``ExtraConfig(registration_config=RegistrationConfig(...))``. Для уже
57
+ существующих аккаунтов настройка не нужна.
@@ -175,6 +175,18 @@ Raw events
175
175
  async def raw(frame: InboundFrame, client: Client) -> None:
176
176
  print(frame.opcode, frame.payload)
177
177
 
178
+ Другие события
179
+ --------------
180
+
181
+ Кроме новых и измененных сообщений, доступны специализированные декораторы:
182
+
183
+ * ``on_message_delete()`` и ``on_message_read()``;
184
+ * ``on_typing()`` и ``on_presence()``;
185
+ * ``on_reaction_update()`` и ``on_chat_update()``.
186
+
187
+ Все они поддерживают те же sync/async-фильтры и сигнатуру
188
+ ``handler(event, client)``.
189
+
178
190
  Частые ошибки
179
191
  -------------
180
192
 
@@ -85,6 +85,10 @@ API reference
85
85
  chat
86
86
  message
87
87
  message_delete_event
88
+ message_read_event
89
+ typing_event
90
+ presence_event
91
+ reaction_update_event
88
92
  reaction_counter
89
93
  reaction_info
90
94
  read_state
@@ -0,0 +1,6 @@
1
+ MessageReadEvent
2
+ ================
3
+
4
+ .. autoclass:: pymax.types.events.mark.MessageReadEvent
5
+ :members:
6
+ :show-inheritance:
@@ -0,0 +1,6 @@
1
+ PresenceEvent
2
+ =============
3
+
4
+ .. autoclass:: pymax.types.events.presence.PresenceEvent
5
+ :members:
6
+ :show-inheritance:
@@ -0,0 +1,6 @@
1
+ ReactionUpdateEvent
2
+ ===================
3
+
4
+ .. autoclass:: pymax.types.events.reaction.ReactionUpdateEvent
5
+ :members:
6
+ :show-inheritance:
@@ -0,0 +1,6 @@
1
+ TypingEvent
2
+ ===========
3
+
4
+ .. autoclass:: pymax.types.events.typing.TypingEvent
5
+ :members:
6
+ :show-inheritance:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "maxapi-python"
3
- version = "2.1.3"
3
+ version = "2.2.0"
4
4
  description = "Python wrapper для API мессенджера Max"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -20,6 +20,7 @@ classifiers = [
20
20
  "Programming Language :: Python :: 3.11",
21
21
  "Programming Language :: Python :: 3.12",
22
22
  "Programming Language :: Python :: 3.13",
23
+ "Programming Language :: Python :: 3.14",
23
24
  ]
24
25
  dependencies = [
25
26
  "aiofiles>=25.1.0",
@@ -36,20 +37,8 @@ dependencies = [
36
37
  Homepage = "https://github.com/MaxApiTeam/PyMax"
37
38
  Repository = "https://github.com/MaxApiTeam/PyMax"
38
39
  Issues = "https://github.com/MaxApiTeam/PyMax/issues"
39
- Documentation = "https://maxapiteam.github.io/PyMax/"
40
+ Documentation = "https://docs.pymax.org"
40
41
 
41
- [project.optional-dependencies]
42
- docs = [
43
- "furo>=2025.12.19",
44
- "sphinx>=8.1.3",
45
- "sphinx-copybutton>=0.5.2",
46
- ]
47
- test = [
48
- "pytest>=8.0.0",
49
- "pytest-asyncio>=0.24.0",
50
- "pytest-cov>=5.0.0",
51
- "pytest-timeout>=2.1.0",
52
- ]
53
42
 
54
43
  [build-system]
55
44
  requires = ["hatchling"]
@@ -88,28 +77,30 @@ test = [
88
77
  dev = [
89
78
  {include-group = "docs"},
90
79
  {include-group = "test"},
91
- "build>=1.2.0",
92
80
  "pre-commit>=4.0.0",
93
81
  "twine>=5.0.0",
94
82
  "pyright>=1.1.390",
95
83
  "ruff>=0.8.0",
96
84
  ]
97
85
 
86
+ [tool.uv]
87
+ package = true
88
+
98
89
  [tool.pyright]
90
+ include = ["src"]
99
91
  venv = ".venv"
100
92
  venvPath = "."
101
93
 
102
94
  [tool.ruff]
103
- line-length = 79
104
- target-version = "py310"
95
+ line-length = 99
105
96
 
106
97
  [tool.ruff.lint]
107
98
  select = ["E", "F", "I"]
108
- ignore = ["E501"]
99
+ ignore = []
109
100
 
110
101
  [tool.ruff.lint.per-file-ignores]
111
- "src/pymax/**/__init__.py" = ["F401", "F403"]
112
102
  "tests/**" = ["F401"]
103
+ "**/__init__.py" = ["F401", "F403"]
113
104
 
114
105
  [tool.ruff.format]
115
106
  quote-style = "double"