maxapi-python 2.1.2__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.2 → 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.2 → maxapi_python-2.2.0}/docs/auth.rst +53 -1
  8. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/client.rst +71 -2
  9. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/conf.py +14 -5
  10. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/index.rst +2 -0
  11. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/messages.rst +60 -1
  12. maxapi_python-2.2.0/docs/release-2-1-3.rst +48 -0
  13. maxapi_python-2.2.0/docs/release-2-2-0.rst +57 -0
  14. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/router.rst +12 -0
  15. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/index.rst +4 -0
  16. maxapi_python-2.2.0/docs/types/message_read_event.rst +6 -0
  17. maxapi_python-2.2.0/docs/types/presence_event.rst +6 -0
  18. maxapi_python-2.2.0/docs/types/reaction_update_event.rst +6 -0
  19. maxapi_python-2.2.0/docs/types/typing_event.rst +6 -0
  20. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/pyproject.toml +10 -19
  21. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/__init__.py +18 -3
  22. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/auth/payloads.py +7 -0
  23. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/auth/service.py +33 -30
  24. maxapi_python-2.2.0/src/pymax/api/binding.py +57 -0
  25. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/chats/service.py +34 -47
  26. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/messages/enums.py +1 -0
  27. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/messages/payloads.py +16 -1
  28. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/messages/service.py +85 -33
  29. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/models.py +4 -6
  30. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/response.py +2 -2
  31. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/self/service.py +17 -26
  32. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/session/payloads.py +2 -9
  33. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/session/service.py +1 -3
  34. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/uploads/payloads.py +3 -9
  35. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/uploads/service.py +33 -99
  36. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/users/service.py +8 -16
  37. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/app.py +20 -4
  38. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/auth/qr.py +3 -9
  39. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/auth/sms.py +23 -11
  40. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/base.py +38 -1
  41. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/client.py +3 -5
  42. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/client_web.py +1 -2
  43. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/config.py +42 -3
  44. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/connection/connection.py +48 -19
  45. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/connection/readers/tcp.py +1 -3
  46. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/dispatch/dispatcher.py +36 -18
  47. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/dispatch/enums.py +4 -0
  48. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/dispatch/mapping.py +34 -11
  49. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/dispatch/resolvers.py +18 -0
  50. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/dispatch/router.py +34 -0
  51. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/files/photo.py +4 -2
  52. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/formatting/markdown.py +22 -13
  53. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/infra/chat.py +12 -0
  54. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/infra/message.py +74 -3
  55. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/logging.py +35 -3
  56. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/protocol/tcp/compression.py +1 -3
  57. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/protocol/tcp/framing.py +1 -3
  58. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/protocol/tcp/payload.py +22 -42
  59. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/protocol/tcp/protocol.py +2 -8
  60. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/protocol/ws/protocol.py +3 -9
  61. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/session/protocol.py +2 -6
  62. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/session/store.py +8 -24
  63. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/telemetry/navigation.py +1 -3
  64. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/telemetry/service.py +5 -17
  65. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/transport/tcp.py +1 -3
  66. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/__init__.py +1 -0
  67. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/audio.py +4 -4
  68. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/enums.py +1 -0
  69. maxapi_python-2.2.0/src/pymax/types/domain/attachments/unknown.py +35 -0
  70. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/video.py +2 -2
  71. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/auth.py +24 -2
  72. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/chat.py +38 -1
  73. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/element.py +3 -3
  74. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/message.py +34 -2
  75. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/presence.py +3 -3
  76. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/sync.py +5 -21
  77. maxapi_python-2.2.0/src/pymax/types/events/__init__.py +7 -0
  78. maxapi_python-2.2.0/src/pymax/types/events/mark.py +23 -0
  79. maxapi_python-2.2.0/src/pymax/types/events/message.py +89 -0
  80. maxapi_python-2.2.0/src/pymax/types/events/presence.py +15 -0
  81. maxapi_python-2.2.0/src/pymax/types/events/reaction.py +21 -0
  82. maxapi_python-2.2.0/src/pymax/types/events/typing.py +14 -0
  83. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/tests/api/test_auth_service.py +60 -13
  84. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/tests/api/test_chat_user_self_session_services.py +46 -59
  85. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/tests/api/test_message_service.py +171 -9
  86. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/tests/api/test_upload_service.py +10 -31
  87. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/tests/app/test_app_runtime.py +47 -12
  88. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/tests/auth/test_auth_flows.py +73 -6
  89. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/tests/conftest.py +7 -21
  90. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/tests/connection/test_connection.py +48 -16
  91. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/tests/connection/test_readers_and_transports.py +3 -9
  92. maxapi_python-2.2.0/tests/dispatch/test_dispatcher.py +328 -0
  93. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/tests/domain/test_bound_models.py +49 -19
  94. maxapi_python-2.2.0/tests/domain/test_message_models.py +105 -0
  95. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/tests/files/test_files_and_formatting.py +7 -3
  96. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/tests/protocol/test_protocols.py +1 -3
  97. maxapi_python-2.2.0/tests/test_logging.py +169 -0
  98. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/uv.lock +1 -51
  99. maxapi_python-2.1.2/docs/api/client.rst +0 -17
  100. maxapi_python-2.1.2/src/pymax/types/events/__init__.py +0 -3
  101. maxapi_python-2.1.2/src/pymax/types/events/message.py +0 -37
  102. maxapi_python-2.1.2/tests/dispatch/test_dispatcher.py +0 -102
  103. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  104. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  105. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/.github/ISSUE_TEMPLATE/refactor.md +0 -0
  106. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/.github/pull_request_template.md +0 -0
  107. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/.github/workflows/publish.yml +0 -0
  108. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/.gitignore +0 -0
  109. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/.pre-commit-config.yaml +0 -0
  110. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/LICENSE +0 -0
  111. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/README.md +0 -0
  112. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/_static/.gitkeep +0 -0
  113. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/account.rst +0 -0
  114. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/api/auth.rst +0 -0
  115. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/api/files.rst +0 -0
  116. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/api/router.rst +0 -0
  117. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/chats.rst +0 -0
  118. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/examples.rst +0 -0
  119. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/faq.rst +0 -0
  120. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/files.rst +0 -0
  121. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/formatting.rst +0 -0
  122. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/getting-started.rst +0 -0
  123. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/release-2-1-0.rst +0 -0
  124. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/release-2-1-1.rst +0 -0
  125. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/release-2-1-2.rst +0 -0
  126. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/troubleshooting.rst +0 -0
  127. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/audio_attachment.rst +0 -0
  128. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/call_attachment.rst +0 -0
  129. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/chat.rst +0 -0
  130. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/contact_attachment.rst +0 -0
  131. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/control_attachment.rst +0 -0
  132. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/element.rst +0 -0
  133. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/enums.rst +0 -0
  134. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/file_attachment.rst +0 -0
  135. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/folder.rst +0 -0
  136. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/folder_list.rst +0 -0
  137. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/folder_update.rst +0 -0
  138. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/inline_keyboard_attachment.rst +0 -0
  139. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/message.rst +0 -0
  140. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/message_delete_event.rst +0 -0
  141. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/name.rst +0 -0
  142. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/photo_attachment.rst +0 -0
  143. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/profile.rst +0 -0
  144. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/reaction_counter.rst +0 -0
  145. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/reaction_info.rst +0 -0
  146. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/read_state.rst +0 -0
  147. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/session.rst +0 -0
  148. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/share_attachment.rst +0 -0
  149. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/sticker_attachment.rst +0 -0
  150. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/sync_overrides.rst +0 -0
  151. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/sync_state.rst +0 -0
  152. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/user.rst +0 -0
  153. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/types/video_attachment.rst +0 -0
  154. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/docs/users.rst +0 -0
  155. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/__init__.py +0 -0
  156. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/auth/__init__.py +0 -0
  157. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/auth/enums.py +0 -0
  158. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/auth/types.py +0 -0
  159. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/bots/__init__.py +0 -0
  160. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/bots/payloads.py +0 -0
  161. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/bots/service.py +0 -0
  162. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/chats/__init__.py +0 -0
  163. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/chats/enums.py +0 -0
  164. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/chats/payloads.py +0 -0
  165. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/facade.py +0 -0
  166. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/messages/__init__.py +0 -0
  167. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/self/__init__.py +0 -0
  168. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/self/enums.py +0 -0
  169. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/self/payloads.py +0 -0
  170. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/session/__init__.py +0 -0
  171. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/session/enums.py +0 -0
  172. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/uploads/__init__.py +0 -0
  173. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/uploads/models.py +0 -0
  174. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/users/__init__.py +0 -0
  175. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/users/enums.py +0 -0
  176. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/api/users/payloads.py +0 -0
  177. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/auth/__init__.py +0 -0
  178. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/auth/base.py +0 -0
  179. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/auth/email.py +0 -0
  180. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/auth/models.py +0 -0
  181. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/auth/providers.py +0 -0
  182. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/auth/service.py +0 -0
  183. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/connection/__init__.py +0 -0
  184. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/connection/pending.py +0 -0
  185. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/connection/readers/__init__.py +0 -0
  186. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/connection/readers/base.py +0 -0
  187. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/connection/readers/ws.py +0 -0
  188. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/dispatch/__init__.py +0 -0
  189. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/exceptions.py +0 -0
  190. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/files/__init__.py +0 -0
  191. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/files/base.py +0 -0
  192. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/files/file.py +0 -0
  193. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/files/static.py +0 -0
  194. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/files/video.py +0 -0
  195. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/formatting/__init__.py +0 -0
  196. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/infra/__init__.py +0 -0
  197. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/infra/auth.py +0 -0
  198. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/infra/base.py +0 -0
  199. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/infra/bots.py +0 -0
  200. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/infra/protocol.py +0 -0
  201. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/infra/self.py +0 -0
  202. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/infra/user.py +0 -0
  203. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/protocol/__init__.py +0 -0
  204. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/protocol/base.py +0 -0
  205. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/protocol/enums.py +0 -0
  206. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/protocol/models.py +0 -0
  207. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/protocol/tcp/__init__.py +0 -0
  208. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/protocol/ws/__init__.py +0 -0
  209. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/py.typed +0 -0
  210. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/routers.py +0 -0
  211. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/session/__init__.py +0 -0
  212. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/session/models.py +0 -0
  213. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/telemetry/__init__.py +0 -0
  214. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/telemetry/payloads.py +0 -0
  215. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/transport/__init__.py +0 -0
  216. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/transport/base.py +0 -0
  217. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/transport/websocket.py +0 -0
  218. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/__init__.py +0 -0
  219. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/__init__.py +0 -0
  220. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/call.py +0 -0
  221. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/contact.py +0 -0
  222. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/control.py +0 -0
  223. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/file.py +0 -0
  224. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/keyboards/__init__.py +0 -0
  225. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/keyboards/inline.py +0 -0
  226. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/photo.py +0 -0
  227. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/share.py +0 -0
  228. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/attachments/sticker.py +0 -0
  229. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/base.py +0 -0
  230. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/bots.py +0 -0
  231. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/enums.py +0 -0
  232. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/error.py +0 -0
  233. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/folder.py +0 -0
  234. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/login.py +0 -0
  235. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/member.py +0 -0
  236. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/name.py +0 -0
  237. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/profile.py +0 -0
  238. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/session.py +0 -0
  239. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/domain/user.py +0 -0
  240. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/events/file.py +0 -0
  241. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/src/pymax/types/events/video.py +0 -0
  242. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/tests/__init__.py +0 -0
  243. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/tests/session/test_store.py +0 -0
  244. {maxapi_python-2.1.2 → maxapi_python-2.2.0}/tests/telemetry/test_telemetry.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.2
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
  Частые ошибки
@@ -78,6 +78,7 @@ release = __version__
78
78
 
79
79
  extensions = [
80
80
  "sphinx.ext.autodoc",
81
+ "sphinx.ext.autosummary",
81
82
  "sphinx.ext.napoleon",
82
83
  "sphinx.ext.viewcode",
83
84
  "sphinx.ext.intersphinx",
@@ -86,6 +87,8 @@ extensions = [
86
87
 
87
88
  templates_path = ["_templates"]
88
89
 
90
+ autosummary_generate = True
91
+
89
92
  exclude_patterns = [
90
93
  "_build",
91
94
  "Thumbs.db",
@@ -99,20 +102,24 @@ language = "ru"
99
102
  autodoc_default_options = {
100
103
  "members": True,
101
104
  "undoc-members": False,
102
- "show-inheritance": False,
105
+ "show-inheritance": True,
103
106
  "private-members": False,
104
107
  "special-members": False,
108
+ "member-order": "bysource",
105
109
  "exclude-members": (
106
- "dict,json,parse_obj,parse_raw,schema,model_dump,model_validate,"
107
- "model_json_schema,model_construct"
110
+ "dict,json,parse_obj,parse_raw,schema,schema_json,"
111
+ "copy,construct,from_orm,update_forward_refs,validate,"
112
+ "model_dump,model_dump_json,model_validate,model_validate_json,"
113
+ "model_validate_strings,model_json_schema,model_construct,"
114
+ "model_copy,model_rebuild,model_post_init,model_parametrized_name"
108
115
  ),
109
116
  }
110
117
 
118
+
119
+ autodoc_typehints_format = "short"
111
120
  autodoc_member_order = "bysource"
112
121
  autodoc_typehints = "description"
113
- autodoc_typehints_format = "short"
114
122
  autodoc_class_signature = "separated"
115
-
116
123
  # -- Napoleon ----------------------------------------------------------------
117
124
 
118
125
  napoleon_google_docstring = True
@@ -131,7 +138,9 @@ intersphinx_mapping = {
131
138
 
132
139
  # -- HTML --------------------------------------------------------------------
133
140
 
141
+ # html_theme = "shibuya"
134
142
  html_theme = "furo"
143
+
135
144
  html_title = "PyMax"
136
145
  html_static_path = ["_static"]
137
146
 
@@ -22,6 +22,8 @@ PyMax - асинхронная Python-библиотека для Max API. Он
22
22
  :maxdepth: 1
23
23
  :caption: Новости
24
24
 
25
+ release-2-2-0
26
+ release-2-1-3
25
27
  release-2-1-2
26
28
  release-2-1-1
27
29
  release-2-1-0
@@ -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,48 @@
1
+ PyMax 2.1.3
2
+ ===========
3
+
4
+ Изменения относительно ``2.1.2``.
5
+
6
+ Добавлено
7
+ ---------
8
+
9
+ * ``UnknownAttachment`` для вложений с неизвестным ``_type``. Такие вложения
10
+ больше не ломают парсинг ``Message`` и сохраняют дополнительные поля
11
+ payload-а.
12
+
13
+ Исправлено
14
+ ----------
15
+
16
+ * ``Message`` больше не падает на неизвестных типах вложений вроде
17
+ ``UNSUPPORTED``.
18
+ * ``AudioAttachment`` принимает payload без ``duration`` и ``audioId``.
19
+ * ``VideoAttachment`` принимает payload без ``duration``.
20
+ * ``ElementAttributes.url`` и ``Element.length`` стали необязательными для
21
+ элементов, где Max не присылает эти поля.
22
+ * ``Photo(url=...)`` корректно определяет расширение и MIME type, если в URL
23
+ есть query string.
24
+ * При потере соединения ``App.started`` сбрасывается, ping-task отменяется, а
25
+ pending API-запросы очищаются без ``Future exception was never retrieved``.
26
+ * Reconnect/close после штатного сетевого обрыва стало меньше шуметь
27
+ exception-логами.
28
+
29
+ Изменилось
30
+ ----------
31
+
32
+ * ``configure_logging()`` теперь уважает уже настроенный logging
33
+ host-приложения: PyMax не очищает чужие handler-ы и не добавляет свой
34
+ stderr-handler, если logging уже сконфигурирован.
35
+ * Если logging не настроен, PyMax по-прежнему включает pretty-логи из коробки.
36
+ * Для принудительного включения pretty-логов PyMax добавлен аргумент
37
+ ``configure_logging(..., force=True)``.
38
+ * TCP msgpack decoder стал проще и подробнее логирует payload при ошибках
39
+ декодирования.
40
+
41
+ Миграция
42
+ --------
43
+
44
+ * Код на ``Client`` и ``WebClient`` обычно менять не нужно.
45
+ * Если приложение рассчитывало, что ``configure_logging()`` всегда заменяет
46
+ существующие handler-ы ``pymax``, передайте ``force=True``.
47
+ * Если код обрабатывал ``ValidationError`` для неизвестных вложений, теперь
48
+ вместо ошибки придет ``UnknownAttachment``.
@@ -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: