Pytdbot 0.9.0.dev6__tar.gz → 0.9.0.dev7__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 (42) hide show
  1. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/LICENSE +1 -1
  2. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/PKG-INFO +44 -15
  3. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/Pytdbot.egg-info/PKG-INFO +44 -15
  4. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/Pytdbot.egg-info/requires.txt +3 -0
  5. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/README.md +26 -11
  6. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/__init__.py +2 -2
  7. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/client.py +47 -82
  8. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/methods/methods.py +0 -65
  9. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/methods/td_functions.py +244 -82
  10. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/tdjson/tdjson.py +59 -36
  11. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/types/__init__.py +23 -5
  12. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/types/td_types/bound_methods/message.py +7 -20
  13. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/types/td_types/types.py +713 -155
  14. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/utils/__init__.py +9 -1
  15. pytdbot-0.9.0.dev7/pytdbot/utils/json_utils.py +27 -0
  16. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/utils/strings.py +19 -0
  17. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/setup.py +4 -1
  18. pytdbot-0.9.0.dev6/pytdbot/utils/json_utils.py +0 -23
  19. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/MANIFEST.in +0 -0
  20. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/Pytdbot.egg-info/SOURCES.txt +0 -0
  21. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/Pytdbot.egg-info/dependency_links.txt +0 -0
  22. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/Pytdbot.egg-info/top_level.txt +0 -0
  23. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/exception/__init__.py +0 -0
  24. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/filters.py +0 -0
  25. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/handlers/__init__.py +0 -0
  26. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/handlers/decorators.py +0 -0
  27. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/handlers/handler.py +0 -0
  28. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/handlers/td_updates.py +0 -0
  29. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/methods/__init__.py +0 -0
  30. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/tdjson/__init__.py +0 -0
  31. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/types/plugins/__init__.py +0 -0
  32. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/types/td_types/__init__.py +0 -0
  33. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/types/td_types/bound_methods/__init__.py +0 -0
  34. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/types/td_types/bound_methods/callback_query.py +0 -0
  35. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/types/td_types/bound_methods/chatActions.py +0 -0
  36. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/types/td_types/bound_methods/file.py +0 -0
  37. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/utils/escape.py +0 -0
  38. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/utils/obj_encoder.py +0 -0
  39. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/utils/text_format.py +0 -0
  40. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/pytdbot/utils/webapps.py +0 -0
  41. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/requirements.txt +0 -0
  42. {pytdbot-0.9.0.dev6 → pytdbot-0.9.0.dev7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2022-2025 Python TDLib
3
+ Copyright (c) 2022-2025 Pytdbot, AYMENJD
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: Pytdbot
3
- Version: 0.9.0.dev6
3
+ Version: 0.9.0.dev7
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
@@ -14,14 +14,28 @@ Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
15
  Requires-Dist: deepdiff
16
16
  Requires-Dist: aio-pika
17
-
18
- # 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.42-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)
19
-
20
- Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/td) wrapper for **Telegram** users/bots written in **Python**.
17
+ Provides-Extra: tdjson
18
+ Requires-Dist: tdjson; extra == "tdjson"
19
+ Dynamic: author
20
+ Dynamic: author-email
21
+ Dynamic: description
22
+ Dynamic: description-content-type
23
+ Dynamic: home-page
24
+ Dynamic: keywords
25
+ Dynamic: license
26
+ Dynamic: project-url
27
+ Dynamic: provides-extra
28
+ Dynamic: requires-dist
29
+ Dynamic: requires-python
30
+ Dynamic: summary
31
+
32
+ # 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.44-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
+
34
+ Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/td) wrapper for **Telegram** users/bots written in **Python**.
21
35
 
22
36
  ### Features
23
37
 
24
- ``Pytdbot`` offers numerous advantages, including:
38
+ `Pytdbot` offers numerous advantages, including:
25
39
 
26
40
  - **Easy to Use**: Designed with simplicity in mind, making it accessible for developers
27
41
  - **Performance**: Fast and powerful, making it ready to fight
@@ -32,30 +46,42 @@ Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/t
32
46
  - **Bound Methods**: Features types bound methods for improved usability
33
47
  - **Unlimited Support**: Supports **Plugins**, [**filters**](pytdbot/filters.py#L23), [**TDLib**](https://github.com/tdlib/td) types/functions and much more
34
48
 
35
-
36
-
37
49
  ### Requirements
38
50
 
39
51
  - Python 3.9+
40
52
  - Telegram [API key](https://my.telegram.org/apps)
41
- - [tdjson](https://github.com/tdlib/td#building)
53
+ - [tdjson](https://github.com/AYMENJD/tdjson) or [TDLib](https://github.com/tdlib/td#building)
42
54
  - [deepdiff](https://github.com/seperman/deepdiff)
43
55
  - [aio-pika](https://github.com/mosquito/aio-pika)
44
56
 
45
57
  ### Installation
58
+
46
59
  > For better performance, it's recommended to install [orjson](https://github.com/ijl/orjson#install) or [ujson](https://github.com/ultrajson/ultrajson#ultrajson).
47
60
 
48
- You can install Pytdbot using pip:
61
+ You can install Pytdbot with TDLib included using pip:
62
+
63
+ ```bash
64
+ pip install pytdbot[tdjson]
65
+ ```
66
+
67
+ or without **pre-built** TDLib:
68
+
49
69
  ```bash
50
70
  pip install pytdbot
51
71
  ```
52
- To install the development version from Github, use the following command:
72
+
73
+ If the install fails, then you need to build TDLib from [source](https://github.com/tdlib/td#building) and pass it to `Client(lib_path="/path/to/libtdjson")`.
74
+
75
+ You could also install the development version from Github, using the following command:
76
+
53
77
  ```bash
54
- pip install git+https://github.com/pytdbot/client.git
78
+ pip install --pre pytdbot
55
79
  ```
56
80
 
57
81
  ### Examples
82
+
58
83
  Basic example:
84
+
59
85
  ```python
60
86
 
61
87
  import asyncio
@@ -64,8 +90,8 @@ from pytdbot import Client, types
64
90
 
65
91
  client = Client(
66
92
  token="1088394097:AAQX2DnWiw4ihwiJUhIHOGog8gGOI", # Your bot token or phone number if you want to login as user
67
- api_id=0,
68
- api_hash="API_HASH",
93
+ api_id=0,
94
+ api_hash="API_HASH",
69
95
  lib_path="/path/to/libtdjson.so", # Path to TDjson shared library
70
96
  files_directory="BotDB", # Path where to store TDLib files
71
97
  database_encryption_key="1234echobot$",
@@ -94,12 +120,15 @@ async def say_hello(c: Client, message: types.Message):
94
120
  client.run()
95
121
 
96
122
  ```
123
+
97
124
  For more examples, check the [examples](https://github.com/pytdbot/client/tree/main/examples) folder.
98
125
 
99
126
  # Thanks to
127
+
100
128
  - You for viewing or using this project.
101
129
 
102
130
  - [@levlam](https://github.com/levlam) for maintaining [TDLib](https://github.com/tdlib/td) and for the help to create [Pytdbot](https://github.com/pytdbot/client).
131
+
103
132
  # License
104
133
 
105
134
  MIT [License](https://github.com/pytdbot/client/blob/main/LICENSE)
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: Pytdbot
3
- Version: 0.9.0.dev6
3
+ Version: 0.9.0.dev7
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
@@ -14,14 +14,28 @@ Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
15
  Requires-Dist: deepdiff
16
16
  Requires-Dist: aio-pika
17
-
18
- # 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.42-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)
19
-
20
- Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/td) wrapper for **Telegram** users/bots written in **Python**.
17
+ Provides-Extra: tdjson
18
+ Requires-Dist: tdjson; extra == "tdjson"
19
+ Dynamic: author
20
+ Dynamic: author-email
21
+ Dynamic: description
22
+ Dynamic: description-content-type
23
+ Dynamic: home-page
24
+ Dynamic: keywords
25
+ Dynamic: license
26
+ Dynamic: project-url
27
+ Dynamic: provides-extra
28
+ Dynamic: requires-dist
29
+ Dynamic: requires-python
30
+ Dynamic: summary
31
+
32
+ # 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.44-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
+
34
+ Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/td) wrapper for **Telegram** users/bots written in **Python**.
21
35
 
22
36
  ### Features
23
37
 
24
- ``Pytdbot`` offers numerous advantages, including:
38
+ `Pytdbot` offers numerous advantages, including:
25
39
 
26
40
  - **Easy to Use**: Designed with simplicity in mind, making it accessible for developers
27
41
  - **Performance**: Fast and powerful, making it ready to fight
@@ -32,30 +46,42 @@ Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/t
32
46
  - **Bound Methods**: Features types bound methods for improved usability
33
47
  - **Unlimited Support**: Supports **Plugins**, [**filters**](pytdbot/filters.py#L23), [**TDLib**](https://github.com/tdlib/td) types/functions and much more
34
48
 
35
-
36
-
37
49
  ### Requirements
38
50
 
39
51
  - Python 3.9+
40
52
  - Telegram [API key](https://my.telegram.org/apps)
41
- - [tdjson](https://github.com/tdlib/td#building)
53
+ - [tdjson](https://github.com/AYMENJD/tdjson) or [TDLib](https://github.com/tdlib/td#building)
42
54
  - [deepdiff](https://github.com/seperman/deepdiff)
43
55
  - [aio-pika](https://github.com/mosquito/aio-pika)
44
56
 
45
57
  ### Installation
58
+
46
59
  > For better performance, it's recommended to install [orjson](https://github.com/ijl/orjson#install) or [ujson](https://github.com/ultrajson/ultrajson#ultrajson).
47
60
 
48
- You can install Pytdbot using pip:
61
+ You can install Pytdbot with TDLib included using pip:
62
+
63
+ ```bash
64
+ pip install pytdbot[tdjson]
65
+ ```
66
+
67
+ or without **pre-built** TDLib:
68
+
49
69
  ```bash
50
70
  pip install pytdbot
51
71
  ```
52
- To install the development version from Github, use the following command:
72
+
73
+ If the install fails, then you need to build TDLib from [source](https://github.com/tdlib/td#building) and pass it to `Client(lib_path="/path/to/libtdjson")`.
74
+
75
+ You could also install the development version from Github, using the following command:
76
+
53
77
  ```bash
54
- pip install git+https://github.com/pytdbot/client.git
78
+ pip install --pre pytdbot
55
79
  ```
56
80
 
57
81
  ### Examples
82
+
58
83
  Basic example:
84
+
59
85
  ```python
60
86
 
61
87
  import asyncio
@@ -64,8 +90,8 @@ from pytdbot import Client, types
64
90
 
65
91
  client = Client(
66
92
  token="1088394097:AAQX2DnWiw4ihwiJUhIHOGog8gGOI", # Your bot token or phone number if you want to login as user
67
- api_id=0,
68
- api_hash="API_HASH",
93
+ api_id=0,
94
+ api_hash="API_HASH",
69
95
  lib_path="/path/to/libtdjson.so", # Path to TDjson shared library
70
96
  files_directory="BotDB", # Path where to store TDLib files
71
97
  database_encryption_key="1234echobot$",
@@ -94,12 +120,15 @@ async def say_hello(c: Client, message: types.Message):
94
120
  client.run()
95
121
 
96
122
  ```
123
+
97
124
  For more examples, check the [examples](https://github.com/pytdbot/client/tree/main/examples) folder.
98
125
 
99
126
  # Thanks to
127
+
100
128
  - You for viewing or using this project.
101
129
 
102
130
  - [@levlam](https://github.com/levlam) for maintaining [TDLib](https://github.com/tdlib/td) and for the help to create [Pytdbot](https://github.com/pytdbot/client).
131
+
103
132
  # License
104
133
 
105
134
  MIT [License](https://github.com/pytdbot/client/blob/main/LICENSE)
@@ -1,2 +1,5 @@
1
1
  deepdiff
2
2
  aio-pika
3
+
4
+ [tdjson]
5
+ tdjson
@@ -1,10 +1,10 @@
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.42-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.44-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)
2
2
 
3
- Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/td) wrapper for **Telegram** users/bots written in **Python**.
3
+ Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/td) wrapper for **Telegram** users/bots written in **Python**.
4
4
 
5
5
  ### Features
6
6
 
7
- ``Pytdbot`` offers numerous advantages, including:
7
+ `Pytdbot` offers numerous advantages, including:
8
8
 
9
9
  - **Easy to Use**: Designed with simplicity in mind, making it accessible for developers
10
10
  - **Performance**: Fast and powerful, making it ready to fight
@@ -15,30 +15,42 @@ Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/t
15
15
  - **Bound Methods**: Features types bound methods for improved usability
16
16
  - **Unlimited Support**: Supports **Plugins**, [**filters**](pytdbot/filters.py#L23), [**TDLib**](https://github.com/tdlib/td) types/functions and much more
17
17
 
18
-
19
-
20
18
  ### Requirements
21
19
 
22
20
  - Python 3.9+
23
21
  - Telegram [API key](https://my.telegram.org/apps)
24
- - [tdjson](https://github.com/tdlib/td#building)
22
+ - [tdjson](https://github.com/AYMENJD/tdjson) or [TDLib](https://github.com/tdlib/td#building)
25
23
  - [deepdiff](https://github.com/seperman/deepdiff)
26
24
  - [aio-pika](https://github.com/mosquito/aio-pika)
27
25
 
28
26
  ### Installation
27
+
29
28
  > For better performance, it's recommended to install [orjson](https://github.com/ijl/orjson#install) or [ujson](https://github.com/ultrajson/ultrajson#ultrajson).
30
29
 
31
- You can install Pytdbot using pip:
30
+ You can install Pytdbot with TDLib included using pip:
31
+
32
+ ```bash
33
+ pip install pytdbot[tdjson]
34
+ ```
35
+
36
+ or without **pre-built** TDLib:
37
+
32
38
  ```bash
33
39
  pip install pytdbot
34
40
  ```
35
- To install the development version from Github, use the following command:
41
+
42
+ If the install fails, then you need to build TDLib from [source](https://github.com/tdlib/td#building) and pass it to `Client(lib_path="/path/to/libtdjson")`.
43
+
44
+ You could also install the development version from Github, using the following command:
45
+
36
46
  ```bash
37
- pip install git+https://github.com/pytdbot/client.git
47
+ pip install --pre pytdbot
38
48
  ```
39
49
 
40
50
  ### Examples
51
+
41
52
  Basic example:
53
+
42
54
  ```python
43
55
 
44
56
  import asyncio
@@ -47,8 +59,8 @@ from pytdbot import Client, types
47
59
 
48
60
  client = Client(
49
61
  token="1088394097:AAQX2DnWiw4ihwiJUhIHOGog8gGOI", # Your bot token or phone number if you want to login as user
50
- api_id=0,
51
- api_hash="API_HASH",
62
+ api_id=0,
63
+ api_hash="API_HASH",
52
64
  lib_path="/path/to/libtdjson.so", # Path to TDjson shared library
53
65
  files_directory="BotDB", # Path where to store TDLib files
54
66
  database_encryption_key="1234echobot$",
@@ -77,12 +89,15 @@ async def say_hello(c: Client, message: types.Message):
77
89
  client.run()
78
90
 
79
91
  ```
92
+
80
93
  For more examples, check the [examples](https://github.com/pytdbot/client/tree/main/examples) folder.
81
94
 
82
95
  # Thanks to
96
+
83
97
  - You for viewing or using this project.
84
98
 
85
99
  - [@levlam](https://github.com/levlam) for maintaining [TDLib](https://github.com/tdlib/td) and for the help to create [Pytdbot](https://github.com/pytdbot/client).
100
+
86
101
  # License
87
102
 
88
103
  MIT [License](https://github.com/pytdbot/client/blob/main/LICENSE)
@@ -4,8 +4,8 @@ from .client import Client
4
4
 
5
5
  __all__ = ["types", "utils", "filters", "exception", "TdJson", "Client"]
6
6
 
7
- __version__ = "0.9.0dev6"
8
- __copyright__ = "Copyright (c) 2022-2025 AYMEN Mohammed ~ https://github.com/AYMENJD"
7
+ __version__ = "0.9.0dev7"
8
+ __copyright__ = "Copyright (c) 2022-2025 Pytdbot, AYMENJD"
9
9
  __license__ = "MIT License"
10
10
 
11
11
  VERSION = __version__
@@ -33,6 +33,13 @@ from .utils import (
33
33
  )
34
34
 
35
35
 
36
+ def get_running_loop():
37
+ try:
38
+ return asyncio.get_running_loop()
39
+ except RuntimeError:
40
+ return asyncio.new_event_loop()
41
+
42
+
36
43
  class Client(Decorators, Methods):
37
44
  r"""Pytdbot, a TDLib client
38
45
 
@@ -92,10 +99,6 @@ class Client(Decorators, Methods):
92
99
  options (``dict``, *optional*):
93
100
  Pass key-value dictionary to set TDLib options. Check the list of available options at https://core.telegram.org/tdlib/options
94
101
 
95
- sleep_threshold (``int``, *optional*):
96
- Sleep threshold for all ``FLOOD_WAIT_X`` a.k.a ``Too Many Requests: retry after`` errors occur to this client.
97
- If any request is rate limited (flood waited) the client will repeat the request after sleeping the required amount of seconds returned by the error. If the ``retry after`` value is higher than ``sleep_threshold`` the error is returned. Default is ``None`` (Disabled)
98
-
99
102
  workers (``int``, *optional*):
100
103
  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.
101
104
 
@@ -129,7 +132,6 @@ class Client(Decorators, Methods):
129
132
  use_message_database: bool = True,
130
133
  loop: asyncio.AbstractEventLoop = None,
131
134
  options: dict = None,
132
- sleep_threshold: int = None,
133
135
  workers: int = 5,
134
136
  no_updates: bool = False,
135
137
  td_verbosity: int = 2,
@@ -159,9 +161,6 @@ class Client(Decorators, Methods):
159
161
  self.use_chat_info_database = use_chat_info_database
160
162
  self.use_message_database = use_message_database
161
163
  self.td_options = options
162
- self.sleep_threshold = (
163
- sleep_threshold if isinstance(sleep_threshold, int) else 0
164
- )
165
164
  self.workers = workers
166
165
  self.no_updates = no_updates
167
166
  self.queue = asyncio.Queue()
@@ -180,7 +179,7 @@ class Client(Decorators, Methods):
180
179
  self._handlers = {"initializer": [], "finalizer": []}
181
180
  self._results: Dict[str, asyncio.Future] = {}
182
181
  self._tdjson = None if self.is_rabbitmq else TdJson(lib_path, td_verbosity)
183
- self._retry_after_prefex = "Too Many Requests: retry after "
182
+ self.__listen_loop_task = None
184
183
  self._workers_tasks = None
185
184
  self.__authorization_state = None
186
185
  self.__cache = {"is_coro_filter": {}}
@@ -196,9 +195,7 @@ class Client(Decorators, Methods):
196
195
  self.__is_closing = False
197
196
 
198
197
  self.loop = (
199
- loop
200
- if isinstance(loop, asyncio.AbstractEventLoop)
201
- else asyncio.get_event_loop()
198
+ loop if isinstance(loop, asyncio.AbstractEventLoop) else get_running_loop()
202
199
  )
203
200
 
204
201
  if plugins is not None:
@@ -254,7 +251,7 @@ class Client(Decorators, Methods):
254
251
  if self.is_rabbitmq:
255
252
  await self.__startRabbitMQ()
256
253
  else:
257
- self.loop.create_task(self.__listen_loop())
254
+ self.__listen_loop_task = self.loop.create_task(self.__listen_loop())
258
255
 
259
256
  if login:
260
257
  await self.login()
@@ -399,54 +396,47 @@ class Client(Decorators, Methods):
399
396
  ): # dumping all requests may create performance issues
400
397
  self.logger.debug(f"Sending: {dumps(request, indent=4)}")
401
398
 
402
- await self.__send(request)
403
- result = await future
404
-
405
- if isinstance(result, types.Error):
406
- if result.code == 429:
407
- retry_after = self.get_retry_after_time(result.message)
408
-
409
- if retry_after <= self.sleep_threshold:
410
- self.logger.error(
411
- f"Sleeping for {retry_after}s (Caused by {request['@type']})"
412
- )
399
+ is_chat_attempted_load = False
413
400
 
414
- await asyncio.sleep(retry_after)
401
+ while True:
402
+ future = self._create_request_future(request)
403
+ await self.__send(request)
404
+ result = await future
415
405
 
416
- future = self._create_request_future(request)
406
+ if isinstance(result, types.Error):
407
+ if result.code == 400:
408
+ if result.message.startswith(
409
+ "Failed to parse JSON object as TDLib request:"
410
+ ):
411
+ raise ValueError(result.message)
412
+ elif not is_chat_attempted_load and (
413
+ result.message == "Chat not found" and "chat_id" in request
414
+ ):
415
+ is_chat_attempted_load = True
417
416
 
418
- await self.__send(request)
419
- result = await future
420
- elif not self.use_message_database and (
421
- result.code == 400
422
- and result.message == "Chat not found"
423
- and "chat_id" in request
424
- ):
425
- chat_id = request["chat_id"]
417
+ chat_id = request["chat_id"]
426
418
 
427
- self.logger.debug(f"Attempt to load chat {chat_id}")
419
+ self.logger.debug(f"Attempt to load chat {chat_id}")
428
420
 
429
- load_chat = await self.getChat(chat_id)
421
+ load_chat = await self.getChat(chat_id)
430
422
 
431
- if not isinstance(load_chat, types.Error):
432
- self.logger.debug(f"Chat {chat_id} is loaded")
423
+ if not isinstance(load_chat, types.Error):
424
+ self.logger.debug(f"Chat {chat_id} is loaded")
433
425
 
434
- reply_to_message_id = (request.get("reply_to") or {}).get(
435
- "message_id", 0
436
- )
426
+ reply_to_message_id = (request.get("reply_to") or {}).get(
427
+ "message_id", 0
428
+ )
437
429
 
438
- # if the request is a reply to another message
439
- # load the replied message to avoid "Message not found"
440
- if reply_to_message_id > 0:
441
- await self.getMessage(chat_id, reply_to_message_id)
430
+ # if the request is a reply to another message
431
+ # load the replied message to avoid "Message not found"
432
+ if reply_to_message_id > 0:
433
+ await self.getMessage(chat_id, reply_to_message_id)
442
434
 
443
- # repeat the first request
444
- future = self._create_request_future(request)
435
+ continue
436
+ else:
437
+ self.logger.error(f"Couldn't load chat {chat_id}")
445
438
 
446
- await self.__send(request)
447
- result = await future
448
- else:
449
- self.logger.error(f"Couldn't load chat {chat_id}")
439
+ break
450
440
 
451
441
  return result
452
442
 
@@ -592,22 +582,6 @@ class Client(Decorators, Methods):
592
582
  if isinstance(self.workers, int) and self.workers < 1:
593
583
  raise ValueError("workers must be greater than 0")
594
584
 
595
- def get_retry_after_time(self, error_message: str) -> int:
596
- r"""Get the retry after time from flood wait error message
597
-
598
- Parameters:
599
- error_message (``str``):
600
- The returned error message from TDLib
601
-
602
- Returns:
603
- py:class:`int`
604
- """
605
-
606
- try:
607
- return int(error_message.removeprefix(self._retry_after_prefex))
608
- except Exception:
609
- return 0
610
-
611
585
  def _load_plugins(self):
612
586
  count = 0
613
587
  handlers = 0
@@ -694,7 +668,7 @@ class Client(Decorators, Methods):
694
668
  update = await self.loop.run_in_executor(
695
669
  thread,
696
670
  self._tdjson.receive,
697
- 100000.0, # Seconds
671
+ 1.0, # Seconds
698
672
  )
699
673
  if update is None:
700
674
  continue
@@ -858,6 +832,7 @@ class Client(Decorators, Methods):
858
832
  application_version=f"Pytdbot {pytdbot.__version__}",
859
833
  )
860
834
  if isinstance(res, types.Error):
835
+ await self.stop()
861
836
  raise AuthorizationError(res.message)
862
837
 
863
838
  async def _set_options(self):
@@ -929,20 +904,7 @@ class Client(Decorators, Methods):
929
904
  m_id = f"{update.message.chat_id}:{update.old_message_id}"
930
905
 
931
906
  if result := self._results.pop(m_id, None):
932
- if update.error.code == 429:
933
- retry_after = update.message.sending_state.retry_after
934
-
935
- if retry_after <= self.sleep_threshold:
936
- self.logger.error(
937
- f"Sleeping for {retry_after}s (Caused by {result.request['@type']})"
938
- )
939
-
940
- await asyncio.sleep(retry_after)
941
- res = await self.invoke(result.request)
942
-
943
- self._results[f"{res.id}{update.message.chat_id}"] = result
944
- else:
945
- result.set_result(update.error)
907
+ result.set_result(update.error)
946
908
 
947
909
  async def __handle_update_option(self, update: types.UpdateOption):
948
910
  if isinstance(update.value, types.OptionValueBoolean):
@@ -1067,6 +1029,7 @@ class Client(Decorators, Methods):
1067
1029
  res = await self.checkAuthenticationBotToken(self.__token)
1068
1030
 
1069
1031
  if isinstance(res, types.Error):
1032
+ await self.stop()
1070
1033
  raise AuthorizationError(res.message)
1071
1034
 
1072
1035
  def __stop_client(self) -> None:
@@ -1077,6 +1040,8 @@ class Client(Decorators, Methods):
1077
1040
  for worker_task in self._workers_tasks:
1078
1041
  worker_task.cancel()
1079
1042
 
1043
+ self.__listen_loop_task.cancel()
1044
+
1080
1045
  def _register_signal_handlers(self):
1081
1046
  def _handle_signal():
1082
1047
  self.loop.create_task(self.stop())