pybotx 0.77.1__tar.gz → 0.77.2__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.
- pybotx-0.77.2/.gitlab-ci.yml +56 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/PKG-INFO +2 -2
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/bot.py +192 -73
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/bot_account_provider.py +1 -1
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/bot_accounts_storage.py +11 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/events_api/reply_event.py +28 -3
- {pybotx-0.77.1 → pybotx-0.77.2}/pyproject.toml +6 -5
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/events_api/test_reply_event.py +75 -9
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/deprecated/test_verify_request_v1.py +10 -3
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_bot_account_provider.py +340 -1
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_verify_request.py +49 -2
- {pybotx-0.77.1 → pybotx-0.77.2}/uv.lock +1 -1
- {pybotx-0.77.1 → pybotx-0.77.2}/.github/dependabot.yml +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/.github/pull_request_template.md +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/.github/workflows/publish-pypi.yml +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/.github/workflows/python-app.yml +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/.gitignore +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/LICENSE +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/README.md +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/production_presets.md +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/retry_safety.md +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/widgets/WIDGETS.md +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/widgets/img.png +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/widgets/img_1.png +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/widgets/img_10.png +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/widgets/img_11.png +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/widgets/img_12.png +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/widgets/img_13.png +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/widgets/img_14.png +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/widgets/img_15.png +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/widgets/img_2.png +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/widgets/img_3.png +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/widgets/img_4.png +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/widgets/img_5.png +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/widgets/img_6.png +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/widgets/img_7.png +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/widgets/img_8.png +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/docs/widgets/img_9.png +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/example/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/example/main.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/mkdocs.yml +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/poetry.lock +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/async_buffer.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/auth.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/api/exceptions.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/api/responses/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/api/responses/bot_disabled.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/api/responses/command_accepted.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/api/responses/unverified_request.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/callbacks/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/callbacks/callback_manager.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/callbacks/callback_memory_repo.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/callbacks/callback_repo_proto.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/command_processing.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/contextvars.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/exceptions.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/handler.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/handler_collector.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/healthcheck.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/ingress_observability.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/middlewares/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/middlewares/exception_middleware.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/bot/testing.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/cli.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/authorized_botx_method.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/bots_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/bots_api/bot_catalog.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/bots_api/get_token.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/botx_method.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/chats_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/chats_api/add_admin.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/chats_api/add_user.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/chats_api/chat_info.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/chats_api/create_chat.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/chats_api/create_chat_link.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/chats_api/create_thread.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/chats_api/disable_stealth.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/chats_api/list_chats.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/chats_api/personal_chat.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/chats_api/pin_message.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/chats_api/remove_user.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/chats_api/set_stealth.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/chats_api/unpin_message.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/events_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/events_api/delete_event.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/events_api/edit_event.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/events_api/message_status_event.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/events_api/stop_typing_event.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/events_api/typing_event.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/exceptions/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/exceptions/base.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/exceptions/callbacks.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/exceptions/chats.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/exceptions/common.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/exceptions/event.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/exceptions/files.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/exceptions/http.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/exceptions/message.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/exceptions/notifications.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/exceptions/users.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/files_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/files_api/download_file.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/files_api/upload_file.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/get_token.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/http_config.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/mertics_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/mertics_api/collect_bot_function.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/notifications_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/notifications_api/direct_notification.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/notifications_api/internal_bot_notification.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/observability.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/openid_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/openid_api/refresh_access_token.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/smartapps_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/smartapps_api/exceptions.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/smartapps_api/smartapp_custom_notification.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/smartapps_api/smartapp_event.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/smartapps_api/smartapp_manifest.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/smartapps_api/smartapp_notification.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/smartapps_api/smartapp_unread_counter.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/smartapps_api/smartapps_list.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/smartapps_api/upload_file.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/stickers_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/stickers_api/add_sticker.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/stickers_api/create_sticker_pack.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/stickers_api/delete_sticker.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/stickers_api/delete_sticker_pack.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/stickers_api/edit_sticker_pack.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/stickers_api/exceptions.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/stickers_api/get_sticker.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/stickers_api/get_sticker_pack.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/stickers_api/get_sticker_packs.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/stickers_api/sticker_pack.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/users_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/users_api/search_user_by_email.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/users_api/search_user_by_emails.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/users_api/search_user_by_huid.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/users_api/search_user_by_login.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/users_api/search_user_by_other_id.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/users_api/trusted_search.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/users_api/update_user_profile.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/users_api/user_from_csv.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/users_api/user_from_search.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/users_api/users_as_csv.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/voex_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/voex_api/exceptions.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/voex_api/get_call.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/client/voex_api/get_conference.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/constants.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/converters.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/image_validators.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/integrations/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/integrations/fastapi.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/logger.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/missing.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/api_base.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/async_files.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/attachments.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/base_command.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/bot_account.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/bot_catalog.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/bot_sender.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/call.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/chats.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/commands.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/conference.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/enums.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/message/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/message/edit_message.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/message/forward.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/message/incoming_message.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/message/markup.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/message/mentions.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/message/message_status.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/message/outgoing_message.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/message/reply.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/message/reply_message.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/method_callbacks.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/smartapps.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/status.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/stickers.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/sync_smartapp_event.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/system_events/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/system_events/added_to_chat.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/system_events/chat_created.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/system_events/chat_deleted_by_user.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/system_events/conference_changed.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/system_events/conference_created.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/system_events/conference_deleted.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/system_events/cts_login.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/system_events/cts_logout.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/system_events/deleted_from_chat.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/system_events/event_delete.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/system_events/event_edit.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/system_events/internal_bot_notification.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/system_events/left_from_chat.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/system_events/smartapp_event.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/system_events/user_joined_to_chat.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/models/users.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/presets.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/py.typed +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/scaffold/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/scaffold/_shared.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/scaffold/command.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/scaffold/fsm_flow.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/scaffold/manifest.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/scaffold/port.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/scaffold/project.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/scaffold/repository.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/scaffold/service.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/scaffold/templates.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/scaffold/widget.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/scaffold/widget_flow.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/approval.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/async_job.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/base.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/calendar.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/carousel.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/checklist.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/checktable.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/confirm.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/date_range.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/factory.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/file_batch.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/form_wizard.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/markup.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/messages_pager.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/multi_select.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/observability.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/pagination.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/presets.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/range.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/runner.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/search_select.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/select.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/service.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/strings.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/table.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/pybotx/widgets/undefined.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/scripts/docs-lint +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/scripts/format +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/scripts/lint +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/scripts/test +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/scripts/wip-marks +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/setup.cfg +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/bots_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/bots_api/test_bots_list.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/bots_api/test_get_token.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/chats_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/chats_api/factories.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/chats_api/test_add_admin.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/chats_api/test_add_user.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/chats_api/test_chat_info.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/chats_api/test_chat_info_validation.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/chats_api/test_create_chat.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/chats_api/test_create_chat_link.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/chats_api/test_create_thread.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/chats_api/test_disable_stealth.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/chats_api/test_list_chats.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/chats_api/test_list_chats_validation.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/chats_api/test_personal_chat.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/chats_api/test_personal_chat_additional.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/chats_api/test_pin_message.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/chats_api/test_remove_user.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/chats_api/test_set_stealth.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/chats_api/test_unpin_message.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/events_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/events_api/test_delete_event.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/events_api/test_edit_event.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/events_api/test_message_status_event.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/events_api/test_stop_typing_event.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/events_api/test_typing_event.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/exceptions/test_callbacks.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/exceptions/test_http.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/files_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/files_api/test_download_file.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/files_api/test_upload_file.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/notifications_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/notifications_api/test_direct_notification.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/notifications_api/test_direct_notification_sync.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/notifications_api/test_internal_bot_notification.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/notifications_api/test_markup.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/openid_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/openid_api/test_resfesh_access_token.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/smartapps_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/smartapps_api/test_smartapp_custom_notification.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/smartapps_api/test_smartapp_event.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/smartapps_api/test_smartapp_manifest.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/smartapps_api/test_smartapp_notification.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/smartapps_api/test_smartapp_unread_counter.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/smartapps_api/test_smartapp_upload_file.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/smartapps_api/test_smartapps_list.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/stickers_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/stickers_api/test_add_sticker.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/stickers_api/test_create_sticker_pack.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/stickers_api/test_delete_sticker.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/stickers_api/test_delete_sticker_pack.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/stickers_api/test_edit_sticker_pack.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/stickers_api/test_get_sticker.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/stickers_api/test_get_sticker_pack.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/stickers_api/test_get_sticker_packs.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/test_authorized_botx_method.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/test_botx_method.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/test_botx_method_callback.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/test_botx_method_stream.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/test_botx_method_undefined_cleaned.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/test_http_config.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/test_metrics_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/test_metrics_api/test_collect_metric.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/test_open_telemetry_tracing_collector.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/test_prometheus_metrics_collector.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/users_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/users_api/conftest.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/users_api/convert_to_datetime.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/users_api/test_search_user_by_email_post.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/users_api/test_search_user_by_emails.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/users_api/test_search_user_by_huid.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/users_api/test_search_user_by_login.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/users_api/test_search_user_by_other_id.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/users_api/test_trusted_search.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/users_api/test_update_user_profile.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/users_api/test_users_as_csv.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/voex_api/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/voex_api/test_call.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/client/voex_api/test_conference.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/conftest.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/deprecated/test_authorized_botx_method_v1.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/deprecated/test_lifespan_v1.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/deprecated/test_search_user_by_email_get.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/fixtures/users_api.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/models/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/models/test_api_base_property.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/models/test_bot_account.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/models/test_bot_account_with_secret.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/models/test_botx_api_markup.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/models/test_enums.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/models/test_enums_property.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/models/test_incoming_message.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/models/test_incoming_message_validation.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/models/test_markup.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/models/test_mentions_list.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/models/test_status_recipient.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/models/test_sync_smartapp_event.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/models/test_users.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/system_events/factories.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/system_events/test_added_to_chat.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/system_events/test_chat_created.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/system_events/test_chat_deleted_by_user.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/system_events/test_conference_changed.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/system_events/test_conference_created.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/system_events/test_conference_deleted.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/system_events/test_cts_login.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/system_events/test_cts_logout.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/system_events/test_deleted_from_chat.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/system_events/test_event_delete.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/system_events/test_event_edit.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/system_events/test_internal_bot_notification.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/system_events/test_join_to_chat.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/system_events/test_left_from_chat.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/system_events/test_smartapp_event.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_async_buffer.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_attachments.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_base_command.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_bot_constructing.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_bot_edge_cases.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_command_processing.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_end_to_end.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_exception_middleware.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_fastapi_adapter.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_files.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_handler_collector.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_healthcheck.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_incoming_message.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_ingress_observability.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_lifespan.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_logger.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_logs.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_middlewares.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_personal_chat_ensure.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_presets.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_scaffold.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_scaffold_edge_cases.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_state.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_status.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_stickers.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/test_system_events_routing.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/testkit/__init__.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/testkit/botx.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_approval.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_async_job.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_base.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_calendar.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_carousel.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_checklist.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_checktable.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_confirm.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_date_range.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_factory.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_file_batch.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_form_wizard.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_markup.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_messages_pager.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_module.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_multi_select.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_observability.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_pagination.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_presets.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_range.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_runner.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_search_select.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_select.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_service.py +0 -0
- {pybotx-0.77.1 → pybotx-0.77.2}/tests/widgets/test_table.py +0 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
workflow:
|
|
2
|
+
rules:
|
|
3
|
+
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
|
4
|
+
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
|
|
5
|
+
when: never
|
|
6
|
+
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH'
|
|
7
|
+
|
|
8
|
+
stages:
|
|
9
|
+
- check
|
|
10
|
+
- package
|
|
11
|
+
|
|
12
|
+
variables:
|
|
13
|
+
PYTHON_VERSION: "3.13"
|
|
14
|
+
|
|
15
|
+
default:
|
|
16
|
+
image: "python:${PYTHON_VERSION}-bookworm"
|
|
17
|
+
tags:
|
|
18
|
+
- docker
|
|
19
|
+
before_script:
|
|
20
|
+
- python -m pip install uv
|
|
21
|
+
- uv sync --locked --dev
|
|
22
|
+
|
|
23
|
+
test:
|
|
24
|
+
stage: check
|
|
25
|
+
parallel:
|
|
26
|
+
matrix:
|
|
27
|
+
- PYTHON_VERSION: ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
|
28
|
+
script:
|
|
29
|
+
- >-
|
|
30
|
+
uv run --no-sync ./scripts/test -n 4 --cov-report=xml
|
|
31
|
+
--junitxml=junit.xml --junit-prefix="py${PYTHON_VERSION}"
|
|
32
|
+
coverage: '/^TOTAL\s+.*\s+([0-9]+(?:\.[0-9]+)?%)\s*$/'
|
|
33
|
+
artifacts:
|
|
34
|
+
reports:
|
|
35
|
+
junit: junit.xml
|
|
36
|
+
coverage_report:
|
|
37
|
+
coverage_format: cobertura
|
|
38
|
+
path: coverage.xml
|
|
39
|
+
|
|
40
|
+
lint:
|
|
41
|
+
stage: check
|
|
42
|
+
script:
|
|
43
|
+
- uv run --no-sync ./scripts/lint
|
|
44
|
+
|
|
45
|
+
docs-lint:
|
|
46
|
+
stage: check
|
|
47
|
+
script:
|
|
48
|
+
- uv run --no-sync bash ./scripts/docs-lint
|
|
49
|
+
|
|
50
|
+
package:
|
|
51
|
+
stage: package
|
|
52
|
+
script:
|
|
53
|
+
- uv build
|
|
54
|
+
artifacts:
|
|
55
|
+
paths:
|
|
56
|
+
- dist/
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pybotx
|
|
3
|
-
Version: 0.77.
|
|
3
|
+
Version: 0.77.2
|
|
4
4
|
Summary: A python library for interacting with eXpress BotX API
|
|
5
5
|
Project-URL: Repository, https://github.com/ExpressApp/pybotx
|
|
6
|
-
Author
|
|
6
|
+
Author: Sidnev Nikolay, Maxim Gorbachev, Alexander Samoylenko, Arseniy Zhiltsov, Aleksandr Osovskii
|
|
7
7
|
License-File: LICENSE
|
|
8
8
|
Requires-Python: <4.0,>=3.10
|
|
9
9
|
Requires-Dist: aiocsv<2,>=1.4.0
|
|
@@ -4,7 +4,7 @@ from contextlib import AsyncExitStack, asynccontextmanager, contextmanager
|
|
|
4
4
|
from contextvars import ContextVar, Token
|
|
5
5
|
from datetime import datetime
|
|
6
6
|
from types import SimpleNamespace
|
|
7
|
-
from typing import Any, TypeAlias
|
|
7
|
+
from typing import Any, Literal, TypeAlias
|
|
8
8
|
from uuid import UUID
|
|
9
9
|
|
|
10
10
|
import aiofiles
|
|
@@ -38,6 +38,7 @@ from pybotx.bot.contextvars import (
|
|
|
38
38
|
trace_id_var,
|
|
39
39
|
)
|
|
40
40
|
from pybotx.bot.exceptions import (
|
|
41
|
+
AmbiguousBotAccountError,
|
|
41
42
|
AnswerDestinationLookupError,
|
|
42
43
|
RequestHeadersNotProvidedError,
|
|
43
44
|
UnknownBotAccountError,
|
|
@@ -409,22 +410,51 @@ class Bot:
|
|
|
409
410
|
if logging_command:
|
|
410
411
|
log_incoming_request(raw_bot_command, message="Got command: ")
|
|
411
412
|
|
|
413
|
+
account_key = None
|
|
412
414
|
if verify_request:
|
|
413
|
-
self._verify_request(
|
|
415
|
+
account_key = self._verify_request(
|
|
416
|
+
request_headers,
|
|
417
|
+
trusted_issuers=trusted_issuers,
|
|
418
|
+
)
|
|
414
419
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
420
|
+
with self._verified_account_scope(account_key):
|
|
421
|
+
try:
|
|
422
|
+
command_type = raw_bot_command.get("command", {}).get(
|
|
423
|
+
"command_type"
|
|
424
|
+
)
|
|
425
|
+
if command_type == BotAPICommandTypes.USER:
|
|
426
|
+
bot_api_command = BotAPIIncomingMessage.model_validate(
|
|
427
|
+
raw_bot_command
|
|
428
|
+
)
|
|
429
|
+
else:
|
|
430
|
+
bot_api_command = TypeAdapter(
|
|
431
|
+
BotAPISystemEvent
|
|
432
|
+
).validate_python(raw_bot_command)
|
|
433
|
+
except ValidationError as validation_exc:
|
|
434
|
+
raise ValueError("Bot command validation error") from validation_exc
|
|
435
|
+
|
|
436
|
+
bot_command = bot_api_command.to_domain(raw_bot_command)
|
|
437
|
+
if account_key is None:
|
|
438
|
+
return self.async_execute_bot_command(bot_command)
|
|
439
|
+
|
|
440
|
+
if bot_command.bot.id != account_key.bot_id:
|
|
441
|
+
raise UnverifiedRequestError(
|
|
442
|
+
"Command bot_id does not match the verified bot account",
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
verified_account = self._bot_accounts_storage.get_bot_account_by_key(
|
|
446
|
+
account_key,
|
|
447
|
+
)
|
|
448
|
+
if bot_command.bot.host != verified_account.host:
|
|
449
|
+
raise UnverifiedRequestError(
|
|
450
|
+
"Command host does not match the verified CTS",
|
|
422
451
|
)
|
|
423
|
-
except ValidationError as validation_exc:
|
|
424
|
-
raise ValueError("Bot command validation error") from validation_exc
|
|
425
452
|
|
|
426
|
-
|
|
427
|
-
|
|
453
|
+
return self._handler_collector.async_handle_bot_command(
|
|
454
|
+
self,
|
|
455
|
+
bot_command,
|
|
456
|
+
account_key=account_key,
|
|
457
|
+
)
|
|
428
458
|
finally:
|
|
429
459
|
self._reset_contextvars(context_tokens)
|
|
430
460
|
|
|
@@ -482,20 +512,25 @@ class Bot:
|
|
|
482
512
|
message="Got sync smartapp event: ",
|
|
483
513
|
)
|
|
484
514
|
|
|
515
|
+
account_key = None
|
|
485
516
|
if verify_request:
|
|
486
|
-
self._verify_request(
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
bot_api_smartapp_event = BotAPISyncSmartAppEvent.model_validate(
|
|
490
|
-
raw_smartapp_event
|
|
517
|
+
account_key = self._verify_request(
|
|
518
|
+
request_headers,
|
|
519
|
+
trusted_issuers=trusted_issuers,
|
|
491
520
|
)
|
|
492
|
-
except ValidationError as validation_exc:
|
|
493
|
-
raise ValueError(
|
|
494
|
-
"Sync smartapp event validation error",
|
|
495
|
-
) from validation_exc
|
|
496
521
|
|
|
497
|
-
|
|
498
|
-
|
|
522
|
+
with self._verified_account_scope(account_key):
|
|
523
|
+
try:
|
|
524
|
+
bot_api_smartapp_event = BotAPISyncSmartAppEvent.model_validate(
|
|
525
|
+
raw_smartapp_event
|
|
526
|
+
)
|
|
527
|
+
except ValidationError as validation_exc:
|
|
528
|
+
raise ValueError(
|
|
529
|
+
"Sync smartapp event validation error",
|
|
530
|
+
) from validation_exc
|
|
531
|
+
|
|
532
|
+
smartapp_event = bot_api_smartapp_event.to_domain(raw_smartapp_event)
|
|
533
|
+
return await self.sync_execute_smartapp_event(smartapp_event)
|
|
499
534
|
finally:
|
|
500
535
|
self._reset_contextvars(context_tokens)
|
|
501
536
|
|
|
@@ -533,20 +568,25 @@ class Bot:
|
|
|
533
568
|
status=lambda: pformat_jsonable_obj(query_params),
|
|
534
569
|
)
|
|
535
570
|
|
|
571
|
+
account_key = None
|
|
536
572
|
if verify_request:
|
|
537
|
-
self._verify_request(
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
bot_api_status_recipient = BotAPIStatusRecipient.model_validate(
|
|
541
|
-
query_params
|
|
573
|
+
account_key = self._verify_request(
|
|
574
|
+
request_headers,
|
|
575
|
+
trusted_issuers=trusted_issuers,
|
|
542
576
|
)
|
|
543
|
-
except ValidationError as exc:
|
|
544
|
-
raise ValueError("Status request validation error") from exc
|
|
545
577
|
|
|
546
|
-
|
|
578
|
+
with self._verified_account_scope(account_key):
|
|
579
|
+
try:
|
|
580
|
+
bot_api_status_recipient = BotAPIStatusRecipient.model_validate(
|
|
581
|
+
query_params
|
|
582
|
+
)
|
|
583
|
+
except ValidationError as exc:
|
|
584
|
+
raise ValueError("Status request validation error") from exc
|
|
585
|
+
|
|
586
|
+
status_recipient = bot_api_status_recipient.to_domain()
|
|
547
587
|
|
|
548
|
-
|
|
549
|
-
|
|
588
|
+
bot_menu = await self.get_status(status_recipient)
|
|
589
|
+
return build_bot_status_response(bot_menu)
|
|
550
590
|
finally:
|
|
551
591
|
self._reset_contextvars(context_tokens)
|
|
552
592
|
|
|
@@ -570,16 +610,20 @@ class Bot:
|
|
|
570
610
|
try:
|
|
571
611
|
logger.debug("Got callback: {callback}", callback=raw_botx_method_result)
|
|
572
612
|
|
|
613
|
+
account_key = None
|
|
573
614
|
if verify_request:
|
|
574
|
-
self._verify_request(
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
615
|
+
account_key = self._verify_request(
|
|
616
|
+
request_headers,
|
|
617
|
+
trusted_issuers=trusted_issuers,
|
|
618
|
+
)
|
|
619
|
+
with self._verified_account_scope(account_key):
|
|
620
|
+
callback: BotXMethodCallback = TypeAdapter(
|
|
621
|
+
BotXMethodCallback
|
|
622
|
+
).validate_python(
|
|
623
|
+
raw_botx_method_result,
|
|
624
|
+
)
|
|
581
625
|
|
|
582
|
-
|
|
626
|
+
await self._callbacks_manager.set_botx_method_callback_result(callback)
|
|
583
627
|
finally:
|
|
584
628
|
self._reset_contextvars(context_tokens)
|
|
585
629
|
|
|
@@ -622,6 +666,20 @@ class Bot:
|
|
|
622
666
|
finally:
|
|
623
667
|
bot_account_key_var.reset(account_key_token)
|
|
624
668
|
|
|
669
|
+
@contextmanager
|
|
670
|
+
def _verified_account_scope(
|
|
671
|
+
self, account_key: BotAccountKey | None
|
|
672
|
+
) -> Iterator[None]:
|
|
673
|
+
if account_key is None:
|
|
674
|
+
yield
|
|
675
|
+
return
|
|
676
|
+
|
|
677
|
+
account_key_token = bot_account_key_var.set(account_key)
|
|
678
|
+
try:
|
|
679
|
+
yield
|
|
680
|
+
finally:
|
|
681
|
+
bot_account_key_var.reset(account_key_token)
|
|
682
|
+
|
|
625
683
|
def invalidate_account(self, account_key: BotAccountKey) -> None:
|
|
626
684
|
"""Discard cached legacy JWTs after registration lifecycle changes."""
|
|
627
685
|
self._bot_accounts_storage.invalidate(account_key)
|
|
@@ -1057,13 +1115,16 @@ class Bot:
|
|
|
1057
1115
|
self,
|
|
1058
1116
|
*,
|
|
1059
1117
|
message: ReplyMessage,
|
|
1060
|
-
|
|
1061
|
-
|
|
1118
|
+
api_version: Literal[3, 4] = 4,
|
|
1119
|
+
) -> UUID | None:
|
|
1120
|
+
"""Reply to a message.
|
|
1062
1121
|
|
|
1063
1122
|
:param message: Built outgoing reply message.
|
|
1123
|
+
:param api_version: Use v4 (BotX >= 3.79) by default or deprecated v3.
|
|
1124
|
+
:return: Sync ID of the sent reply for v4, or `None` for v3.
|
|
1064
1125
|
"""
|
|
1065
1126
|
|
|
1066
|
-
await self.reply_message(
|
|
1127
|
+
return await self.reply_message(
|
|
1067
1128
|
bot_id=message.bot_id,
|
|
1068
1129
|
sync_id=message.sync_id,
|
|
1069
1130
|
body=message.body,
|
|
@@ -1076,6 +1137,7 @@ class Bot:
|
|
|
1076
1137
|
stealth_mode=message.stealth_mode,
|
|
1077
1138
|
send_push=message.send_push,
|
|
1078
1139
|
ignore_mute=message.ignore_mute,
|
|
1140
|
+
api_version=api_version,
|
|
1079
1141
|
)
|
|
1080
1142
|
|
|
1081
1143
|
async def reply_message(
|
|
@@ -1093,8 +1155,9 @@ class Bot:
|
|
|
1093
1155
|
stealth_mode: Missing[bool] = Undefined,
|
|
1094
1156
|
send_push: Missing[bool] = Undefined,
|
|
1095
1157
|
ignore_mute: Missing[bool] = Undefined,
|
|
1096
|
-
|
|
1097
|
-
|
|
1158
|
+
api_version: Literal[3, 4] = 4,
|
|
1159
|
+
) -> UUID | None:
|
|
1160
|
+
"""Reply to a message by `sync_id`.
|
|
1098
1161
|
|
|
1099
1162
|
:param bot_id: Bot which should perform the request.
|
|
1100
1163
|
:param sync_id: `sync_id` of message to reply on.
|
|
@@ -1112,6 +1175,8 @@ class Bot:
|
|
|
1112
1175
|
devices.
|
|
1113
1176
|
:param ignore_mute: (BotX default: False) Ignore mute or dnd (do not
|
|
1114
1177
|
disturb).
|
|
1178
|
+
:param api_version: Use v4 (BotX >= 3.79) by default or deprecated v3.
|
|
1179
|
+
:return: Sync ID of the sent reply for v4, or `None` for v3.
|
|
1115
1180
|
"""
|
|
1116
1181
|
|
|
1117
1182
|
payload = BotXAPIReplyEventRequestPayload.from_domain(
|
|
@@ -1132,7 +1197,7 @@ class Bot:
|
|
|
1132
1197
|
self._httpx_client,
|
|
1133
1198
|
self._bot_accounts_storage,
|
|
1134
1199
|
)
|
|
1135
|
-
await method.execute(payload)
|
|
1200
|
+
return await method.execute(payload, api_version=api_version)
|
|
1136
1201
|
|
|
1137
1202
|
async def get_message_status(self, *, bot_id: UUID, sync_id: UUID) -> MessageStatus:
|
|
1138
1203
|
"""
|
|
@@ -2611,7 +2676,9 @@ class Bot:
|
|
|
2611
2676
|
parts = traceparent.split("-")
|
|
2612
2677
|
if len(parts) >= 4:
|
|
2613
2678
|
trace_id = parts[1].lower()
|
|
2614
|
-
if len(trace_id) == 32 and all(
|
|
2679
|
+
if len(trace_id) == 32 and all(
|
|
2680
|
+
char in "0123456789abcdef" for char in trace_id
|
|
2681
|
+
):
|
|
2615
2682
|
return trace_id
|
|
2616
2683
|
|
|
2617
2684
|
b3 = self._get_header_value(request_headers, "b3")
|
|
@@ -2678,7 +2745,7 @@ class Bot:
|
|
|
2678
2745
|
headers: Mapping[str, str] | None,
|
|
2679
2746
|
*,
|
|
2680
2747
|
trusted_issuers: set[str] | None = None,
|
|
2681
|
-
) ->
|
|
2748
|
+
) -> BotAccountKey:
|
|
2682
2749
|
if headers is None:
|
|
2683
2750
|
raise RequestHeadersNotProvidedError
|
|
2684
2751
|
|
|
@@ -2700,14 +2767,13 @@ class Bot:
|
|
|
2700
2767
|
except jwt.DecodeError as decode_exc:
|
|
2701
2768
|
raise UnverifiedRequestError(decode_exc.args[0]) from decode_exc
|
|
2702
2769
|
if self._is_v2_payload(token_payload):
|
|
2703
|
-
self._verify_request_v2(token, token_payload, decode_algorithms)
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
)
|
|
2770
|
+
return self._verify_request_v2(token, token_payload, decode_algorithms)
|
|
2771
|
+
return self._verify_request_v1(
|
|
2772
|
+
token,
|
|
2773
|
+
token_payload,
|
|
2774
|
+
decode_algorithms,
|
|
2775
|
+
trusted_issuers,
|
|
2776
|
+
)
|
|
2711
2777
|
|
|
2712
2778
|
@staticmethod
|
|
2713
2779
|
def _is_v2_payload(token_payload: Mapping[str, Any]) -> bool:
|
|
@@ -2731,7 +2797,7 @@ class Bot:
|
|
|
2731
2797
|
token: str,
|
|
2732
2798
|
token_payload: Mapping[str, Any],
|
|
2733
2799
|
decode_algorithms: list[str],
|
|
2734
|
-
) ->
|
|
2800
|
+
) -> BotAccountKey:
|
|
2735
2801
|
issuer = token_payload.get("iss")
|
|
2736
2802
|
if issuer is None:
|
|
2737
2803
|
raise UnverifiedRequestError('Token is missing the "iss" claim')
|
|
@@ -2743,16 +2809,23 @@ class Bot:
|
|
|
2743
2809
|
except (TypeError, ValueError) as exc:
|
|
2744
2810
|
raise UnverifiedRequestError("Invalid issuer") from exc
|
|
2745
2811
|
|
|
2746
|
-
try:
|
|
2747
|
-
bot_account = self._bot_accounts_storage.get_bot_account(bot_id)
|
|
2748
|
-
except UnknownBotAccountError as unknown_bot_exc:
|
|
2749
|
-
raise UnverifiedRequestError(unknown_bot_exc.args[0]) from unknown_bot_exc
|
|
2750
|
-
|
|
2751
2812
|
audience = token_payload.get("aud")
|
|
2752
2813
|
if not audience or not isinstance(audience, str):
|
|
2753
2814
|
raise UnverifiedRequestError("Invalid audience parameter was provided.")
|
|
2815
|
+
|
|
2816
|
+
try:
|
|
2817
|
+
account_key = self._bot_accounts_storage.resolve_incoming_account_key(
|
|
2818
|
+
bot_id=bot_id,
|
|
2819
|
+
host=audience,
|
|
2820
|
+
)
|
|
2821
|
+
bot_account = self._bot_accounts_storage.get_bot_account_by_key(account_key)
|
|
2822
|
+
except (AmbiguousBotAccountError, UnknownBotAccountError) as exp:
|
|
2823
|
+
raise UnverifiedRequestError(str(exp)) from exp
|
|
2824
|
+
|
|
2754
2825
|
if audience != bot_account.host:
|
|
2755
|
-
raise UnverifiedRequestError(
|
|
2826
|
+
raise UnverifiedRequestError(
|
|
2827
|
+
"Invalid audience parameter was provided.",
|
|
2828
|
+
)
|
|
2756
2829
|
|
|
2757
2830
|
try:
|
|
2758
2831
|
jwt.decode(
|
|
@@ -2766,13 +2839,15 @@ class Bot:
|
|
|
2766
2839
|
except jwt.InvalidTokenError as exc:
|
|
2767
2840
|
raise UnverifiedRequestError(exc.args[0]) from exc
|
|
2768
2841
|
|
|
2842
|
+
return account_key
|
|
2843
|
+
|
|
2769
2844
|
def _verify_request_v1(
|
|
2770
2845
|
self,
|
|
2771
2846
|
token: str,
|
|
2772
2847
|
token_payload: Mapping[str, Any],
|
|
2773
2848
|
decode_algorithms: list[str],
|
|
2774
2849
|
trusted_issuers: set[str] | None,
|
|
2775
|
-
) ->
|
|
2850
|
+
) -> BotAccountKey:
|
|
2776
2851
|
audience = token_payload.get("aud")
|
|
2777
2852
|
if (
|
|
2778
2853
|
not audience
|
|
@@ -2783,9 +2858,55 @@ class Bot:
|
|
|
2783
2858
|
raise UnverifiedRequestError("Invalid audience parameter was provided.")
|
|
2784
2859
|
|
|
2785
2860
|
try:
|
|
2786
|
-
|
|
2787
|
-
except
|
|
2788
|
-
raise UnverifiedRequestError(
|
|
2861
|
+
bot_id = UUID(audience[-1])
|
|
2862
|
+
except (TypeError, ValueError) as exc:
|
|
2863
|
+
raise UnverifiedRequestError(
|
|
2864
|
+
"Invalid audience parameter was provided.",
|
|
2865
|
+
) from exc
|
|
2866
|
+
|
|
2867
|
+
issuer = token_payload.get("iss")
|
|
2868
|
+
if issuer is None:
|
|
2869
|
+
raise UnverifiedRequestError('Token is missing the "iss" claim')
|
|
2870
|
+
|
|
2871
|
+
if not isinstance(issuer, str):
|
|
2872
|
+
raise UnverifiedRequestError("Invalid issuer")
|
|
2873
|
+
|
|
2874
|
+
try:
|
|
2875
|
+
account_key = self._bot_accounts_storage.resolve_incoming_account_key(
|
|
2876
|
+
bot_id=bot_id,
|
|
2877
|
+
host=issuer,
|
|
2878
|
+
)
|
|
2879
|
+
bot_account = self._bot_accounts_storage.get_bot_account_by_key(
|
|
2880
|
+
account_key,
|
|
2881
|
+
)
|
|
2882
|
+
except (UnknownBotAccountError, AmbiguousBotAccountError) as exc:
|
|
2883
|
+
if not trusted_issuers or issuer not in trusted_issuers:
|
|
2884
|
+
raise UnverifiedRequestError(str(exc)) from exc
|
|
2885
|
+
|
|
2886
|
+
try:
|
|
2887
|
+
bot_account = self._bot_accounts_storage.get_bot_account(bot_id)
|
|
2888
|
+
except (UnknownBotAccountError, AmbiguousBotAccountError) as fallback_exc:
|
|
2889
|
+
raise UnverifiedRequestError(str(fallback_exc)) from fallback_exc
|
|
2890
|
+
|
|
2891
|
+
fallback_account_key = bot_account.account_key
|
|
2892
|
+
if fallback_account_key is not None:
|
|
2893
|
+
account_key = fallback_account_key
|
|
2894
|
+
else:
|
|
2895
|
+
try:
|
|
2896
|
+
account_key = (
|
|
2897
|
+
self._bot_accounts_storage.resolve_incoming_account_key(
|
|
2898
|
+
bot_id=bot_id,
|
|
2899
|
+
host=bot_account.host,
|
|
2900
|
+
)
|
|
2901
|
+
)
|
|
2902
|
+
bot_account = self._bot_accounts_storage.get_bot_account_by_key(
|
|
2903
|
+
account_key,
|
|
2904
|
+
)
|
|
2905
|
+
except (UnknownBotAccountError, AmbiguousBotAccountError):
|
|
2906
|
+
account_key = BotAccountKey(
|
|
2907
|
+
server_id=bot_account.host,
|
|
2908
|
+
bot_id=bot_id,
|
|
2909
|
+
)
|
|
2789
2910
|
|
|
2790
2911
|
try:
|
|
2791
2912
|
jwt.decode(
|
|
@@ -2802,14 +2923,12 @@ class Bot:
|
|
|
2802
2923
|
except jwt.InvalidTokenError as exc:
|
|
2803
2924
|
raise UnverifiedRequestError(exc.args[0]) from exc
|
|
2804
2925
|
|
|
2805
|
-
issuer = token_payload.get("iss")
|
|
2806
|
-
if issuer is None:
|
|
2807
|
-
raise UnverifiedRequestError('Token is missing the "iss" claim')
|
|
2808
|
-
|
|
2809
2926
|
if issuer != bot_account.host:
|
|
2810
2927
|
if not trusted_issuers or issuer not in trusted_issuers:
|
|
2811
2928
|
raise UnverifiedRequestError("Invalid issuer")
|
|
2812
2929
|
|
|
2930
|
+
return account_key
|
|
2931
|
+
|
|
2813
2932
|
@staticmethod
|
|
2814
2933
|
def _build_main_collector(
|
|
2815
2934
|
collectors: Sequence[HandlerCollector],
|
|
@@ -58,7 +58,7 @@ class StaticBotAccountProvider:
|
|
|
58
58
|
host: str | None,
|
|
59
59
|
) -> BotAccountKey:
|
|
60
60
|
account = self.get_account_by_bot_id(bot_id)
|
|
61
|
-
return BotAccountKey(server_id=
|
|
61
|
+
return BotAccountKey(server_id=account.host, bot_id=bot_id)
|
|
62
62
|
|
|
63
63
|
def iter_bot_accounts(self) -> Iterator[BotAccountWithSecret]:
|
|
64
64
|
yield from self._bot_accounts
|
|
@@ -60,12 +60,23 @@ class BotAccountsStorage:
|
|
|
60
60
|
return self._account_provider.get_account(account_key)
|
|
61
61
|
return self._account_provider.get_account_by_bot_id(bot_id)
|
|
62
62
|
|
|
63
|
+
def get_bot_account_by_key(
|
|
64
|
+
self,
|
|
65
|
+
account_key: BotAccountKey,
|
|
66
|
+
) -> BotAccountWithSecret:
|
|
67
|
+
return self._account_provider.get_account(account_key)
|
|
68
|
+
|
|
63
69
|
def resolve_incoming_account_key(
|
|
64
70
|
self,
|
|
65
71
|
*,
|
|
66
72
|
bot_id: UUID,
|
|
67
73
|
host: str | None,
|
|
68
74
|
) -> BotAccountKey:
|
|
75
|
+
if host is None:
|
|
76
|
+
current_account_key = self._get_current_account_key(bot_id)
|
|
77
|
+
if current_account_key is not None:
|
|
78
|
+
return current_account_key
|
|
79
|
+
|
|
69
80
|
return self._account_provider.resolve_incoming_account_key(
|
|
70
81
|
bot_id=bot_id,
|
|
71
82
|
host=host,
|
|
@@ -100,13 +100,30 @@ class BotXAPIReplyEventRequestPayload(UnverifiedPayloadBaseModel):
|
|
|
100
100
|
)
|
|
101
101
|
|
|
102
102
|
|
|
103
|
+
class BotXAPIReplyEventV3ResponsePayload(VerifiedPayloadBaseModel):
|
|
104
|
+
status: Literal["ok"]
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class BotXAPIReplyEventResult(VerifiedPayloadBaseModel):
|
|
108
|
+
sync_id: UUID
|
|
109
|
+
|
|
110
|
+
|
|
103
111
|
class BotXAPIReplyEventResponsePayload(VerifiedPayloadBaseModel):
|
|
104
112
|
status: Literal["ok"]
|
|
113
|
+
result: BotXAPIReplyEventResult
|
|
105
114
|
|
|
106
115
|
|
|
107
116
|
class ReplyEventMethod(AuthorizedBotXMethod):
|
|
108
|
-
async def execute(
|
|
109
|
-
|
|
117
|
+
async def execute(
|
|
118
|
+
self,
|
|
119
|
+
payload: BotXAPIReplyEventRequestPayload,
|
|
120
|
+
*,
|
|
121
|
+
api_version: Literal[3, 4] = 4,
|
|
122
|
+
) -> UUID | None:
|
|
123
|
+
if not isinstance(api_version, int) or api_version not in (3, 4):
|
|
124
|
+
raise ValueError(f"Unsupported reply event API version: {api_version}")
|
|
125
|
+
|
|
126
|
+
path = f"/api/v{api_version}/botx/events/reply_event"
|
|
110
127
|
|
|
111
128
|
response = await self._botx_method_call(
|
|
112
129
|
"POST",
|
|
@@ -114,7 +131,15 @@ class ReplyEventMethod(AuthorizedBotXMethod):
|
|
|
114
131
|
json=payload.jsonable_dict(),
|
|
115
132
|
)
|
|
116
133
|
|
|
117
|
-
|
|
134
|
+
if api_version == 3:
|
|
135
|
+
self._verify_and_extract_api_model(
|
|
136
|
+
BotXAPIReplyEventV3ResponsePayload,
|
|
137
|
+
response,
|
|
138
|
+
)
|
|
139
|
+
return None
|
|
140
|
+
|
|
141
|
+
api_model = self._verify_and_extract_api_model(
|
|
118
142
|
BotXAPIReplyEventResponsePayload,
|
|
119
143
|
response,
|
|
120
144
|
)
|
|
145
|
+
return api_model.result.sync_id
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "pybotx"
|
|
3
|
-
version = "0.77.
|
|
3
|
+
version = "0.77.2"
|
|
4
4
|
description = "A python library for interacting with eXpress BotX API"
|
|
5
5
|
authors = [
|
|
6
|
-
{ name = "Sidnev Nikolay"
|
|
7
|
-
{ name = "Maxim Gorbachev"
|
|
8
|
-
{ name = "Alexander Samoylenko"
|
|
9
|
-
{ name = "Arseniy Zhiltsov"
|
|
6
|
+
{ name = "Sidnev Nikolay" },
|
|
7
|
+
{ name = "Maxim Gorbachev" },
|
|
8
|
+
{ name = "Alexander Samoylenko" },
|
|
9
|
+
{ name = "Arseniy Zhiltsov" },
|
|
10
|
+
{ name = "Aleksandr Osovskii" },
|
|
10
11
|
]
|
|
11
12
|
readme = "README.md"
|
|
12
13
|
requires-python = ">=3.10,<4.0"
|