telegrinder 0.3.4__py3-none-any.whl → 0.3.4.post1__py3-none-any.whl
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.
Potentially problematic release.
This version of telegrinder might be problematic. Click here for more details.
- telegrinder/__init__.py +144 -144
- telegrinder/api/__init__.py +8 -8
- telegrinder/api/api.py +93 -93
- telegrinder/api/error.py +16 -16
- telegrinder/api/response.py +20 -20
- telegrinder/api/token.py +36 -36
- telegrinder/bot/__init__.py +66 -66
- telegrinder/bot/bot.py +76 -76
- telegrinder/bot/cute_types/__init__.py +17 -17
- telegrinder/bot/cute_types/base.py +258 -258
- telegrinder/bot/cute_types/callback_query.py +385 -385
- telegrinder/bot/cute_types/chat_join_request.py +61 -61
- telegrinder/bot/cute_types/chat_member_updated.py +160 -160
- telegrinder/bot/cute_types/inline_query.py +43 -43
- telegrinder/bot/cute_types/message.py +2637 -2637
- telegrinder/bot/cute_types/update.py +104 -104
- telegrinder/bot/cute_types/utils.py +95 -95
- telegrinder/bot/dispatch/__init__.py +55 -55
- telegrinder/bot/dispatch/abc.py +77 -77
- telegrinder/bot/dispatch/context.py +98 -98
- telegrinder/bot/dispatch/dispatch.py +202 -202
- telegrinder/bot/dispatch/handler/__init__.py +13 -13
- telegrinder/bot/dispatch/handler/abc.py +24 -24
- telegrinder/bot/dispatch/handler/audio_reply.py +44 -44
- telegrinder/bot/dispatch/handler/base.py +57 -57
- telegrinder/bot/dispatch/handler/document_reply.py +44 -44
- telegrinder/bot/dispatch/handler/func.py +135 -135
- telegrinder/bot/dispatch/handler/media_group_reply.py +43 -43
- telegrinder/bot/dispatch/handler/message_reply.py +36 -36
- telegrinder/bot/dispatch/handler/photo_reply.py +44 -44
- telegrinder/bot/dispatch/handler/sticker_reply.py +37 -37
- telegrinder/bot/dispatch/handler/video_reply.py +44 -44
- telegrinder/bot/dispatch/middleware/__init__.py +3 -3
- telegrinder/bot/dispatch/middleware/abc.py +22 -22
- telegrinder/bot/dispatch/process.py +157 -157
- telegrinder/bot/dispatch/return_manager/__init__.py +13 -13
- telegrinder/bot/dispatch/return_manager/abc.py +108 -108
- telegrinder/bot/dispatch/return_manager/callback_query.py +20 -20
- telegrinder/bot/dispatch/return_manager/inline_query.py +15 -15
- telegrinder/bot/dispatch/return_manager/message.py +36 -36
- telegrinder/bot/dispatch/view/__init__.py +13 -13
- telegrinder/bot/dispatch/view/abc.py +41 -41
- telegrinder/bot/dispatch/view/base.py +200 -200
- telegrinder/bot/dispatch/view/box.py +129 -129
- telegrinder/bot/dispatch/view/callback_query.py +17 -17
- telegrinder/bot/dispatch/view/chat_join_request.py +16 -16
- telegrinder/bot/dispatch/view/chat_member.py +39 -39
- telegrinder/bot/dispatch/view/inline_query.py +17 -17
- telegrinder/bot/dispatch/view/message.py +44 -44
- telegrinder/bot/dispatch/view/raw.py +114 -114
- telegrinder/bot/dispatch/waiter_machine/__init__.py +17 -17
- telegrinder/bot/dispatch/waiter_machine/actions.py +13 -13
- telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py +8 -8
- telegrinder/bot/dispatch/waiter_machine/hasher/callback.py +55 -55
- telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py +57 -57
- telegrinder/bot/dispatch/waiter_machine/hasher/message.py +51 -51
- telegrinder/bot/dispatch/waiter_machine/hasher/state.py +19 -19
- telegrinder/bot/dispatch/waiter_machine/machine.py +172 -172
- telegrinder/bot/dispatch/waiter_machine/middleware.py +89 -89
- telegrinder/bot/dispatch/waiter_machine/short_state.py +68 -68
- telegrinder/bot/polling/__init__.py +4 -4
- telegrinder/bot/polling/abc.py +25 -25
- telegrinder/bot/polling/polling.py +131 -131
- telegrinder/bot/rules/__init__.py +62 -62
- telegrinder/bot/rules/abc.py +206 -206
- telegrinder/bot/rules/adapter/__init__.py +17 -17
- telegrinder/bot/rules/adapter/abc.py +31 -31
- telegrinder/bot/rules/adapter/errors.py +5 -5
- telegrinder/bot/rules/adapter/event.py +65 -65
- telegrinder/bot/rules/adapter/node.py +48 -48
- telegrinder/bot/rules/adapter/raw_event.py +27 -27
- telegrinder/bot/rules/adapter/raw_update.py +30 -30
- telegrinder/bot/rules/callback_data.py +163 -163
- telegrinder/bot/rules/chat_join.py +43 -43
- telegrinder/bot/rules/command.py +126 -126
- telegrinder/bot/rules/enum_text.py +36 -36
- telegrinder/bot/rules/func.py +26 -26
- telegrinder/bot/rules/fuzzy.py +24 -24
- telegrinder/bot/rules/inline.py +56 -56
- telegrinder/bot/rules/integer.py +20 -20
- telegrinder/bot/rules/is_from.py +127 -127
- telegrinder/bot/rules/markup.py +43 -43
- telegrinder/bot/rules/mention.py +14 -14
- telegrinder/bot/rules/message.py +17 -17
- telegrinder/bot/rules/message_entities.py +35 -35
- telegrinder/bot/rules/node.py +27 -27
- telegrinder/bot/rules/regex.py +37 -37
- telegrinder/bot/rules/rule_enum.py +72 -72
- telegrinder/bot/rules/start.py +42 -42
- telegrinder/bot/rules/state.py +37 -37
- telegrinder/bot/rules/text.py +33 -33
- telegrinder/bot/rules/update.py +15 -15
- telegrinder/bot/scenario/__init__.py +5 -5
- telegrinder/bot/scenario/abc.py +19 -19
- telegrinder/bot/scenario/checkbox.py +176 -176
- telegrinder/bot/scenario/choice.py +51 -51
- telegrinder/client/__init__.py +4 -4
- telegrinder/client/abc.py +75 -75
- telegrinder/client/aiohttp.py +130 -130
- telegrinder/model.py +313 -313
- telegrinder/modules.py +237 -237
- telegrinder/msgspec_json.py +14 -14
- telegrinder/msgspec_utils.py +410 -410
- telegrinder/node/__init__.py +20 -20
- telegrinder/node/attachment.py +87 -87
- telegrinder/node/base.py +157 -157
- telegrinder/node/callback_query.py +53 -53
- telegrinder/node/command.py +33 -33
- telegrinder/node/composer.py +198 -198
- telegrinder/node/container.py +27 -27
- telegrinder/node/event.py +65 -65
- telegrinder/node/me.py +16 -16
- telegrinder/node/message.py +14 -14
- telegrinder/node/polymorphic.py +48 -48
- telegrinder/node/rule.py +76 -76
- telegrinder/node/scope.py +38 -38
- telegrinder/node/source.py +71 -71
- telegrinder/node/text.py +41 -41
- telegrinder/node/tools/__init__.py +3 -3
- telegrinder/node/tools/generator.py +40 -40
- telegrinder/node/update.py +15 -15
- telegrinder/rules.py +5 -5
- telegrinder/tools/__init__.py +74 -74
- telegrinder/tools/buttons.py +79 -79
- telegrinder/tools/error_handler/__init__.py +7 -7
- telegrinder/tools/error_handler/abc.py +33 -33
- telegrinder/tools/error_handler/error.py +9 -9
- telegrinder/tools/error_handler/error_handler.py +193 -193
- telegrinder/tools/formatting/__init__.py +46 -46
- telegrinder/tools/formatting/html.py +283 -283
- telegrinder/tools/formatting/links.py +33 -33
- telegrinder/tools/formatting/spec_html_formats.py +111 -111
- telegrinder/tools/functional.py +12 -12
- telegrinder/tools/global_context/__init__.py +7 -7
- telegrinder/tools/global_context/abc.py +63 -63
- telegrinder/tools/global_context/global_context.py +412 -412
- telegrinder/tools/global_context/telegrinder_ctx.py +27 -27
- telegrinder/tools/i18n/__init__.py +7 -7
- telegrinder/tools/i18n/abc.py +30 -30
- telegrinder/tools/i18n/middleware/__init__.py +3 -3
- telegrinder/tools/i18n/middleware/abc.py +25 -25
- telegrinder/tools/i18n/simple.py +43 -43
- telegrinder/tools/kb_set/__init__.py +4 -4
- telegrinder/tools/kb_set/base.py +15 -15
- telegrinder/tools/kb_set/yaml.py +63 -63
- telegrinder/tools/keyboard.py +128 -128
- telegrinder/tools/limited_dict.py +37 -37
- telegrinder/tools/loop_wrapper/__init__.py +4 -4
- telegrinder/tools/loop_wrapper/abc.py +15 -15
- telegrinder/tools/loop_wrapper/loop_wrapper.py +224 -224
- telegrinder/tools/magic.py +157 -157
- telegrinder/tools/parse_mode.py +6 -6
- telegrinder/tools/state_storage/__init__.py +4 -4
- telegrinder/tools/state_storage/abc.py +35 -35
- telegrinder/tools/state_storage/memory.py +25 -25
- telegrinder/types/__init__.py +260 -260
- telegrinder/types/enums.py +701 -701
- telegrinder/types/methods.py +4633 -4633
- telegrinder/types/objects.py +6950 -6950
- telegrinder/verification_utils.py +32 -32
- {telegrinder-0.3.4.dist-info → telegrinder-0.3.4.post1.dist-info}/LICENSE +22 -22
- {telegrinder-0.3.4.dist-info → telegrinder-0.3.4.post1.dist-info}/METADATA +1 -1
- telegrinder-0.3.4.post1.dist-info/RECORD +165 -0
- telegrinder-0.3.4.dist-info/RECORD +0 -165
- {telegrinder-0.3.4.dist-info → telegrinder-0.3.4.post1.dist-info}/WHEEL +0 -0
telegrinder/__init__.py
CHANGED
|
@@ -1,145 +1,145 @@
|
|
|
1
|
-
"""Telegrinder
|
|
2
|
-
|
|
3
|
-
Modern visionary telegram bot framework.
|
|
4
|
-
|
|
5
|
-
* Type hinted
|
|
6
|
-
* Customizable and extensible
|
|
7
|
-
* Ready to use scenarios and rules
|
|
8
|
-
* Fast models built on [msgspec](https://github.com/jcrist/msgspec)
|
|
9
|
-
* Both low-level and high-level API
|
|
10
|
-
* Support [optional dependecies](https://github.com/timoniq/telegrinder/blob/dev/docs/guide/optional_dependencies.md)
|
|
11
|
-
|
|
12
|
-
Basic example:
|
|
13
|
-
|
|
14
|
-
```python
|
|
15
|
-
from telegrinder import API, Message, Telegrinder, Token
|
|
16
|
-
from telegrinder.modules import logger
|
|
17
|
-
from telegrinder.rules import Text
|
|
18
|
-
|
|
19
|
-
api = API(token=Token("123:token"))
|
|
20
|
-
bot = Telegrinder(api)
|
|
21
|
-
logger.set_level("INFO")
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
@bot.on.message(Text("/start"))
|
|
25
|
-
async def start(message: Message):
|
|
26
|
-
me = (await api.get_me()).unwrap()
|
|
27
|
-
await message.answer(f"Hello, {message.from_user.full_name}! I'm {me.full_name}.")
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
bot.run_forever()
|
|
31
|
-
```
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
import typing
|
|
35
|
-
|
|
36
|
-
from .api import API, APIError, APIResponse, Token
|
|
37
|
-
from .bot import (
|
|
38
|
-
CALLBACK_QUERY_FOR_MESSAGE,
|
|
39
|
-
CALLBACK_QUERY_FROM_CHAT,
|
|
40
|
-
CALLBACK_QUERY_IN_CHAT_FOR_MESSAGE,
|
|
41
|
-
MESSAGE_FROM_USER,
|
|
42
|
-
MESSAGE_FROM_USER_IN_CHAT,
|
|
43
|
-
MESSAGE_IN_CHAT,
|
|
44
|
-
ABCDispatch,
|
|
45
|
-
ABCHandler,
|
|
46
|
-
ABCMiddleware,
|
|
47
|
-
ABCPolling,
|
|
48
|
-
ABCReturnManager,
|
|
49
|
-
ABCRule,
|
|
50
|
-
ABCScenario,
|
|
51
|
-
ABCStateView,
|
|
52
|
-
ABCView,
|
|
53
|
-
AudioReplyHandler,
|
|
54
|
-
BaseCute,
|
|
55
|
-
BaseReturnManager,
|
|
56
|
-
BaseStateView,
|
|
57
|
-
BaseView,
|
|
58
|
-
CallbackQueryCute,
|
|
59
|
-
CallbackQueryReturnManager,
|
|
60
|
-
CallbackQueryRule,
|
|
61
|
-
CallbackQueryView,
|
|
62
|
-
ChatJoinRequestCute,
|
|
63
|
-
ChatJoinRequestRule,
|
|
64
|
-
ChatJoinRequestView,
|
|
65
|
-
ChatMemberUpdatedCute,
|
|
66
|
-
ChatMemberView,
|
|
67
|
-
Checkbox,
|
|
68
|
-
Choice,
|
|
69
|
-
Context,
|
|
70
|
-
Dispatch,
|
|
71
|
-
DocumentReplyHandler,
|
|
72
|
-
FuncHandler,
|
|
73
|
-
Hasher,
|
|
74
|
-
InlineQueryCute,
|
|
75
|
-
InlineQueryReturnManager,
|
|
76
|
-
InlineQueryRule,
|
|
77
|
-
MediaGroupReplyHandler,
|
|
78
|
-
MessageCute,
|
|
79
|
-
MessageReplyHandler,
|
|
80
|
-
MessageReturnManager,
|
|
81
|
-
MessageRule,
|
|
82
|
-
MessageView,
|
|
83
|
-
PhotoReplyHandler,
|
|
84
|
-
Polling,
|
|
85
|
-
RawEventView,
|
|
86
|
-
ShortState,
|
|
87
|
-
StateViewHasher,
|
|
88
|
-
StickerReplyHandler,
|
|
89
|
-
Telegrinder,
|
|
90
|
-
UpdateCute,
|
|
91
|
-
VideoReplyHandler,
|
|
92
|
-
ViewBox,
|
|
93
|
-
WaiterMachine,
|
|
94
|
-
register_manager,
|
|
95
|
-
)
|
|
96
|
-
from .bot.rules import StateMeta
|
|
97
|
-
from .client import ABCClient, AiohttpClient
|
|
98
|
-
from .model import Model
|
|
99
|
-
from .modules import logger
|
|
100
|
-
from .tools import (
|
|
101
|
-
ABCErrorHandler,
|
|
102
|
-
ABCGlobalContext,
|
|
103
|
-
ABCLoopWrapper,
|
|
104
|
-
ABCStateStorage,
|
|
105
|
-
ABCTranslator,
|
|
106
|
-
ABCTranslatorMiddleware,
|
|
107
|
-
AnyMarkup,
|
|
108
|
-
Button,
|
|
109
|
-
CtxVar,
|
|
110
|
-
DelayedTask,
|
|
111
|
-
ErrorHandler,
|
|
112
|
-
FormatString,
|
|
113
|
-
GlobalContext,
|
|
114
|
-
HTMLFormatter,
|
|
115
|
-
I18nEnum,
|
|
116
|
-
InlineButton,
|
|
117
|
-
InlineKeyboard,
|
|
118
|
-
Keyboard,
|
|
119
|
-
KeyboardSetBase,
|
|
120
|
-
KeyboardSetYAML,
|
|
121
|
-
Lifespan,
|
|
122
|
-
LoopWrapper,
|
|
123
|
-
MemoryStateStorage,
|
|
124
|
-
ParseMode,
|
|
125
|
-
RowButtons,
|
|
126
|
-
SimpleI18n,
|
|
127
|
-
SimpleTranslator,
|
|
128
|
-
StateData,
|
|
129
|
-
ctx_var,
|
|
130
|
-
magic_bundle,
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
Update: typing.TypeAlias = UpdateCute
|
|
134
|
-
Message: typing.TypeAlias = MessageCute
|
|
135
|
-
ChatJoinRequest: typing.TypeAlias = ChatJoinRequestCute
|
|
136
|
-
ChatMemberUpdated: typing.TypeAlias = ChatMemberUpdatedCute
|
|
137
|
-
CallbackQuery: typing.TypeAlias = CallbackQueryCute
|
|
138
|
-
InlineQuery: typing.TypeAlias = InlineQueryCute
|
|
139
|
-
Bot: typing.TypeAlias = Telegrinder
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
__all__ = (
|
|
1
|
+
"""Telegrinder
|
|
2
|
+
|
|
3
|
+
Modern visionary telegram bot framework.
|
|
4
|
+
|
|
5
|
+
* Type hinted
|
|
6
|
+
* Customizable and extensible
|
|
7
|
+
* Ready to use scenarios and rules
|
|
8
|
+
* Fast models built on [msgspec](https://github.com/jcrist/msgspec)
|
|
9
|
+
* Both low-level and high-level API
|
|
10
|
+
* Support [optional dependecies](https://github.com/timoniq/telegrinder/blob/dev/docs/guide/optional_dependencies.md)
|
|
11
|
+
|
|
12
|
+
Basic example:
|
|
13
|
+
|
|
14
|
+
```python
|
|
15
|
+
from telegrinder import API, Message, Telegrinder, Token
|
|
16
|
+
from telegrinder.modules import logger
|
|
17
|
+
from telegrinder.rules import Text
|
|
18
|
+
|
|
19
|
+
api = API(token=Token("123:token"))
|
|
20
|
+
bot = Telegrinder(api)
|
|
21
|
+
logger.set_level("INFO")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@bot.on.message(Text("/start"))
|
|
25
|
+
async def start(message: Message):
|
|
26
|
+
me = (await api.get_me()).unwrap()
|
|
27
|
+
await message.answer(f"Hello, {message.from_user.full_name}! I'm {me.full_name}.")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
bot.run_forever()
|
|
31
|
+
```
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
import typing
|
|
35
|
+
|
|
36
|
+
from .api import API, APIError, APIResponse, Token
|
|
37
|
+
from .bot import (
|
|
38
|
+
CALLBACK_QUERY_FOR_MESSAGE,
|
|
39
|
+
CALLBACK_QUERY_FROM_CHAT,
|
|
40
|
+
CALLBACK_QUERY_IN_CHAT_FOR_MESSAGE,
|
|
41
|
+
MESSAGE_FROM_USER,
|
|
42
|
+
MESSAGE_FROM_USER_IN_CHAT,
|
|
43
|
+
MESSAGE_IN_CHAT,
|
|
44
|
+
ABCDispatch,
|
|
45
|
+
ABCHandler,
|
|
46
|
+
ABCMiddleware,
|
|
47
|
+
ABCPolling,
|
|
48
|
+
ABCReturnManager,
|
|
49
|
+
ABCRule,
|
|
50
|
+
ABCScenario,
|
|
51
|
+
ABCStateView,
|
|
52
|
+
ABCView,
|
|
53
|
+
AudioReplyHandler,
|
|
54
|
+
BaseCute,
|
|
55
|
+
BaseReturnManager,
|
|
56
|
+
BaseStateView,
|
|
57
|
+
BaseView,
|
|
58
|
+
CallbackQueryCute,
|
|
59
|
+
CallbackQueryReturnManager,
|
|
60
|
+
CallbackQueryRule,
|
|
61
|
+
CallbackQueryView,
|
|
62
|
+
ChatJoinRequestCute,
|
|
63
|
+
ChatJoinRequestRule,
|
|
64
|
+
ChatJoinRequestView,
|
|
65
|
+
ChatMemberUpdatedCute,
|
|
66
|
+
ChatMemberView,
|
|
67
|
+
Checkbox,
|
|
68
|
+
Choice,
|
|
69
|
+
Context,
|
|
70
|
+
Dispatch,
|
|
71
|
+
DocumentReplyHandler,
|
|
72
|
+
FuncHandler,
|
|
73
|
+
Hasher,
|
|
74
|
+
InlineQueryCute,
|
|
75
|
+
InlineQueryReturnManager,
|
|
76
|
+
InlineQueryRule,
|
|
77
|
+
MediaGroupReplyHandler,
|
|
78
|
+
MessageCute,
|
|
79
|
+
MessageReplyHandler,
|
|
80
|
+
MessageReturnManager,
|
|
81
|
+
MessageRule,
|
|
82
|
+
MessageView,
|
|
83
|
+
PhotoReplyHandler,
|
|
84
|
+
Polling,
|
|
85
|
+
RawEventView,
|
|
86
|
+
ShortState,
|
|
87
|
+
StateViewHasher,
|
|
88
|
+
StickerReplyHandler,
|
|
89
|
+
Telegrinder,
|
|
90
|
+
UpdateCute,
|
|
91
|
+
VideoReplyHandler,
|
|
92
|
+
ViewBox,
|
|
93
|
+
WaiterMachine,
|
|
94
|
+
register_manager,
|
|
95
|
+
)
|
|
96
|
+
from .bot.rules import StateMeta
|
|
97
|
+
from .client import ABCClient, AiohttpClient
|
|
98
|
+
from .model import Model
|
|
99
|
+
from .modules import logger
|
|
100
|
+
from .tools import (
|
|
101
|
+
ABCErrorHandler,
|
|
102
|
+
ABCGlobalContext,
|
|
103
|
+
ABCLoopWrapper,
|
|
104
|
+
ABCStateStorage,
|
|
105
|
+
ABCTranslator,
|
|
106
|
+
ABCTranslatorMiddleware,
|
|
107
|
+
AnyMarkup,
|
|
108
|
+
Button,
|
|
109
|
+
CtxVar,
|
|
110
|
+
DelayedTask,
|
|
111
|
+
ErrorHandler,
|
|
112
|
+
FormatString,
|
|
113
|
+
GlobalContext,
|
|
114
|
+
HTMLFormatter,
|
|
115
|
+
I18nEnum,
|
|
116
|
+
InlineButton,
|
|
117
|
+
InlineKeyboard,
|
|
118
|
+
Keyboard,
|
|
119
|
+
KeyboardSetBase,
|
|
120
|
+
KeyboardSetYAML,
|
|
121
|
+
Lifespan,
|
|
122
|
+
LoopWrapper,
|
|
123
|
+
MemoryStateStorage,
|
|
124
|
+
ParseMode,
|
|
125
|
+
RowButtons,
|
|
126
|
+
SimpleI18n,
|
|
127
|
+
SimpleTranslator,
|
|
128
|
+
StateData,
|
|
129
|
+
ctx_var,
|
|
130
|
+
magic_bundle,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
Update: typing.TypeAlias = UpdateCute
|
|
134
|
+
Message: typing.TypeAlias = MessageCute
|
|
135
|
+
ChatJoinRequest: typing.TypeAlias = ChatJoinRequestCute
|
|
136
|
+
ChatMemberUpdated: typing.TypeAlias = ChatMemberUpdatedCute
|
|
137
|
+
CallbackQuery: typing.TypeAlias = CallbackQueryCute
|
|
138
|
+
InlineQuery: typing.TypeAlias = InlineQueryCute
|
|
139
|
+
Bot: typing.TypeAlias = Telegrinder
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
__all__ = (
|
|
143
143
|
"ABCClient",
|
|
144
144
|
"ABCDispatch",
|
|
145
145
|
"ABCErrorHandler",
|
|
@@ -247,5 +247,5 @@ __all__ = (
|
|
|
247
247
|
"ctx_var",
|
|
248
248
|
"logger",
|
|
249
249
|
"magic_bundle",
|
|
250
|
-
"register_manager",
|
|
251
|
-
)
|
|
250
|
+
"register_manager",
|
|
251
|
+
)
|
telegrinder/api/__init__.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
from .api import API
|
|
2
|
-
from .error import APIError, InvalidTokenError
|
|
3
|
-
from .response import APIResponse
|
|
4
|
-
from .token import Token
|
|
5
|
-
|
|
6
|
-
__all__ = (
|
|
1
|
+
from .api import API
|
|
2
|
+
from .error import APIError, InvalidTokenError
|
|
3
|
+
from .response import APIResponse
|
|
4
|
+
from .token import Token
|
|
5
|
+
|
|
6
|
+
__all__ = (
|
|
7
7
|
"API",
|
|
8
8
|
"APIError",
|
|
9
9
|
"APIResponse",
|
|
10
10
|
"InvalidTokenError",
|
|
11
|
-
"Token",
|
|
12
|
-
)
|
|
11
|
+
"Token",
|
|
12
|
+
)
|
telegrinder/api/api.py
CHANGED
|
@@ -1,93 +1,93 @@
|
|
|
1
|
-
import typing
|
|
2
|
-
from functools import cached_property
|
|
3
|
-
|
|
4
|
-
import msgspec
|
|
5
|
-
from fntypes.result import Error, Ok, Result
|
|
6
|
-
|
|
7
|
-
from telegrinder.api.error import APIError
|
|
8
|
-
from telegrinder.api.response import APIResponse
|
|
9
|
-
from telegrinder.api.token import Token
|
|
10
|
-
from telegrinder.client import ABCClient, AiohttpClient
|
|
11
|
-
from telegrinder.model import DataConverter, decoder
|
|
12
|
-
from telegrinder.types.methods import APIMethods
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def compose_data(
|
|
16
|
-
client: ABCClient,
|
|
17
|
-
data: dict[str, typing.Any],
|
|
18
|
-
files: dict[str, tuple[str, bytes]],
|
|
19
|
-
) -> typing.Any:
|
|
20
|
-
converter = DataConverter(_files=files.copy())
|
|
21
|
-
return client.get_form(
|
|
22
|
-
data={k: converter(v) for k, v in data.items()},
|
|
23
|
-
files=converter.files,
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class API(APIMethods):
|
|
28
|
-
"""Bot API with available API methods and http client."""
|
|
29
|
-
|
|
30
|
-
API_URL = "https://api.telegram.org/"
|
|
31
|
-
API_FILE_URL = "https://api.telegram.org/file/"
|
|
32
|
-
|
|
33
|
-
def __init__(self, token: Token, *, http: ABCClient | None = None) -> None:
|
|
34
|
-
self.token = token
|
|
35
|
-
self.http = http or AiohttpClient()
|
|
36
|
-
super().__init__(self)
|
|
37
|
-
|
|
38
|
-
def __repr__(self) -> str:
|
|
39
|
-
return "<{}: token={!r}, http={!r}>".format(
|
|
40
|
-
self.__class__.__name__,
|
|
41
|
-
self.token,
|
|
42
|
-
self.http,
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
@cached_property
|
|
46
|
-
def id(self) -> int:
|
|
47
|
-
return self.token.bot_id
|
|
48
|
-
|
|
49
|
-
@property
|
|
50
|
-
def request_url(self) -> str:
|
|
51
|
-
return self.API_URL + f"bot{self.token}/"
|
|
52
|
-
|
|
53
|
-
@property
|
|
54
|
-
def request_file_url(self) -> str:
|
|
55
|
-
return self.API_FILE_URL + f"bot{self.token}/"
|
|
56
|
-
|
|
57
|
-
async def download_file(self, file_path: str) -> bytes:
|
|
58
|
-
return await self.http.request_content(f"{self.request_file_url}/{file_path}")
|
|
59
|
-
|
|
60
|
-
async def request(
|
|
61
|
-
self,
|
|
62
|
-
method: str,
|
|
63
|
-
data: dict[str, typing.Any] | None = None,
|
|
64
|
-
files: dict[str, tuple[str, bytes]] | None = None,
|
|
65
|
-
) -> Result[dict[str, typing.Any] | list[typing.Any] | bool, APIError]:
|
|
66
|
-
response = await self.http.request_json(
|
|
67
|
-
url=self.request_url + method,
|
|
68
|
-
data=compose_data(self.http, data or {}, files or {}),
|
|
69
|
-
)
|
|
70
|
-
if response.get("ok"):
|
|
71
|
-
assert "result" in response
|
|
72
|
-
return Ok(response["result"])
|
|
73
|
-
return Error(
|
|
74
|
-
APIError(
|
|
75
|
-
code=response.get("error_code", 400),
|
|
76
|
-
error=response.get("description"),
|
|
77
|
-
)
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
async def request_raw(
|
|
81
|
-
self,
|
|
82
|
-
method: str,
|
|
83
|
-
data: dict[str, typing.Any] | None = None,
|
|
84
|
-
files: dict[str, tuple[str, bytes]] | None = None,
|
|
85
|
-
) -> Result[msgspec.Raw, APIError]:
|
|
86
|
-
response_bytes = await self.http.request_bytes(
|
|
87
|
-
url=self.request_url + method,
|
|
88
|
-
data=compose_data(self.http, data or {}, files or {}),
|
|
89
|
-
)
|
|
90
|
-
return decoder.decode(response_bytes, type=APIResponse).to_result()
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
__all__ = ("API",)
|
|
1
|
+
import typing
|
|
2
|
+
from functools import cached_property
|
|
3
|
+
|
|
4
|
+
import msgspec
|
|
5
|
+
from fntypes.result import Error, Ok, Result
|
|
6
|
+
|
|
7
|
+
from telegrinder.api.error import APIError
|
|
8
|
+
from telegrinder.api.response import APIResponse
|
|
9
|
+
from telegrinder.api.token import Token
|
|
10
|
+
from telegrinder.client import ABCClient, AiohttpClient
|
|
11
|
+
from telegrinder.model import DataConverter, decoder
|
|
12
|
+
from telegrinder.types.methods import APIMethods
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def compose_data(
|
|
16
|
+
client: ABCClient,
|
|
17
|
+
data: dict[str, typing.Any],
|
|
18
|
+
files: dict[str, tuple[str, bytes]],
|
|
19
|
+
) -> typing.Any:
|
|
20
|
+
converter = DataConverter(_files=files.copy())
|
|
21
|
+
return client.get_form(
|
|
22
|
+
data={k: converter(v) for k, v in data.items()},
|
|
23
|
+
files=converter.files,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class API(APIMethods):
|
|
28
|
+
"""Bot API with available API methods and http client."""
|
|
29
|
+
|
|
30
|
+
API_URL = "https://api.telegram.org/"
|
|
31
|
+
API_FILE_URL = "https://api.telegram.org/file/"
|
|
32
|
+
|
|
33
|
+
def __init__(self, token: Token, *, http: ABCClient | None = None) -> None:
|
|
34
|
+
self.token = token
|
|
35
|
+
self.http = http or AiohttpClient()
|
|
36
|
+
super().__init__(self)
|
|
37
|
+
|
|
38
|
+
def __repr__(self) -> str:
|
|
39
|
+
return "<{}: token={!r}, http={!r}>".format(
|
|
40
|
+
self.__class__.__name__,
|
|
41
|
+
self.token,
|
|
42
|
+
self.http,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
@cached_property
|
|
46
|
+
def id(self) -> int:
|
|
47
|
+
return self.token.bot_id
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def request_url(self) -> str:
|
|
51
|
+
return self.API_URL + f"bot{self.token}/"
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def request_file_url(self) -> str:
|
|
55
|
+
return self.API_FILE_URL + f"bot{self.token}/"
|
|
56
|
+
|
|
57
|
+
async def download_file(self, file_path: str) -> bytes:
|
|
58
|
+
return await self.http.request_content(f"{self.request_file_url}/{file_path}")
|
|
59
|
+
|
|
60
|
+
async def request(
|
|
61
|
+
self,
|
|
62
|
+
method: str,
|
|
63
|
+
data: dict[str, typing.Any] | None = None,
|
|
64
|
+
files: dict[str, tuple[str, bytes]] | None = None,
|
|
65
|
+
) -> Result[dict[str, typing.Any] | list[typing.Any] | bool, APIError]:
|
|
66
|
+
response = await self.http.request_json(
|
|
67
|
+
url=self.request_url + method,
|
|
68
|
+
data=compose_data(self.http, data or {}, files or {}),
|
|
69
|
+
)
|
|
70
|
+
if response.get("ok"):
|
|
71
|
+
assert "result" in response
|
|
72
|
+
return Ok(response["result"])
|
|
73
|
+
return Error(
|
|
74
|
+
APIError(
|
|
75
|
+
code=response.get("error_code", 400),
|
|
76
|
+
error=response.get("description"),
|
|
77
|
+
)
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
async def request_raw(
|
|
81
|
+
self,
|
|
82
|
+
method: str,
|
|
83
|
+
data: dict[str, typing.Any] | None = None,
|
|
84
|
+
files: dict[str, tuple[str, bytes]] | None = None,
|
|
85
|
+
) -> Result[msgspec.Raw, APIError]:
|
|
86
|
+
response_bytes = await self.http.request_bytes(
|
|
87
|
+
url=self.request_url + method,
|
|
88
|
+
data=compose_data(self.http, data or {}, files or {}),
|
|
89
|
+
)
|
|
90
|
+
return decoder.decode(response_bytes, type=APIResponse).to_result()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
__all__ = ("API",)
|
telegrinder/api/error.py
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
class APIError(BaseException):
|
|
2
|
-
def __init__(self, code: int, error: str | None = None) -> None:
|
|
3
|
-
self.code, self.error = code, error
|
|
4
|
-
|
|
5
|
-
def __str__(self) -> str:
|
|
6
|
-
return f"[{self.code}] {self.error or 'Something went wrong'}"
|
|
7
|
-
|
|
8
|
-
def __repr__(self) -> str:
|
|
9
|
-
return f"<APIError: {self.__str__()}>"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class InvalidTokenError(BaseException):
|
|
13
|
-
pass
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
__all__ = ("APIError", "InvalidTokenError")
|
|
1
|
+
class APIError(BaseException):
|
|
2
|
+
def __init__(self, code: int, error: str | None = None) -> None:
|
|
3
|
+
self.code, self.error = code, error
|
|
4
|
+
|
|
5
|
+
def __str__(self) -> str:
|
|
6
|
+
return f"[{self.code}] {self.error or 'Something went wrong'}"
|
|
7
|
+
|
|
8
|
+
def __repr__(self) -> str:
|
|
9
|
+
return f"<APIError: {self.__str__()}>"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class InvalidTokenError(BaseException):
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
__all__ = ("APIError", "InvalidTokenError")
|
telegrinder/api/response.py
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import msgspec
|
|
2
|
-
from fntypes.result import Error, Ok, Result
|
|
3
|
-
|
|
4
|
-
from telegrinder.api.error import APIError
|
|
5
|
-
from telegrinder.model import Model
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class APIResponse(Model):
|
|
9
|
-
ok: bool = False
|
|
10
|
-
result: msgspec.Raw = msgspec.Raw(b"")
|
|
11
|
-
error_code: int = 0
|
|
12
|
-
description: str = ""
|
|
13
|
-
|
|
14
|
-
def to_result(self) -> Result[msgspec.Raw, APIError]:
|
|
15
|
-
if self.ok:
|
|
16
|
-
return Ok(self.result)
|
|
17
|
-
return Error(APIError(self.error_code, self.description))
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
__all__ = ("APIResponse",)
|
|
1
|
+
import msgspec
|
|
2
|
+
from fntypes.result import Error, Ok, Result
|
|
3
|
+
|
|
4
|
+
from telegrinder.api.error import APIError
|
|
5
|
+
from telegrinder.model import Model
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class APIResponse(Model):
|
|
9
|
+
ok: bool = False
|
|
10
|
+
result: msgspec.Raw = msgspec.Raw(b"")
|
|
11
|
+
error_code: int = 0
|
|
12
|
+
description: str = ""
|
|
13
|
+
|
|
14
|
+
def to_result(self) -> Result[msgspec.Raw, APIError]:
|
|
15
|
+
if self.ok:
|
|
16
|
+
return Ok(self.result)
|
|
17
|
+
return Error(APIError(self.error_code, self.description))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
__all__ = ("APIResponse",)
|
telegrinder/api/token.py
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import pathlib
|
|
2
|
-
import typing
|
|
3
|
-
from functools import cached_property
|
|
4
|
-
|
|
5
|
-
from envparse import env
|
|
6
|
-
|
|
7
|
-
from .error import InvalidTokenError
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class Token(str):
|
|
11
|
-
def __new__(cls, token: str) -> typing.Self:
|
|
12
|
-
if token.count(":") != 1 or not token.split(":")[0].isdigit():
|
|
13
|
-
raise InvalidTokenError("Invalid token, it should look like this '123:ABC'.")
|
|
14
|
-
return super().__new__(cls, token)
|
|
15
|
-
|
|
16
|
-
def __repr__(self) -> str:
|
|
17
|
-
return f"<Token: {self.bot_id}:{''.join(self.split(':')[-1])[:6]}...>"
|
|
18
|
-
|
|
19
|
-
@classmethod
|
|
20
|
-
def from_env(
|
|
21
|
-
cls,
|
|
22
|
-
var_name: str = "BOT_TOKEN",
|
|
23
|
-
*,
|
|
24
|
-
is_read: bool = False,
|
|
25
|
-
path_to_envfile: str | pathlib.Path | None = None,
|
|
26
|
-
) -> typing.Self:
|
|
27
|
-
if not is_read:
|
|
28
|
-
env.read_envfile(path_to_envfile)
|
|
29
|
-
return cls(env.str(var_name))
|
|
30
|
-
|
|
31
|
-
@cached_property
|
|
32
|
-
def bot_id(self) -> int:
|
|
33
|
-
return int(self.split(":")[0])
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
__all__ = ("Token",)
|
|
1
|
+
import pathlib
|
|
2
|
+
import typing
|
|
3
|
+
from functools import cached_property
|
|
4
|
+
|
|
5
|
+
from envparse import env
|
|
6
|
+
|
|
7
|
+
from .error import InvalidTokenError
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Token(str):
|
|
11
|
+
def __new__(cls, token: str) -> typing.Self:
|
|
12
|
+
if token.count(":") != 1 or not token.split(":")[0].isdigit():
|
|
13
|
+
raise InvalidTokenError("Invalid token, it should look like this '123:ABC'.")
|
|
14
|
+
return super().__new__(cls, token)
|
|
15
|
+
|
|
16
|
+
def __repr__(self) -> str:
|
|
17
|
+
return f"<Token: {self.bot_id}:{''.join(self.split(':')[-1])[:6]}...>"
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def from_env(
|
|
21
|
+
cls,
|
|
22
|
+
var_name: str = "BOT_TOKEN",
|
|
23
|
+
*,
|
|
24
|
+
is_read: bool = False,
|
|
25
|
+
path_to_envfile: str | pathlib.Path | None = None,
|
|
26
|
+
) -> typing.Self:
|
|
27
|
+
if not is_read:
|
|
28
|
+
env.read_envfile(path_to_envfile)
|
|
29
|
+
return cls(env.str(var_name))
|
|
30
|
+
|
|
31
|
+
@cached_property
|
|
32
|
+
def bot_id(self) -> int:
|
|
33
|
+
return int(self.split(":")[0])
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
__all__ = ("Token",)
|