Pytdbot 0.9.2.dev1__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.dev1 → pytdbot-0.9.2.dev3}/PKG-INFO +2 -2
  2. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/Pytdbot.egg-info/PKG-INFO +2 -2
  3. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/Pytdbot.egg-info/SOURCES.txt +2 -0
  4. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/README.md +1 -1
  5. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/__init__.py +11 -2
  6. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/client.py +90 -170
  7. pytdbot-0.9.2.dev3/pytdbot/client_manager.py +197 -0
  8. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/handlers/td_updates.py +68 -0
  9. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/methods/td_functions.py +550 -72
  10. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/tdjson/tdjson.py +12 -4
  11. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/types/__init__.py +43 -13
  12. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/types/td_types/types.py +898 -84
  13. {pytdbot-0.9.2.dev1 → 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.dev1 → pytdbot-0.9.2.dev3}/LICENSE +0 -0
  16. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/MANIFEST.in +0 -0
  17. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/Pytdbot.egg-info/dependency_links.txt +0 -0
  18. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/Pytdbot.egg-info/requires.txt +0 -0
  19. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/Pytdbot.egg-info/top_level.txt +0 -0
  20. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/exception/__init__.py +0 -0
  21. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/filters.py +0 -0
  22. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/handlers/__init__.py +0 -0
  23. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/handlers/decorators.py +0 -0
  24. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/handlers/handler.py +0 -0
  25. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/methods/__init__.py +0 -0
  26. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/methods/methods.py +0 -0
  27. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/tdjson/__init__.py +0 -0
  28. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/types/plugins/__init__.py +0 -0
  29. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/types/td_types/__init__.py +0 -0
  30. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/types/td_types/bound_methods/__init__.py +0 -0
  31. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/types/td_types/bound_methods/callback_query.py +0 -0
  32. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/types/td_types/bound_methods/chatActions.py +0 -0
  33. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/types/td_types/bound_methods/file.py +0 -0
  34. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/types/td_types/bound_methods/message.py +0 -0
  35. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/utils/escape.py +0 -0
  36. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/utils/json_utils.py +0 -0
  37. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/utils/obj_encoder.py +0 -0
  38. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/utils/strings.py +0 -0
  39. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/utils/text_format.py +0 -0
  40. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/pytdbot/utils/webapps.py +0 -0
  41. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/requirements.txt +0 -0
  42. {pytdbot-0.9.2.dev1 → pytdbot-0.9.2.dev3}/setup.cfg +0 -0
  43. {pytdbot-0.9.2.dev1 → 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.dev1
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.dev1
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.dev1"
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
@@ -802,7 +730,8 @@ class Client(Decorators, Methods):
802
730
  async def _handle_update(self, update):
803
731
  if update.getType() in self._handlers:
804
732
  if (
805
- isinstance(update, types.UpdateNewMessage)
733
+ not self.user_bot
734
+ and isinstance(update, types.UpdateNewMessage)
806
735
  and update.message.is_outgoing
807
736
  ):
808
737
  return
@@ -890,13 +819,23 @@ class Client(Decorators, Methods):
890
819
  f"Authorization state changed to {self.authorization_state.removeprefix('authorizationState')}"
891
820
  )
892
821
 
893
- if self.__login:
894
- if self.authorization_state == "authorizationStateWaitTdlibParameters":
895
- await self._set_options()
896
- await self.set_td_parameters()
897
- elif self.authorization_state == "authorizationStateWaitPhoneNumber":
898
- self._print_welcome()
899
- 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
+ )
900
839
 
901
840
  if (
902
841
  self.authorization_state == "authorizationStateClosed"
@@ -960,7 +899,7 @@ class Client(Decorators, Methods):
960
899
  f"Could not connect to TDLib Server after {delay * retries} seconds timeout"
961
900
  )
962
901
 
963
- async def __startRabbitMQ(self):
902
+ async def __start_rabbitmq(self):
964
903
  self.__rconnection = await aio_pika.connect_robust(
965
904
  self.__rabbitmq_url,
966
905
  client_properties={
@@ -997,19 +936,7 @@ class Client(Decorators, Methods):
997
936
  for update in res.updates:
998
937
  # when using obj_to_dict the key "@client_id" won't exists
999
938
  # since it's not part of the object
1000
- await self._process_update(obj_to_dict(update))
1001
-
1002
- self.me = await self.getMe()
1003
- self.is_authenticated = True
1004
-
1005
- self.logger.info(
1006
- "Logged in as {} {}".format(
1007
- self.me.first_name,
1008
- str(self.me.id)
1009
- if not self.me.usernames
1010
- else "@" + self.me.usernames.editable_username,
1011
- )
1012
- )
939
+ await self.process_update(obj_to_dict(update))
1013
940
 
1014
941
  if not self.no_updates:
1015
942
  await self.__rqueues["updates"].consume(self.__on_update, no_ack=True)
@@ -1017,7 +944,7 @@ class Client(Decorators, Methods):
1017
944
  await self.__rqueues["notify"].consume(self.__on_update, no_ack=True)
1018
945
 
1019
946
  async def __handle_rabbitmq_message(self, message: aio_pika.IncomingMessage):
1020
- await self._process_update(json_loads(message.body))
947
+ await self.process_update(json_loads(message.body))
1021
948
 
1022
949
  async def __on_update(self, update):
1023
950
  self.loop.create_task(self.__handle_rabbitmq_message(update))
@@ -1025,12 +952,8 @@ class Client(Decorators, Methods):
1025
952
  async def __handle_update_user(self, update: types.UpdateUser):
1026
953
  if self.is_authenticated and update.user.id == self.me.id:
1027
954
  self.logger.info(
1028
- "Updating {} ({}) info".format(
1029
- self.me.first_name,
1030
- str(self.me.id)
1031
- if not self.me.usernames
1032
- else "@" + self.me.usernames.editable_username,
1033
- )
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"
1034
957
  )
1035
958
 
1036
959
  try:
@@ -1060,28 +983,25 @@ class Client(Decorators, Methods):
1060
983
  for worker_task in self._workers_tasks:
1061
984
  worker_task.cancel()
1062
985
 
1063
- if self.__listen_loop_task:
1064
- self.__listen_loop_task.cancel()
1065
-
1066
986
  def _register_signal_handlers(self):
1067
987
  def _handle_signal():
1068
988
  self.loop.create_task(self.stop())
1069
- for sig in {
989
+ for sig in (
1070
990
  signal.SIGINT,
1071
991
  signal.SIGTERM,
1072
992
  signal.SIGABRT,
1073
993
  signal.SIGSEGV,
1074
- }:
994
+ ):
1075
995
  self.loop.remove_signal_handler(sig)
1076
996
 
1077
997
  if current_thread() is main_thread():
1078
998
  try:
1079
- for sig in {
999
+ for sig in (
1080
1000
  signal.SIGINT,
1081
1001
  signal.SIGTERM,
1082
1002
  signal.SIGABRT,
1083
1003
  signal.SIGSEGV,
1084
- }:
1004
+ ):
1085
1005
  self.loop.add_signal_handler(sig, _handle_signal)
1086
1006
  except NotImplementedError: # Windows dosen't support add_signal_handler
1087
1007
  pass
@@ -1100,12 +1020,12 @@ def deepdiff(self, d1, d2):
1100
1020
 
1101
1021
  deep = DeepDiff(d1, d2, ignore_order=True, view="tree")
1102
1022
 
1103
- for parent in deep.keys():
1104
- for diff in deep[parent]:
1023
+ for parent, diffs in deep.items():
1024
+ for diff in diffs:
1105
1025
  difflist = diff.path(output_format="list")
1106
- key = ".".join(str(v) for v in difflist)
1026
+ key = ".".join(map(str, difflist))
1107
1027
 
1108
- if parent in {"dictionary_item_added", "values_changed"}:
1028
+ if parent in ("dictionary_item_added", "values_changed"):
1109
1029
  self.logger.info(f"{key} changed to {diff.t2}")
1110
1030
  elif parent == "dictionary_item_removed":
1111
1031
  self.logger.info(f"{key} removed")