telegrinder 0.1.dev164__py3-none-any.whl → 0.1.dev165__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 CHANGED
@@ -1,3 +1,37 @@
1
+ """Telegrinder
2
+
3
+ Framework for effective and reliable telegram bot building.
4
+
5
+ * Type hinted
6
+ * Customizable and extensible
7
+ * Ready to use scenarios and rules
8
+ * Fast models built on msgspec
9
+ * Both low-level and high-level API
10
+
11
+ Basic example:
12
+
13
+ ```python
14
+ from telegrinder import API, Message, Telegrinder, Token
15
+ from telegrinder.modules import logger
16
+ from telegrinder.rules import Text
17
+
18
+ api = API(token=Token("123:token"))
19
+ bot = Telegrinder(api)
20
+ logger.set_level("INFO")
21
+
22
+
23
+ @bot.on.message(Text("/start"))
24
+ async def start(message: Message):
25
+ me = (await api.get_me()).unwrap()
26
+ await message.answer(
27
+ f"Hello, {message.from_user.full_name}! I'm {me.full_name}."
28
+ )
29
+
30
+
31
+ bot.run_forever()
32
+ ```
33
+ """
34
+
1
35
  import typing
2
36
 
3
37
  from .api import ABCAPI, API, APIError, APIResponse, Token
@@ -58,6 +92,7 @@ from .tools import (
58
92
  Keyboard,
59
93
  KeyboardSetBase,
60
94
  KeyboardSetYAML,
95
+ Lifespan,
61
96
  LoopWrapper,
62
97
  ParseMode,
63
98
  RowButtons,
@@ -123,6 +158,7 @@ __all__ = (
123
158
  "Keyboard",
124
159
  "KeyboardSetBase",
125
160
  "KeyboardSetYAML",
161
+ "Lifespan",
126
162
  "LoopWrapper",
127
163
  "Message",
128
164
  "MessageCute",
telegrinder/bot/bot.py CHANGED
@@ -24,6 +24,15 @@ class Telegrinder(typing.Generic[DispatchT, PollingT, LoopWrapperT]):
24
24
  self.dispatch = typing.cast(DispatchT, dispatch or Dispatch())
25
25
  self.polling = typing.cast(PollingT, polling or Polling(api))
26
26
  self.loop_wrapper = typing.cast(LoopWrapperT, loop_wrapper or LoopWrapper())
27
+
28
+ def __repr__(self) -> str:
29
+ return "<{}: api={!r}, dispatch={!r}, polling={!r}, loop_wrapper={!r}>".format(
30
+ self.__class__.__name__,
31
+ self.api,
32
+ self.dispatch,
33
+ self.polling,
34
+ self.loop_wrapper,
35
+ )
27
36
 
28
37
  @property
29
38
  def on(self) -> DispatchT:
@@ -80,7 +80,7 @@ async def execute_method_answer(
80
80
  params["link_preview_options"] = compose_link_preview_options(
81
81
  **link_preview_options
82
82
  )
83
-
83
+
84
84
  result = await getattr(message.ctx_api, method_name)(**params)
85
85
  return result.map(
86
86
  lambda x: (
@@ -43,6 +43,12 @@ class ABCReturnManager(ABC, typing.Generic[EventT]):
43
43
 
44
44
 
45
45
  class BaseReturnManager(ABCReturnManager[EventT]):
46
+ def __repr__(self) -> str:
47
+ return "<{}: {}>".format(
48
+ self.__class__.__name__,
49
+ ", ".join(x.callback.__name__ + "=" + repr(x) for x in self.managers),
50
+ )
51
+
46
52
  @property
47
53
  def managers(self) -> list[Manager]:
48
54
  return [
@@ -33,6 +33,20 @@ class Polling(ABCPolling):
33
33
  self.max_reconnetions = 10 if max_reconnetions < 0 else max_reconnetions
34
34
  self.offset = offset
35
35
  self._stop = False
36
+
37
+ def __repr__(self) -> str:
38
+ return (
39
+ "<{}: with api={!r}, stopped={}, offset={}, allowed_updates={!r}, "
40
+ "max_reconnetions={}, reconnection_timeout={}>"
41
+ ).format(
42
+ self.__class__.__name__,
43
+ self.api,
44
+ self._stop,
45
+ self.offset,
46
+ self.allowed_updates,
47
+ self.max_reconnetions,
48
+ self.reconnection_timeout,
49
+ )
36
50
 
37
51
  def get_allowed_updates(
38
52
  self,
@@ -24,7 +24,7 @@ def check_string(patterns: list[vbml.Pattern], s: str, ctx: Context) -> bool:
24
24
 
25
25
 
26
26
  class Markup(TextMessageRule):
27
- def __init__(self, patterns: PatternLike | list[PatternLike]):
27
+ def __init__(self, patterns: PatternLike | list[PatternLike], /):
28
28
  if not isinstance(patterns, list):
29
29
  patterns = [patterns]
30
30
  self.patterns = [
telegrinder/model.py CHANGED
@@ -57,6 +57,10 @@ def get_params(params: dict[str, typing.Any]) -> dict[str, typing.Any]:
57
57
 
58
58
 
59
59
  class Model(msgspec.Struct, **MODEL_CONFIG):
60
+ @classmethod
61
+ def from_bytes(cls, data: bytes) -> typing.Self:
62
+ return decoder.decode(data, type=cls)
63
+
60
64
  def to_dict(
61
65
  self,
62
66
  *,
@@ -76,6 +80,12 @@ class Model(msgspec.Struct, **MODEL_CONFIG):
76
80
  class DataConverter:
77
81
  files: dict[str, tuple[str, bytes]] = dataclasses.field(default_factory=lambda: {})
78
82
 
83
+ def __repr__(self) -> str:
84
+ return "<{}: {}>".format(
85
+ self.__class__.__name__,
86
+ ", ".join(f"{k}={v!r}" for k, v in self.converters),
87
+ )
88
+
79
89
  @property
80
90
  def converters(self) -> dict[type[typing.Any], typing.Callable[..., typing.Any]]:
81
91
  return {
@@ -51,8 +51,7 @@ def msgspec_convert(obj: typing.Any, t: type[T]) -> Result[T, msgspec.Validation
51
51
  def option_dec_hook(tp: type[Option[typing.Any]], obj: typing.Any) -> Option[typing.Any]:
52
52
  if obj is None:
53
53
  return Nothing
54
- generic_args = typing.get_args(tp)
55
- value_type: typing.Any | type[typing.Any] = typing.Any if not generic_args else generic_args[0]
54
+ value_type, = typing.get_args(tp) or (typing.Any,)
56
55
  return msgspec_convert({"value": obj}, fntypes.option.Some[value_type]).unwrap()
57
56
 
58
57
 
@@ -123,6 +122,12 @@ class Decoder:
123
122
  Variative: variative_dec_hook,
124
123
  datetime: lambda t, obj: t.fromtimestamp(obj),
125
124
  }
125
+
126
+ def __repr__(self) -> str:
127
+ return "<{}: dec_hooks={!r}>".format(
128
+ self.__class__.__name__,
129
+ self.dec_hooks,
130
+ )
126
131
 
127
132
  def add_dec_hook(self, t: T): # type: ignore
128
133
  def decorator(func: DecHook[T]) -> DecHook[T]:
@@ -216,6 +221,12 @@ class Encoder:
216
221
  datetime: lambda date: int(date.timestamp()),
217
222
  }
218
223
 
224
+ def __repr__(self) -> str:
225
+ return "<{}: enc_hooks={!r}>".format(
226
+ self.__class__.__name__,
227
+ self.enc_hooks,
228
+ )
229
+
219
230
  def add_dec_hook(self, t: type[T]):
220
231
  def decorator(func: EncHook[T]) -> EncHook[T]:
221
232
  encode_hook = self.enc_hooks.setdefault(get_origin(t), func)
@@ -27,7 +27,7 @@ class NodeSession:
27
27
  self.generator = None
28
28
 
29
29
  def __repr__(self) -> str:
30
- return f"<NodeSession: {self.value}" + ("ACTIVE>" if self.generator else ">")
30
+ return f"<{self.__class__.__name__}: {self.value}" + ("ACTIVE>" if self.generator else ">")
31
31
 
32
32
 
33
33
  class NodeCollection:
@@ -66,7 +66,7 @@ from .keyboard import (
66
66
  Keyboard,
67
67
  RowButtons,
68
68
  )
69
- from .loop_wrapper import ABCLoopWrapper, DelayedTask, LoopWrapper
69
+ from .loop_wrapper import ABCLoopWrapper, DelayedTask, Lifespan, LoopWrapper
70
70
  from .magic import magic_bundle, resolve_arg_names
71
71
  from .parse_mode import ParseMode
72
72
 
@@ -99,6 +99,7 @@ __all__ = (
99
99
  "KeyboardSetBase",
100
100
  "KeyboardSetYAML",
101
101
  "Link",
102
+ "Lifespan",
102
103
  "LoopWrapper",
103
104
  "Mention",
104
105
  "ParseMode",
@@ -200,11 +200,8 @@ def bold(string: str) -> TagFormat:
200
200
  return TagFormat(string, tag="b")
201
201
 
202
202
 
203
- def channel_boost_link(channel_username: str, string: str | None = None):
204
- return link(
205
- get_channel_boost_link(channel_username),
206
- string or f"t.me/{channel_username}?boost",
207
- )
203
+ def channel_boost_link(channel_id: str | int, string: str | None = None):
204
+ return link(get_channel_boost_link(channel_id), string)
208
205
 
209
206
 
210
207
  def code_inline(string: str) -> TagFormat:
@@ -234,15 +231,12 @@ def spoiler(string: str) -> TagFormat:
234
231
  return TagFormat(string, tag="tg-spoiler")
235
232
 
236
233
 
237
- def start_bot_link(bot_username: str, data: str, string: str | None = None) -> TagFormat:
238
- return link(
239
- get_start_bot_link(bot_username, data),
240
- string or f"t.me/{bot_username}?start={data}"
241
- )
234
+ def start_bot_link(bot_id: str | int, data: str, string: str | None = None) -> TagFormat:
235
+ return link(get_start_bot_link(bot_id, data), string)
242
236
 
243
237
 
244
- def start_group_link(bot_username: str, data: str, string: str | None = None) -> TagFormat:
245
- return link(get_start_group_link(bot_username, data), string)
238
+ def start_group_link(bot_id: str | int, data: str, string: str | None = None) -> TagFormat:
239
+ return link(get_start_group_link(bot_id, data), string)
246
240
 
247
241
 
248
242
  def strike(string: str) -> TagFormat:
@@ -6,16 +6,22 @@ def get_resolve_domain_link(username: str) -> str:
6
6
  return f"tg://resolve?domain={username}"
7
7
 
8
8
 
9
- def get_start_bot_link(bot_username: str, data: str) -> str:
10
- return get_resolve_domain_link(bot_username) + f"&start={data}"
9
+ def get_start_bot_link(bot_id: str | int, data: str) -> str:
10
+ if isinstance(bot_id, int):
11
+ return get_mention_link(bot_id) + f"&start={data}"
12
+ return get_resolve_domain_link(bot_id) + f"&start={data}"
11
13
 
12
14
 
13
- def get_start_group_link(bot_username: str, data: str) -> str:
14
- return get_resolve_domain_link(bot_username) + f"&startgroup={data}"
15
+ def get_start_group_link(bot_id: str | int, data: str) -> str:
16
+ if isinstance(bot_id, int):
17
+ return get_mention_link(bot_id) + f"&startgroup={data}"
18
+ return get_resolve_domain_link(bot_id) + f"&startgroup={data}"
15
19
 
16
20
 
17
- def get_channel_boost_link(channel_username: str) -> str:
18
- return get_resolve_domain_link(channel_username) + "&boost"
21
+ def get_channel_boost_link(channel_id: str | int) -> str:
22
+ if isinstance(channel_id, int):
23
+ return get_mention_link(channel_id) + "&boost"
24
+ return get_resolve_domain_link(channel_id) + "&boost"
19
25
 
20
26
 
21
27
  def get_invite_chat_link(invite_link: str) -> str:
@@ -3,14 +3,13 @@ import typing
3
3
 
4
4
  from telegrinder.types.enums import ProgrammingLanguage
5
5
 
6
- SpecialFormat = typing.Union[
6
+ SpecialFormat: typing.TypeAlias = typing.Union[
7
7
  "ChannelBoostLink",
8
8
  "InviteChatLink",
9
9
  "Link",
10
10
  "Mention",
11
11
  "PreCode",
12
12
  "ResolveDomain",
13
- "SpecialFormat",
14
13
  "StartBotLink",
15
14
  "StartGroupLink",
16
15
  "TgEmoji",
@@ -38,7 +37,7 @@ class BaseSpecFormat:
38
37
  class ChannelBoostLink(BaseSpecFormat):
39
38
  __formatter_name__ = "channel_boost_link"
40
39
 
41
- channel_username: str
40
+ channel_id: str | int
42
41
  string: str | None = None
43
42
 
44
43
 
@@ -86,7 +85,7 @@ class TgEmoji(BaseSpecFormat):
86
85
  class StartBotLink(BaseSpecFormat):
87
86
  __formatter_name__ = "start_bot_link"
88
87
 
89
- bot_username: str
88
+ bot_id: str | int
90
89
  data: str
91
90
  string: str | None
92
91
 
@@ -95,7 +94,7 @@ class StartBotLink(BaseSpecFormat):
95
94
  class StartGroupLink(BaseSpecFormat):
96
95
  __formatter_name__ = "start_group_link"
97
96
 
98
- bot_username: str
97
+ bot_id: str | int
99
98
  data: str
100
99
  string: str | None = None
101
100
 
@@ -199,8 +199,8 @@ class GlobalContext(ABCGlobalContext, typing.Generic[CtxValueT], dict[str, Globa
199
199
  self.set_context_variables(variables)
200
200
 
201
201
  def __repr__(self) -> str:
202
- return "<{!r} -> ({})>".format(
203
- f"{self.__class__.__name__}@{self.ctx_name}",
202
+ return "<{} -> ({})>".format(
203
+ f"{self.__class__.__name__}@{self.ctx_name!r}",
204
204
  ", ".join(repr(var) for var in self),
205
205
  )
206
206
 
@@ -1,4 +1,4 @@
1
1
  from .abc import ABCLoopWrapper
2
- from .loop_wrapper import DelayedTask, LoopWrapper
2
+ from .loop_wrapper import DelayedTask, Lifespan, LoopWrapper
3
3
 
4
- __all__ = ("ABCLoopWrapper", "DelayedTask", "LoopWrapper")
4
+ __all__ = ("ABCLoopWrapper", "DelayedTask", "Lifespan", "LoopWrapper")
@@ -1,13 +1,10 @@
1
1
  import typing
2
2
  from abc import ABC, abstractmethod
3
3
 
4
- CoroutineTask: typing.TypeAlias = typing.Coroutine[typing.Any, typing.Any, typing.Any]
5
- CoroutineFunc: typing.TypeAlias = typing.Callable[..., CoroutineTask]
6
-
7
4
 
8
5
  class ABCLoopWrapper(ABC):
9
6
  @abstractmethod
10
- def add_task(self, task: CoroutineFunc | CoroutineTask) -> None:
7
+ def add_task(self, task: typing.Any) -> None:
11
8
  pass
12
9
 
13
10
  @abstractmethod
@@ -5,12 +5,33 @@ import typing
5
5
 
6
6
  from telegrinder.modules import logger
7
7
 
8
- from .abc import ABCLoopWrapper, CoroutineFunc, CoroutineTask
8
+ from .abc import ABCLoopWrapper
9
+
10
+ T = typing.TypeVar("T")
11
+ P = typing.ParamSpec("P")
12
+ CoroFunc = typing.TypeVar("CoroFunc", bound="CoroutineFunc")
13
+
14
+ CoroutineTask: typing.TypeAlias = typing.Coroutine[typing.Any, typing.Any, T]
15
+ CoroutineFunc: typing.TypeAlias = typing.Callable[P, CoroutineTask[T]]
16
+ Task: typing.TypeAlias = typing.Union[CoroutineFunc, CoroutineTask, "DelayedTask"]
17
+
18
+
19
+ def run_tasks(tasks: list[CoroutineTask[typing.Any]], loop: asyncio.AbstractEventLoop) -> None:
20
+ while len(tasks) != 0:
21
+ loop.run_until_complete(tasks.pop(0))
22
+
23
+
24
+ def to_coroutine_task(task: Task) -> CoroutineTask:
25
+ if asyncio.iscoroutinefunction(task) or isinstance(task, DelayedTask):
26
+ task = task()
27
+ elif not asyncio.iscoroutine(task):
28
+ raise TypeError("Task should be coroutine or coroutine function.")
29
+ return task
9
30
 
10
31
 
11
32
  @dataclasses.dataclass
12
- class DelayedTask:
13
- handler: CoroutineFunc
33
+ class DelayedTask(typing.Generic[CoroFunc]):
34
+ handler: CoroFunc
14
35
  seconds: float
15
36
  repeat: bool = dataclasses.field(default=False, kw_only=True)
16
37
  _cancelled: bool = dataclasses.field(default=False, init=False, repr=False)
@@ -33,28 +54,59 @@ class DelayedTask:
33
54
  self._cancelled = True
34
55
 
35
56
 
57
+ @dataclasses.dataclass(kw_only=True)
58
+ class Lifespan:
59
+ startup_tasks: list[CoroutineTask[typing.Any]] = dataclasses.field(default_factory=lambda: [])
60
+ shutdown_tasks: list[CoroutineTask[typing.Any]] = dataclasses.field(default_factory=lambda: [])
61
+
62
+ def on_startup(self, task_or_func: Task) -> Task:
63
+ task_or_func = to_coroutine_task(task_or_func)
64
+ self.startup_tasks.append(task_or_func)
65
+ return task_or_func
66
+
67
+ def on_shutdown(self, task_or_func: Task) -> Task:
68
+ task_or_func = to_coroutine_task(task_or_func)
69
+ self.shutdown_tasks.append(task_or_func)
70
+ return task_or_func
71
+
72
+ def start(self, loop: asyncio.AbstractEventLoop) -> None:
73
+ run_tasks(self.startup_tasks, loop)
74
+
75
+ def shutdown(self, loop: asyncio.AbstractEventLoop) -> None:
76
+ run_tasks(self.shutdown_tasks, loop)
77
+
78
+
36
79
  class LoopWrapper(ABCLoopWrapper):
37
- def __init__(self, tasks: list[CoroutineTask] | None = None):
38
- self.on_startup: list[CoroutineTask] = []
39
- self.on_shutdown: list[CoroutineTask] = []
40
- self.tasks = tasks or []
80
+ def __init__(
81
+ self,
82
+ *,
83
+ tasks: list[CoroutineTask[typing.Any]] | None = None,
84
+ lifespan: Lifespan | None = None,
85
+ ) -> None:
86
+ self.tasks: list[CoroutineTask[typing.Any]] = tasks or []
87
+ self.lifespan = lifespan or Lifespan()
41
88
  self._loop = asyncio.new_event_loop()
89
+
90
+ def __repr__(self) -> str:
91
+ return "<{}: loop={!r} with tasks={!r}, lifespan={!r}>".format(
92
+ self.__class__.__name__,
93
+ self._loop,
94
+ self.tasks,
95
+ self.lifespan,
96
+ )
42
97
 
43
98
  def run_event_loop(self) -> None:
44
99
  if not self.tasks:
45
100
  logger.warning("You run loop with 0 tasks!")
46
101
 
47
- for startup_task in self.on_startup:
48
- self._loop.run_until_complete(startup_task)
49
- for task in self.tasks:
50
- self._loop.create_task(task)
51
-
52
- self.tasks.clear()
102
+ self.lifespan.start(self._loop)
103
+ run_tasks(self.tasks, self._loop)
53
104
  tasks = asyncio.all_tasks(self._loop)
105
+
54
106
  try:
55
107
  while tasks:
56
108
  tasks_results, _ = self._loop.run_until_complete(
57
- asyncio.wait(tasks, return_when=asyncio.FIRST_EXCEPTION)
109
+ asyncio.wait(tasks, return_when=asyncio.FIRST_EXCEPTION),
58
110
  )
59
111
  for task_result in tasks_results:
60
112
  try:
@@ -64,19 +116,15 @@ class LoopWrapper(ABCLoopWrapper):
64
116
  tasks = asyncio.all_tasks(self._loop)
65
117
  except KeyboardInterrupt:
66
118
  print() # blank print for ^C
67
- logger.info("KeyboardInterrupt")
119
+ logger.info("Caught KeyboardInterrupt, cancellation...")
68
120
  self.complete_tasks(tasks)
69
121
  finally:
70
- for shutdown_task in self.on_shutdown:
71
- self._loop.run_until_complete(shutdown_task)
122
+ self.lifespan.shutdown(self._loop)
72
123
  if self._loop.is_running():
73
124
  self._loop.close()
74
125
 
75
- def add_task(self, task: CoroutineFunc | CoroutineTask | DelayedTask):
76
- if asyncio.iscoroutinefunction(task) or isinstance(task, DelayedTask):
77
- task = task()
78
- elif not asyncio.iscoroutine(task):
79
- raise TypeError("Task should be coroutine or coroutine function.")
126
+ def add_task(self, task: Task) -> None:
127
+ task = to_coroutine_task(task)
80
128
 
81
129
  if self._loop and self._loop.is_running():
82
130
  self._loop.create_task(task)
@@ -97,15 +145,14 @@ class LoopWrapper(ABCLoopWrapper):
97
145
  hours: int = 0,
98
146
  minutes: int = 0,
99
147
  seconds: float = 0,
100
- ) -> typing.Callable[[typing.Callable], DelayedTask]:
148
+ ):
101
149
  seconds += minutes * 60
102
150
  seconds += hours * 60 * 60
103
151
  seconds += days * 24 * 60 * 60
104
152
 
105
- def decorator(func: typing.Callable) -> DelayedTask:
106
- delayed_task = DelayedTask(func, seconds, repeat=False)
107
- self.add_task(delayed_task)
108
- return delayed_task
153
+ def decorator(func: CoroFunc) -> CoroFunc:
154
+ self.add_task(DelayedTask(func, seconds, repeat=False))
155
+ return func
109
156
 
110
157
  return decorator
111
158
 
@@ -116,17 +163,16 @@ class LoopWrapper(ABCLoopWrapper):
116
163
  hours: int = 0,
117
164
  minutes: int = 0,
118
165
  seconds: float = 0,
119
- ) -> typing.Callable[[typing.Callable], DelayedTask]:
166
+ ):
120
167
  seconds += minutes * 60
121
168
  seconds += hours * 60 * 60
122
169
  seconds += days * 24 * 60 * 60
123
170
 
124
- def decorator(func: typing.Callable) -> DelayedTask:
125
- delayed_task = DelayedTask(func, seconds, repeat=True)
126
- self.add_task(delayed_task)
127
- return delayed_task
171
+ def decorator(func: CoroFunc) -> CoroFunc:
172
+ self.add_task(DelayedTask(func, seconds, repeat=True))
173
+ return func
128
174
 
129
175
  return decorator
130
176
 
131
177
 
132
- __all__ = ("DelayedTask", "LoopWrapper")
178
+ __all__ = ("DelayedTask", "Lifespan", "LoopWrapper", "to_coroutine_task")
@@ -0,0 +1,31 @@
1
+ import hashlib
2
+ import hmac
3
+ import typing
4
+
5
+ from telegrinder.api.abc import Token
6
+
7
+
8
+ def verify_webapp_request(secret_token: str, request_headers: typing.Mapping[str, typing.Any]) -> bool:
9
+ """Verifies update request is from telegram."""
10
+
11
+ return request_headers.get("X-Telegram-Bot-Api-Secret-Token") == secret_token
12
+
13
+
14
+ def webapp_validate_request(
15
+ bot_token: Token,
16
+ request_query_params: typing.Mapping[str, typing.Any],
17
+ ) -> bool:
18
+ """Verifies authentity of webapp request by counting hash of its parameters."""
19
+
20
+ items = sorted(request_query_params.items(), key=lambda kv: kv[0])
21
+ data_check_string = "\n".join(f"{k}={param}" for k, param in items if k != "hash")
22
+ secret = hmac.new(
23
+ "WebAppData".encode(),
24
+ bot_token.encode(),
25
+ hashlib.sha256,
26
+ ).digest()
27
+ data_chk = hmac.new(secret, data_check_string.encode(), hashlib.sha256)
28
+ return data_chk.hexdigest() == request_query_params.get("hash")
29
+
30
+
31
+ __all__ = ("verify_webapp_request", "webapp_validate_request")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: telegrinder
3
- Version: 0.1.dev164
3
+ Version: 0.1.dev165
4
4
  Summary: Framework for effective and reliable async telegram bot building.
5
5
  Home-page: https://github.com/timoniq/telegrinder
6
6
  License: MIT
@@ -1,16 +1,16 @@
1
- telegrinder/__init__.py,sha256=iAaXnpZbc6xcdpHv56K6Hbi8KFryT--wC8UZo4sOUXk,2859
1
+ telegrinder/__init__.py,sha256=UWGzZrq4fnPTEiJr4lMBSK8gsnB4oV-v5YW7fOzTvKc,3593
2
2
  telegrinder/api/__init__.py,sha256=pIDtnsL0NwT5PgVm43Gkp-ByOqDsqnD-oFDiC9tcPT4,246
3
3
  telegrinder/api/abc.py,sha256=5pK6zqZtLphnOVAYwa8sT15F940gCQNzy53nyUTZWWQ,1803
4
4
  telegrinder/api/api.py,sha256=6gq39odyNjyu58l7UrZKnOTMbgA5pR9nJ4ArAJFxNEY,2442
5
5
  telegrinder/api/error.py,sha256=KjZ-14L3xY3KB0VvKktspnzRpkMBCmtwP-rg_hbohwM,425
6
6
  telegrinder/api/response.py,sha256=d7Oxd5kOdbZNJiALkzkecHl8Y3K_BzCmsRq2Sn3otqA,491
7
7
  telegrinder/bot/__init__.py,sha256=tLEUne5ftvKUVlkMAtPTO1_TSHkYJBbG73LuiBeC7gk,1560
8
- telegrinder/bot/bot.py,sha256=iOmbJ9bXL5P2NG_cO4n8lGyAr-QTv5idfwo4xtsdWjc,2195
8
+ telegrinder/bot/bot.py,sha256=TLpdgIWEvjAooMOL1hsIkAsdRZFJiZvRErIxLJWqYCw,2472
9
9
  telegrinder/bot/cute_types/__init__.py,sha256=HeuWq297lY209MssrEbj5MsxsGfOhwVLo1pH_-pHv_I,295
10
10
  telegrinder/bot/cute_types/base.py,sha256=DDIJCCW-R6OxXp806aFSAdK88WSmzNPgUe1uzx6hgiI,4542
11
11
  telegrinder/bot/cute_types/callback_query.py,sha256=gSohTLjq9IQimya41Vl6i8HvGSKwLzbkjV00Jgp13QY,20270
12
12
  telegrinder/bot/cute_types/inline_query.py,sha256=QmaYkXSOQHrkWs7N6eD_HiTGGOtegN10hVppU37z3bE,2475
13
- telegrinder/bot/cute_types/message.py,sha256=xYlbHfKP1kbVpUXOLed8yCuxW8v1cD7lV6NMopyq0PI,140752
13
+ telegrinder/bot/cute_types/message.py,sha256=lf5exKXqD0SzpJKGPj5y7umD0pq3qegUhANEKYjPlsA,140760
14
14
  telegrinder/bot/cute_types/update.py,sha256=VakZ2FwapOJvpEBIyzuiT8eftHHzBS-uPXrAUROQxOg,752
15
15
  telegrinder/bot/cute_types/utils.py,sha256=Gp7zHUn5gEfxFItIYbzkaj6wxWoPNe7hM9abHkn3Jug,16349
16
16
  telegrinder/bot/dispatch/__init__.py,sha256=o10t98PY1BuIGaJcloxfbgUYp0bf5ZqAaBQScIaV3VQ,1322
@@ -26,7 +26,7 @@ telegrinder/bot/dispatch/middleware/__init__.py,sha256=qDuTt2ZZKX9UMjPdw5xaaNZdM
26
26
  telegrinder/bot/dispatch/middleware/abc.py,sha256=mF_G22pes-qJg6wqK9Tf71sduODXSyPjWyPT1hAiDo0,429
27
27
  telegrinder/bot/dispatch/process.py,sha256=J9MYuP-soXXa0eFjJ-5wE_bNEFmr4SukJzdajDSTfAw,2313
28
28
  telegrinder/bot/dispatch/return_manager/__init__.py,sha256=-4h9nU-vdyPgv7bqKi1fAlfzNOKTO9m9FtdTZOhrmuc,447
29
- telegrinder/bot/dispatch/return_manager/abc.py,sha256=dGPwsIUJW_6SRsNxSiWS69xOOwSOATzMP2a7FoD90sA,3150
29
+ telegrinder/bot/dispatch/return_manager/abc.py,sha256=5EWmdQJExdHkbmpqK4ZBU3Uj-aCkfnTp9B94KRU7-40,3346
30
30
  telegrinder/bot/dispatch/return_manager/callback_query.py,sha256=LIkXTGGyEnAHY-L_F82sbtzQtjvOHBi2GeL2eiWsEFc,656
31
31
  telegrinder/bot/dispatch/return_manager/inline_query.py,sha256=-GRnPcdnNamtKL0IbbxCynyO3Dimk9Uz-_-wegfr1h4,484
32
32
  telegrinder/bot/dispatch/return_manager/message.py,sha256=MNML9jGAAkmza1bwUOQVn9l2FmFqGHP4npub6TM_vqs,1139
@@ -42,7 +42,7 @@ telegrinder/bot/dispatch/waiter_machine/middleware.py,sha256=6i_E2VPX71wYFnjESsU
42
42
  telegrinder/bot/dispatch/waiter_machine/short_state.py,sha256=2jYjr5RM2DknakcdbTc_xvH8FCrKKvDI8tsUwG0I5Hg,1200
43
43
  telegrinder/bot/polling/__init__.py,sha256=OqfIFPS_V6UrCg-vCv9pkMFzTKdNbDP2faBfATs_TGg,94
44
44
  telegrinder/bot/polling/abc.py,sha256=-5BpX55SJfDlEJWt15yOXWCizQRrgeY5oiA5eHkm1Nw,434
45
- telegrinder/bot/polling/polling.py,sha256=GPXXlAhI81PZVUMGXsPd4j67GO19zozMRJaVNAgsBMg,4280
45
+ telegrinder/bot/polling/polling.py,sha256=IhtdF-_n77T9epntZuX6y25-pPZUkogxJelVYm308k8,4717
46
46
  telegrinder/bot/rules/__init__.py,sha256=4jBfvj6-xLt7bpEPUOUlcG7it-HLrGMzLbDQ4gYwUNc,2119
47
47
  telegrinder/bot/rules/abc.py,sha256=yqHIvvSuBTser6UCJgnVj1HHh7gfghzYaoV9hAFhfFM,3676
48
48
  telegrinder/bot/rules/adapter/__init__.py,sha256=jFWpi3te8n-Ega3caCwLiA3iTW7F86brae0TZzH_BaU,231
@@ -58,7 +58,7 @@ telegrinder/bot/rules/fuzzy.py,sha256=ReweSKmql4a6AHFv2tXqCQoGktYpeezBLWvW_hS1YJ
58
58
  telegrinder/bot/rules/inline.py,sha256=iN3BQr-TabRBItk0Gcy_YeqPhebnVmKgP1c_MEMpR_Q,1950
59
59
  telegrinder/bot/rules/integer.py,sha256=iZWctQQbrUV5kIhv8GI-O3iYzeI2d0dUdQ8uCaLB9gQ,531
60
60
  telegrinder/bot/rules/is_from.py,sha256=WdKAuU9tY9BaRt0997nCM4RKqw4jHjpSLlQIW4dgSWw,5263
61
- telegrinder/bot/rules/markup.py,sha256=bgLm4-GKxWB1jm0ZDcKFcqnU5OaKEpJHuiVhWuJqyhc,1107
61
+ telegrinder/bot/rules/markup.py,sha256=pqmuEhBpnZBVyLA-P2mqgfZ_MqACeu6mDNlYPAFcr8I,1110
62
62
  telegrinder/bot/rules/mention.py,sha256=ozXV3awsrJhkFKrTvPEl1iyVkDs0GWMmuRSLSnSdOmo,493
63
63
  telegrinder/bot/rules/message_entities.py,sha256=_lWHCNymbV1Sv-f2Q8Ca3SOxqIPSHVyVXgfYIBPy9dE,1096
64
64
  telegrinder/bot/rules/regex.py,sha256=wqGEEiFqe5t_RwX9KjVCtg0wRZfwqo1ktGvNBo9JaKE,1191
@@ -72,14 +72,14 @@ telegrinder/bot/scenario/choice.py,sha256=-NYyzgfGI0njVuT-EY0j3jS4tPlsKOEkZaUagt
72
72
  telegrinder/client/__init__.py,sha256=ZiS1Wb_l_kv3FHzEEi1oXtFLwlA_HXmWOzeN0xA3E7Y,104
73
73
  telegrinder/client/abc.py,sha256=OxsTX_PLYBEeFT9zpidFUzAbQL9BM7rQqru7zdn5DiQ,1611
74
74
  telegrinder/client/aiohttp.py,sha256=RLhjWy-RGZ7848o75ASXBD9bqo06gaPfOv3d8QlyRYI,4147
75
- telegrinder/model.py,sha256=VEM7meEQ8O7Gdt1cBGLjQxJODPqE4Q7lppeYWVchXYA,4380
75
+ telegrinder/model.py,sha256=OpOiiW_KEi7lwhzIT0zmqgBO-LRyzaDOdoEgPFKuXck,4675
76
76
  telegrinder/modules.py,sha256=wJM8C1MbciJE-T3iPmxNXpHEQxO1ln35eDv7joRDNwc,7977
77
77
  telegrinder/msgspec_json.py,sha256=phfyhUvYYZUGEcI6RAyRx9lnARPK_Fqtw3Q0MEJnuUk,226
78
- telegrinder/msgspec_utils.py,sha256=ZA_qj36FabalE65J82j_Hp34umHhUFbNIOt8CBYbqvA,7987
78
+ telegrinder/msgspec_utils.py,sha256=BciLRVZh3IJHawFN3Hia-QC3SK587JhinULEigzPEtk,8213
79
79
  telegrinder/node/__init__.py,sha256=01XTe8GPUBp5LXayDshihTxre7ejf99NYte20d08JLM,706
80
80
  telegrinder/node/attachment.py,sha256=vMnD2tWQQQ6PFuXEIq2ZdL91xcBxiwlAkMkqJqseLlk,2587
81
81
  telegrinder/node/base.py,sha256=rEYPjLQ5EqahyIvH9ktlk_iOiym2NGK2wzh9akVIs6I,2220
82
- telegrinder/node/composer.py,sha256=OQj3WpY5EJ2UyFa5BWw70-AvXBny9jcuOVMRbrgOQWg,2226
82
+ telegrinder/node/composer.py,sha256=pGB41IzjLOJz909bVP72gzB9RZF_kqt18e1etqj_GeU,2240
83
83
  telegrinder/node/container.py,sha256=sECP3TyC6AaNcJqKOfrL1T7-N8fkZzP2vB84kku6Jxg,636
84
84
  telegrinder/node/message.py,sha256=2IW6DjF0KqH2_TZbZ-MXNsDioQRVPg9TUt86aQos0Kk,415
85
85
  telegrinder/node/rule.py,sha256=VGmS4lJAFCoR0hCZSLn56fonMt0FhOGyZ1BQn_1vgeg,1724
@@ -89,19 +89,19 @@ telegrinder/node/tools/__init__.py,sha256=TI_o7MbS4DUOSkNNgJGLocXfRybPFv2WOhBty0
89
89
  telegrinder/node/tools/generator.py,sha256=bc3kJSvS2TdIcBXkEbI4tpfhnvVe16m9ba5-WcIPy0c,1025
90
90
  telegrinder/node/update.py,sha256=QD-m9soBgsP3voTbhaErWdE1FciwYyJCIFNDYf_zra0,253
91
91
  telegrinder/rules.py,sha256=BFB8RFwKKxqs9HFfo_p0RfulQNonPZAX8cHpmnG7qCU,39
92
- telegrinder/tools/__init__.py,sha256=EssNbs2XHkoL-tRMB_nk5pQsgdDLg2zb0nSUY8liXIM,2878
92
+ telegrinder/tools/__init__.py,sha256=9KScN5t8fuyjN2ERf20PRu4eLBwfVtfRyE6zsJmL08E,2904
93
93
  telegrinder/tools/buttons.py,sha256=qMvtpawzkjdqopqE7o9C0k-no1dGJVy5gjFX4SiOE6A,2430
94
94
  telegrinder/tools/error_handler/__init__.py,sha256=WmYWZCNhhSk32j4lIOltEwzoYUx086TGTbOF5h3Ps7s,207
95
95
  telegrinder/tools/error_handler/abc.py,sha256=ymQGDXgnIkfjMMBsLeNcpekQ-p7lj9kSSTLFWqpZ8Ok,952
96
96
  telegrinder/tools/error_handler/error.py,sha256=jVp3J4pMkkL20QHvDtlid9hKtAc66jZIcpsecB3-f98,188
97
97
  telegrinder/tools/error_handler/error_handler.py,sha256=GpGNkEHZAv_4awk96tpJwcnm_YdI3MAfWVILS49jNQ4,5992
98
98
  telegrinder/tools/formatting/__init__.py,sha256=_oxb-4y_vyIgALlO2rfaa-azqicySpHHIcaYBrVPdSg,1609
99
- telegrinder/tools/formatting/html.py,sha256=-tvN1zJK_Q7evil3-XgRdvsdYsOgaG9eX2KsIQkt0m8,8718
100
- telegrinder/tools/formatting/links.py,sha256=ABglEz8EA6XitSM5xJt2FU78ffUdXVNbziJUjoUjKnI,1074
101
- telegrinder/tools/formatting/spec_html_formats.py,sha256=VMPw39IQEM7XUy0r9uzpkGfYmyE2ItJiSEmXCbyKUuE,2750
99
+ telegrinder/tools/formatting/html.py,sha256=QxgCSmfuESnsIsg-UjRPBcBjWNT04j1xV_6G4z9FtR8,8580
100
+ telegrinder/tools/formatting/links.py,sha256=thRwOUBoJvg7iLUD1WMeV23V7T4XUj_J4EJgLcAOXts,1334
101
+ telegrinder/tools/formatting/spec_html_formats.py,sha256=gBsPlDCOEzPMPk_wUmmNEQUFxV8USHQgBuJOyE4y0EY,2747
102
102
  telegrinder/tools/global_context/__init__.py,sha256=QcNZpVTS-ZsPGdF4BQ10wnrfr1fZ3jX9aI-6It0nQxE,282
103
103
  telegrinder/tools/global_context/abc.py,sha256=twwAmbTk49KGl_POImr4yj6POr-zdx8mz74McuphZH0,1644
104
- telegrinder/tools/global_context/global_context.py,sha256=hXlGkU2M4Cw8m_-b1uFZojlVDkhzUhNfBFbp-nr78eE,13947
104
+ telegrinder/tools/global_context/global_context.py,sha256=XhrpRGYcW7I3Ke3D89ervSRZbMa6crkkiqeH8n9eqt0,13947
105
105
  telegrinder/tools/global_context/telegrinder_ctx.py,sha256=g4iXYlK2IEi2sbJz1MqfBIDBrqF_4vznddjOUSEW8f8,651
106
106
  telegrinder/tools/i18n/__init__.py,sha256=CLUoiCJzOZzF-dqDIHZ5Fc8QUa38cYhIG4WF-ctPLfE,288
107
107
  telegrinder/tools/i18n/base.py,sha256=sJwgw6lobMIQEKIC4QH5O4sPKZADHAcxltZJvTtvaFE,637
@@ -112,16 +112,17 @@ telegrinder/tools/kb_set/__init__.py,sha256=k1KCQTnvEgJ2y4KlghhJWOh5rccwg_27cs82
112
112
  telegrinder/tools/kb_set/base.py,sha256=mbZs-ViUErfSibzyN064IqZp76LBJPg3NB4D9v4VFtg,243
113
113
  telegrinder/tools/kb_set/yaml.py,sha256=rDoVkdfxp3gz-pS82nB1LDQU8cyckErwMee4nCXHunI,2027
114
114
  telegrinder/tools/keyboard.py,sha256=TZ5vVRQKbXrVqZNnok9jrbwNQYSaGpA41wsGHUNJkwo,3738
115
- telegrinder/tools/loop_wrapper/__init__.py,sha256=os6kfzNEpGa7EHBbwFpym-iEnQvJGokEyHtyuVIOtks,143
116
- telegrinder/tools/loop_wrapper/abc.py,sha256=nUr2o24jaja4mpCcvbZRxHYq4hDsnGReC9yYHacQ4pw,443
117
- telegrinder/tools/loop_wrapper/loop_wrapper.py,sha256=ZEwuqqEz-r5BehCRG-E5K1lg2i4ODyyhOh0iKFT8GDw,4306
115
+ telegrinder/tools/loop_wrapper/__init__.py,sha256=ZQ5jmE1lOKnqJlMZ9k2OYmjvOEhOlHPijUWqZ4nHIgk,165
116
+ telegrinder/tools/loop_wrapper/abc.py,sha256=ET_Dp-kRz75Jo1fZB3qofUgEXN4FqlU0xH2diESKGCM,266
117
+ telegrinder/tools/loop_wrapper/loop_wrapper.py,sha256=A-kO6F5KzQJXkLbxe-2Vex_TNTAgpUEawyZ6JLFao2A,5702
118
118
  telegrinder/tools/magic.py,sha256=AA7jVv5NNOepWjv8rdPdUmeYj7_XfeCl3laYdRreZc0,1856
119
119
  telegrinder/tools/parse_mode.py,sha256=JyQ-x9YAMPLhIIiUX01acyKkpWgs5TBA07W-iUyPHpE,92
120
120
  telegrinder/types/__init__.py,sha256=pvPKWDXq9PBiIOCW8dFcJMqgr1kAqodPhwT-u8I4kug,78
121
121
  telegrinder/types/enums.py,sha256=9ZYiz_KRP1o7jB5If6730YLDfLt_-wKVK8UFs5a6CVI,18330
122
122
  telegrinder/types/methods.py,sha256=CbeuZgtH5IIH1cKZlMWVkTnNAFqQLOYLw-_DeWHKKhk,186385
123
123
  telegrinder/types/objects.py,sha256=znpGLbPrFu5GCUf4j6p_XA7iCVaxYqUZN1UqBEpr5FY,214803
124
- telegrinder-0.1.dev164.dist-info/LICENSE,sha256=J9ngGsqHCNNjpm3xYPT7EnlzsnjhfqNXej5mJFjM6lw,1094
125
- telegrinder-0.1.dev164.dist-info/METADATA,sha256=iaWGLP29CV1O042MEqTS25vDC7FsqUSB9Zh5cE62gGc,2892
126
- telegrinder-0.1.dev164.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
127
- telegrinder-0.1.dev164.dist-info/RECORD,,
124
+ telegrinder/verification_utils.py,sha256=zpQ_ZOJGj9Lix3gbWiHuVzIYg48jad5CqIaeu4QcfJQ,1017
125
+ telegrinder-0.1.dev165.dist-info/LICENSE,sha256=J9ngGsqHCNNjpm3xYPT7EnlzsnjhfqNXej5mJFjM6lw,1094
126
+ telegrinder-0.1.dev165.dist-info/METADATA,sha256=TePH1bhDDmVftka-P9VbCNVc5D6721ITDYM-7lWh68k,2892
127
+ telegrinder-0.1.dev165.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
128
+ telegrinder-0.1.dev165.dist-info/RECORD,,