telegrinder 0.3.4.post1__py3-none-any.whl → 0.4.0__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.

Files changed (169) hide show
  1. telegrinder/__init__.py +30 -31
  2. telegrinder/api/__init__.py +2 -1
  3. telegrinder/api/api.py +28 -20
  4. telegrinder/api/error.py +8 -4
  5. telegrinder/api/response.py +2 -2
  6. telegrinder/api/token.py +2 -2
  7. telegrinder/bot/__init__.py +6 -0
  8. telegrinder/bot/bot.py +38 -31
  9. telegrinder/bot/cute_types/__init__.py +2 -0
  10. telegrinder/bot/cute_types/base.py +54 -128
  11. telegrinder/bot/cute_types/callback_query.py +76 -61
  12. telegrinder/bot/cute_types/chat_join_request.py +4 -3
  13. telegrinder/bot/cute_types/chat_member_updated.py +28 -31
  14. telegrinder/bot/cute_types/inline_query.py +5 -4
  15. telegrinder/bot/cute_types/message.py +555 -602
  16. telegrinder/bot/cute_types/pre_checkout_query.py +42 -0
  17. telegrinder/bot/cute_types/update.py +20 -12
  18. telegrinder/bot/cute_types/utils.py +3 -36
  19. telegrinder/bot/dispatch/__init__.py +4 -0
  20. telegrinder/bot/dispatch/abc.py +8 -9
  21. telegrinder/bot/dispatch/context.py +5 -7
  22. telegrinder/bot/dispatch/dispatch.py +85 -33
  23. telegrinder/bot/dispatch/handler/abc.py +5 -6
  24. telegrinder/bot/dispatch/handler/audio_reply.py +2 -2
  25. telegrinder/bot/dispatch/handler/base.py +3 -3
  26. telegrinder/bot/dispatch/handler/document_reply.py +2 -2
  27. telegrinder/bot/dispatch/handler/func.py +36 -42
  28. telegrinder/bot/dispatch/handler/media_group_reply.py +5 -4
  29. telegrinder/bot/dispatch/handler/message_reply.py +2 -2
  30. telegrinder/bot/dispatch/handler/photo_reply.py +2 -2
  31. telegrinder/bot/dispatch/handler/sticker_reply.py +2 -2
  32. telegrinder/bot/dispatch/handler/video_reply.py +2 -2
  33. telegrinder/bot/dispatch/middleware/abc.py +83 -8
  34. telegrinder/bot/dispatch/middleware/global_middleware.py +70 -0
  35. telegrinder/bot/dispatch/process.py +44 -50
  36. telegrinder/bot/dispatch/return_manager/__init__.py +2 -0
  37. telegrinder/bot/dispatch/return_manager/abc.py +6 -10
  38. telegrinder/bot/dispatch/return_manager/pre_checkout_query.py +20 -0
  39. telegrinder/bot/dispatch/view/__init__.py +2 -0
  40. telegrinder/bot/dispatch/view/abc.py +10 -6
  41. telegrinder/bot/dispatch/view/base.py +81 -50
  42. telegrinder/bot/dispatch/view/box.py +20 -9
  43. telegrinder/bot/dispatch/view/callback_query.py +3 -4
  44. telegrinder/bot/dispatch/view/chat_join_request.py +2 -7
  45. telegrinder/bot/dispatch/view/chat_member.py +3 -5
  46. telegrinder/bot/dispatch/view/inline_query.py +3 -4
  47. telegrinder/bot/dispatch/view/message.py +3 -4
  48. telegrinder/bot/dispatch/view/pre_checkout_query.py +16 -0
  49. telegrinder/bot/dispatch/view/raw.py +42 -40
  50. telegrinder/bot/dispatch/waiter_machine/actions.py +5 -4
  51. telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py +0 -0
  52. telegrinder/bot/dispatch/waiter_machine/hasher/callback.py +0 -0
  53. telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py +9 -7
  54. telegrinder/bot/dispatch/waiter_machine/hasher/message.py +0 -0
  55. telegrinder/bot/dispatch/waiter_machine/hasher/state.py +3 -2
  56. telegrinder/bot/dispatch/waiter_machine/machine.py +113 -34
  57. telegrinder/bot/dispatch/waiter_machine/middleware.py +15 -10
  58. telegrinder/bot/dispatch/waiter_machine/short_state.py +7 -18
  59. telegrinder/bot/polling/polling.py +62 -54
  60. telegrinder/bot/rules/__init__.py +24 -1
  61. telegrinder/bot/rules/abc.py +17 -10
  62. telegrinder/bot/rules/callback_data.py +20 -61
  63. telegrinder/bot/rules/chat_join.py +6 -4
  64. telegrinder/bot/rules/command.py +4 -4
  65. telegrinder/bot/rules/enum_text.py +1 -4
  66. telegrinder/bot/rules/func.py +5 -3
  67. telegrinder/bot/rules/fuzzy.py +1 -1
  68. telegrinder/bot/rules/id.py +24 -0
  69. telegrinder/bot/rules/inline.py +6 -4
  70. telegrinder/bot/rules/integer.py +2 -1
  71. telegrinder/bot/rules/logic.py +18 -0
  72. telegrinder/bot/rules/markup.py +5 -6
  73. telegrinder/bot/rules/message.py +2 -4
  74. telegrinder/bot/rules/message_entities.py +1 -3
  75. telegrinder/bot/rules/node.py +15 -9
  76. telegrinder/bot/rules/payload.py +81 -0
  77. telegrinder/bot/rules/payment_invoice.py +29 -0
  78. telegrinder/bot/rules/regex.py +5 -6
  79. telegrinder/bot/rules/state.py +1 -3
  80. telegrinder/bot/rules/text.py +10 -5
  81. telegrinder/bot/rules/update.py +0 -0
  82. telegrinder/bot/scenario/abc.py +2 -4
  83. telegrinder/bot/scenario/checkbox.py +12 -14
  84. telegrinder/bot/scenario/choice.py +6 -9
  85. telegrinder/client/__init__.py +9 -1
  86. telegrinder/client/abc.py +35 -10
  87. telegrinder/client/aiohttp.py +28 -24
  88. telegrinder/client/form_data.py +31 -0
  89. telegrinder/client/sonic.py +212 -0
  90. telegrinder/model.py +38 -145
  91. telegrinder/modules.py +3 -1
  92. telegrinder/msgspec_utils.py +136 -68
  93. telegrinder/node/__init__.py +74 -13
  94. telegrinder/node/attachment.py +92 -16
  95. telegrinder/node/base.py +196 -68
  96. telegrinder/node/callback_query.py +17 -16
  97. telegrinder/node/command.py +3 -2
  98. telegrinder/node/composer.py +40 -75
  99. telegrinder/node/container.py +13 -7
  100. telegrinder/node/either.py +82 -0
  101. telegrinder/node/event.py +20 -31
  102. telegrinder/node/file.py +51 -0
  103. telegrinder/node/me.py +4 -5
  104. telegrinder/node/payload.py +78 -0
  105. telegrinder/node/polymorphic.py +27 -8
  106. telegrinder/node/rule.py +2 -6
  107. telegrinder/node/scope.py +4 -6
  108. telegrinder/node/source.py +37 -21
  109. telegrinder/node/text.py +20 -8
  110. telegrinder/node/tools/generator.py +7 -11
  111. telegrinder/py.typed +0 -0
  112. telegrinder/rules.py +0 -61
  113. telegrinder/tools/__init__.py +97 -38
  114. telegrinder/tools/adapter/__init__.py +19 -0
  115. telegrinder/tools/adapter/abc.py +49 -0
  116. telegrinder/tools/adapter/dataclass.py +56 -0
  117. telegrinder/{bot/rules → tools}/adapter/event.py +8 -10
  118. telegrinder/{bot/rules → tools}/adapter/node.py +8 -10
  119. telegrinder/{bot/rules → tools}/adapter/raw_event.py +2 -2
  120. telegrinder/{bot/rules → tools}/adapter/raw_update.py +2 -2
  121. telegrinder/tools/buttons.py +52 -26
  122. telegrinder/tools/callback_data_serilization/__init__.py +5 -0
  123. telegrinder/tools/callback_data_serilization/abc.py +51 -0
  124. telegrinder/tools/callback_data_serilization/json_ser.py +60 -0
  125. telegrinder/tools/callback_data_serilization/msgpack_ser.py +172 -0
  126. telegrinder/tools/error_handler/abc.py +4 -7
  127. telegrinder/tools/error_handler/error.py +0 -0
  128. telegrinder/tools/error_handler/error_handler.py +34 -48
  129. telegrinder/tools/formatting/__init__.py +57 -37
  130. telegrinder/tools/formatting/deep_links.py +541 -0
  131. telegrinder/tools/formatting/{html.py → html_formatter.py} +51 -79
  132. telegrinder/tools/formatting/spec_html_formats.py +14 -60
  133. telegrinder/tools/functional.py +1 -5
  134. telegrinder/tools/global_context/global_context.py +26 -51
  135. telegrinder/tools/global_context/telegrinder_ctx.py +3 -3
  136. telegrinder/tools/i18n/abc.py +0 -0
  137. telegrinder/tools/i18n/middleware/abc.py +3 -6
  138. telegrinder/tools/input_file_directory.py +30 -0
  139. telegrinder/tools/keyboard.py +9 -9
  140. telegrinder/tools/lifespan.py +105 -0
  141. telegrinder/tools/limited_dict.py +5 -10
  142. telegrinder/tools/loop_wrapper/abc.py +7 -2
  143. telegrinder/tools/loop_wrapper/loop_wrapper.py +40 -95
  144. telegrinder/tools/magic.py +184 -34
  145. telegrinder/tools/state_storage/__init__.py +0 -0
  146. telegrinder/tools/state_storage/abc.py +5 -9
  147. telegrinder/tools/state_storage/memory.py +1 -1
  148. telegrinder/tools/strings.py +13 -0
  149. telegrinder/types/__init__.py +8 -0
  150. telegrinder/types/enums.py +31 -21
  151. telegrinder/types/input_file.py +51 -0
  152. telegrinder/types/methods.py +531 -109
  153. telegrinder/types/objects.py +934 -826
  154. telegrinder/verification_utils.py +0 -2
  155. {telegrinder-0.3.4.post1.dist-info → telegrinder-0.4.0.dist-info}/LICENSE +2 -2
  156. telegrinder-0.4.0.dist-info/METADATA +144 -0
  157. telegrinder-0.4.0.dist-info/RECORD +182 -0
  158. {telegrinder-0.3.4.post1.dist-info → telegrinder-0.4.0.dist-info}/WHEEL +1 -1
  159. telegrinder/bot/rules/adapter/__init__.py +0 -17
  160. telegrinder/bot/rules/adapter/abc.py +0 -31
  161. telegrinder/node/message.py +0 -14
  162. telegrinder/node/update.py +0 -15
  163. telegrinder/tools/formatting/links.py +0 -38
  164. telegrinder/tools/kb_set/__init__.py +0 -4
  165. telegrinder/tools/kb_set/base.py +0 -15
  166. telegrinder/tools/kb_set/yaml.py +0 -63
  167. telegrinder-0.3.4.post1.dist-info/METADATA +0 -110
  168. telegrinder-0.3.4.post1.dist-info/RECORD +0 -165
  169. /telegrinder/{bot/rules → tools}/adapter/errors.py +0 -0
@@ -6,29 +6,18 @@ from fntypes.result import Error, Ok, Result
6
6
  from telegrinder.api.api import API
7
7
  from telegrinder.bot.dispatch.context import Context
8
8
  from telegrinder.modules import logger
9
- from telegrinder.node.base import is_node
10
- from telegrinder.tools.error_handler.abc import ABCErrorHandler, Event, Handler
9
+ from telegrinder.tools.error_handler.abc import ABCErrorHandler
11
10
  from telegrinder.tools.error_handler.error import CatcherError
12
- from telegrinder.tools.magic import get_annotations, magic_bundle
11
+ from telegrinder.tools.magic import magic_bundle
13
12
 
14
- F = typing.TypeVar("F", bound="FuncCatcher[typing.Any]")
15
- ExceptionT = typing.TypeVar("ExceptionT", bound=BaseException, contravariant=True)
16
- FuncCatcher = typing.Callable[typing.Concatenate[ExceptionT, ...], typing.Awaitable[typing.Any]]
17
-
18
-
19
- async def run_handler(
20
- handler: Handler,
21
- event: typing.Any,
22
- ctx: dict[str, typing.Any],
23
- ) -> typing.Any:
24
- annotations = tuple(get_annotations(handler).values())
25
- start_idx = 0 if is_node(None if not annotations else annotations[0]) else 1
26
- context = magic_bundle(handler, ctx, start_idx=start_idx)
27
- return await (handler(event, **context) if start_idx == 1 else handler(**context))
13
+ type FuncCatcher[Exc: BaseException] = typing.Callable[
14
+ typing.Concatenate[Exc, ...],
15
+ typing.Awaitable[typing.Any],
16
+ ]
28
17
 
29
18
 
30
19
  @dataclasses.dataclass(frozen=True, repr=False, slots=True)
31
- class Catcher(typing.Generic[Event]):
20
+ class Catcher[Event]:
32
21
  func: FuncCatcher[BaseException]
33
22
  exceptions: list[type[BaseException] | BaseException] = dataclasses.field(
34
23
  default_factory=lambda: [],
@@ -48,15 +37,12 @@ class Catcher(typing.Generic[Event]):
48
37
 
49
38
  async def __call__(
50
39
  self,
51
- handler: Handler,
40
+ exception: BaseException,
52
41
  event: Event,
53
42
  api: API,
54
43
  ctx: Context,
55
44
  ) -> Result[typing.Any, BaseException]:
56
- try:
57
- return Ok(await run_handler(handler, event, ctx))
58
- except BaseException as exc:
59
- return await self.run(api, event, ctx, exc, handler.__name__)
45
+ return await self.run(api, event, ctx, exception)
60
46
 
61
47
  def match_exception(self, exception: BaseException) -> bool:
62
48
  for exc in self.exceptions:
@@ -73,27 +59,27 @@ class Catcher(typing.Generic[Event]):
73
59
  event: Event,
74
60
  ctx: Context,
75
61
  exception: BaseException,
76
- handler_name: str,
77
62
  ) -> Result[typing.Any, BaseException]:
78
63
  if self.match_exception(exception):
79
64
  logger.debug(
80
- "Error handler caught an exception {!r} in handler {!r}, running catcher {!r}...".format(
81
- exception, handler_name, self.func.__name__
65
+ "Error handler caught an exception {!r}, running catcher {!r}...".format(
66
+ exception,
67
+ self.func.__name__,
82
68
  )
83
69
  )
84
- return Ok(await run_handler(self.func, event, {"event": event, "api": api} | ctx))
70
+ return Ok(await self.func(exception, **magic_bundle(self.func, {"event": event, "api": api} | ctx)))
85
71
 
86
72
  logger.debug("Failed to match exception {!r}.", exception.__class__.__name__)
87
73
  return Error(exception)
88
74
 
89
75
 
90
- class ErrorHandler(ABCErrorHandler[Event]):
76
+ class ErrorHandler[Event](ABCErrorHandler[Event]):
91
77
  def __init__(self, catcher: Catcher[Event] | None = None, /) -> None:
92
78
  self.catcher = catcher
93
79
 
94
80
  def __repr__(self) -> str:
95
81
  return (
96
- "<{}: exceptions_handled=[{}], catcher={!r}>".format(
82
+ "<{}: exceptions=[{}], catcher={!r}>".format(
97
83
  self.__class__.__name__,
98
84
  ", ".join(e.__name__ if isinstance(e, type) else repr(e) for e in self.catcher.exceptions),
99
85
  self.catcher,
@@ -116,16 +102,16 @@ class ErrorHandler(ABCErrorHandler[Event]):
116
102
  :param ignore_errors: Ignore errors that may occur.
117
103
  """
118
104
 
119
- def decorator(func: F) -> F:
105
+ def decorator[Func: FuncCatcher](catcher: Func, /) -> Func:
120
106
  if not self.catcher:
121
107
  self.catcher = Catcher(
122
- func,
108
+ catcher,
123
109
  exceptions=list(exceptions),
124
110
  logging=logging,
125
111
  raise_exception=raise_exception,
126
112
  ignore_errors=ignore_errors,
127
113
  )
128
- return func
114
+ return catcher
129
115
 
130
116
  return decorator
131
117
 
@@ -141,53 +127,53 @@ class ErrorHandler(ABCErrorHandler[Event]):
141
127
 
142
128
  return Ok(None)
143
129
 
144
- async def process(
130
+ async def suppress(
145
131
  self,
146
- handler: Handler,
132
+ exception: BaseException,
147
133
  event: Event,
148
134
  api: API,
149
135
  ctx: Context,
150
136
  ) -> Result[typing.Any, BaseException]:
151
137
  assert self.catcher is not None
152
- logger.debug("Processing the error handler for handler {!r}...", handler.__name__)
153
138
 
154
139
  try:
155
- return await self.catcher(handler, event, api, ctx)
140
+ return await self.catcher(exception, event, api, ctx)
156
141
  except BaseException as exc:
157
142
  return Error(
158
143
  CatcherError(
159
144
  exc,
160
- "Exception {} was occurred during the running catcher {!r}.".format(
161
- repr(exc), self.catcher.func.__name__
145
+ "{!r} was occurred during the running catcher {!r}.".format(
146
+ exc,
147
+ self.catcher.func.__name__,
162
148
  ),
163
149
  )
164
150
  )
165
151
 
166
152
  async def run(
167
153
  self,
168
- handler: Handler,
154
+ exception: BaseException,
169
155
  event: Event,
170
156
  api: API,
171
157
  ctx: Context,
172
- ) -> Result[typing.Any, BaseException]:
158
+ ) -> typing.Any:
173
159
  if not self.catcher:
174
- return Ok(await run_handler(handler, event, ctx))
160
+ raise exception from None
175
161
 
176
- match await self.process(handler, event, api, ctx):
177
- case Ok(value) as ok:
162
+ match await self.suppress(exception, event, api, ctx):
163
+ case Ok(value):
178
164
  if self.catcher.logging:
179
165
  logger.debug(
180
166
  "Catcher {!r} returned: {!r}",
181
167
  self.catcher.func.__name__,
182
168
  value,
183
169
  )
184
- return ok
185
- case Error(exc) as err:
170
+ return value
171
+ case Error(exc):
186
172
  if isinstance(exc, CatcherError):
187
- return self._process_catcher_error(exc)
173
+ return self._process_catcher_error(exc).unwrap()
188
174
  if self.catcher.ignore_errors:
189
- return Ok(None)
190
- return err
175
+ return None
176
+ raise exc from None
191
177
 
192
178
 
193
179
  __all__ = ("Catcher", "ErrorHandler")
@@ -1,81 +1,101 @@
1
- from .html import (
1
+ from .deep_links import (
2
+ tg_bot_attach_open_any_chat,
3
+ tg_bot_attach_open_current_chat,
4
+ tg_bot_attach_open_specific_chat,
5
+ tg_bot_start_link,
6
+ tg_bot_startchannel_link,
7
+ tg_bot_startgroup_link,
8
+ tg_chat_folder_link,
9
+ tg_chat_invite_link,
10
+ tg_direct_mini_app_link,
11
+ tg_emoji_link,
12
+ tg_emoji_stickerset_link,
13
+ tg_invoice_link,
14
+ tg_language_pack_link,
15
+ tg_main_mini_app_link,
16
+ tg_mention_link,
17
+ tg_open_message_link,
18
+ tg_premium_multigift_link,
19
+ tg_premium_offer_link,
20
+ tg_private_channel_boost_link,
21
+ tg_private_message_link,
22
+ tg_public_channel_boost_link,
23
+ tg_public_message_link,
24
+ tg_public_username_link,
25
+ tg_share_link,
26
+ tg_story_link,
27
+ )
28
+ from .html_formatter import (
2
29
  FormatString,
3
30
  HTMLFormatter,
4
31
  block_quote,
5
32
  bold,
6
- channel_boost_link,
7
33
  code_inline,
8
34
  escape,
9
- invite_chat_link,
10
35
  italic,
11
36
  link,
12
37
  mention,
13
38
  pre_code,
14
- resolve_domain,
15
39
  spoiler,
16
- start_bot_link,
17
- start_group_link,
18
40
  strike,
19
41
  tg_emoji,
20
42
  underline,
21
43
  )
22
- from .links import (
23
- get_channel_boost_link,
24
- get_invite_chat_link,
25
- get_mention_link,
26
- get_resolve_domain_link,
27
- get_start_bot_link,
28
- get_start_group_link,
29
- )
30
44
  from .spec_html_formats import (
31
- BaseSpecFormat,
32
- ChannelBoostLink,
33
- InviteChatLink,
45
+ Base,
46
+ BlockQuote,
34
47
  Link,
35
48
  Mention,
36
49
  PreCode,
37
- ResolveDomain,
38
50
  SpecialFormat,
39
- StartBotLink,
40
- StartGroupLink,
41
51
  TgEmoji,
42
52
  )
43
53
 
44
54
  __all__ = (
45
- "BaseSpecFormat",
46
- "ChannelBoostLink",
55
+ "Base",
56
+ "BlockQuote",
47
57
  "FormatString",
48
58
  "HTMLFormatter",
49
- "InviteChatLink",
50
59
  "Link",
51
60
  "Mention",
52
61
  "PreCode",
53
- "ResolveDomain",
54
62
  "SpecialFormat",
55
- "StartBotLink",
56
- "StartGroupLink",
57
63
  "TgEmoji",
58
64
  "block_quote",
59
65
  "bold",
60
- "channel_boost_link",
61
66
  "code_inline",
62
67
  "escape",
63
- "get_channel_boost_link",
64
- "get_invite_chat_link",
65
- "get_mention_link",
66
- "get_resolve_domain_link",
67
- "get_start_bot_link",
68
- "get_start_group_link",
69
- "invite_chat_link",
70
68
  "italic",
71
69
  "link",
72
70
  "mention",
73
71
  "pre_code",
74
- "resolve_domain",
75
72
  "spoiler",
76
- "start_bot_link",
77
- "start_group_link",
78
73
  "strike",
74
+ "tg_bot_attach_open_any_chat",
75
+ "tg_bot_attach_open_current_chat",
76
+ "tg_bot_attach_open_specific_chat",
77
+ "tg_bot_start_link",
78
+ "tg_bot_startchannel_link",
79
+ "tg_bot_startgroup_link",
80
+ "tg_chat_folder_link",
81
+ "tg_chat_invite_link",
82
+ "tg_direct_mini_app_link",
79
83
  "tg_emoji",
84
+ "tg_emoji_link",
85
+ "tg_emoji_stickerset_link",
86
+ "tg_invoice_link",
87
+ "tg_language_pack_link",
88
+ "tg_main_mini_app_link",
89
+ "tg_mention_link",
90
+ "tg_open_message_link",
91
+ "tg_premium_multigift_link",
92
+ "tg_premium_offer_link",
93
+ "tg_private_channel_boost_link",
94
+ "tg_private_message_link",
95
+ "tg_public_channel_boost_link",
96
+ "tg_public_message_link",
97
+ "tg_public_username_link",
98
+ "tg_share_link",
99
+ "tg_story_link",
80
100
  "underline",
81
101
  )