Pytdbot 0.9.6.dev1__tar.gz → 0.9.8.dev0__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 (49) hide show
  1. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/PKG-INFO +2 -2
  2. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/Pytdbot.egg-info/PKG-INFO +2 -2
  3. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/Pytdbot.egg-info/SOURCES.txt +7 -7
  4. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/README.md +1 -1
  5. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/__init__.py +1 -1
  6. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/client.py +72 -28
  7. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/handlers/decorators.py +95 -15
  8. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/handlers/handler.py +3 -1
  9. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/handlers/td_updates.py +4193 -492
  10. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/methods/td_functions.py +971 -87
  11. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/tdjson/tdjson.py +15 -2
  12. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/types/__init__.py +207 -17
  13. pytdbot-0.9.8.dev0/pytdbot/types/bound_methods/__init__.py +10 -0
  14. {pytdbot-0.9.6.dev1/pytdbot/types/td_types → pytdbot-0.9.8.dev0/pytdbot/types}/bound_methods/callback_query.py +128 -110
  15. {pytdbot-0.9.6.dev1/pytdbot/types/td_types → pytdbot-0.9.8.dev0/pytdbot/types}/bound_methods/file.py +36 -36
  16. {pytdbot-0.9.6.dev1/pytdbot/types/td_types → pytdbot-0.9.8.dev0/pytdbot/types}/bound_methods/message.py +890 -881
  17. pytdbot-0.9.8.dev0/pytdbot/types/bound_methods/sender_id.py +36 -0
  18. pytdbot-0.9.6.dev1/pytdbot/types/td_types/types.py → pytdbot-0.9.8.dev0/pytdbot/types/td_types.py +4462 -275
  19. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/types/tdserver/schedule.py +8 -0
  20. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/utils/__init__.py +13 -1
  21. pytdbot-0.9.8.dev0/pytdbot/utils/json_utils.py +83 -0
  22. pytdbot-0.9.6.dev1/pytdbot/types/td_types/__init__.py +0 -1
  23. pytdbot-0.9.6.dev1/pytdbot/types/td_types/bound_methods/__init__.py +0 -4
  24. pytdbot-0.9.6.dev1/pytdbot/utils/json_utils.py +0 -27
  25. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/LICENSE +0 -0
  26. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/MANIFEST.in +0 -0
  27. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/Pytdbot.egg-info/dependency_links.txt +0 -0
  28. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/Pytdbot.egg-info/requires.txt +0 -0
  29. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/Pytdbot.egg-info/top_level.txt +0 -0
  30. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/client_manager.py +0 -0
  31. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/exception/__init__.py +0 -0
  32. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/filters.py +0 -0
  33. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/handlers/__init__.py +0 -0
  34. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/methods/__init__.py +0 -0
  35. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/methods/methods.py +0 -0
  36. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/tdjson/__init__.py +0 -0
  37. {pytdbot-0.9.6.dev1/pytdbot/types/td_types → pytdbot-0.9.8.dev0/pytdbot/types}/bound_methods/chatActions.py +0 -0
  38. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/types/plugins/__init__.py +0 -0
  39. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/types/tdserver/__init__.py +0 -0
  40. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/types/tdserver/stats.py +0 -0
  41. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/utils/asyncio_utils.py +0 -0
  42. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/utils/escape.py +0 -0
  43. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/utils/obj_encoder.py +0 -0
  44. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/utils/strings.py +0 -0
  45. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/utils/text_format.py +0 -0
  46. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/pytdbot/utils/webapps.py +0 -0
  47. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/requirements.txt +0 -0
  48. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/setup.cfg +0 -0
  49. {pytdbot-0.9.6.dev1 → pytdbot-0.9.8.dev0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Pytdbot
3
- Version: 0.9.6.dev1
3
+ Version: 0.9.8.dev0
4
4
  Summary: Easy-to-use asynchronous TDLib wrapper for Python.
5
5
  Home-page: https://github.com/pytdbot/client
6
6
  Author: AYMEN Mohammed
@@ -30,7 +30,7 @@ Dynamic: requires-dist
30
30
  Dynamic: requires-python
31
31
  Dynamic: summary
32
32
 
33
- # Pytdbot [![Version](https://img.shields.io/pypi/v/Pytdbot?style=flat&logo=pypi)](https://pypi.org/project/Pytdbot) [![TDLib version](https://img.shields.io/badge/TDLib-v1.8.51-blue?logo=telegram)](https://github.com/tdlib/td) [![Downloads](https://static.pepy.tech/personalized-badge/pytdbot?period=month&units=none&left_color=grey&right_color=brightgreen&left_text=Downloads)](https://pepy.tech/project/pytdbot) [![Telegram Chat](https://img.shields.io/badge/Pytdbot%20chat-blue?logo=telegram&label=Telegram)](https://t.me/pytdbotchat)
33
+ # Pytdbot [![Version](https://img.shields.io/pypi/v/Pytdbot?style=flat&logo=pypi)](https://pypi.org/project/Pytdbot) [![TDLib version](https://img.shields.io/badge/TDLib-v1.8.55-blue?logo=telegram)](https://github.com/tdlib/td) [![Downloads](https://static.pepy.tech/personalized-badge/pytdbot?period=month&units=none&left_color=grey&right_color=brightgreen&left_text=Downloads)](https://pepy.tech/project/pytdbot) [![Telegram Chat](https://img.shields.io/badge/Pytdbot%20chat-blue?logo=telegram&label=Telegram)](https://t.me/pytdbotchat)
34
34
 
35
35
  Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/td) wrapper for **Telegram** users/bots written in **Python**.
36
36
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Pytdbot
3
- Version: 0.9.6.dev1
3
+ Version: 0.9.8.dev0
4
4
  Summary: Easy-to-use asynchronous TDLib wrapper for Python.
5
5
  Home-page: https://github.com/pytdbot/client
6
6
  Author: AYMEN Mohammed
@@ -30,7 +30,7 @@ Dynamic: requires-dist
30
30
  Dynamic: requires-python
31
31
  Dynamic: summary
32
32
 
33
- # Pytdbot [![Version](https://img.shields.io/pypi/v/Pytdbot?style=flat&logo=pypi)](https://pypi.org/project/Pytdbot) [![TDLib version](https://img.shields.io/badge/TDLib-v1.8.51-blue?logo=telegram)](https://github.com/tdlib/td) [![Downloads](https://static.pepy.tech/personalized-badge/pytdbot?period=month&units=none&left_color=grey&right_color=brightgreen&left_text=Downloads)](https://pepy.tech/project/pytdbot) [![Telegram Chat](https://img.shields.io/badge/Pytdbot%20chat-blue?logo=telegram&label=Telegram)](https://t.me/pytdbotchat)
33
+ # Pytdbot [![Version](https://img.shields.io/pypi/v/Pytdbot?style=flat&logo=pypi)](https://pypi.org/project/Pytdbot) [![TDLib version](https://img.shields.io/badge/TDLib-v1.8.55-blue?logo=telegram)](https://github.com/tdlib/td) [![Downloads](https://static.pepy.tech/personalized-badge/pytdbot?period=month&units=none&left_color=grey&right_color=brightgreen&left_text=Downloads)](https://pepy.tech/project/pytdbot) [![Telegram Chat](https://img.shields.io/badge/Pytdbot%20chat-blue?logo=telegram&label=Telegram)](https://t.me/pytdbotchat)
34
34
 
35
35
  Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/td) wrapper for **Telegram** users/bots written in **Python**.
36
36
 
@@ -23,14 +23,14 @@ pytdbot/methods/td_functions.py
23
23
  pytdbot/tdjson/__init__.py
24
24
  pytdbot/tdjson/tdjson.py
25
25
  pytdbot/types/__init__.py
26
+ pytdbot/types/td_types.py
27
+ pytdbot/types/bound_methods/__init__.py
28
+ pytdbot/types/bound_methods/callback_query.py
29
+ pytdbot/types/bound_methods/chatActions.py
30
+ pytdbot/types/bound_methods/file.py
31
+ pytdbot/types/bound_methods/message.py
32
+ pytdbot/types/bound_methods/sender_id.py
26
33
  pytdbot/types/plugins/__init__.py
27
- pytdbot/types/td_types/__init__.py
28
- pytdbot/types/td_types/types.py
29
- pytdbot/types/td_types/bound_methods/__init__.py
30
- pytdbot/types/td_types/bound_methods/callback_query.py
31
- pytdbot/types/td_types/bound_methods/chatActions.py
32
- pytdbot/types/td_types/bound_methods/file.py
33
- pytdbot/types/td_types/bound_methods/message.py
34
34
  pytdbot/types/tdserver/__init__.py
35
35
  pytdbot/types/tdserver/schedule.py
36
36
  pytdbot/types/tdserver/stats.py
@@ -1,4 +1,4 @@
1
- # Pytdbot [![Version](https://img.shields.io/pypi/v/Pytdbot?style=flat&logo=pypi)](https://pypi.org/project/Pytdbot) [![TDLib version](https://img.shields.io/badge/TDLib-v1.8.51-blue?logo=telegram)](https://github.com/tdlib/td) [![Downloads](https://static.pepy.tech/personalized-badge/pytdbot?period=month&units=none&left_color=grey&right_color=brightgreen&left_text=Downloads)](https://pepy.tech/project/pytdbot) [![Telegram Chat](https://img.shields.io/badge/Pytdbot%20chat-blue?logo=telegram&label=Telegram)](https://t.me/pytdbotchat)
1
+ # Pytdbot [![Version](https://img.shields.io/pypi/v/Pytdbot?style=flat&logo=pypi)](https://pypi.org/project/Pytdbot) [![TDLib version](https://img.shields.io/badge/TDLib-v1.8.55-blue?logo=telegram)](https://github.com/tdlib/td) [![Downloads](https://static.pepy.tech/personalized-badge/pytdbot?period=month&units=none&left_color=grey&right_color=brightgreen&left_text=Downloads)](https://pepy.tech/project/pytdbot) [![Telegram Chat](https://img.shields.io/badge/Pytdbot%20chat-blue?logo=telegram&label=Telegram)](https://t.me/pytdbotchat)
2
2
 
3
3
  Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/td) wrapper for **Telegram** users/bots written in **Python**.
4
4
 
@@ -13,7 +13,7 @@ __all__ = [
13
13
  "Client",
14
14
  ]
15
15
 
16
- __version__ = "0.9.6.dev1"
16
+ __version__ = "0.9.8.dev0"
17
17
  __copyright__ = "Copyright (c) 2022-2025 Pytdbot, AYMENJD"
18
18
  __license__ = "MIT License"
19
19
 
@@ -94,8 +94,8 @@ class Client(Decorators, Methods):
94
94
  workers (``int``, *optional*):
95
95
  Number of workers to handle updates. Default is ``5``. If set to ``None``, updates will be immediately handled instead of being queued, which can impact performance.
96
96
 
97
- handlers_timeout (``float``, *optional*):
98
- Timeout for handlers. If set, each handler will be awaited with this timeout. Default is ``None`` (no timeout)
97
+ default_handlers_timeout (``float``, *optional*):
98
+ Default timeout for handlers. If set, each handler will be awaited with this timeout (ignored if ``timeout`` is set when registering handler). Default is ``None`` (no timeout)
99
99
 
100
100
  no_updates (``bool``, *optional*):
101
101
  Whether the client should handle updates or not. Applicable only when using [TDLib Server](https://github.com/pytdbot/tdlib-server). Default is ``False``
@@ -131,12 +131,14 @@ class Client(Decorators, Methods):
131
131
  loop: asyncio.AbstractEventLoop = None,
132
132
  options: dict = None,
133
133
  workers: int = 5,
134
- handlers_timeout: float = None,
134
+ queue_size: int = 1000,
135
+ default_handlers_timeout: float = None,
135
136
  no_updates: bool = False,
136
137
  load_messages_before_reply: bool = False,
137
138
  td_verbosity: int = 2,
138
139
  td_log: LogStream = None,
139
140
  user_bot: bool = False,
141
+ server_ack: bool = True,
140
142
  ) -> None:
141
143
  self.__api_id = api_id
142
144
  self.__api_hash = api_hash
@@ -163,11 +165,13 @@ class Client(Decorators, Methods):
163
165
  self.use_message_database = use_message_database
164
166
  self.td_options = options
165
167
  self.workers = workers
166
- self.handlers_timeout = handlers_timeout
168
+ self.queue_size = queue_size
169
+ self.default_handlers_timeout = default_handlers_timeout
167
170
  self.no_updates = no_updates
168
171
  self.load_messages_before_reply = load_messages_before_reply
169
172
  self.queue = asyncio.Queue()
170
173
  self.user_bot = user_bot
174
+ self.server_ack = server_ack
171
175
  self.my_id = (
172
176
  get_bot_id_from_token(self.__token)
173
177
  if isinstance(self.__token, str)
@@ -253,11 +257,14 @@ class Client(Decorators, Methods):
253
257
  return await self.invoke({"@type": "getServerStats"})
254
258
 
255
259
  async def scheduleEvent(
256
- self, payload: str, send_at: int
260
+ self, name: str, payload: str, send_at: int
257
261
  ) -> Union["pytdbot.types.ScheduledEvent", "pytdbot.types.Error"]:
258
262
  """Schedule an event
259
263
 
260
264
  Parameters:
265
+ name (:class:`str`):
266
+ Event name
267
+
261
268
  payload (:class:`str`):
262
269
  The event payload to be scheduled
263
270
 
@@ -267,13 +274,20 @@ class Client(Decorators, Methods):
267
274
 
268
275
  self._check_rabbitmq()
269
276
 
277
+ if not isinstance(name, str):
278
+ raise ValueError("name must be str")
270
279
  if not isinstance(payload, str):
271
280
  raise ValueError("payload must be str")
272
281
  if not isinstance(send_at, (int, float)):
273
282
  raise ValueError("send_at must be int")
274
283
 
275
284
  return await self.invoke(
276
- {"@type": "scheduleEvent", "payload": payload, "send_at": send_at}
285
+ {
286
+ "@type": "scheduleEvent",
287
+ "name": name,
288
+ "payload": payload,
289
+ "send_at": send_at,
290
+ }
277
291
  )
278
292
 
279
293
  async def cancelScheduledEvent(
@@ -344,6 +358,7 @@ class Client(Decorators, Methods):
344
358
  filters: pytdbot.filters.Filter = None,
345
359
  position: int = None,
346
360
  inner_object: bool = False,
361
+ timeout: float = None,
347
362
  is_from_plugin: bool = False,
348
363
  ) -> None:
349
364
  r"""Add an update handler
@@ -364,6 +379,9 @@ class Client(Decorators, Methods):
364
379
  inner_object (``bool``, *optional*):
365
380
  Wether to pass an inner object of update or not; for example ``UpdateNewMessage.message``. Default is ``False``
366
381
 
382
+ timeout (``float``, *optional*):
383
+ Max execution time for the handler before it timeout. If ``None``, ``Client.default_handlers_timeout`` is preferred. Default is ``None``
384
+
367
385
  is_from_plugin (``bool``, *optional*):
368
386
  Wether this handler is from a loaded plugin (this can help reloading plugin during runtime; for development only). Default is ``False``
369
387
 
@@ -384,7 +402,13 @@ class Client(Decorators, Methods):
384
402
  raise TypeError("filters must be instance of pytdbot.filters.Filter")
385
403
 
386
404
  handler = Handler(
387
- func, update_type, filters, position, inner_object, is_from_plugin
405
+ func=func,
406
+ update_type=update_type,
407
+ filter=filters,
408
+ position=position,
409
+ inner_object=inner_object,
410
+ timeout=timeout,
411
+ is_from_plugin=is_from_plugin,
388
412
  )
389
413
 
390
414
  if update_type not in self._handlers:
@@ -741,12 +765,13 @@ class Client(Decorators, Methods):
741
765
  for handler in handlers_to_load:
742
766
  if asyncio.iscoroutinefunction(handler.func):
743
767
  self.add_handler(
744
- handler.update_type,
745
- handler.func,
746
- handler.filter,
747
- handler.position,
748
- handler.inner_object,
749
- True,
768
+ update_type=handler.update_type,
769
+ func=handler.func,
770
+ filters=handler.filter,
771
+ position=handler.position,
772
+ inner_object=handler.inner_object,
773
+ timeout=handler.timeout,
774
+ is_from_plugin=True,
750
775
  )
751
776
  handlers += 1
752
777
  plugin_handlers_count += 1
@@ -825,17 +850,21 @@ class Client(Decorators, Methods):
825
850
  elif not filter_function(self, handler_value):
826
851
  continue
827
852
 
828
- if self.handlers_timeout is None:
853
+ if (
854
+ self.default_handlers_timeout is None
855
+ and initializer.timeout is None
856
+ ):
829
857
  await initializer(self, handler_value)
830
858
  else:
859
+ timeout = initializer.timeout or self.default_handlers_timeout
831
860
  try:
832
861
  await asyncio.wait_for(
833
862
  initializer(self, handler_value),
834
- timeout=self.handlers_timeout,
863
+ timeout=timeout,
835
864
  )
836
865
  except asyncio.TimeoutError:
837
866
  self.logger.warning(
838
- f"Initializer {initializer} timed out after {self.handlers_timeout} seconds"
867
+ f"Initializer {initializer} timed out after {timeout} seconds"
839
868
  )
840
869
  except StopHandlers as e:
841
870
  raise e
@@ -857,16 +886,17 @@ class Client(Decorators, Methods):
857
886
  elif not filter_function(self, handler_value):
858
887
  continue
859
888
 
860
- if self.handlers_timeout is None:
889
+ if self.default_handlers_timeout is None and handler.timeout is None:
861
890
  await handler(self, handler_value)
862
891
  else:
892
+ timeout = handler.timeout or self.default_handlers_timeout
863
893
  try:
864
894
  await asyncio.wait_for(
865
- handler(self, handler_value), timeout=self.handlers_timeout
895
+ handler(self, handler_value), timeout=timeout
866
896
  )
867
897
  except asyncio.TimeoutError:
868
898
  self.logger.warning(
869
- f"Handler {handler} timed out after {self.handlers_timeout} seconds"
899
+ f"Handler {handler} timed out after {timeout} seconds"
870
900
  )
871
901
  except StopHandlers as e:
872
902
  raise e
@@ -889,17 +919,18 @@ class Client(Decorators, Methods):
889
919
  elif not filter_function(self, handler_value):
890
920
  continue
891
921
 
892
- if self.handlers_timeout is None:
922
+ if self.default_handlers_timeout is None and finalizer.timeout is None:
893
923
  await finalizer(self, handler_value)
894
924
  else:
895
925
  try:
926
+ timeout = finalizer.timeout or self.default_handlers_timeout
896
927
  await asyncio.wait_for(
897
928
  finalizer(self, handler_value),
898
- timeout=self.handlers_timeout,
929
+ timeout=timeout,
899
930
  )
900
931
  except asyncio.TimeoutError:
901
932
  self.logger.warning(
902
- f"Finalizer {finalizer} timed out after {self.handlers_timeout} seconds"
933
+ f"Finalizer {finalizer} timed out after {timeout} seconds"
903
934
  )
904
935
  except StopHandlers as e:
905
936
  raise e
@@ -941,6 +972,9 @@ class Client(Decorators, Methods):
941
972
  `AuthorizationError`
942
973
  """
943
974
 
975
+ if self.is_rabbitmq:
976
+ return
977
+
944
978
  if isinstance(self.__database_encryption_key, str):
945
979
  self.__database_encryption_key = self.__database_encryption_key.encode(
946
980
  "utf-8"
@@ -1097,12 +1131,12 @@ class Client(Decorators, Methods):
1097
1131
  updates_queue = await self.__get_updates_queue()
1098
1132
 
1099
1133
  notify_queue = await self.__rchannel.declare_queue(
1100
- f"notify_{self._rabbitmq_instance_id}", exclusive=True
1134
+ f"{self.my_id}_notify_{self._rabbitmq_instance_id}", exclusive=True
1101
1135
  )
1102
1136
  await notify_queue.bind(await self.__rchannel.get_exchange("broadcast"))
1103
1137
 
1104
1138
  responses_queue = await self.__rchannel.declare_queue(
1105
- f"res_{self._rabbitmq_instance_id}", exclusive=True
1139
+ f"{self.my_id}_res_{self._rabbitmq_instance_id}", exclusive=True
1106
1140
  )
1107
1141
 
1108
1142
  self.__rqueues = {
@@ -1132,13 +1166,22 @@ class Client(Decorators, Methods):
1132
1166
  await self.__rqueues["notify"].consume(self.__on_update, no_ack=True)
1133
1167
 
1134
1168
  async def __rabbitmq_iterator(self):
1135
- async with self.__rqueues["updates"].iterator() as iterator:
1169
+ async with self.__rqueues["updates"].iterator(
1170
+ no_ack=not self.server_ack
1171
+ ) as iterator:
1136
1172
  async for message in iterator:
1137
- await self.queue.put(message)
1173
+ if self.queue.qsize() > self.queue_size:
1174
+ await message.nack(requeue=True)
1175
+ continue
1176
+
1177
+ self.queue.put_nowait(message)
1138
1178
 
1139
1179
  async def __rabbitmq_worker(self):
1140
1180
  while self.is_running:
1141
- message: aio_pika.IncomingMessage = await self.queue.get()
1181
+ try:
1182
+ message: aio_pika.IncomingMessage = self.queue.get_nowait()
1183
+ except asyncio.QueueEmpty:
1184
+ message: aio_pika.IncomingMessage = await self.queue.get()
1142
1185
 
1143
1186
  try:
1144
1187
  update = json_loads(message.body)
@@ -1175,7 +1218,8 @@ class Client(Decorators, Methods):
1175
1218
 
1176
1219
  async def __handle_authorization_state_wait_phone_number(self):
1177
1220
  if (
1178
- self.authorization_state != "authorizationStateWaitPhoneNumber"
1221
+ self.is_rabbitmq
1222
+ or self.authorization_state != "authorizationStateWaitPhoneNumber"
1179
1223
  or not self.__token
1180
1224
  ):
1181
1225
  return
@@ -18,6 +18,7 @@ class Decorators(Updates):
18
18
  filters: "pytdbot.filters.Filter" = None,
19
19
  position: int = None,
20
20
  inner_object: bool = False,
21
+ timeout: float = None,
21
22
  ) -> None:
22
23
  r"""A decorator to initialize an event object before running other handlers
23
24
 
@@ -31,6 +32,9 @@ class Decorators(Updates):
31
32
  inner_object (``bool``, *optional*):
32
33
  Wether to pass an inner object of update or not; for example ``UpdateNewMessage.message``. Default is ``False``
33
34
 
35
+ timeout (``float``, *optional*):
36
+ Max execution time for the initializer before it timeout. Default is ``None``
37
+
34
38
  Raises:
35
39
  :py:class:`TypeError`
36
40
  """
@@ -41,17 +45,32 @@ class Decorators(Updates):
41
45
  elif isinstance(self, pytdbot.Client):
42
46
  if iscoroutinefunction(func):
43
47
  self.add_handler(
44
- "initializer", func, filters, position, inner_object
48
+ update_type="initializer",
49
+ func=func,
50
+ filters=filters,
51
+ position=position,
52
+ inner_object=inner_object,
53
+ timeout=timeout,
45
54
  )
46
55
  else:
47
56
  raise TypeError("Handler must be async")
48
57
  elif isinstance(self, pytdbot.filters.Filter):
49
58
  func._handler = Handler(
50
- func, "initializer", self, position, inner_object
59
+ func=func,
60
+ update_type="initializer",
61
+ filter=self,
62
+ position=position,
63
+ inner_object=inner_object,
64
+ timeout=timeout,
51
65
  )
52
66
  else:
53
67
  func._handler = Handler(
54
- func, "initializer", filters, position, inner_object
68
+ func=func,
69
+ update_type="initializer",
70
+ filter=filters,
71
+ position=position,
72
+ inner_object=inner_object,
73
+ timeout=timeout,
55
74
  )
56
75
 
57
76
  return func
@@ -63,6 +82,7 @@ class Decorators(Updates):
63
82
  filters: "pytdbot.filters.Filter" = None,
64
83
  position: int = None,
65
84
  inner_object: bool = False,
85
+ timeout: float = None,
66
86
  ) -> None:
67
87
  r"""A decorator to finalize an event object after running all handlers
68
88
 
@@ -76,6 +96,9 @@ class Decorators(Updates):
76
96
  inner_object (``bool``, *optional*):
77
97
  Wether to pass an inner object of update or not; for example ``UpdateNewMessage.message``. Default is ``False``
78
98
 
99
+ timeout (``float``, *optional*):
100
+ Max execution time for the finalizer before it timeout. Default is ``None``
101
+
79
102
  Raises:
80
103
  :py:class:`TypeError`
81
104
  """
@@ -85,14 +108,33 @@ class Decorators(Updates):
85
108
  return func
86
109
  elif isinstance(self, pytdbot.Client):
87
110
  if iscoroutinefunction(func):
88
- self.add_handler("finalizer", func, filters, position, inner_object)
111
+ self.add_handler(
112
+ update_type="finalizer",
113
+ func=func,
114
+ filters=filters,
115
+ position=position,
116
+ inner_object=inner_object,
117
+ timeout=timeout,
118
+ )
89
119
  else:
90
120
  raise TypeError("Handler must be async")
91
121
  elif isinstance(self, pytdbot.filters.Filter):
92
- func._handler = Handler(func, "finalizer", self, position, inner_object)
122
+ func._handler = Handler(
123
+ func=func,
124
+ update_type="finalizer",
125
+ filter=self,
126
+ position=position,
127
+ inner_object=inner_object,
128
+ timeout=timeout,
129
+ )
93
130
  else:
94
131
  func._handler = Handler(
95
- func, "finalizer", filters, position, inner_object
132
+ func=func,
133
+ update_type="finalizer",
134
+ filter=filters,
135
+ position=position,
136
+ inner_object=inner_object,
137
+ timeout=timeout,
96
138
  )
97
139
  return func
98
140
 
@@ -102,6 +144,7 @@ class Decorators(Updates):
102
144
  self: "pytdbot.Client" = None,
103
145
  filters: "pytdbot.filters.Filter" = None,
104
146
  position: int = None,
147
+ timeout: float = None,
105
148
  ) -> None:
106
149
  r"""A decorator to handle ``updateNewMessage`` but with ``Message`` object.
107
150
 
@@ -112,6 +155,9 @@ class Decorators(Updates):
112
155
  position (``int``, *optional*):
113
156
  The function position in handlers list. Default is ``None`` (append)
114
157
 
158
+ timeout (``float``, *optional*):
159
+ Max execution time for the handler before it timeout. Default is ``None``
160
+
115
161
  Raises:
116
162
  :py:class:`TypeError`
117
163
  """
@@ -121,14 +167,33 @@ class Decorators(Updates):
121
167
  return func
122
168
  elif isinstance(self, pytdbot.Client):
123
169
  if iscoroutinefunction(func):
124
- self.add_handler("updateNewMessage", func, filters, position, True)
170
+ self.add_handler(
171
+ update_type="updateNewMessage",
172
+ func=func,
173
+ filters=filters,
174
+ position=position,
175
+ inner_object=True,
176
+ timeout=timeout,
177
+ )
125
178
  else:
126
179
  raise TypeError("Handler must be async")
127
180
  elif isinstance(self, pytdbot.filters.Filter):
128
- func._handler = Handler(func, "updateNewMessage", self, position, True)
181
+ func._handler = Handler(
182
+ func=func,
183
+ update_type="updateNewMessage",
184
+ filter=self,
185
+ position=position,
186
+ inner_object=True,
187
+ timeout=timeout,
188
+ )
129
189
  else:
130
190
  func._handler = Handler(
131
- func, "updateNewMessage", filters, position, True
191
+ func=func,
192
+ update_type="updateNewMessage",
193
+ filter=filters,
194
+ position=position,
195
+ inner_object=True,
196
+ timeout=timeout,
132
197
  )
133
198
 
134
199
  return func
@@ -139,7 +204,7 @@ class Decorators(Updates):
139
204
  self: "pytdbot.Client" = None,
140
205
  filters: "pytdbot.filters.Filter" = None,
141
206
  position: int = None,
142
- inner_object: bool = False,
207
+ timeout: float = None,
143
208
  ) -> None:
144
209
  r"""A scheduled event has been triggered
145
210
 
@@ -150,8 +215,8 @@ class Decorators(Updates):
150
215
  position (``int``, *optional*):
151
216
  The function position in handlers list. Default is ``None`` (append)
152
217
 
153
- inner_object (``bool``, *optional*):
154
- Wether to pass an inner object of update or not; for example ``UpdateNewMessage.message``. Default is ``False``
218
+ timeout (``float``, *optional*):
219
+ Max execution time for the handler before it timeout. Default is ``None``
155
220
 
156
221
  Raises:
157
222
  :py:class:`TypeError`
@@ -163,17 +228,32 @@ class Decorators(Updates):
163
228
  elif isinstance(self, pytdbot.Client):
164
229
  if iscoroutinefunction(func):
165
230
  self.add_handler(
166
- "updateScheduledEvent", func, filters, position, inner_object
231
+ update_type="updateScheduledEvent",
232
+ func=func,
233
+ filters=filters,
234
+ position=position,
235
+ inner_object=False,
236
+ timeout=timeout,
167
237
  )
168
238
  else:
169
239
  raise TypeError("Handler must be async")
170
240
  elif isinstance(self, pytdbot.filters.Filter):
171
241
  func._handler = Handler(
172
- func, "updateScheduledEvent", self, position, inner_object
242
+ func=func,
243
+ update_type="updateScheduledEvent",
244
+ filter=self,
245
+ position=position,
246
+ inner_object=False,
247
+ timeout=timeout,
173
248
  )
174
249
  else:
175
250
  func._handler = Handler(
176
- func, "updateScheduledEvent", filters, position, inner_object
251
+ func=func,
252
+ update_type="updateScheduledEvent",
253
+ filter=filters,
254
+ position=position,
255
+ inner_object=False,
256
+ timeout=timeout,
177
257
  )
178
258
 
179
259
  return func
@@ -15,6 +15,7 @@ class Handler:
15
15
  filter: Filter = None,
16
16
  position: int = None,
17
17
  inner_object: bool = False,
18
+ timeout: float = None,
18
19
  is_from_plugin: bool = False,
19
20
  ) -> None:
20
21
  self.func = func
@@ -22,13 +23,14 @@ class Handler:
22
23
  self.filter = filter
23
24
  self.position = position
24
25
  self.inner_object = inner_object
26
+ self.timeout = timeout
25
27
  self.is_from_plugin = is_from_plugin
26
28
 
27
29
  def __call__(self, client: "pytdbot.Client", update: "pytdbot.types.Update"):
28
30
  return self.func(client, update)
29
31
 
30
32
  def __str__(self) -> str:
31
- return f"Handler(func={self.func}, update_type={self.update_type}, filter={self.filter}, position={self.position}, inner_object={self.inner_object}, is_from_plugin={self.is_from_plugin})"
33
+ return f"Handler(func={self.func}, update_type={self.update_type}, filter={self.filter}, position={self.position}, inner_object={self.inner_object}, timeout={self.timeout}, is_from_plugin={self.is_from_plugin})"
32
34
 
33
35
  def __repr__(self) -> str:
34
36
  return str(self)