telegrinder 0.1.dev171__tar.gz → 0.2.0.post1__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.

Potentially problematic release.


This version of telegrinder might be problematic. Click here for more details.

Files changed (160) hide show
  1. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/PKG-INFO +1 -1
  2. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/pyproject.toml +2 -2
  3. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/__init__.py +2 -2
  4. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/api/__init__.py +1 -2
  5. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/api/api.py +3 -3
  6. telegrinder-0.2.0.post1/telegrinder/api/token.py +36 -0
  7. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/__init__.py +12 -6
  8. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/bot.py +12 -5
  9. telegrinder-0.2.0.post1/telegrinder/bot/cute_types/__init__.py +17 -0
  10. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/base.py +17 -43
  11. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/callback_query.py +5 -6
  12. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/chat_join_request.py +4 -5
  13. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/chat_member_updated.py +3 -4
  14. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/inline_query.py +3 -4
  15. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/message.py +9 -10
  16. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/update.py +13 -13
  17. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/cute_types/utils.py +1 -1
  18. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/__init__.py +9 -9
  19. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/abc.py +2 -2
  20. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/context.py +11 -2
  21. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/dispatch.py +18 -33
  22. telegrinder-0.2.0.post1/telegrinder/bot/dispatch/handler/__init__.py +5 -0
  23. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/handler/abc.py +3 -3
  24. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/handler/func.py +17 -12
  25. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/handler/message_reply.py +6 -7
  26. telegrinder-0.2.0.post1/telegrinder/bot/dispatch/middleware/__init__.py +3 -0
  27. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/process.py +30 -11
  28. telegrinder-0.2.0.post1/telegrinder/bot/dispatch/return_manager/__init__.py +19 -0
  29. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/return_manager/callback_query.py +1 -2
  30. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/return_manager/inline_query.py +1 -2
  31. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/return_manager/message.py +1 -2
  32. telegrinder-0.2.0.post1/telegrinder/bot/dispatch/view/__init__.py +22 -0
  33. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/abc.py +9 -4
  34. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/box.py +2 -2
  35. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/callback_query.py +1 -2
  36. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/chat_join_request.py +1 -2
  37. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/chat_member.py +16 -2
  38. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/inline_query.py +1 -2
  39. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/message.py +1 -2
  40. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/view/raw.py +8 -10
  41. telegrinder-0.2.0.post1/telegrinder/bot/dispatch/waiter_machine/__init__.py +10 -0
  42. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/waiter_machine/machine.py +10 -6
  43. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/waiter_machine/short_state.py +2 -2
  44. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/polling/abc.py +1 -1
  45. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/polling/polling.py +3 -3
  46. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/__init__.py +20 -20
  47. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/abc.py +50 -40
  48. telegrinder-0.2.0.post1/telegrinder/bot/rules/adapter/__init__.py +14 -0
  49. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/adapter/abc.py +6 -3
  50. telegrinder-0.2.0.post1/telegrinder/bot/rules/adapter/errors.py +5 -0
  51. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/adapter/event.py +27 -15
  52. telegrinder-0.2.0.post1/telegrinder/bot/rules/adapter/node.py +48 -0
  53. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/adapter/raw_update.py +13 -5
  54. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/callback_data.py +12 -6
  55. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/chat_join.py +4 -4
  56. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/func.py +1 -1
  57. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/inline.py +3 -3
  58. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/markup.py +3 -1
  59. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/message_entities.py +1 -1
  60. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/text.py +1 -2
  61. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/update.py +1 -2
  62. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/scenario/abc.py +2 -2
  63. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/scenario/checkbox.py +1 -2
  64. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/scenario/choice.py +1 -2
  65. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/model.py +9 -2
  66. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/msgspec_utils.py +55 -55
  67. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/node/__init__.py +1 -3
  68. telegrinder-0.2.0.post1/telegrinder/node/base.py +138 -0
  69. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/node/command.py +3 -3
  70. telegrinder-0.2.0.post1/telegrinder/node/composer.py +185 -0
  71. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/node/container.py +3 -3
  72. telegrinder-0.2.0.post1/telegrinder/node/event.py +71 -0
  73. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/node/me.py +3 -4
  74. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/node/polymorphic.py +12 -6
  75. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/node/rule.py +1 -9
  76. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/node/scope.py +9 -1
  77. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/node/source.py +11 -0
  78. telegrinder-0.2.0.post1/telegrinder/node/update.py +15 -0
  79. telegrinder-0.2.0.post1/telegrinder/rules.py +60 -0
  80. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/error_handler/abc.py +2 -2
  81. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/error_handler/error_handler.py +5 -5
  82. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/global_context/global_context.py +1 -1
  83. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/keyboard.py +1 -1
  84. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/loop_wrapper/loop_wrapper.py +9 -9
  85. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/magic.py +64 -19
  86. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/types/__init__.py +1 -0
  87. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/types/enums.py +1 -0
  88. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/types/methods.py +78 -11
  89. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/types/objects.py +46 -24
  90. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/verification_utils.py +1 -3
  91. telegrinder-0.1.dev171/telegrinder/api/abc.py +0 -79
  92. telegrinder-0.1.dev171/telegrinder/bot/cute_types/__init__.py +0 -17
  93. telegrinder-0.1.dev171/telegrinder/bot/dispatch/handler/__init__.py +0 -5
  94. telegrinder-0.1.dev171/telegrinder/bot/dispatch/middleware/__init__.py +0 -3
  95. telegrinder-0.1.dev171/telegrinder/bot/dispatch/return_manager/__init__.py +0 -19
  96. telegrinder-0.1.dev171/telegrinder/bot/dispatch/view/__init__.py +0 -22
  97. telegrinder-0.1.dev171/telegrinder/bot/dispatch/waiter_machine/__init__.py +0 -10
  98. telegrinder-0.1.dev171/telegrinder/bot/rules/adapter/__init__.py +0 -14
  99. telegrinder-0.1.dev171/telegrinder/bot/rules/adapter/errors.py +0 -4
  100. telegrinder-0.1.dev171/telegrinder/bot/rules/adapter/node.py +0 -42
  101. telegrinder-0.1.dev171/telegrinder/node/base.py +0 -203
  102. telegrinder-0.1.dev171/telegrinder/node/composer.py +0 -188
  103. telegrinder-0.1.dev171/telegrinder/node/event.py +0 -59
  104. telegrinder-0.1.dev171/telegrinder/node/update.py +0 -11
  105. telegrinder-0.1.dev171/telegrinder/rules.py +0 -1
  106. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/LICENSE +0 -0
  107. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/readme.md +0 -0
  108. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/api/error.py +0 -0
  109. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/api/response.py +0 -0
  110. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/middleware/abc.py +0 -0
  111. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/return_manager/abc.py +0 -0
  112. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/dispatch/waiter_machine/middleware.py +0 -0
  113. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/polling/__init__.py +0 -0
  114. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/command.py +0 -0
  115. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/enum_text.py +0 -0
  116. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/fuzzy.py +0 -0
  117. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/integer.py +0 -0
  118. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/is_from.py +0 -0
  119. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/mention.py +0 -0
  120. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/message.py +0 -0
  121. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/node.py +0 -0
  122. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/regex.py +0 -0
  123. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/rule_enum.py +0 -0
  124. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/rules/start.py +0 -0
  125. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/bot/scenario/__init__.py +0 -0
  126. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/client/__init__.py +0 -0
  127. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/client/abc.py +0 -0
  128. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/client/aiohttp.py +0 -0
  129. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/modules.py +0 -0
  130. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/msgspec_json.py +0 -0
  131. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/node/attachment.py +0 -0
  132. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/node/callback_query.py +0 -0
  133. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/node/message.py +0 -0
  134. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/node/text.py +0 -0
  135. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/node/tools/__init__.py +0 -0
  136. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/node/tools/generator.py +0 -0
  137. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/py.typed +0 -0
  138. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/__init__.py +0 -0
  139. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/buttons.py +0 -0
  140. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/error_handler/__init__.py +0 -0
  141. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/error_handler/error.py +0 -0
  142. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/formatting/__init__.py +0 -0
  143. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/formatting/html.py +0 -0
  144. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/formatting/links.py +0 -0
  145. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/formatting/spec_html_formats.py +0 -0
  146. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/global_context/__init__.py +0 -0
  147. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/global_context/abc.py +0 -0
  148. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/global_context/telegrinder_ctx.py +0 -0
  149. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/i18n/__init__.py +0 -0
  150. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/i18n/base.py +0 -0
  151. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/i18n/middleware/__init__.py +0 -0
  152. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/i18n/middleware/base.py +0 -0
  153. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/i18n/simple.py +0 -0
  154. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/kb_set/__init__.py +0 -0
  155. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/kb_set/base.py +0 -0
  156. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/kb_set/yaml.py +0 -0
  157. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/limited_dict.py +0 -0
  158. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/loop_wrapper/__init__.py +0 -0
  159. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/loop_wrapper/abc.py +0 -0
  160. {telegrinder-0.1.dev171 → telegrinder-0.2.0.post1}/telegrinder/tools/parse_mode.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: telegrinder
3
- Version: 0.1.dev171
3
+ Version: 0.2.0.post1
4
4
  Summary: Modern visionary telegram bot framework.
5
5
  Home-page: https://github.com/timoniq/telegrinder
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "telegrinder"
3
- version = "0.1.dev171"
3
+ version = "0.2.0.post1"
4
4
  description = "Modern visionary telegram bot framework."
5
5
  authors = ["timoniq <tesseradecades@mail.ru>"]
6
6
  maintainers = ["luwqz1 <howluwqz1@gmail.com>"]
@@ -54,7 +54,7 @@ fntypes = "^0.1.3"
54
54
 
55
55
  [tool.poetry.group.dev.dependencies]
56
56
  pre-commit = "^3.8.0"
57
- ruff = "^0.5.0"
57
+ ruff = ">=0.5,<0.7"
58
58
  basedpyright = "^1.12.1"
59
59
  sort-all = "1.2.0"
60
60
  pytest = "^8.0.0"
@@ -34,7 +34,7 @@ bot.run_forever()
34
34
 
35
35
  import typing
36
36
 
37
- from .api import ABCAPI, API, APIError, APIResponse, Token
37
+ from .api import API, APIError, APIResponse, Token
38
38
  from .bot import (
39
39
  ABCDispatch,
40
40
  ABCHandler,
@@ -122,7 +122,7 @@ Bot: typing.TypeAlias = Telegrinder
122
122
 
123
123
 
124
124
  __all__ = (
125
- "ABCAPI",
125
+ "API",
126
126
  "ABCClient",
127
127
  "ABCDispatch",
128
128
  "ABCErrorHandler",
@@ -1,10 +1,9 @@
1
- from .abc import ABCAPI, Token
2
1
  from .api import API
3
2
  from .error import APIError, InvalidTokenError
4
3
  from .response import APIResponse
4
+ from .token import Token
5
5
 
6
6
  __all__ = (
7
- "ABCAPI",
8
7
  "API",
9
8
  "APIError",
10
9
  "APIResponse",
@@ -4,13 +4,13 @@ from functools import cached_property
4
4
  import msgspec
5
5
  from fntypes.result import Error, Ok, Result
6
6
 
7
+ from telegrinder.api.error import APIError
7
8
  from telegrinder.api.response import APIResponse
9
+ from telegrinder.api.token import Token
8
10
  from telegrinder.client import ABCClient, AiohttpClient
9
11
  from telegrinder.model import DataConverter, decoder
10
12
  from telegrinder.types.methods import APIMethods
11
13
 
12
- from .abc import ABCAPI, APIError, Token
13
-
14
14
 
15
15
  def compose_data(
16
16
  client: ABCClient,
@@ -24,7 +24,7 @@ def compose_data(
24
24
  )
25
25
 
26
26
 
27
- class API(ABCAPI, APIMethods):
27
+ class API(APIMethods):
28
28
  """Bot API with available API methods and http client."""
29
29
 
30
30
  API_URL = "https://api.telegram.org/"
@@ -0,0 +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,5 +1,5 @@
1
- from .bot import Telegrinder
2
- from .cute_types import (
1
+ from telegrinder.bot.bot import Telegrinder
2
+ from telegrinder.bot.cute_types import (
3
3
  BaseCute,
4
4
  CallbackQueryCute,
5
5
  ChatJoinRequestCute,
@@ -8,7 +8,7 @@ from .cute_types import (
8
8
  MessageCute,
9
9
  UpdateCute,
10
10
  )
11
- from .dispatch import (
11
+ from telegrinder.bot.dispatch import (
12
12
  ABCDispatch,
13
13
  ABCHandler,
14
14
  ABCMiddleware,
@@ -37,9 +37,15 @@ from .dispatch import (
37
37
  clear_wm_storage_worker,
38
38
  register_manager,
39
39
  )
40
- from .polling import ABCPolling, Polling
41
- from .rules import ABCRule, CallbackQueryRule, ChatJoinRequestRule, InlineQueryRule, MessageRule
42
- from .scenario import ABCScenario, Checkbox, Choice
40
+ from telegrinder.bot.polling import ABCPolling, Polling
41
+ from telegrinder.bot.rules import (
42
+ ABCRule,
43
+ CallbackQueryRule,
44
+ ChatJoinRequestRule,
45
+ InlineQueryRule,
46
+ MessageRule,
47
+ )
48
+ from telegrinder.bot.scenario import ABCScenario, Checkbox, Choice
43
49
 
44
50
  __all__ = (
45
51
  "ABCDispatch",
@@ -1,10 +1,13 @@
1
1
  import typing_extensions as typing
2
2
 
3
- from telegrinder.api import API
4
- from telegrinder.bot.dispatch import ABCDispatch, Dispatch
5
- from telegrinder.bot.polling import ABCPolling, Polling
3
+ from telegrinder.api.api import API
4
+ from telegrinder.bot.dispatch.abc import ABCDispatch
5
+ from telegrinder.bot.dispatch.dispatch import Dispatch
6
+ from telegrinder.bot.polling.abc import ABCPolling
7
+ from telegrinder.bot.polling.polling import Polling
6
8
  from telegrinder.modules import logger
7
- from telegrinder.tools.loop_wrapper import ABCLoopWrapper, LoopWrapper
9
+ from telegrinder.tools.loop_wrapper import ABCLoopWrapper
10
+ from telegrinder.tools.loop_wrapper.loop_wrapper import LoopWrapper
8
11
 
9
12
  DispatchT = typing.TypeVar("DispatchT", bound=ABCDispatch, default=Dispatch)
10
13
  PollingT = typing.TypeVar("PollingT", bound=ABCPolling, default=Polling)
@@ -57,7 +60,11 @@ class Telegrinder(typing.Generic[DispatchT, PollingT, LoopWrapperT]):
57
60
 
58
61
  async for updates in self.polling.listen():
59
62
  for update in updates:
60
- logger.debug("Received update (update_id={})", update.update_id)
63
+ logger.debug(
64
+ "Received update (update_id={}, update_type={!r})",
65
+ update.update_id,
66
+ update.update_type.name,
67
+ )
61
68
  self.loop_wrapper.add_task(self.dispatch.feed(update, self.api))
62
69
 
63
70
  def run_forever(self, *, offset: int = 0, skip_updates: bool = False) -> None:
@@ -0,0 +1,17 @@
1
+ from telegrinder.bot.cute_types.base import BaseCute
2
+ from telegrinder.bot.cute_types.callback_query import CallbackQueryCute
3
+ from telegrinder.bot.cute_types.chat_join_request import ChatJoinRequestCute
4
+ from telegrinder.bot.cute_types.chat_member_updated import ChatMemberUpdatedCute
5
+ from telegrinder.bot.cute_types.inline_query import InlineQueryCute
6
+ from telegrinder.bot.cute_types.message import MessageCute
7
+ from telegrinder.bot.cute_types.update import UpdateCute
8
+
9
+ __all__ = (
10
+ "BaseCute",
11
+ "CallbackQueryCute",
12
+ "ChatJoinRequestCute",
13
+ "ChatMemberUpdatedCute",
14
+ "InlineQueryCute",
15
+ "MessageCute",
16
+ "UpdateCute",
17
+ )
@@ -6,13 +6,13 @@ from functools import wraps
6
6
  import typing_extensions
7
7
  from fntypes.result import Result
8
8
 
9
- from telegrinder.api import ABCAPI, API
9
+ from telegrinder.api.api import API
10
10
  from telegrinder.model import Model, get_params
11
11
 
12
12
  F = typing.TypeVar("F", bound=typing.Callable[..., typing.Any])
13
13
  Cute = typing.TypeVar("Cute", bound="BaseCute")
14
14
  Update = typing_extensions.TypeVar("Update", bound=Model)
15
- CtxAPI = typing_extensions.TypeVar("CtxAPI", bound=ABCAPI, default=API)
15
+ CtxAPI = typing_extensions.TypeVar("CtxAPI", bound=API, default=API)
16
16
 
17
17
  Executor: typing.TypeAlias = typing.Callable[
18
18
  [Cute, str, dict[str, typing.Any]],
@@ -22,10 +22,10 @@ Executor: typing.TypeAlias = typing.Callable[
22
22
  if typing.TYPE_CHECKING:
23
23
 
24
24
  class BaseCute(Model, typing.Generic[Update, CtxAPI]):
25
- api: ABCAPI
25
+ api: API
26
26
 
27
27
  @classmethod
28
- def from_update(cls, update: Update, bound_api: ABCAPI) -> typing.Self: ...
28
+ def from_update(cls, update: Update, bound_api: API) -> typing.Self: ...
29
29
 
30
30
  @property
31
31
  def ctx_api(self) -> CtxAPI: ...
@@ -56,41 +56,20 @@ if typing.TYPE_CHECKING:
56
56
 
57
57
  else:
58
58
  from fntypes.co import Nothing, Some, Variative
59
- from msgspec._utils import get_class_annotations as _get_class_annotations
60
59
 
61
60
  from telegrinder.msgspec_utils import Option, decoder
61
+ from telegrinder.msgspec_utils import get_class_annotations as _get_class_annotations
62
62
 
63
- _DEFAULT_API_CLASS = API
63
+ def _get_cute_from_generic(generic_args):
64
+ for arg in generic_args:
65
+ orig_arg = typing.get_origin(arg) or arg
64
66
 
65
- def _get_ctx_api_class(cute_class):
66
- if hasattr(cute_class, "__ctx_api_class__"):
67
- return cute_class.__ctx_api_class__
68
-
69
- ctx_api_class = _DEFAULT_API_CLASS
70
- for base in cute_class.__dict__.get("__orig_bases__", ()):
71
- if ctx_api_class is not _DEFAULT_API_CLASS:
72
- break
73
- if issubclass(typing.get_origin(base) or base, BaseCute):
74
- for generic_type in typing.get_args(base):
75
- if issubclass(typing.get_origin(generic_type) or generic_type, ABCAPI):
76
- ctx_api_class = generic_type
77
- break
78
-
79
- cute_class.__ctx_api_class__ = ctx_api_class
80
- return ctx_api_class
81
-
82
- def _get_cute_from_args(args):
83
- for hint in args:
84
- if not isinstance(hint, type):
85
- hint = typing.get_origin(hint) or hint
86
- if not isinstance(hint, type):
87
- continue
88
-
89
- if hint is Variative or issubclass(hint, Option) or issubclass(hint, Some | Nothing):
90
- return _get_cute_from_args(typing.get_args(hint))
91
-
92
- if issubclass(hint, BaseCute):
93
- return hint
67
+ if not isinstance(orig_arg, type):
68
+ continue
69
+ if orig_arg in (Variative, Some, Option):
70
+ return _get_cute_from_generic(typing.get_args(arg))
71
+ if issubclass(arg, BaseCute):
72
+ return arg
94
73
 
95
74
  return None
96
75
 
@@ -99,8 +78,8 @@ else:
99
78
 
100
79
  for key, hint in annotations.items():
101
80
  if not isinstance(hint, type):
102
- if (val := _get_cute_from_args(typing.get_args(hint))) is not None:
103
- cute_annotations[key] = val
81
+ if (cute := _get_cute_from_generic(typing.get_args(hint))) is not None:
82
+ cute_annotations[key] = cute
104
83
 
105
84
  elif issubclass(hint, BaseCute):
106
85
  cute_annotations[key] = hint
@@ -140,7 +119,7 @@ else:
140
119
  cls.__cute_annotations__[field].from_update(_get_value(value), bound_api=bound_api),
141
120
  type=cls.__annotations__[field],
142
121
  )
143
- if field in cls.__cute_annotations__ and value
122
+ if field in cls.__cute_annotations__ and not isinstance(value, Nothing)
144
123
  else value
145
124
  for field, value in update.to_dict().items()
146
125
  },
@@ -149,11 +128,6 @@ else:
149
128
 
150
129
  @property
151
130
  def ctx_api(self):
152
- ctx_api_class = _get_ctx_api_class(self.__class__)
153
- assert isinstance(
154
- self.api,
155
- ctx_api_class,
156
- ), f"Bound API of type {self.api.__class__.__name__!r} is incompatible with {ctx_api_class.__name__!r}."
157
131
  return self.api
158
132
 
159
133
  def to_dict(self, *, exclude_fields=None):
@@ -4,7 +4,9 @@ from contextlib import suppress
4
4
  import msgspec
5
5
  from fntypes.co import Nothing, Result, Some, Variative, unwrapping
6
6
 
7
- from telegrinder.api import ABCAPI, APIError
7
+ from telegrinder.api import API, APIError
8
+ from telegrinder.bot.cute_types.base import BaseCute, compose_method_params, shortcut
9
+ from telegrinder.bot.cute_types.message import MediaType, MessageCute, ReplyMarkup, execute_method_edit
8
10
  from telegrinder.model import get_params
9
11
  from telegrinder.msgspec_utils import Option, decoder
10
12
  from telegrinder.types.objects import (
@@ -21,12 +23,9 @@ from telegrinder.types.objects import (
21
23
  User,
22
24
  )
23
25
 
24
- from .base import BaseCute, compose_method_params, shortcut
25
- from .message import MediaType, MessageCute, ReplyMarkup, execute_method_edit
26
26
 
27
-
28
- class CallbackQueryCute(BaseCute[CallbackQuery], CallbackQuery, kw_only=True, dict=True):
29
- api: ABCAPI
27
+ class CallbackQueryCute(BaseCute[CallbackQuery], CallbackQuery, kw_only=True):
28
+ api: API
30
29
 
31
30
  message: Option[Variative[MessageCute, InaccessibleMessage]] = Nothing()
32
31
  """Optional. Message sent by the bot with the callback button that originated
@@ -2,15 +2,14 @@ import typing
2
2
 
3
3
  from fntypes.result import Result
4
4
 
5
- from telegrinder.api.abc import ABCAPI, APIError
5
+ from telegrinder.api import API, APIError
6
+ from telegrinder.bot.cute_types.base import BaseCute, shortcut
7
+ from telegrinder.bot.cute_types.chat_member_updated import ChatMemberShortcuts, chat_member_interaction
6
8
  from telegrinder.types.objects import ChatJoinRequest, User
7
9
 
8
- from .base import BaseCute, shortcut
9
- from .chat_member_updated import ChatMemberShortcuts, chat_member_interaction
10
-
11
10
 
12
11
  class ChatJoinRequestCute(BaseCute[ChatJoinRequest], ChatJoinRequest, ChatMemberShortcuts, kw_only=True):
13
- api: ABCAPI
12
+ api: API
14
13
 
15
14
  @property
16
15
  def from_user(self) -> User:
@@ -3,12 +3,11 @@ from datetime import datetime
3
3
 
4
4
  from fntypes.result import Result
5
5
 
6
- from telegrinder.api import ABCAPI, APIError
6
+ from telegrinder.api import API, APIError
7
+ from telegrinder.bot.cute_types.base import BaseCute, compose_method_params, shortcut
7
8
  from telegrinder.model import get_params
8
9
  from telegrinder.types.objects import ChatMemberUpdated, ChatPermissions, User
9
10
 
10
- from .base import BaseCute, compose_method_params, shortcut
11
-
12
11
 
13
12
  async def chat_member_interaction(
14
13
  update: BaseCute[typing.Any],
@@ -234,7 +233,7 @@ class ChatMemberShortcuts:
234
233
  class ChatMemberUpdatedCute(
235
234
  BaseCute[ChatMemberUpdated], ChatMemberUpdated, ChatMemberShortcuts, kw_only=True
236
235
  ):
237
- api: ABCAPI
236
+ api: API
238
237
 
239
238
  @property
240
239
  def from_user(self) -> User:
@@ -2,7 +2,8 @@ import typing
2
2
 
3
3
  from fntypes.result import Result
4
4
 
5
- from telegrinder.api import ABCAPI, APIError
5
+ from telegrinder.api import API, APIError
6
+ from telegrinder.bot.cute_types.base import BaseCute, compose_method_params, shortcut
6
7
  from telegrinder.model import get_params
7
8
  from telegrinder.types import (
8
9
  InlineQuery,
@@ -11,11 +12,9 @@ from telegrinder.types import (
11
12
  User,
12
13
  )
13
14
 
14
- from .base import BaseCute, compose_method_params, shortcut
15
-
16
15
 
17
16
  class InlineQueryCute(BaseCute[InlineQuery], InlineQuery, kw_only=True):
18
- api: ABCAPI
17
+ api: API
19
18
 
20
19
  @property
21
20
  def from_user(self) -> User:
@@ -5,7 +5,14 @@ import typing
5
5
  import fntypes.option
6
6
  from fntypes.co import Result, Some, Variative
7
7
 
8
- from telegrinder.api import ABCAPI, APIError
8
+ from telegrinder.api import API, APIError
9
+ from telegrinder.bot.cute_types.base import BaseCute, compose_method_params, shortcut
10
+ from telegrinder.bot.cute_types.utils import (
11
+ compose_link_preview_options,
12
+ compose_reactions,
13
+ compose_reply_params,
14
+ input_media,
15
+ )
9
16
  from telegrinder.model import get_params
10
17
  from telegrinder.msgspec_utils import Nothing, Option
11
18
  from telegrinder.types.objects import (
@@ -30,14 +37,6 @@ from telegrinder.types.objects import (
30
37
  User,
31
38
  )
32
39
 
33
- from .base import BaseCute, compose_method_params, shortcut
34
- from .utils import (
35
- compose_link_preview_options,
36
- compose_reactions,
37
- compose_reply_params,
38
- input_media,
39
- )
40
-
41
40
  if typing.TYPE_CHECKING:
42
41
  from datetime import datetime
43
42
 
@@ -154,7 +153,7 @@ def get_entity_value(
154
153
 
155
154
 
156
155
  class MessageCute(BaseCute[Message], Message, kw_only=True):
157
- api: ABCAPI
156
+ api: API
158
157
 
159
158
  reply_to_message: Option[MessageCute] = Nothing
160
159
  """Optional. For replies in the same chat and message thread, the original
@@ -1,23 +1,23 @@
1
1
  import typing
2
+ from functools import cached_property
2
3
 
3
4
  from fntypes.co import Nothing, Some
4
5
 
5
- from telegrinder.api import ABCAPI
6
+ from telegrinder.api.api import API
7
+ from telegrinder.bot.cute_types.base import BaseCute
8
+ from telegrinder.bot.cute_types.callback_query import CallbackQueryCute
9
+ from telegrinder.bot.cute_types.chat_join_request import ChatJoinRequestCute
10
+ from telegrinder.bot.cute_types.chat_member_updated import ChatMemberUpdatedCute
11
+ from telegrinder.bot.cute_types.inline_query import InlineQueryCute
12
+ from telegrinder.bot.cute_types.message import MessageCute
6
13
  from telegrinder.msgspec_utils import Option
7
- from telegrinder.types import Model, Update
14
+ from telegrinder.types.objects import Model, Update
8
15
 
9
- from .base import BaseCute
10
- from .callback_query import CallbackQueryCute
11
- from .chat_join_request import ChatJoinRequestCute
12
- from .chat_member_updated import ChatMemberUpdatedCute
13
- from .inline_query import InlineQueryCute
14
- from .message import MessageCute
15
-
16
- ModelT = typing.TypeVar("ModelT", bound=Model)
16
+ EventModel = typing.TypeVar("EventModel", bound=Model)
17
17
 
18
18
 
19
19
  class UpdateCute(BaseCute[Update], Update, kw_only=True):
20
- api: ABCAPI
20
+ api: API
21
21
 
22
22
  message: Option[MessageCute] = Nothing()
23
23
  """Optional. New incoming message of any kind - text, photo, sticker, etc."""
@@ -62,11 +62,11 @@ class UpdateCute(BaseCute[Update], Update, kw_only=True):
62
62
  """Optional. A request to join the chat has been sent. The bot must have the can_invite_users
63
63
  administrator right in the chat to receive these updates."""
64
64
 
65
- @property
65
+ @cached_property
66
66
  def incoming_update(self) -> Model:
67
67
  return getattr(self, self.update_type.value).unwrap()
68
68
 
69
- def get_event(self, event_model: type[ModelT]) -> Option[ModelT]:
69
+ def get_event(self, event_model: type[EventModel]) -> Option[EventModel]:
70
70
  if isinstance(self.incoming_update, event_model):
71
71
  return Some(self.incoming_update)
72
72
  return Nothing()
@@ -1,7 +1,7 @@
1
1
  import typing
2
2
 
3
3
  from telegrinder.model import get_params
4
- from telegrinder.types import (
4
+ from telegrinder.types.objects import (
5
5
  InputFile,
6
6
  InputMediaAnimation,
7
7
  InputMediaAudio,
@@ -1,10 +1,10 @@
1
- from .abc import ABCDispatch
2
- from .context import Context
3
- from .dispatch import Dispatch, TelegrinderContext
4
- from .handler import ABCHandler, FuncHandler, MessageReplyHandler
5
- from .middleware import ABCMiddleware
6
- from .process import check_rule, process_inner
7
- from .return_manager import (
1
+ from telegrinder.bot.dispatch.abc import ABCDispatch
2
+ from telegrinder.bot.dispatch.context import Context
3
+ from telegrinder.bot.dispatch.dispatch import Dispatch, TelegrinderContext
4
+ from telegrinder.bot.dispatch.handler import ABCHandler, FuncHandler, MessageReplyHandler
5
+ from telegrinder.bot.dispatch.middleware import ABCMiddleware
6
+ from telegrinder.bot.dispatch.process import check_rule, process_inner
7
+ from telegrinder.bot.dispatch.return_manager import (
8
8
  ABCReturnManager,
9
9
  BaseReturnManager,
10
10
  CallbackQueryReturnManager,
@@ -13,7 +13,7 @@ from .return_manager import (
13
13
  MessageReturnManager,
14
14
  register_manager,
15
15
  )
16
- from .view import (
16
+ from telegrinder.bot.dispatch.view import (
17
17
  ABCStateView,
18
18
  ABCView,
19
19
  BaseStateView,
@@ -26,7 +26,7 @@ from .view import (
26
26
  RawEventView,
27
27
  ViewBox,
28
28
  )
29
- from .waiter_machine import ShortState, WaiterMachine, clear_wm_storage_worker
29
+ from telegrinder.bot.dispatch.waiter_machine import ShortState, WaiterMachine, clear_wm_storage_worker
30
30
 
31
31
  __all__ = (
32
32
  "ABCDispatch",
@@ -1,7 +1,7 @@
1
1
  import typing
2
2
  from abc import ABC, abstractmethod
3
3
 
4
- from telegrinder.api.abc import ABCAPI
4
+ from telegrinder.api import API
5
5
  from telegrinder.tools.global_context.abc import ABCGlobalContext
6
6
  from telegrinder.types.objects import Update
7
7
 
@@ -13,7 +13,7 @@ class ABCDispatch(ABC):
13
13
  pass
14
14
 
15
15
  @abstractmethod
16
- async def feed(self, event: Update, api: ABCAPI) -> bool:
16
+ async def feed(self, event: Update, api: API) -> bool:
17
17
  pass
18
18
 
19
19
  @abstractmethod
@@ -68,13 +68,22 @@ class Context(dict[str, AnyValue]):
68
68
  def set(self, key: Key, value: AnyValue) -> None:
69
69
  self[key] = value
70
70
 
71
- def get(self, key: Key, default: T | None = None) -> T | AnyValue:
71
+ @typing.overload
72
+ def get(self, key: Key) -> AnyValue | None: ...
73
+
74
+ @typing.overload
75
+ def get(self, key: Key, default: T) -> T | AnyValue: ...
76
+
77
+ @typing.overload
78
+ def get(self, key: Key, default: None = None) -> AnyValue | None: ...
79
+
80
+ def get(self, key: Key, default: T | None = None) -> T | AnyValue | None:
72
81
  return dict.get(self, key, default)
73
82
 
74
83
  def get_or_set(self, key: Key, default: T) -> T:
75
84
  if key not in self:
76
85
  self.set(key, default)
77
- return self.get(key)
86
+ return self.get(key, default)
78
87
 
79
88
  def delete(self, key: Key) -> None:
80
89
  del self[key]