pybotx 0.76.2__tar.gz → 0.76.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. {pybotx-0.76.2 → pybotx-0.76.4}/PKG-INFO +1 -1
  2. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/__init__.py +7 -1
  3. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/bot.py +78 -2
  4. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/chats_api/create_chat.py +2 -0
  5. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/exceptions/users.py +4 -0
  6. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/users_api/search_user_by_email.py +22 -3
  7. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/users_api/search_user_by_emails.py +10 -1
  8. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/users_api/update_user_profile.py +6 -1
  9. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/users_api/user_from_csv.py +9 -9
  10. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/users_api/user_from_search.py +9 -1
  11. pybotx-0.76.4/pybotx/client/voex_api/exceptions.py +9 -0
  12. pybotx-0.76.4/pybotx/client/voex_api/get_call.py +59 -0
  13. pybotx-0.76.4/pybotx/client/voex_api/get_conference.py +63 -0
  14. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/attachments.py +7 -4
  15. pybotx-0.76.4/pybotx/models/call.py +8 -0
  16. pybotx-0.76.4/pybotx/models/conference.py +10 -0
  17. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/enums.py +29 -0
  18. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/message/incoming_message.py +2 -0
  19. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/message/markup.py +1 -1
  20. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/sync_smartapp_event.py +13 -2
  21. pybotx-0.76.4/pybotx/py.typed +0 -0
  22. {pybotx-0.76.2 → pybotx-0.76.4}/pyproject.toml +1 -1
  23. {pybotx-0.76.2 → pybotx-0.76.4}/LICENSE +0 -0
  24. {pybotx-0.76.2 → pybotx-0.76.4}/README.md +0 -0
  25. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/async_buffer.py +0 -0
  26. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/auth.py +0 -0
  27. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/__init__.py +0 -0
  28. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/api/__init__.py +0 -0
  29. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/api/exceptions.py +0 -0
  30. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/api/responses/__init__.py +0 -0
  31. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/api/responses/bot_disabled.py +0 -0
  32. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/api/responses/command_accepted.py +0 -0
  33. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/api/responses/unverified_request.py +0 -0
  34. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/bot_accounts_storage.py +0 -0
  35. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/callbacks/__init__.py +0 -0
  36. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/callbacks/callback_manager.py +0 -0
  37. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/callbacks/callback_memory_repo.py +0 -0
  38. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/callbacks/callback_repo_proto.py +0 -0
  39. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/contextvars.py +0 -0
  40. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/exceptions.py +0 -0
  41. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/handler.py +0 -0
  42. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/handler_collector.py +0 -0
  43. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/middlewares/__init__.py +0 -0
  44. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/middlewares/exception_middleware.py +0 -0
  45. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/bot/testing.py +0 -0
  46. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/__init__.py +0 -0
  47. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/authorized_botx_method.py +0 -0
  48. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/bots_api/__init__.py +0 -0
  49. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/bots_api/bot_catalog.py +0 -0
  50. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/bots_api/get_token.py +0 -0
  51. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/botx_method.py +0 -0
  52. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/chats_api/__init__.py +0 -0
  53. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/chats_api/add_admin.py +0 -0
  54. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/chats_api/add_user.py +0 -0
  55. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/chats_api/chat_info.py +0 -0
  56. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/chats_api/create_chat_link.py +0 -0
  57. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/chats_api/create_thread.py +0 -0
  58. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/chats_api/disable_stealth.py +0 -0
  59. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/chats_api/list_chats.py +0 -0
  60. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/chats_api/personal_chat.py +0 -0
  61. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/chats_api/pin_message.py +0 -0
  62. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/chats_api/remove_user.py +0 -0
  63. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/chats_api/set_stealth.py +0 -0
  64. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/chats_api/unpin_message.py +0 -0
  65. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/events_api/__init__.py +0 -0
  66. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/events_api/delete_event.py +0 -0
  67. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/events_api/edit_event.py +0 -0
  68. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/events_api/message_status_event.py +0 -0
  69. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/events_api/reply_event.py +0 -0
  70. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/events_api/stop_typing_event.py +0 -0
  71. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/events_api/typing_event.py +0 -0
  72. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/exceptions/__init__.py +0 -0
  73. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/exceptions/base.py +0 -0
  74. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/exceptions/callbacks.py +0 -0
  75. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/exceptions/chats.py +0 -0
  76. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/exceptions/common.py +0 -0
  77. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/exceptions/event.py +0 -0
  78. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/exceptions/files.py +0 -0
  79. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/exceptions/http.py +0 -0
  80. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/exceptions/message.py +0 -0
  81. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/exceptions/notifications.py +0 -0
  82. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/files_api/__init__.py +0 -0
  83. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/files_api/download_file.py +0 -0
  84. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/files_api/upload_file.py +0 -0
  85. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/get_token.py +0 -0
  86. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/mertics_api/__init__.py +0 -0
  87. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/mertics_api/collect_bot_function.py +0 -0
  88. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/notifications_api/__init__.py +0 -0
  89. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/notifications_api/direct_notification.py +0 -0
  90. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/notifications_api/internal_bot_notification.py +0 -0
  91. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/openid_api/__init__.py +0 -0
  92. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/openid_api/refresh_access_token.py +0 -0
  93. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/smartapps_api/__init__.py +0 -0
  94. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/smartapps_api/exceptions.py +0 -0
  95. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/smartapps_api/smartapp_custom_notification.py +0 -0
  96. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/smartapps_api/smartapp_event.py +0 -0
  97. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/smartapps_api/smartapp_manifest.py +0 -0
  98. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/smartapps_api/smartapp_notification.py +0 -0
  99. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/smartapps_api/smartapp_unread_counter.py +0 -0
  100. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/smartapps_api/smartapps_list.py +0 -0
  101. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/smartapps_api/upload_file.py +0 -0
  102. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/stickers_api/__init__.py +0 -0
  103. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/stickers_api/add_sticker.py +0 -0
  104. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/stickers_api/create_sticker_pack.py +0 -0
  105. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/stickers_api/delete_sticker.py +0 -0
  106. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/stickers_api/delete_sticker_pack.py +0 -0
  107. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/stickers_api/edit_sticker_pack.py +0 -0
  108. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/stickers_api/exceptions.py +0 -0
  109. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/stickers_api/get_sticker.py +0 -0
  110. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/stickers_api/get_sticker_pack.py +0 -0
  111. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/stickers_api/get_sticker_packs.py +0 -0
  112. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/stickers_api/sticker_pack.py +0 -0
  113. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/users_api/__init__.py +0 -0
  114. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/users_api/search_user_by_huid.py +0 -0
  115. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/users_api/search_user_by_login.py +0 -0
  116. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/users_api/search_user_by_other_id.py +0 -0
  117. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/client/users_api/users_as_csv.py +0 -0
  118. {pybotx-0.76.2/pybotx/models → pybotx-0.76.4/pybotx/client/voex_api}/__init__.py +0 -0
  119. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/constants.py +0 -0
  120. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/converters.py +0 -0
  121. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/image_validators.py +0 -0
  122. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/logger.py +0 -0
  123. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/missing.py +0 -0
  124. {pybotx-0.76.2/pybotx/models/message → pybotx-0.76.4/pybotx/models}/__init__.py +0 -0
  125. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/api_base.py +0 -0
  126. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/async_files.py +0 -0
  127. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/base_command.py +0 -0
  128. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/bot_account.py +0 -0
  129. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/bot_catalog.py +0 -0
  130. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/bot_sender.py +0 -0
  131. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/chats.py +0 -0
  132. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/commands.py +0 -0
  133. {pybotx-0.76.2/pybotx/models/system_events → pybotx-0.76.4/pybotx/models/message}/__init__.py +0 -0
  134. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/message/edit_message.py +0 -0
  135. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/message/forward.py +0 -0
  136. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/message/mentions.py +0 -0
  137. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/message/message_status.py +0 -0
  138. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/message/outgoing_message.py +0 -0
  139. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/message/reply.py +0 -0
  140. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/message/reply_message.py +0 -0
  141. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/method_callbacks.py +0 -0
  142. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/smartapps.py +0 -0
  143. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/status.py +0 -0
  144. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/stickers.py +0 -0
  145. /pybotx-0.76.2/pybotx/py.typed → /pybotx-0.76.4/pybotx/models/system_events/__init__.py +0 -0
  146. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/system_events/added_to_chat.py +0 -0
  147. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/system_events/chat_created.py +0 -0
  148. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/system_events/chat_deleted_by_user.py +0 -0
  149. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/system_events/conference_changed.py +0 -0
  150. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/system_events/conference_created.py +0 -0
  151. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/system_events/conference_deleted.py +0 -0
  152. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/system_events/cts_login.py +0 -0
  153. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/system_events/cts_logout.py +0 -0
  154. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/system_events/deleted_from_chat.py +0 -0
  155. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/system_events/event_delete.py +0 -0
  156. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/system_events/event_edit.py +0 -0
  157. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/system_events/internal_bot_notification.py +0 -0
  158. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/system_events/left_from_chat.py +0 -0
  159. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/system_events/smartapp_event.py +0 -0
  160. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/system_events/user_joined_to_chat.py +0 -0
  161. {pybotx-0.76.2 → pybotx-0.76.4}/pybotx/models/users.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pybotx
3
- Version: 0.76.2
3
+ Version: 0.76.4
4
4
  Summary: A python library for interacting with eXpress BotX API
5
5
  License-File: LICENSE
6
6
  Author: Sidnev Nikolay
@@ -64,7 +64,10 @@ from pybotx.client.exceptions.notifications import (
64
64
  FinalRecipientsListEmptyError,
65
65
  StealthModeDisabledError,
66
66
  )
67
- from pybotx.client.exceptions.users import UserNotFoundError
67
+ from pybotx.client.exceptions.users import (
68
+ UserNotFoundError,
69
+ UserProfileUpdateUnavailableError,
70
+ )
68
71
  from pybotx.client.smartapps_api.exceptions import SyncSmartAppEventHandlerNotFoundError
69
72
  from pybotx.client.smartapps_api.smartapp_manifest import (
70
73
  SmartappManifest,
@@ -102,6 +105,7 @@ from pybotx.models.enums import (
102
105
  AttachmentTypes,
103
106
  ChatLinkTypes,
104
107
  ChatTypes,
108
+ ClientNetworkContours,
105
109
  ClientPlatforms,
106
110
  ConferenceLinkTypes,
107
111
  MentionTypes,
@@ -221,6 +225,7 @@ __all__ = (
221
225
  "ChatNotFoundError",
222
226
  "ChatLinkTypes",
223
227
  "ChatTypes",
228
+ "ClientNetworkContours",
224
229
  "ClientPlatforms",
225
230
  "ConferenceChangedEvent",
226
231
  "ConferenceCreatedEvent",
@@ -299,6 +304,7 @@ __all__ = (
299
304
  "UserFromSearch",
300
305
  "UserKinds",
301
306
  "UserNotFoundError",
307
+ "UserProfileUpdateUnavailableError",
302
308
  "UserSender",
303
309
  "Video",
304
310
  "Voice",
@@ -224,6 +224,14 @@ from pybotx.client.users_api.users_as_csv import (
224
224
  BotXAPIUsersAsCSVRequestPayload,
225
225
  UsersAsCSVMethod,
226
226
  )
227
+ from pybotx.client.voex_api.get_call import (
228
+ BotXAPIGetCallRequestPayload,
229
+ GetCallMethod,
230
+ )
231
+ from pybotx.client.voex_api.get_conference import (
232
+ BotXAPIGetConferenceRequestPayload,
233
+ GetConferenceMethod,
234
+ )
227
235
  from pybotx.constants import BOTX_DEFAULT_TIMEOUT, STICKER_PACKS_PER_PAGE
228
236
  from pybotx.converters import optional_sequence_to_list
229
237
  from pybotx.image_validators import (
@@ -236,12 +244,14 @@ from pybotx.models.async_files import File
236
244
  from pybotx.models.attachments import IncomingFileAttachment, OutgoingAttachment
237
245
  from pybotx.models.bot_account import BotAccountWithSecret
238
246
  from pybotx.models.bot_catalog import BotsListItem
247
+ from pybotx.models.call import Call
239
248
  from pybotx.models.chats import ChatInfo, ChatLink, ChatListItem
240
249
  from pybotx.models.commands import (
241
250
  BotAPISystemEvent,
242
251
  BotAPIIncomingMessage,
243
252
  BotCommand,
244
253
  )
254
+ from pybotx.models.conference import Conference
245
255
  from pybotx.models.enums import BotAPICommandTypes, ChatLinkTypes, ChatTypes
246
256
  from pybotx.models.message.edit_message import EditMessage
247
257
  from pybotx.models.message.markup import BubbleMarkup, KeyboardMarkup
@@ -1395,6 +1405,56 @@ class Bot:
1395
1405
 
1396
1406
  await method.execute(payload)
1397
1407
 
1408
+ async def get_call(
1409
+ self,
1410
+ *,
1411
+ bot_id: UUID,
1412
+ call_id: UUID,
1413
+ ) -> Call:
1414
+ """Get call.
1415
+
1416
+ :param bot_id: Bot which should perform the request.
1417
+ :param call_id: Call id.
1418
+
1419
+ :return: Call.
1420
+ """
1421
+ method = GetCallMethod(
1422
+ bot_id,
1423
+ self._httpx_client,
1424
+ self._bot_accounts_storage,
1425
+ )
1426
+ payload = BotXAPIGetCallRequestPayload.from_domain(
1427
+ call_id=call_id,
1428
+ )
1429
+ botx_call = await method.execute(payload)
1430
+
1431
+ return botx_call.to_domain()
1432
+
1433
+ async def get_conference(
1434
+ self,
1435
+ *,
1436
+ bot_id: UUID,
1437
+ call_id: UUID,
1438
+ ) -> Conference:
1439
+ """Get Conference.
1440
+
1441
+ :param bot_id: Bot which should perform the request.
1442
+ :param call_id: Call id.
1443
+
1444
+ :return: Conference.
1445
+ """
1446
+ method = GetConferenceMethod(
1447
+ bot_id,
1448
+ self._httpx_client,
1449
+ self._bot_accounts_storage,
1450
+ )
1451
+ payload = BotXAPIGetConferenceRequestPayload.from_domain(
1452
+ call_id=call_id,
1453
+ )
1454
+ botx_conference = await method.execute(payload)
1455
+
1456
+ return botx_conference.to_domain()
1457
+
1398
1458
  async def unpin_message(
1399
1459
  self,
1400
1460
  *,
@@ -1421,11 +1481,15 @@ class Bot:
1421
1481
  *,
1422
1482
  bot_id: UUID,
1423
1483
  emails: list[str],
1484
+ trusts_search: bool = False,
1485
+ partial_response: bool = False,
1424
1486
  ) -> list[UserFromSearch]:
1425
1487
  """Search user by emails for search.
1426
1488
 
1427
1489
  :param bot_id: Bot which should perform the request.
1428
1490
  :param emails: User emails.
1491
+ :param trusts_search: Search users on trusted servers.
1492
+ :param partial_response: Return local results if trusted server lookup fails.
1429
1493
 
1430
1494
  :return: Search result with user information.
1431
1495
  """
@@ -1435,7 +1499,11 @@ class Bot:
1435
1499
  self._httpx_client,
1436
1500
  self._bot_accounts_storage,
1437
1501
  )
1438
- payload = BotXAPISearchUserByEmailsRequestPayload.from_domain(emails=emails)
1502
+ payload = BotXAPISearchUserByEmailsRequestPayload.from_domain(
1503
+ emails=emails,
1504
+ trusts_search=trusts_search,
1505
+ partial_response=partial_response,
1506
+ )
1439
1507
 
1440
1508
  botx_api_users_from_search = await method.execute(payload)
1441
1509
 
@@ -1447,6 +1515,8 @@ class Bot:
1447
1515
  *,
1448
1516
  bot_id: UUID,
1449
1517
  email: str,
1518
+ trusts_search: bool = False,
1519
+ partial_response: bool = False,
1450
1520
  ) -> UserFromSearch:
1451
1521
  """Search user by email for search.
1452
1522
 
@@ -1455,6 +1525,8 @@ class Bot:
1455
1525
 
1456
1526
  :param bot_id: Bot which should perform the request.
1457
1527
  :param email: User email.
1528
+ :param trusts_search: Search users on trusted servers.
1529
+ :param partial_response: Return local results if trusted server lookup fails.
1458
1530
 
1459
1531
  :return: User information.
1460
1532
  """
@@ -1464,7 +1536,11 @@ class Bot:
1464
1536
  self._httpx_client,
1465
1537
  self._bot_accounts_storage,
1466
1538
  )
1467
- payload = BotXAPISearchUserByEmailRequestPayload.from_domain(email=email)
1539
+ payload = BotXAPISearchUserByEmailRequestPayload.from_domain(
1540
+ email=email,
1541
+ trusts_search=trusts_search,
1542
+ partial_response=partial_response,
1543
+ )
1468
1544
 
1469
1545
  botx_api_user_from_search = await method.execute(payload)
1470
1546
 
@@ -39,6 +39,8 @@ class BotXAPICreateChatRequestPayload(UnverifiedPayloadBaseModel):
39
39
  @model_validator(mode="before")
40
40
  def _convert_chat_type(cls, values: dict[str, Any]) -> dict[str, Any]:
41
41
  chat_type = values.get("chat_type")
42
+ if isinstance(chat_type, APIChatTypes) and chat_type == APIChatTypes.VOEX_CALL:
43
+ raise ValueError("Bot cannot create a chat of type 'voex_call'")
42
44
  if isinstance(chat_type, ChatTypes):
43
45
  values["chat_type"] = convert_chat_type_from_domain(chat_type)
44
46
  return values
@@ -11,3 +11,7 @@ class InvalidProfileDataError(BaseClientError):
11
11
 
12
12
  class NoUserKindSelectedError(BaseClientError):
13
13
  """No user kind selected."""
14
+
15
+
16
+ class UserProfileUpdateUnavailableError(BaseClientError):
17
+ """User profile update service is unavailable."""
@@ -9,15 +9,27 @@ from pybotx.client.users_api.user_from_search import (
9
9
  BotXAPISearchUserResponsePayload,
10
10
  )
11
11
  from pybotx.logger import logger
12
+ from pybotx.missing import Missing, Undefined
12
13
  from pybotx.models.api_base import UnverifiedPayloadBaseModel
13
14
 
14
15
 
15
16
  class BotXAPISearchUserByEmailRequestPayload(UnverifiedPayloadBaseModel):
16
17
  email: str
18
+ trusts_search: Missing[bool] = Undefined
19
+ partial_response: Missing[bool] = Undefined
17
20
 
18
21
  @classmethod
19
- def from_domain(cls, email: str) -> "BotXAPISearchUserByEmailRequestPayload":
20
- return cls(email=email)
22
+ def from_domain(
23
+ cls,
24
+ email: str,
25
+ trusts_search: bool = False,
26
+ partial_response: bool = False,
27
+ ) -> "BotXAPISearchUserByEmailRequestPayload":
28
+ return cls(
29
+ email=email,
30
+ trusts_search=trusts_search or Undefined,
31
+ partial_response=partial_response or Undefined,
32
+ )
21
33
 
22
34
 
23
35
  class SearchUserByEmailMethod(AuthorizedBotXMethod):
@@ -67,7 +79,14 @@ class SearchUserByEmailPostMethod(AuthorizedBotXMethod):
67
79
  path = "/api/v3/botx/users/by_email"
68
80
 
69
81
  email = payload.email
70
- request_json = {"emails": [email]}
82
+ request_json = {
83
+ "emails": [email],
84
+ "trusts_search": payload.trusts_search,
85
+ "partial_response": payload.partial_response,
86
+ }
87
+ request_json = {
88
+ key: value for key, value in request_json.items() if value is not Undefined
89
+ }
71
90
 
72
91
  response = await self._botx_method_call(
73
92
  "POST",
@@ -3,18 +3,27 @@ from pybotx.client.authorized_botx_method import AuthorizedBotXMethod
3
3
  from pybotx.client.users_api.user_from_search import (
4
4
  BotXAPISearchUserByEmailsResponsePayload,
5
5
  )
6
+ from pybotx.missing import Missing, Undefined
6
7
  from pybotx.models.api_base import UnverifiedPayloadBaseModel
7
8
 
8
9
 
9
10
  class BotXAPISearchUserByEmailsRequestPayload(UnverifiedPayloadBaseModel):
10
11
  emails: list[str]
12
+ trusts_search: Missing[bool] = Undefined
13
+ partial_response: Missing[bool] = Undefined
11
14
 
12
15
  @classmethod
13
16
  def from_domain(
14
17
  cls,
15
18
  emails: list[str],
19
+ trusts_search: bool = False,
20
+ partial_response: bool = False,
16
21
  ) -> "BotXAPISearchUserByEmailsRequestPayload":
17
- return cls(emails=emails)
22
+ return cls(
23
+ emails=emails,
24
+ trusts_search=trusts_search or Undefined,
25
+ partial_response=partial_response or Undefined,
26
+ )
18
27
 
19
28
 
20
29
  class SearchUserByEmailsMethod(AuthorizedBotXMethod):
@@ -3,7 +3,11 @@ from uuid import UUID
3
3
 
4
4
  from pybotx.client.authorized_botx_method import AuthorizedBotXMethod
5
5
  from pybotx.client.botx_method import response_exception_thrower
6
- from pybotx.client.exceptions.users import InvalidProfileDataError, UserNotFoundError
6
+ from pybotx.client.exceptions.users import (
7
+ InvalidProfileDataError,
8
+ UserNotFoundError,
9
+ UserProfileUpdateUnavailableError,
10
+ )
7
11
  from pybotx.missing import Missing, Undefined
8
12
  from pybotx.models.api_base import UnverifiedPayloadBaseModel, VerifiedPayloadBaseModel
9
13
  from pybotx.models.attachments import (
@@ -67,6 +71,7 @@ class UpdateUsersProfileMethod(AuthorizedBotXMethod):
67
71
  **AuthorizedBotXMethod.status_handlers,
68
72
  400: response_exception_thrower(InvalidProfileDataError),
69
73
  404: response_exception_thrower(UserNotFoundError),
74
+ 503: response_exception_thrower(UserProfileUpdateUnavailableError),
70
75
  }
71
76
 
72
77
  async def execute(
@@ -23,17 +23,17 @@ class BotXAPIUserFromCSVResult(VerifiedPayloadBaseModel):
23
23
  company: str | None = Field(alias="Company")
24
24
  department: str | None = Field(alias="Department")
25
25
  position: str | None = Field(alias="Position")
26
- avatar: str | None = Field(alias="Avatar")
27
- avatar_preview: str | None = Field(alias="Avatar preview")
28
- office: str | None = Field(alias="Office")
26
+ avatar: str | None = Field(default=None, alias="Avatar")
27
+ avatar_preview: str | None = Field(default=None, alias="Avatar preview")
28
+ office: str | None = Field(default=None, alias="Office")
29
29
  manager: str | None = Field(alias="Manager")
30
30
  manager_huid: UUID | None = Field(alias="Manager HUID")
31
- description: str | None = Field(alias="Description")
32
- phone: str | None = Field(alias="Phone")
33
- other_phone: str | None = Field(alias="Other phone")
34
- ip_phone: str | None = Field(alias="IP phone")
35
- other_ip_phone: str | None = Field(alias="Other IP phone")
36
- personnel_number: str | None = Field(alias="Personnel number")
31
+ description: str | None = Field(default=None, alias="Description")
32
+ phone: str | None = Field(default=None, alias="Phone")
33
+ other_phone: str | None = Field(default=None, alias="Other phone")
34
+ ip_phone: str | None = Field(default=None, alias="IP phone")
35
+ other_ip_phone: str | None = Field(default=None, alias="Other IP phone")
36
+ personnel_number: str | None = Field(default=None, alias="Personnel number")
37
37
 
38
38
  @field_validator(
39
39
  "email",
@@ -5,7 +5,7 @@ from uuid import UUID
5
5
  from pybotx.models.api_base import VerifiedPayloadBaseModel
6
6
  from pybotx.models.enums import APIUserKinds, convert_user_kind_to_domain
7
7
  from pybotx.models.users import UserFromSearch
8
- from pydantic import Field
8
+ from pydantic import Field, field_validator
9
9
 
10
10
 
11
11
  class BotXAPISearchUserResult(VerifiedPayloadBaseModel):
@@ -32,6 +32,14 @@ class BotXAPISearchUserResult(VerifiedPayloadBaseModel):
32
32
  created_at: datetime | None = None
33
33
  updated_at: datetime | None = None
34
34
 
35
+ @field_validator("ip_phone", "other_ip_phone", "other_phone", mode="before")
36
+ @classmethod
37
+ def convert_phone_to_string(cls, value: str | int | None) -> str | None:
38
+ if value is None:
39
+ return None
40
+
41
+ return str(value)
42
+
35
43
 
36
44
  class BotXAPISearchUserResponsePayload(VerifiedPayloadBaseModel):
37
45
  status: Literal["ok"]
@@ -0,0 +1,9 @@
1
+ from pybotx.client.exceptions.base import BaseClientError
2
+
3
+
4
+ class ConferenceNotFoundError(BaseClientError):
5
+ """Conference with specified call_id not found."""
6
+
7
+
8
+ class CallNotFoundError(BaseClientError):
9
+ """Call with specified call_id not found."""
@@ -0,0 +1,59 @@
1
+ from typing import Literal
2
+ from uuid import UUID
3
+
4
+ from pybotx.client.authorized_botx_method import AuthorizedBotXMethod
5
+ from pybotx.client.botx_method import response_exception_thrower
6
+ from pybotx.client.voex_api.exceptions import CallNotFoundError
7
+ from pybotx.models.api_base import UnverifiedPayloadBaseModel, VerifiedPayloadBaseModel
8
+ from pybotx.models.call import Call
9
+
10
+
11
+ class BotXAPIGetCallRequestPayload(UnverifiedPayloadBaseModel):
12
+ call_id: UUID
13
+
14
+ @classmethod
15
+ def from_domain(
16
+ cls,
17
+ call_id: UUID,
18
+ ) -> "BotXAPIGetCallRequestPayload":
19
+ return cls(call_id=call_id)
20
+
21
+
22
+ class BotXAPIGetCallResult(VerifiedPayloadBaseModel):
23
+ id: UUID
24
+ members: list[UUID]
25
+
26
+
27
+ class BotXAPIGetCallResponsePayload(VerifiedPayloadBaseModel):
28
+ status: Literal["ok"]
29
+ result: BotXAPIGetCallResult
30
+
31
+ def to_domain(self) -> Call:
32
+ return Call(
33
+ id=self.result.id,
34
+ members=self.result.members,
35
+ )
36
+
37
+
38
+ class GetCallMethod(AuthorizedBotXMethod):
39
+ status_handlers = {
40
+ **AuthorizedBotXMethod.status_handlers,
41
+ 404: response_exception_thrower(CallNotFoundError),
42
+ }
43
+
44
+ async def execute(
45
+ self,
46
+ payload: BotXAPIGetCallRequestPayload,
47
+ ) -> BotXAPIGetCallResponsePayload:
48
+ jsonable_dict = payload.jsonable_dict()
49
+ path = f"/api/v3/botx/voex/calls/{jsonable_dict['call_id']}"
50
+
51
+ response = await self._botx_method_call(
52
+ "GET",
53
+ self._build_url(path),
54
+ )
55
+
56
+ return self._verify_and_extract_api_model(
57
+ BotXAPIGetCallResponsePayload,
58
+ response,
59
+ )
@@ -0,0 +1,63 @@
1
+ from typing import Literal
2
+ from uuid import UUID
3
+
4
+ from pybotx.client.authorized_botx_method import AuthorizedBotXMethod
5
+ from pybotx.client.botx_method import response_exception_thrower
6
+ from pybotx.client.voex_api.exceptions import ConferenceNotFoundError
7
+ from pybotx.models.api_base import UnverifiedPayloadBaseModel, VerifiedPayloadBaseModel
8
+ from pybotx.models.conference import Conference
9
+
10
+
11
+ class BotXAPIGetConferenceRequestPayload(UnverifiedPayloadBaseModel):
12
+ call_id: UUID
13
+
14
+ @classmethod
15
+ def from_domain(
16
+ cls,
17
+ call_id: UUID,
18
+ ) -> "BotXAPIGetConferenceRequestPayload":
19
+ return cls(call_id=call_id)
20
+
21
+
22
+ class BotXAPIGetConferenceResult(VerifiedPayloadBaseModel):
23
+ id: UUID
24
+ name: str
25
+ link: str
26
+ members: list[UUID]
27
+
28
+
29
+ class BotXAPIGetConferenceResponsePayload(VerifiedPayloadBaseModel):
30
+ status: Literal["ok"]
31
+ result: BotXAPIGetConferenceResult
32
+
33
+ def to_domain(self) -> Conference:
34
+ return Conference(
35
+ id=self.result.id,
36
+ name=self.result.name,
37
+ link=self.result.link,
38
+ members=self.result.members,
39
+ )
40
+
41
+
42
+ class GetConferenceMethod(AuthorizedBotXMethod):
43
+ status_handlers = {
44
+ **AuthorizedBotXMethod.status_handlers,
45
+ 404: response_exception_thrower(ConferenceNotFoundError),
46
+ }
47
+
48
+ async def execute(
49
+ self,
50
+ payload: BotXAPIGetConferenceRequestPayload,
51
+ ) -> BotXAPIGetConferenceResponsePayload:
52
+ jsonable_dict = payload.jsonable_dict()
53
+ path = f"/api/v3/botx/voex/conferences/{jsonable_dict['call_id']}"
54
+
55
+ response = await self._botx_method_call(
56
+ "GET",
57
+ self._build_url(path),
58
+ )
59
+
60
+ return self._verify_and_extract_api_model(
61
+ BotXAPIGetConferenceResponsePayload,
62
+ response,
63
+ )
@@ -501,6 +501,12 @@ def encode_rfc2397(content: bytes, mimetype: str) -> str:
501
501
  return f"data:{mimetype};base64,{b64_content}"
502
502
 
503
503
 
504
+ def get_mimetype_by_filename(filename: str) -> str:
505
+ extension = filename.rsplit(".", 1)[-1].lower()
506
+
507
+ return EXTENSIONS_TO_MIMETYPES.get(extension, DEFAULT_MIMETYPE)
508
+
509
+
504
510
  class BotXAPIAttachment(UnverifiedPayloadBaseModel):
505
511
  file_name: str
506
512
  data: str
@@ -512,10 +518,7 @@ class BotXAPIAttachment(UnverifiedPayloadBaseModel):
512
518
  ) -> "BotXAPIAttachment":
513
519
  assert attachment.content is not None
514
520
 
515
- mimetype = EXTENSIONS_TO_MIMETYPES.get(
516
- attachment.filename.split(".")[-1],
517
- DEFAULT_MIMETYPE,
518
- )
521
+ mimetype = get_mimetype_by_filename(attachment.filename)
519
522
 
520
523
  return cls(
521
524
  file_name=attachment.filename,
@@ -0,0 +1,8 @@
1
+ from dataclasses import dataclass
2
+ from uuid import UUID
3
+
4
+
5
+ @dataclass(slots=True)
6
+ class Call:
7
+ id: UUID
8
+ members: list[UUID]
@@ -0,0 +1,10 @@
1
+ from dataclasses import dataclass
2
+ from uuid import UUID
3
+
4
+
5
+ @dataclass(slots=True)
6
+ class Conference:
7
+ id: UUID
8
+ name: str
9
+ link: str
10
+ members: list[UUID]
@@ -39,6 +39,11 @@ class ClientPlatforms(AutoName):
39
39
  AURORA = auto()
40
40
 
41
41
 
42
+ class ClientNetworkContours(AutoName):
43
+ INTERNAL = auto()
44
+ EXTERNAL = auto()
45
+
46
+
42
47
  class MentionTypes(AutoName):
43
48
  CONTACT = auto()
44
49
  CHAT = auto()
@@ -103,6 +108,7 @@ class APIChatTypes(Enum):
103
108
  GROUP_CHAT = "group_chat"
104
109
  CHANNEL = "channel"
105
110
  THREAD = "thread"
111
+ VOEX_CALL = "voex_call"
106
112
 
107
113
 
108
114
  class BotAPICommandTypes(StrEnum):
@@ -136,6 +142,11 @@ class BotAPIClientPlatforms(Enum):
136
142
  AURORA = "aurora"
137
143
 
138
144
 
145
+ class BotAPIClientNetworkContours(StrEnum):
146
+ INTERNAL = "internal"
147
+ EXTERNAL = "external"
148
+
149
+
139
150
  class BotAPIEntityTypes(StrEnum):
140
151
  MENTION = "mention"
141
152
  FORWARD = "forward"
@@ -208,6 +219,23 @@ def convert_client_platform_to_domain(
208
219
  return converted_type
209
220
 
210
221
 
222
+ def convert_client_network_contour_to_domain(
223
+ client_network_contour: BotAPIClientNetworkContours,
224
+ ) -> ClientNetworkContours:
225
+ client_network_contours_mapping = {
226
+ BotAPIClientNetworkContours.INTERNAL: ClientNetworkContours.INTERNAL,
227
+ BotAPIClientNetworkContours.EXTERNAL: ClientNetworkContours.EXTERNAL,
228
+ }
229
+
230
+ converted_type = client_network_contours_mapping.get(client_network_contour)
231
+ if converted_type is None:
232
+ raise NotImplementedError(
233
+ f"Unsupported client network contour: {client_network_contour}",
234
+ )
235
+
236
+ return converted_type
237
+
238
+
211
239
  def convert_mention_type_from_domain(
212
240
  mention_type: MentionTypes,
213
241
  ) -> BotAPIMentionTypes:
@@ -338,6 +366,7 @@ def convert_chat_type_to_domain(
338
366
  APIChatTypes.GROUP_CHAT: ChatTypes.GROUP_CHAT,
339
367
  APIChatTypes.CHANNEL: ChatTypes.CHANNEL,
340
368
  APIChatTypes.THREAD: ChatTypes.THREAD,
369
+ APIChatTypes.VOEX_CALL: ChatTypes.GROUP_CHAT,
341
370
  }
342
371
 
343
372
  converted_type: IncomingChatTypes | None
@@ -26,6 +26,7 @@ from pybotx.models.chats import Chat
26
26
  from pybotx.models.enums import (
27
27
  BotAPIEntityTypes,
28
28
  BotAPIMentionTypes,
29
+ ClientNetworkContours,
29
30
  ClientPlatforms,
30
31
  convert_chat_type_to_domain,
31
32
  convert_client_platform_to_domain,
@@ -68,6 +69,7 @@ class UserSender:
68
69
  is_chat_admin: bool | None
69
70
  is_chat_creator: bool | None
70
71
  device: UserDevice
72
+ client_network_contour: ClientNetworkContours | None = None
71
73
 
72
74
  @property
73
75
  def upn(self) -> str | None:
@@ -178,7 +178,7 @@ class BotXAPIButtonOptions(UnverifiedPayloadBaseModel):
178
178
 
179
179
 
180
180
  class BotXAPIButton(UnverifiedPayloadBaseModel):
181
- command: str
181
+ command: Missing[str]
182
182
  label: str
183
183
  data: dict[str, Any]
184
184
  opts: BotXAPIButtonOptions
@@ -14,7 +14,9 @@ from pybotx.models.bot_account import BotAccount
14
14
  from pybotx.models.chats import Chat
15
15
  from pybotx.models.enums import (
16
16
  BotAPIClientPlatforms,
17
+ BotAPIClientNetworkContours,
17
18
  ChatTypes,
19
+ convert_client_network_contour_to_domain,
18
20
  convert_client_platform_to_domain,
19
21
  )
20
22
  from pybotx.models.message.incoming_message import UserDevice, UserSender
@@ -25,6 +27,7 @@ class BotAPISyncSmartAppSender(VerifiedPayloadBaseModel):
25
27
  user_huid: UUID
26
28
  udid: UUID | None
27
29
  platform: BotAPIClientPlatforms | None
30
+ client_network_contour: BotAPIClientNetworkContours | None = None
28
31
 
29
32
 
30
33
  class BotAPISyncSmartAppPayload(VerifiedPayloadBaseModel):
@@ -59,6 +62,14 @@ class BotAPISyncSmartAppEvent(VerifiedPayloadBaseModel):
59
62
  locale=None,
60
63
  )
61
64
 
65
+ client_network_contour = (
66
+ convert_client_network_contour_to_domain(
67
+ self.sender_info.client_network_contour,
68
+ )
69
+ if self.sender_info.client_network_contour
70
+ else None
71
+ )
72
+
62
73
  sender = UserSender(
63
74
  huid=self.sender_info.user_huid,
64
75
  udid=self.sender_info.udid,
@@ -68,6 +79,7 @@ class BotAPISyncSmartAppEvent(VerifiedPayloadBaseModel):
68
79
  username=None,
69
80
  is_chat_admin=None,
70
81
  is_chat_creator=None,
82
+ client_network_contour=client_network_contour,
71
83
  )
72
84
 
73
85
  return SmartAppEvent(
@@ -143,6 +155,5 @@ class BotAPISyncSmartAppEventErrorResponse(UnverifiedPayloadBaseModel):
143
155
 
144
156
 
145
157
  BotAPISyncSmartAppEventResponse = (
146
- BotAPISyncSmartAppEventResultResponse
147
- | BotAPISyncSmartAppEventErrorResponse
158
+ BotAPISyncSmartAppEventResultResponse | BotAPISyncSmartAppEventErrorResponse
148
159
  )
File without changes