Pytdbot 0.9.2.dev2__tar.gz → 0.9.2.dev3__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 (43) hide show
  1. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/PKG-INFO +2 -2
  2. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/Pytdbot.egg-info/PKG-INFO +2 -2
  3. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/Pytdbot.egg-info/SOURCES.txt +2 -0
  4. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/README.md +1 -1
  5. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/__init__.py +11 -2
  6. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/client.py +88 -169
  7. pytdbot-0.9.2.dev3/pytdbot/client_manager.py +197 -0
  8. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/handlers/td_updates.py +68 -0
  9. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/methods/td_functions.py +550 -72
  10. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/tdjson/tdjson.py +12 -4
  11. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/types/__init__.py +43 -13
  12. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/types/td_types/types.py +898 -84
  13. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/utils/__init__.py +2 -0
  14. pytdbot-0.9.2.dev3/pytdbot/utils/asyncio_utils.py +10 -0
  15. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/LICENSE +0 -0
  16. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/MANIFEST.in +0 -0
  17. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/Pytdbot.egg-info/dependency_links.txt +0 -0
  18. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/Pytdbot.egg-info/requires.txt +0 -0
  19. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/Pytdbot.egg-info/top_level.txt +0 -0
  20. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/exception/__init__.py +0 -0
  21. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/filters.py +0 -0
  22. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/handlers/__init__.py +0 -0
  23. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/handlers/decorators.py +0 -0
  24. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/handlers/handler.py +0 -0
  25. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/methods/__init__.py +0 -0
  26. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/methods/methods.py +0 -0
  27. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/tdjson/__init__.py +0 -0
  28. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/types/plugins/__init__.py +0 -0
  29. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/types/td_types/__init__.py +0 -0
  30. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/types/td_types/bound_methods/__init__.py +0 -0
  31. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/types/td_types/bound_methods/callback_query.py +0 -0
  32. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/types/td_types/bound_methods/chatActions.py +0 -0
  33. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/types/td_types/bound_methods/file.py +0 -0
  34. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/types/td_types/bound_methods/message.py +0 -0
  35. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/utils/escape.py +0 -0
  36. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/utils/json_utils.py +0 -0
  37. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/utils/obj_encoder.py +0 -0
  38. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/utils/strings.py +0 -0
  39. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/utils/text_format.py +0 -0
  40. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/pytdbot/utils/webapps.py +0 -0
  41. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/requirements.txt +0 -0
  42. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/setup.cfg +0 -0
  43. {pytdbot-0.9.2.dev2 → pytdbot-0.9.2.dev3}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Pytdbot
3
- Version: 0.9.2.dev2
3
+ Version: 0.9.2.dev3
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.46-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)
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.47-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.2.dev2
3
+ Version: 0.9.2.dev3
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.46-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)
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.47-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
 
@@ -10,6 +10,7 @@ Pytdbot.egg-info/requires.txt
10
10
  Pytdbot.egg-info/top_level.txt
11
11
  pytdbot/__init__.py
12
12
  pytdbot/client.py
13
+ pytdbot/client_manager.py
13
14
  pytdbot/filters.py
14
15
  pytdbot/exception/__init__.py
15
16
  pytdbot/handlers/__init__.py
@@ -31,6 +32,7 @@ pytdbot/types/td_types/bound_methods/chatActions.py
31
32
  pytdbot/types/td_types/bound_methods/file.py
32
33
  pytdbot/types/td_types/bound_methods/message.py
33
34
  pytdbot/utils/__init__.py
35
+ pytdbot/utils/asyncio_utils.py
34
36
  pytdbot/utils/escape.py
35
37
  pytdbot/utils/json_utils.py
36
38
  pytdbot/utils/obj_encoder.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.46-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)
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.47-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
 
@@ -1,10 +1,19 @@
1
1
  from . import types, utils, filters, exception
2
2
  from .tdjson import TdJson
3
+ from .client_manager import ClientManager
3
4
  from .client import Client
4
5
 
5
- __all__ = ["types", "utils", "filters", "exception", "TdJson", "Client"]
6
+ __all__ = [
7
+ "types",
8
+ "utils",
9
+ "filters",
10
+ "exception",
11
+ "TdJson",
12
+ "ClientManager",
13
+ "Client",
14
+ ]
6
15
 
7
- __version__ = "0.9.2.dev2"
16
+ __version__ = "0.9.2.dev3"
8
17
  __copyright__ = "Copyright (c) 2022-2025 Pytdbot, AYMENJD"
9
18
  __license__ = "MIT License"
10
19
 
@@ -1,45 +1,37 @@
1
- import signal
2
- import pytdbot
3
1
  import asyncio
4
- import aio_pika
5
-
6
- from platform import python_implementation, python_version
2
+ import signal
3
+ from importlib import import_module
4
+ from json import dumps
5
+ from logging import DEBUG, getLogger
7
6
  from os.path import join as join_path
8
7
  from pathlib import Path
9
- from importlib import import_module
10
-
11
- from typing import Callable, Union, Dict
12
- from logging import getLogger, DEBUG
8
+ from platform import python_implementation, python_version
9
+ from threading import current_thread, main_thread
10
+ from typing import Callable, Dict, Union
13
11
 
12
+ import aio_pika
14
13
  from deepdiff import DeepDiff
15
- from concurrent.futures import ThreadPoolExecutor
16
- from threading import current_thread, main_thread
17
- from json import dumps
18
14
 
19
- from .tdjson import TdJson
20
- from .handlers import Decorators, Handler
21
- from .methods import Methods
22
- from .types import Plugins, LogStream
15
+ import pytdbot
16
+
23
17
  from . import types
18
+ from .client_manager import ClientManager
19
+ from .exception import AuthorizationError, StopHandlers
24
20
  from .filters import Filter
25
- from .exception import StopHandlers, AuthorizationError
21
+ from .handlers import Decorators, Handler
22
+ from .methods import Methods
23
+ from .types import LogStream, Plugins
26
24
  from .utils import (
27
25
  create_extra_id,
28
- json_loads,
29
- json_dumps,
26
+ dict_to_obj,
30
27
  get_bot_id_from_token,
28
+ get_running_loop,
29
+ json_dumps,
30
+ json_loads,
31
31
  obj_to_dict,
32
- dict_to_obj,
33
32
  )
34
33
 
35
34
 
36
- def get_running_loop():
37
- try:
38
- return asyncio.get_running_loop()
39
- except RuntimeError:
40
- return asyncio.new_event_loop()
41
-
42
-
43
35
  class Client(Decorators, Methods):
44
36
  r"""Pytdbot, a TDLib client
45
37
 
@@ -171,8 +163,11 @@ class Client(Decorators, Methods):
171
163
  if isinstance(self.__token, str)
172
164
  else None
173
165
  )
166
+ self.client_id = None
167
+ self.client_manager = None
174
168
  self.logger = getLogger(f"{__name__}:{self.my_id or 0}")
175
169
  self.td_verbosity = td_verbosity
170
+ self.td_log = td_log
176
171
  self.connection_state: str = None
177
172
  self.is_running = None
178
173
  self.me: types.User = None
@@ -184,8 +179,6 @@ class Client(Decorators, Methods):
184
179
 
185
180
  self._handlers = {"initializer": [], "finalizer": []}
186
181
  self._results: Dict[str, asyncio.Future] = {}
187
- self._tdjson = None if self.is_rabbitmq else TdJson(lib_path, td_verbosity)
188
- self.__listen_loop_task = None
189
182
  self._workers_tasks = None
190
183
  self.__authorization_state = None
191
184
  self.__cache = {"is_coro_filter": {}}
@@ -197,9 +190,14 @@ class Client(Decorators, Methods):
197
190
  "updateOption": self.__handle_update_option,
198
191
  "updateUser": self.__handle_update_user,
199
192
  }
200
- self.__login = False
193
+ self.__is_queue_worker = False
201
194
  self.__is_closing = False
202
195
 
196
+ # RabbitMQ
197
+ self.__rqueues = None
198
+ self.__rconnection = None
199
+ self.__rchannel = None
200
+
203
201
  self.loop = (
204
202
  loop if isinstance(loop, asyncio.AbstractEventLoop) else get_running_loop()
205
203
  )
@@ -207,16 +205,10 @@ class Client(Decorators, Methods):
207
205
  if plugins is not None:
208
206
  self._load_plugins()
209
207
 
210
- if isinstance(td_log, LogStream) and not self.is_rabbitmq:
211
- self._tdjson.execute(
212
- {"@type": "setLogStream", "log_stream": obj_to_dict(td_log)}
213
- )
214
-
215
208
  self.logger.info(f"Pytdbot v{pytdbot.VERSION}")
216
209
 
217
210
  async def __aenter__(self):
218
211
  await self.start()
219
- await self.login()
220
212
  return self
221
213
 
222
214
  async def __aexit__(self, exc_type, exc_val, exc_tb):
@@ -231,24 +223,27 @@ class Client(Decorators, Methods):
231
223
 
232
224
  return self.__authorization_state
233
225
 
234
- async def start(self, login: bool = True) -> None:
235
- r"""Start pytdbot client
236
-
237
- Parameters:
238
- login (``bool``, *optional*):
239
- Login after start. Default is ``True``
240
- """
241
-
242
- if self.user_bot:
243
- login = False
226
+ async def start(self) -> None:
227
+ r"""Start pytdbot client"""
244
228
 
245
229
  if not self.is_running:
246
230
  self.logger.info("Starting pytdbot client...")
247
231
 
232
+ if not self.client_manager:
233
+ self.client_manager = ClientManager(
234
+ self, self.lib_path, self.td_verbosity, loop=self.loop
235
+ )
236
+ await self.client_manager.start()
237
+
238
+ if isinstance(self.td_log, LogStream) and not self.is_rabbitmq:
239
+ await self.__send(
240
+ {"@type": "setLogStream", "log_stream": obj_to_dict(self.td_log)}
241
+ )
242
+
248
243
  if isinstance(self.workers, int):
249
244
  self._workers_tasks = [
250
245
  self.loop.create_task(self._queue_update_worker())
251
- for x in range(self.workers)
246
+ for _ in range(self.workers)
252
247
  ]
253
248
  self.__is_queue_worker = True
254
249
 
@@ -258,52 +253,14 @@ class Client(Decorators, Methods):
258
253
  self.logger.info("Started with unlimited updates processes")
259
254
 
260
255
  if self.is_rabbitmq:
261
- await self.__startRabbitMQ()
262
- else:
263
- self.__listen_loop_task = self.loop.create_task(self.__listen_loop())
256
+ await self.__start_rabbitmq()
257
+ else: # client_manager
258
+ self.is_running = True
264
259
 
265
260
  self.loop.create_task(
266
261
  self.getOption("version")
267
262
  ) # Ping TDLib to start processing updates
268
263
 
269
- if login:
270
- await self.login()
271
-
272
- async def login(self) -> None:
273
- r"""Login to Telegram."""
274
-
275
- if (
276
- not self.__token
277
- or self.user_bot
278
- or (self.is_authenticated or self.is_rabbitmq)
279
- ):
280
- return
281
-
282
- self.__login = True
283
-
284
- while self.authorization_state != "authorizationStateReady":
285
- await asyncio.sleep(0.1)
286
- if self.authorization_state == "authorizationStateClosed":
287
- return
288
-
289
- if not self.is_running:
290
- return
291
-
292
- self.me = await self.getMe()
293
- if isinstance(self.me, types.Error):
294
- self.logger.error(f"Get me error: {self.me.message}")
295
-
296
- self.is_authenticated = True
297
-
298
- self.logger.info(
299
- "Logged in as {} {}".format(
300
- self.me.first_name,
301
- str(self.me.id)
302
- if not self.me.usernames
303
- else "@" + self.me.usernames.editable_username,
304
- )
305
- )
306
-
307
264
  def add_handler(
308
265
  self,
309
266
  update_type: str,
@@ -366,13 +323,11 @@ class Client(Decorators, Methods):
366
323
 
367
324
  if not isinstance(func, Callable):
368
325
  raise TypeError("func must be callable")
369
- for update_type in self._handlers:
370
- for handler in self._handlers[update_type]:
326
+ for _, handlers in self._handlers.items():
327
+ for handler in handlers.copy():
371
328
  if handler.func == func:
372
- self._handlers[update_type].remove(handler)
373
- self._handlers[update_type].sort(
374
- key=lambda x: (x.position is None, x.position)
375
- )
329
+ handlers.remove(handler)
330
+ handlers.sort(key=lambda x: (x.position is None, x.position))
376
331
  return True
377
332
  return False
378
333
 
@@ -481,7 +436,7 @@ class Client(Decorators, Methods):
481
436
 
482
437
  return await self.invoke(kwargs)
483
438
 
484
- def run(self, login: bool = True) -> None:
439
+ def run(self) -> None:
485
440
  r"""Start the client and block until the client is stopped
486
441
 
487
442
  Example:
@@ -496,15 +451,11 @@ class Client(Decorators, Methods):
496
451
  await update.reply_text('Hello!')
497
452
 
498
453
  client.run()
499
-
500
- Parameters:
501
- login (``bool``, *optional*):
502
- Login after start. Default is ``True``
503
454
  """
504
455
 
505
456
  self._register_signal_handlers()
506
457
 
507
- self.loop.run_until_complete(self.start(login))
458
+ self.loop.run_until_complete(self.start())
508
459
  self.loop.run_until_complete(self.idle())
509
460
 
510
461
  async def idle(self):
@@ -549,6 +500,9 @@ class Client(Decorators, Methods):
549
500
 
550
501
  self.__stop_client()
551
502
 
503
+ if not self.client_manager.start_clients_on_add:
504
+ await self.client_manager.close()
505
+
552
506
  self.logger.info("Instance closed")
553
507
 
554
508
  return True
@@ -567,11 +521,7 @@ class Client(Decorators, Methods):
567
521
  return result
568
522
 
569
523
  async def __send(self, request: dict) -> None:
570
- if not self.is_rabbitmq:
571
- self._tdjson.send(
572
- request
573
- ) # tdjson.send is non-blocking method, So we don't need run_in_executor. This improves performance
574
- else:
524
+ if self.is_rabbitmq:
575
525
  await self.__rchannel.default_exchange.publish(
576
526
  aio_pika.Message(
577
527
  json_dumps(request, encode=True),
@@ -579,6 +529,8 @@ class Client(Decorators, Methods):
579
529
  ),
580
530
  routing_key=self.__rqueues["requests"].name,
581
531
  )
532
+ else:
533
+ self.client_manager.send(self.client_id, request)
582
534
 
583
535
  def _check_init_args(self):
584
536
  if self.user_bot:
@@ -675,31 +627,7 @@ class Client(Decorators, Methods):
675
627
  self.__cache["is_coro_filter"][func] = is_coro
676
628
  return is_coro
677
629
 
678
- async def __listen_loop(self):
679
- if self.is_rabbitmq:
680
- return
681
-
682
- with ThreadPoolExecutor(1, "pytdbot_listener") as thread:
683
- try:
684
- self.is_running = True
685
- self.logger.info("Listening to updates...")
686
-
687
- while self.is_running:
688
- update = await self.loop.run_in_executor(
689
- thread,
690
- self._tdjson.receive,
691
- 1.0, # Seconds
692
- )
693
- if update is None:
694
- continue
695
- self.loop.create_task(self._process_update(update))
696
-
697
- except Exception:
698
- self.logger.exception("Exception in __listen_loop")
699
- finally:
700
- self.is_running = False
701
-
702
- async def _process_update(self, update):
630
+ async def process_update(self, update):
703
631
  if not update:
704
632
  self.logger.warning("Received None update")
705
633
  return
@@ -891,13 +819,23 @@ class Client(Decorators, Methods):
891
819
  f"Authorization state changed to {self.authorization_state.removeprefix('authorizationState')}"
892
820
  )
893
821
 
894
- if self.__login:
895
- if self.authorization_state == "authorizationStateWaitTdlibParameters":
896
- await self._set_options()
897
- await self.set_td_parameters()
898
- elif self.authorization_state == "authorizationStateWaitPhoneNumber":
899
- self._print_welcome()
900
- await self.__handle_authorization_state_wait_phone_number()
822
+ if self.authorization_state == "authorizationStateWaitTdlibParameters":
823
+ await self._set_options()
824
+ await self.set_td_parameters()
825
+ elif self.authorization_state == "authorizationStateWaitPhoneNumber":
826
+ self._print_welcome()
827
+ await self.__handle_authorization_state_wait_phone_number()
828
+ elif self.authorization_state == "authorizationStateReady":
829
+ self.is_authenticated = True
830
+
831
+ self.me = await self.getMe()
832
+ if isinstance(self.me, types.Error):
833
+ self.logger.error(f"Get me error: {self.me.message}")
834
+
835
+ self.logger.info(
836
+ f"Logged in as {self.me.first_name} "
837
+ f"{str(self.me.id) if not self.me.usernames else '@' + self.me.usernames.editable_username}"
838
+ )
901
839
 
902
840
  if (
903
841
  self.authorization_state == "authorizationStateClosed"
@@ -961,7 +899,7 @@ class Client(Decorators, Methods):
961
899
  f"Could not connect to TDLib Server after {delay * retries} seconds timeout"
962
900
  )
963
901
 
964
- async def __startRabbitMQ(self):
902
+ async def __start_rabbitmq(self):
965
903
  self.__rconnection = await aio_pika.connect_robust(
966
904
  self.__rabbitmq_url,
967
905
  client_properties={
@@ -998,19 +936,7 @@ class Client(Decorators, Methods):
998
936
  for update in res.updates:
999
937
  # when using obj_to_dict the key "@client_id" won't exists
1000
938
  # since it's not part of the object
1001
- await self._process_update(obj_to_dict(update))
1002
-
1003
- self.me = await self.getMe()
1004
- self.is_authenticated = True
1005
-
1006
- self.logger.info(
1007
- "Logged in as {} {}".format(
1008
- self.me.first_name,
1009
- str(self.me.id)
1010
- if not self.me.usernames
1011
- else "@" + self.me.usernames.editable_username,
1012
- )
1013
- )
939
+ await self.process_update(obj_to_dict(update))
1014
940
 
1015
941
  if not self.no_updates:
1016
942
  await self.__rqueues["updates"].consume(self.__on_update, no_ack=True)
@@ -1018,7 +944,7 @@ class Client(Decorators, Methods):
1018
944
  await self.__rqueues["notify"].consume(self.__on_update, no_ack=True)
1019
945
 
1020
946
  async def __handle_rabbitmq_message(self, message: aio_pika.IncomingMessage):
1021
- await self._process_update(json_loads(message.body))
947
+ await self.process_update(json_loads(message.body))
1022
948
 
1023
949
  async def __on_update(self, update):
1024
950
  self.loop.create_task(self.__handle_rabbitmq_message(update))
@@ -1026,12 +952,8 @@ class Client(Decorators, Methods):
1026
952
  async def __handle_update_user(self, update: types.UpdateUser):
1027
953
  if self.is_authenticated and update.user.id == self.me.id:
1028
954
  self.logger.info(
1029
- "Updating {} ({}) info".format(
1030
- self.me.first_name,
1031
- str(self.me.id)
1032
- if not self.me.usernames
1033
- else "@" + self.me.usernames.editable_username,
1034
- )
955
+ f"Updating {self.me.first_name} "
956
+ f"({str(self.me.id) if not self.me.usernames else '@' + self.me.usernames.editable_username}) info"
1035
957
  )
1036
958
 
1037
959
  try:
@@ -1061,28 +983,25 @@ class Client(Decorators, Methods):
1061
983
  for worker_task in self._workers_tasks:
1062
984
  worker_task.cancel()
1063
985
 
1064
- if self.__listen_loop_task:
1065
- self.__listen_loop_task.cancel()
1066
-
1067
986
  def _register_signal_handlers(self):
1068
987
  def _handle_signal():
1069
988
  self.loop.create_task(self.stop())
1070
- for sig in {
989
+ for sig in (
1071
990
  signal.SIGINT,
1072
991
  signal.SIGTERM,
1073
992
  signal.SIGABRT,
1074
993
  signal.SIGSEGV,
1075
- }:
994
+ ):
1076
995
  self.loop.remove_signal_handler(sig)
1077
996
 
1078
997
  if current_thread() is main_thread():
1079
998
  try:
1080
- for sig in {
999
+ for sig in (
1081
1000
  signal.SIGINT,
1082
1001
  signal.SIGTERM,
1083
1002
  signal.SIGABRT,
1084
1003
  signal.SIGSEGV,
1085
- }:
1004
+ ):
1086
1005
  self.loop.add_signal_handler(sig, _handle_signal)
1087
1006
  except NotImplementedError: # Windows dosen't support add_signal_handler
1088
1007
  pass
@@ -1101,12 +1020,12 @@ def deepdiff(self, d1, d2):
1101
1020
 
1102
1021
  deep = DeepDiff(d1, d2, ignore_order=True, view="tree")
1103
1022
 
1104
- for parent in deep.keys():
1105
- for diff in deep[parent]:
1023
+ for parent, diffs in deep.items():
1024
+ for diff in diffs:
1106
1025
  difflist = diff.path(output_format="list")
1107
- key = ".".join(str(v) for v in difflist)
1026
+ key = ".".join(map(str, difflist))
1108
1027
 
1109
- if parent in {"dictionary_item_added", "values_changed"}:
1028
+ if parent in ("dictionary_item_added", "values_changed"):
1110
1029
  self.logger.info(f"{key} changed to {diff.t2}")
1111
1030
  elif parent == "dictionary_item_removed":
1112
1031
  self.logger.info(f"{key} removed")