maxapi-python 2.1.3__tar.gz → 2.3.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 (249) hide show
  1. maxapi_python-2.3.0/.github/workflows/tests.yml +66 -0
  2. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/PKG-INFO +3 -11
  3. maxapi_python-2.3.0/docs/api/client-client.rst +18 -0
  4. maxapi_python-2.3.0/docs/api/client-config.rst +14 -0
  5. maxapi_python-2.3.0/docs/api/client-web.rst +17 -0
  6. maxapi_python-2.3.0/docs/api/client.rst +25 -0
  7. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/api/router.rst +6 -0
  8. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/auth.rst +53 -1
  9. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/chats.rst +16 -0
  10. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/client.rst +97 -5
  11. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/index.rst +2 -0
  12. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/messages.rst +61 -1
  13. maxapi_python-2.3.0/docs/release-2-2-0.rst +57 -0
  14. maxapi_python-2.3.0/docs/release-2-3-0.rst +40 -0
  15. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/router.rst +60 -1
  16. maxapi_python-2.3.0/docs/types/contact_info.rst +6 -0
  17. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/index.rst +8 -0
  18. maxapi_python-2.3.0/docs/types/message_read_event.rst +6 -0
  19. maxapi_python-2.3.0/docs/types/presence_event.rst +6 -0
  20. maxapi_python-2.3.0/docs/types/reaction_update_event.rst +6 -0
  21. maxapi_python-2.3.0/docs/types/typing_event.rst +6 -0
  22. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/users.rst +19 -0
  23. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/pyproject.toml +10 -19
  24. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/__init__.py +18 -3
  25. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/auth/payloads.py +7 -0
  26. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/auth/service.py +33 -30
  27. maxapi_python-2.3.0/src/pymax/api/binding.py +57 -0
  28. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/chats/payloads.py +6 -0
  29. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/chats/service.py +52 -47
  30. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/messages/enums.py +1 -0
  31. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/messages/payloads.py +16 -1
  32. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/messages/service.py +78 -34
  33. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/models.py +4 -6
  34. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/response.py +2 -2
  35. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/self/service.py +17 -26
  36. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/session/payloads.py +2 -9
  37. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/session/service.py +1 -3
  38. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/uploads/payloads.py +3 -9
  39. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/uploads/service.py +33 -99
  40. maxapi_python-2.3.0/src/pymax/api/users/payloads.py +38 -0
  41. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/users/service.py +22 -17
  42. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/app.py +28 -6
  43. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/auth/qr.py +3 -9
  44. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/auth/sms.py +23 -11
  45. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/base.py +86 -4
  46. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/client.py +2 -1
  47. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/client_web.py +1 -2
  48. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/config.py +42 -3
  49. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/connection/connection.py +2 -0
  50. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/connection/readers/tcp.py +1 -3
  51. maxapi_python-2.3.0/src/pymax/dispatch/__init__.py +21 -0
  52. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/dispatch/dispatcher.py +170 -34
  53. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/dispatch/enums.py +5 -0
  54. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/dispatch/mapping.py +34 -11
  55. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/dispatch/resolvers.py +18 -0
  56. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/dispatch/router.py +120 -4
  57. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/formatting/markdown.py +22 -13
  58. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/infra/chat.py +33 -0
  59. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/infra/message.py +69 -2
  60. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/infra/user.py +12 -1
  61. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/logging.py +2 -0
  62. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/tcp/compression.py +1 -3
  63. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/tcp/framing.py +1 -3
  64. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/ws/protocol.py +3 -9
  65. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/session/protocol.py +2 -6
  66. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/session/store.py +19 -24
  67. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/telemetry/navigation.py +1 -3
  68. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/telemetry/service.py +5 -17
  69. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/transport/tcp.py +1 -3
  70. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/__init__.py +1 -1
  71. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/unknown.py +1 -3
  72. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/auth.py +24 -2
  73. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/chat.py +58 -1
  74. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/message.py +28 -2
  75. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/presence.py +3 -3
  76. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/sync.py +5 -21
  77. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/user.py +8 -0
  78. maxapi_python-2.3.0/src/pymax/types/events/__init__.py +7 -0
  79. maxapi_python-2.3.0/src/pymax/types/events/mark.py +23 -0
  80. maxapi_python-2.3.0/src/pymax/types/events/message.py +89 -0
  81. maxapi_python-2.3.0/src/pymax/types/events/presence.py +15 -0
  82. maxapi_python-2.3.0/src/pymax/types/events/reaction.py +21 -0
  83. maxapi_python-2.3.0/src/pymax/types/events/typing.py +14 -0
  84. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/api/test_auth_service.py +60 -13
  85. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/api/test_chat_user_self_session_services.py +118 -59
  86. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/api/test_message_service.py +169 -9
  87. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/api/test_upload_service.py +10 -31
  88. maxapi_python-2.3.0/tests/app/test_app_runtime.py +445 -0
  89. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/auth/test_auth_flows.py +73 -6
  90. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/conftest.py +7 -21
  91. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/connection/test_connection.py +9 -27
  92. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/connection/test_readers_and_transports.py +3 -9
  93. maxapi_python-2.3.0/tests/dispatch/test_dispatcher.py +328 -0
  94. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/domain/test_bound_models.py +64 -19
  95. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/files/test_files_and_formatting.py +1 -3
  96. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/protocol/test_protocols.py +1 -3
  97. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/session/test_store.py +20 -0
  98. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/uv.lock +1 -51
  99. maxapi_python-2.1.3/docs/api/client.rst +0 -17
  100. maxapi_python-2.1.3/src/pymax/api/users/payloads.py +0 -16
  101. maxapi_python-2.1.3/src/pymax/dispatch/__init__.py +0 -10
  102. maxapi_python-2.1.3/src/pymax/types/events/__init__.py +0 -3
  103. maxapi_python-2.1.3/src/pymax/types/events/message.py +0 -37
  104. maxapi_python-2.1.3/tests/app/test_app_runtime.py +0 -215
  105. maxapi_python-2.1.3/tests/dispatch/test_dispatcher.py +0 -102
  106. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  107. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  108. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/.github/ISSUE_TEMPLATE/refactor.md +0 -0
  109. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/.github/pull_request_template.md +0 -0
  110. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/.github/workflows/publish.yml +0 -0
  111. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/.gitignore +0 -0
  112. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/.pre-commit-config.yaml +0 -0
  113. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/LICENSE +0 -0
  114. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/README.md +0 -0
  115. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/_static/.gitkeep +0 -0
  116. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/account.rst +0 -0
  117. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/api/auth.rst +0 -0
  118. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/api/files.rst +0 -0
  119. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/conf.py +0 -0
  120. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/examples.rst +0 -0
  121. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/faq.rst +0 -0
  122. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/files.rst +0 -0
  123. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/formatting.rst +0 -0
  124. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/getting-started.rst +0 -0
  125. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/release-2-1-0.rst +0 -0
  126. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/release-2-1-1.rst +0 -0
  127. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/release-2-1-2.rst +0 -0
  128. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/release-2-1-3.rst +0 -0
  129. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/troubleshooting.rst +0 -0
  130. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/audio_attachment.rst +0 -0
  131. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/call_attachment.rst +0 -0
  132. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/chat.rst +0 -0
  133. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/contact_attachment.rst +0 -0
  134. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/control_attachment.rst +0 -0
  135. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/element.rst +0 -0
  136. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/enums.rst +0 -0
  137. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/file_attachment.rst +0 -0
  138. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/folder.rst +0 -0
  139. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/folder_list.rst +0 -0
  140. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/folder_update.rst +0 -0
  141. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/inline_keyboard_attachment.rst +0 -0
  142. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/message.rst +0 -0
  143. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/message_delete_event.rst +0 -0
  144. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/name.rst +0 -0
  145. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/photo_attachment.rst +0 -0
  146. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/profile.rst +0 -0
  147. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/reaction_counter.rst +0 -0
  148. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/reaction_info.rst +0 -0
  149. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/read_state.rst +0 -0
  150. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/session.rst +0 -0
  151. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/share_attachment.rst +0 -0
  152. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/sticker_attachment.rst +0 -0
  153. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/sync_overrides.rst +0 -0
  154. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/sync_state.rst +0 -0
  155. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/user.rst +0 -0
  156. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/video_attachment.rst +0 -0
  157. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/__init__.py +0 -0
  158. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/auth/__init__.py +0 -0
  159. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/auth/enums.py +0 -0
  160. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/auth/types.py +0 -0
  161. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/bots/__init__.py +0 -0
  162. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/bots/payloads.py +0 -0
  163. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/bots/service.py +0 -0
  164. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/chats/__init__.py +0 -0
  165. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/chats/enums.py +0 -0
  166. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/facade.py +0 -0
  167. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/messages/__init__.py +0 -0
  168. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/self/__init__.py +0 -0
  169. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/self/enums.py +0 -0
  170. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/self/payloads.py +0 -0
  171. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/session/__init__.py +0 -0
  172. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/session/enums.py +0 -0
  173. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/uploads/__init__.py +0 -0
  174. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/uploads/models.py +0 -0
  175. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/users/__init__.py +0 -0
  176. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/users/enums.py +0 -0
  177. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/auth/__init__.py +0 -0
  178. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/auth/base.py +0 -0
  179. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/auth/email.py +0 -0
  180. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/auth/models.py +0 -0
  181. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/auth/providers.py +0 -0
  182. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/auth/service.py +0 -0
  183. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/connection/__init__.py +0 -0
  184. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/connection/pending.py +0 -0
  185. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/connection/readers/__init__.py +0 -0
  186. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/connection/readers/base.py +0 -0
  187. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/connection/readers/ws.py +0 -0
  188. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/exceptions.py +0 -0
  189. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/files/__init__.py +0 -0
  190. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/files/base.py +0 -0
  191. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/files/file.py +0 -0
  192. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/files/photo.py +0 -0
  193. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/files/static.py +0 -0
  194. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/files/video.py +0 -0
  195. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/formatting/__init__.py +0 -0
  196. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/infra/__init__.py +0 -0
  197. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/infra/auth.py +0 -0
  198. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/infra/base.py +0 -0
  199. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/infra/bots.py +0 -0
  200. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/infra/protocol.py +0 -0
  201. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/infra/self.py +0 -0
  202. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/__init__.py +0 -0
  203. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/base.py +0 -0
  204. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/enums.py +0 -0
  205. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/models.py +0 -0
  206. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/tcp/__init__.py +0 -0
  207. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/tcp/payload.py +0 -0
  208. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/tcp/protocol.py +0 -0
  209. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/ws/__init__.py +0 -0
  210. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/py.typed +0 -0
  211. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/routers.py +0 -0
  212. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/session/__init__.py +0 -0
  213. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/session/models.py +0 -0
  214. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/telemetry/__init__.py +0 -0
  215. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/telemetry/payloads.py +0 -0
  216. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/transport/__init__.py +0 -0
  217. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/transport/base.py +0 -0
  218. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/transport/websocket.py +0 -0
  219. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/__init__.py +0 -0
  220. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/__init__.py +0 -0
  221. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/audio.py +0 -0
  222. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/call.py +0 -0
  223. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/contact.py +0 -0
  224. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/control.py +0 -0
  225. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/enums.py +0 -0
  226. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/file.py +0 -0
  227. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/keyboards/__init__.py +0 -0
  228. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/keyboards/inline.py +0 -0
  229. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/photo.py +0 -0
  230. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/share.py +0 -0
  231. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/sticker.py +0 -0
  232. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/video.py +0 -0
  233. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/base.py +0 -0
  234. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/bots.py +0 -0
  235. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/element.py +0 -0
  236. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/enums.py +0 -0
  237. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/error.py +0 -0
  238. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/folder.py +0 -0
  239. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/login.py +0 -0
  240. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/member.py +0 -0
  241. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/name.py +0 -0
  242. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/profile.py +0 -0
  243. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/session.py +0 -0
  244. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/events/file.py +0 -0
  245. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/events/video.py +0 -0
  246. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/__init__.py +0 -0
  247. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/domain/test_message_models.py +0 -0
  248. {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/telemetry/test_telemetry.py +0 -0
  249. {maxapi_python-2.1.3 → maxapi_python-2.3.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.3.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
@@ -5,6 +5,12 @@ Router API
5
5
  :members:
6
6
  :show-inheritance:
7
7
 
8
+ .. autoclass:: pymax.dispatch.ErrorScope
9
+ :members:
10
+
11
+ .. autoclass:: pymax.dispatch.ErrorContext
12
+ :members:
13
+
8
14
  .. autodata:: pymax.ClientRouter
9
15
 
10
16
  .. autodata:: pymax.WebRouter
@@ -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
 
@@ -142,6 +142,22 @@ login/sync, а также методы для загрузки, создания
142
142
  ``leave()`` зависит от типа чата: для группы вызывает выход из группы, для
143
143
  канала - выход из канала. Из личного диалога выйти нельзя.
144
144
 
145
+ Удалить чат
146
+ -----------
147
+
148
+ .. code-block:: python
149
+
150
+ await client.delete_chat(chat_id=123456)
151
+
152
+ Через объект ``Chat`` PyMax использует ``chat.last_event_time``:
153
+
154
+ .. code-block:: python
155
+
156
+ chat = await client.get_chat(123456)
157
+ await chat.delete(for_all=True)
158
+
159
+ После успешного удаления чат убирается из локального кеша ``client.chats``.
160
+
145
161
  Invite-ссылки
146
162
  -------------
147
163
 
@@ -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
 
@@ -162,6 +231,21 @@ PyMax потеряет token и попросит авторизацию снов
162
231
  сессии можно удалить файл ``work_dir/session_name``; тогда потребуется новая
163
232
  авторизация.
164
233
 
234
+ Повторная авторизация
235
+ ---------------------
236
+
237
+ Если нужно сбросить текущую локальную сессию и пройти авторизацию заново,
238
+ используйте ``relogin()``:
239
+
240
+ .. code-block:: python
241
+
242
+ await client.relogin()
243
+
244
+ ``relogin()`` удаляет загруженную сессию из store, закрывает текущий runtime и
245
+ по умолчанию сразу запускает клиента снова. Если token был передан через
246
+ ``ExtraConfig(token=...)``, он тоже сбрасывается; это можно отключить через
247
+ ``drop_config_token=False``.
248
+
165
249
  Reconnect
166
250
  ---------
167
251
 
@@ -173,6 +257,14 @@ Reconnect
173
257
  а новый ``App`` снова получает тот же root router. ``on_start`` вызывается
174
258
  после каждого успешного reconnect.
175
259
 
260
+ Перед повторным подключением можно зарегистрировать ``on_disconnect``:
261
+
262
+ .. code-block:: python
263
+
264
+ @client.on_disconnect()
265
+ async def disconnected(exc: Exception, reconnect: bool, delay: float) -> None:
266
+ print("connection lost:", exc, reconnect, delay)
267
+
176
268
  Отключить reconnect:
177
269
 
178
270
  .. code-block:: python
@@ -214,19 +306,19 @@ Debug-логи показывают handshake, login, входящие собы
214
306
 
215
307
  Чаты
216
308
  ``get_chat()``, ``fetch_chats()``, создание групп, invite-ссылки,
217
- участники, настройки групп и выход из групп/каналов.
309
+ участники, настройки групп, удаление чатов и выход из групп/каналов.
218
310
 
219
311
  Пользователи
220
312
  ``get_user()``, ``get_users()``, ``fetch_users()``, ``search_by_phone()``,
221
- ``add_contact()``, ``remove_contact()`` и ``get_chat_id()``. Подробнее:
222
- :doc:`users`.
313
+ ``add_contact()``, ``remove_contact()``, ``import_contacts()`` и
314
+ ``get_chat_id()``. Подробнее: :doc:`users`.
223
315
 
224
316
  Аккаунт
225
317
  ``change_profile()``, папки чатов, активные сессии, ``logout()`` и
226
318
  ``close_all_sessions()``. Подробнее: :doc:`account`.
227
319
 
228
320
  Auth
229
- ``set_2fa()`` и ``remove_2fa()`` для управления паролем 2FA. Подробнее:
321
+ ``set_2fa()``, ``remove_2fa()`` и ``authorize_qr_login()``. Подробнее:
230
322
  :doc:`auth`.
231
323
 
232
324
  Частые ошибки
@@ -22,6 +22,8 @@ PyMax - асинхронная Python-библиотека для Max API. Он
22
22
  :maxdepth: 1
23
23
  :caption: Новости
24
24
 
25
+ release-2-3-0
26
+ release-2-2-0
25
27
  release-2-1-3
26
28
  release-2-1-2
27
29
  release-2-1-1
@@ -30,7 +30,28 @@ 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, ...)``.
54
+ Новые вложения передаются через ``attachments``.
34
55
 
35
56
  Отправлять сообщения
36
57
  --------------------
@@ -69,6 +90,45 @@ Messages
69
90
  elif message.text == "/delete":
70
91
  await message.delete(for_me=False)
71
92
 
93
+ .. note::
94
+
95
+ У низкоуровневого ``client.read_message(...)`` есть особенность Max:
96
+ для отметки прочтения TCP-клиент ожидает ``message_id`` как ``int``, а
97
+ WebSocket-клиент - как ``str``. Если вызываете метод напрямую, выбирайте
98
+ тип по клиенту.
99
+
100
+ Служебные события
101
+ -----------------
102
+
103
+ Начиная с ``2.2.0`` доступны отдельные обработчики набора текста, присутствия,
104
+ прочтения и реакций:
105
+
106
+ .. code-block:: python
107
+
108
+ from pymax import (
109
+ Client,
110
+ MessageReadEvent,
111
+ PresenceEvent,
112
+ ReactionUpdateEvent,
113
+ TypingEvent,
114
+ )
115
+
116
+ @client.on_typing()
117
+ async def typing(event: TypingEvent, client: Client) -> None:
118
+ print(event.chat_id, event.user_id)
119
+
120
+ @client.on_presence()
121
+ async def presence(event: PresenceEvent, client: Client) -> None:
122
+ print(event.user_id, event.presence.status)
123
+
124
+ @client.on_message_read()
125
+ async def read(event: MessageReadEvent, client: Client) -> None:
126
+ print(event.chat_id, event.mark)
127
+
128
+ @client.on_reaction_update()
129
+ async def reactions(event: ReactionUpdateEvent, client: Client) -> None:
130
+ print(event.message_id, event.total_count)
131
+
72
132
  История сообщений
73
133
  -----------------
74
134
 
@@ -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
+ существующих аккаунтов настройка не нужна.
@@ -0,0 +1,40 @@
1
+ PyMax 2.3.0
2
+ ===========
3
+
4
+ Изменения относительно ``2.2.0``.
5
+
6
+ Добавлено
7
+ ---------
8
+
9
+ * Несколько ``on_start``-обработчиков на одном клиенте или роутере. Все
10
+ зарегистрированные callbacks запускаются после успешного login.
11
+ * ``on_error()`` для централизованной обработки ошибок из handler-ов,
12
+ фильтров, ``on_start`` и login на этапе запуска.
13
+ * ``ErrorScope.GLOBAL`` и ``ErrorScope.LOCAL`` для выбора области действия
14
+ error-handler-а.
15
+ * ``on_disconnect()`` для реакции на сетевое отключение перед reconnect. В
16
+ callback передаются исходная ошибка, флаг reconnect и задержка.
17
+ * ``relogin()`` для удаления текущей локальной сессии и повторной авторизации.
18
+ * ``delete_chat()`` на клиенте и ``Chat.delete()`` на bound-объекте чата.
19
+ * ``import_contacts()`` и ``ContactInfo`` для импорта контактов из телефонной
20
+ книги.
21
+ * ``SessionStore.delete_all_sessions()`` для очистки встроенного SQLite-store.
22
+
23
+ Изменилось
24
+ ----------
25
+
26
+ * ``edit_message()`` и ``Message.edit()`` принимают новые вложения только через
27
+ ``attachments=[...]``.
28
+ * Тип ``attachments`` для отправки и редактирования сообщений теперь принимает
29
+ любую ``Sequence`` из ``Photo``, ``File`` и ``Video``.
30
+ * Обработанные login-ошибки на этапе ``start`` больше не приводят к запуску
31
+ ``on_start``.
32
+
33
+ Миграция
34
+ --------
35
+
36
+ * В ``edit_message()`` и ``Message.edit()`` используйте ``attachments=[...]``.
37
+ Параметр ``attachment`` удален.
38
+ * Если error-handler зарегистрирован и успешно отработал, исходная ошибка
39
+ считается обработанной. Если сам error-handler падает, исходная ошибка
40
+ продолжает распространяться.