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.
- maxapi_python-2.3.0/.github/workflows/tests.yml +66 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/PKG-INFO +3 -11
- maxapi_python-2.3.0/docs/api/client-client.rst +18 -0
- maxapi_python-2.3.0/docs/api/client-config.rst +14 -0
- maxapi_python-2.3.0/docs/api/client-web.rst +17 -0
- maxapi_python-2.3.0/docs/api/client.rst +25 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/api/router.rst +6 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/auth.rst +53 -1
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/chats.rst +16 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/client.rst +97 -5
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/index.rst +2 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/messages.rst +61 -1
- maxapi_python-2.3.0/docs/release-2-2-0.rst +57 -0
- maxapi_python-2.3.0/docs/release-2-3-0.rst +40 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/router.rst +60 -1
- maxapi_python-2.3.0/docs/types/contact_info.rst +6 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/index.rst +8 -0
- maxapi_python-2.3.0/docs/types/message_read_event.rst +6 -0
- maxapi_python-2.3.0/docs/types/presence_event.rst +6 -0
- maxapi_python-2.3.0/docs/types/reaction_update_event.rst +6 -0
- maxapi_python-2.3.0/docs/types/typing_event.rst +6 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/users.rst +19 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/pyproject.toml +10 -19
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/__init__.py +18 -3
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/auth/payloads.py +7 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/auth/service.py +33 -30
- maxapi_python-2.3.0/src/pymax/api/binding.py +57 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/chats/payloads.py +6 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/chats/service.py +52 -47
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/messages/enums.py +1 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/messages/payloads.py +16 -1
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/messages/service.py +78 -34
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/models.py +4 -6
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/response.py +2 -2
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/self/service.py +17 -26
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/session/payloads.py +2 -9
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/session/service.py +1 -3
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/uploads/payloads.py +3 -9
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/uploads/service.py +33 -99
- maxapi_python-2.3.0/src/pymax/api/users/payloads.py +38 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/users/service.py +22 -17
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/app.py +28 -6
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/auth/qr.py +3 -9
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/auth/sms.py +23 -11
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/base.py +86 -4
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/client.py +2 -1
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/client_web.py +1 -2
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/config.py +42 -3
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/connection/connection.py +2 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/connection/readers/tcp.py +1 -3
- maxapi_python-2.3.0/src/pymax/dispatch/__init__.py +21 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/dispatch/dispatcher.py +170 -34
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/dispatch/enums.py +5 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/dispatch/mapping.py +34 -11
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/dispatch/resolvers.py +18 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/dispatch/router.py +120 -4
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/formatting/markdown.py +22 -13
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/infra/chat.py +33 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/infra/message.py +69 -2
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/infra/user.py +12 -1
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/logging.py +2 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/tcp/compression.py +1 -3
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/tcp/framing.py +1 -3
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/ws/protocol.py +3 -9
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/session/protocol.py +2 -6
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/session/store.py +19 -24
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/telemetry/navigation.py +1 -3
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/telemetry/service.py +5 -17
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/transport/tcp.py +1 -3
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/__init__.py +1 -1
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/unknown.py +1 -3
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/auth.py +24 -2
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/chat.py +58 -1
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/message.py +28 -2
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/presence.py +3 -3
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/sync.py +5 -21
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/user.py +8 -0
- maxapi_python-2.3.0/src/pymax/types/events/__init__.py +7 -0
- maxapi_python-2.3.0/src/pymax/types/events/mark.py +23 -0
- maxapi_python-2.3.0/src/pymax/types/events/message.py +89 -0
- maxapi_python-2.3.0/src/pymax/types/events/presence.py +15 -0
- maxapi_python-2.3.0/src/pymax/types/events/reaction.py +21 -0
- maxapi_python-2.3.0/src/pymax/types/events/typing.py +14 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/api/test_auth_service.py +60 -13
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/api/test_chat_user_self_session_services.py +118 -59
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/api/test_message_service.py +169 -9
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/api/test_upload_service.py +10 -31
- maxapi_python-2.3.0/tests/app/test_app_runtime.py +445 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/auth/test_auth_flows.py +73 -6
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/conftest.py +7 -21
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/connection/test_connection.py +9 -27
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/connection/test_readers_and_transports.py +3 -9
- maxapi_python-2.3.0/tests/dispatch/test_dispatcher.py +328 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/domain/test_bound_models.py +64 -19
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/files/test_files_and_formatting.py +1 -3
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/protocol/test_protocols.py +1 -3
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/session/test_store.py +20 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/uv.lock +1 -51
- maxapi_python-2.1.3/docs/api/client.rst +0 -17
- maxapi_python-2.1.3/src/pymax/api/users/payloads.py +0 -16
- maxapi_python-2.1.3/src/pymax/dispatch/__init__.py +0 -10
- maxapi_python-2.1.3/src/pymax/types/events/__init__.py +0 -3
- maxapi_python-2.1.3/src/pymax/types/events/message.py +0 -37
- maxapi_python-2.1.3/tests/app/test_app_runtime.py +0 -215
- maxapi_python-2.1.3/tests/dispatch/test_dispatcher.py +0 -102
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/.github/ISSUE_TEMPLATE/refactor.md +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/.github/pull_request_template.md +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/.github/workflows/publish.yml +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/.gitignore +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/.pre-commit-config.yaml +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/LICENSE +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/README.md +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/_static/.gitkeep +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/account.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/api/auth.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/api/files.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/conf.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/examples.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/faq.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/files.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/formatting.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/getting-started.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/release-2-1-0.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/release-2-1-1.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/release-2-1-2.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/release-2-1-3.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/troubleshooting.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/audio_attachment.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/call_attachment.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/chat.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/contact_attachment.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/control_attachment.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/element.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/enums.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/file_attachment.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/folder.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/folder_list.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/folder_update.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/inline_keyboard_attachment.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/message.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/message_delete_event.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/name.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/photo_attachment.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/profile.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/reaction_counter.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/reaction_info.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/read_state.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/session.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/share_attachment.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/sticker_attachment.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/sync_overrides.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/sync_state.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/user.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/docs/types/video_attachment.rst +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/auth/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/auth/enums.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/auth/types.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/bots/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/bots/payloads.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/bots/service.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/chats/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/chats/enums.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/facade.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/messages/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/self/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/self/enums.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/self/payloads.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/session/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/session/enums.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/uploads/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/uploads/models.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/users/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/api/users/enums.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/auth/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/auth/base.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/auth/email.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/auth/models.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/auth/providers.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/auth/service.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/connection/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/connection/pending.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/connection/readers/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/connection/readers/base.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/connection/readers/ws.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/exceptions.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/files/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/files/base.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/files/file.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/files/photo.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/files/static.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/files/video.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/formatting/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/infra/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/infra/auth.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/infra/base.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/infra/bots.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/infra/protocol.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/infra/self.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/base.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/enums.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/models.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/tcp/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/tcp/payload.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/tcp/protocol.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/protocol/ws/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/py.typed +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/routers.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/session/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/session/models.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/telemetry/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/telemetry/payloads.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/transport/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/transport/base.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/transport/websocket.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/audio.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/call.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/contact.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/control.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/enums.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/file.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/keyboards/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/keyboards/inline.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/photo.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/share.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/sticker.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/attachments/video.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/base.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/bots.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/element.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/enums.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/error.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/folder.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/login.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/member.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/name.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/profile.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/domain/session.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/events/file.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/src/pymax/types/events/video.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/__init__.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/domain/test_message_models.py +0 -0
- {maxapi_python-2.1.3 → maxapi_python-2.3.0}/tests/telemetry/test_telemetry.py +0 -0
- {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.
|
|
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://
|
|
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`` не
|
|
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()
|
|
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()
|
|
321
|
+
``set_2fa()``, ``remove_2fa()`` и ``authorize_qr_login()``. Подробнее:
|
|
230
322
|
:doc:`auth`.
|
|
231
323
|
|
|
232
324
|
Частые ошибки
|
|
@@ -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.
|
|
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
|
+
продолжает распространяться.
|