funpaybotengine 0.7.1__tar.gz → 0.10.0rc2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/PKG-INFO +4 -4
  2. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/examples/basic.py +4 -3
  3. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/examples/with_redis_storage.py +4 -3
  4. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/__init__.py +2 -2
  5. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/base.py +2 -20
  6. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/client/bot.py +51 -45
  7. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/client/session/aiohttp_session.py +7 -14
  8. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/client/session/base.py +3 -3
  9. funpaybotengine-0.10.0rc2/funpaybotengine/dispatching/__init__.py +7 -0
  10. funpaybotengine-0.10.0rc2/funpaybotengine/dispatching/dispatcher.py +47 -0
  11. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/dispatching/events/base.py +22 -20
  12. funpaybotengine-0.10.0rc2/funpaybotengine/dispatching/events/builtin_events.py +171 -0
  13. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/dispatching/filters/message_filters.py +2 -2
  14. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/dispatching/filters/order_filters.py +7 -4
  15. funpaybotengine-0.10.0rc2/funpaybotengine/dispatching/handler_manager.py +45 -0
  16. funpaybotengine-0.10.0rc2/funpaybotengine/dispatching/router.py +53 -0
  17. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/exceptions/method_exceptions.py +19 -20
  18. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/loggers.py +1 -2
  19. funpaybotengine-0.10.0rc2/funpaybotengine/methods/__init__.py +36 -0
  20. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/methods/base.py +79 -92
  21. funpaybotengine-0.10.0rc2/funpaybotengine/methods/calc_chips.py +30 -0
  22. funpaybotengine-0.10.0rc2/funpaybotengine/methods/calc_lots.py +29 -0
  23. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/methods/check_banned.py +6 -14
  24. funpaybotengine-0.10.0rc2/funpaybotengine/methods/delete_review.py +36 -0
  25. funpaybotengine-0.10.0rc2/funpaybotengine/methods/get_2fa_status.py +26 -0
  26. funpaybotengine-0.10.0rc2/funpaybotengine/methods/get_chat_history.py +58 -0
  27. funpaybotengine-0.10.0rc2/funpaybotengine/methods/get_chat_page.py +30 -0
  28. funpaybotengine-0.10.0rc2/funpaybotengine/methods/get_main_page.py +35 -0
  29. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/methods/get_my_chips_page.py +6 -11
  30. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/methods/get_my_offers_page.py +6 -11
  31. funpaybotengine-0.10.0rc2/funpaybotengine/methods/get_offer_fields.py +42 -0
  32. funpaybotengine-0.10.0rc2/funpaybotengine/methods/get_offer_page.py +29 -0
  33. funpaybotengine-0.10.0rc2/funpaybotengine/methods/get_order_page.py +27 -0
  34. funpaybotengine-0.10.0rc2/funpaybotengine/methods/get_profile_page.py +29 -0
  35. funpaybotengine-0.10.0rc2/funpaybotengine/methods/get_purchases.py +68 -0
  36. funpaybotengine-0.10.0rc2/funpaybotengine/methods/get_reviews.py +29 -0
  37. funpaybotengine-0.10.0rc2/funpaybotengine/methods/get_sales.py +76 -0
  38. funpaybotengine-0.10.0rc2/funpaybotengine/methods/get_settings_page.py +23 -0
  39. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/methods/get_sras_info_page.py +4 -8
  40. funpaybotengine-0.10.0rc2/funpaybotengine/methods/get_subcategory_page.py +33 -0
  41. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/methods/get_telegram_connect_url.py +4 -8
  42. funpaybotengine-0.10.0rc2/funpaybotengine/methods/get_transactions.py +42 -0
  43. funpaybotengine-0.10.0rc2/funpaybotengine/methods/get_transactions_page.py +20 -0
  44. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/methods/logout.py +6 -12
  45. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/methods/mute_chat.py +6 -18
  46. funpaybotengine-0.10.0rc2/funpaybotengine/methods/raise_offers.py +39 -0
  47. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/methods/refund.py +10 -22
  48. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/methods/review.py +16 -32
  49. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/methods/runner_request.py +29 -41
  50. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/methods/save_offer_fields.py +17 -29
  51. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/methods/set_offers_hidden.py +6 -20
  52. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/methods/update_notice_channel.py +6 -16
  53. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/methods/upload_avatar.py +11 -16
  54. funpaybotengine-0.10.0rc2/funpaybotengine/methods/upload_image.py +40 -0
  55. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/runner/config.py +4 -0
  56. funpaybotengine-0.10.0rc2/funpaybotengine/runner/event_collector.py +360 -0
  57. funpaybotengine-0.10.0rc2/funpaybotengine/runner/runner.py +137 -0
  58. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/base.py +6 -3
  59. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/calc.py +1 -1
  60. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/enums.py +1 -1
  61. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/messages.py +5 -1
  62. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/offers.py +7 -58
  63. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/orders.py +9 -9
  64. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/pages/settings_page.py +0 -4
  65. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/pyproject.toml +14 -3
  66. funpaybotengine-0.10.0rc2/tests/event_resolving_test.py +75 -0
  67. funpaybotengine-0.10.0rc2/tmp.py +31 -0
  68. funpaybotengine-0.7.1/funpaybotengine/dispatching/__init__.py +0 -6
  69. funpaybotengine-0.7.1/funpaybotengine/dispatching/events/builtin_events.py +0 -191
  70. funpaybotengine-0.7.1/funpaybotengine/dispatching/handlers/__init__.py +0 -3
  71. funpaybotengine-0.7.1/funpaybotengine/dispatching/handlers/handler_manager.py +0 -64
  72. funpaybotengine-0.7.1/funpaybotengine/dispatching/routers/__init__.py +0 -4
  73. funpaybotengine-0.7.1/funpaybotengine/dispatching/routers/base.py +0 -135
  74. funpaybotengine-0.7.1/funpaybotengine/dispatching/routers/dispatcher.py +0 -28
  75. funpaybotengine-0.7.1/funpaybotengine/methods/__init__.py +0 -36
  76. funpaybotengine-0.7.1/funpaybotengine/methods/calc_chips.py +0 -41
  77. funpaybotengine-0.7.1/funpaybotengine/methods/calc_lots.py +0 -44
  78. funpaybotengine-0.7.1/funpaybotengine/methods/delete_review.py +0 -52
  79. funpaybotengine-0.7.1/funpaybotengine/methods/get_2fa_status.py +0 -41
  80. funpaybotengine-0.7.1/funpaybotengine/methods/get_chat_history.py +0 -90
  81. funpaybotengine-0.7.1/funpaybotengine/methods/get_chat_page.py +0 -45
  82. funpaybotengine-0.7.1/funpaybotengine/methods/get_main_page.py +0 -42
  83. funpaybotengine-0.7.1/funpaybotengine/methods/get_offer_fields.py +0 -53
  84. funpaybotengine-0.7.1/funpaybotengine/methods/get_offer_page.py +0 -37
  85. funpaybotengine-0.7.1/funpaybotengine/methods/get_order_page.py +0 -35
  86. funpaybotengine-0.7.1/funpaybotengine/methods/get_profile_page.py +0 -37
  87. funpaybotengine-0.7.1/funpaybotengine/methods/get_purchases.py +0 -103
  88. funpaybotengine-0.7.1/funpaybotengine/methods/get_reviews.py +0 -53
  89. funpaybotengine-0.7.1/funpaybotengine/methods/get_sales.py +0 -111
  90. funpaybotengine-0.7.1/funpaybotengine/methods/get_settings_page.py +0 -28
  91. funpaybotengine-0.7.1/funpaybotengine/methods/get_subcategory_page.py +0 -42
  92. funpaybotengine-0.7.1/funpaybotengine/methods/get_transactions.py +0 -57
  93. funpaybotengine-0.7.1/funpaybotengine/methods/get_transactions_page.py +0 -29
  94. funpaybotengine-0.7.1/funpaybotengine/methods/raise_offers.py +0 -50
  95. funpaybotengine-0.7.1/funpaybotengine/methods/upload_image.py +0 -47
  96. funpaybotengine-0.7.1/funpaybotengine/runner/event_collector.py +0 -467
  97. funpaybotengine-0.7.1/funpaybotengine/runner/runner.py +0 -135
  98. funpaybotengine-0.7.1/temp.py +0 -20
  99. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/.github/CODEOWNERS +0 -0
  100. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/.gitignore +0 -0
  101. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/.pre-commit-config.yaml +0 -0
  102. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/LICENSE +0 -0
  103. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/Makefile +0 -0
  104. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/README.md +0 -0
  105. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/client/__init__.py +0 -0
  106. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/client/default_hooks.py +0 -0
  107. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/client/session/__init__.py +0 -0
  108. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/client/session/http_methods.py +0 -0
  109. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/dispatching/events/__init__.py +0 -0
  110. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/dispatching/filters/__init__.py +0 -0
  111. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/dispatching/filters/base.py +0 -0
  112. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/exceptions/__init__.py +0 -0
  113. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/exceptions/action_exceptions.py +0 -0
  114. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/exceptions/base.py +0 -0
  115. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/exceptions/bot_exceptions.py +0 -0
  116. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/exceptions/message_check_errors.py +0 -0
  117. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/exceptions/runner_exceptions.py +0 -0
  118. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/exceptions/session_exceptions.py +0 -0
  119. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/py.typed +0 -0
  120. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/runner/__init__.py +0 -0
  121. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/storage/__init__.py +0 -0
  122. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/storage/base.py +0 -0
  123. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/storage/inmemory.py +0 -0
  124. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/storage/redis.py +0 -0
  125. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/__init__.py +1 -1
  126. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/categories.py +0 -0
  127. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/chat.py +0 -0
  128. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/common.py +0 -0
  129. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/common_page_elements.py +0 -0
  130. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/finances.py +0 -0
  131. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/pages/__init__.py +1 -1
  132. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/pages/base.py +0 -0
  133. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/pages/chat_page.py +0 -0
  134. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/pages/main_page.py +0 -0
  135. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/pages/my_chips_page.py +0 -0
  136. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/pages/my_offers_page.py +0 -0
  137. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/pages/offer_page.py +0 -0
  138. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/pages/order_page.py +0 -0
  139. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/pages/profile_page.py +0 -0
  140. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/pages/sras_info_page.py +0 -0
  141. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/pages/subcategory_page.py +0 -0
  142. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/pages/transactions_page.py +0 -0
  143. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/requests/__init__.py +0 -0
  144. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/requests/runner.py +0 -0
  145. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/reviews.py +0 -0
  146. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/settings.py +0 -0
  147. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/sras.py +0 -0
  148. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/types/updates.py +0 -0
  149. {funpaybotengine-0.7.1 → funpaybotengine-0.10.0rc2}/funpaybotengine/utils.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: funpaybotengine
3
- Version: 0.7.1
3
+ Version: 0.10.0rc2
4
4
  Summary: Framework for creating FunPay bots.
5
5
  Project-URL: Telegram, https://t.me/funpay_hub
6
6
  Project-URL: Issues, https://github.com/funpayhub/funpaybotengine/issues
@@ -20,9 +20,9 @@ Classifier: Programming Language :: Python :: 3.15
20
20
  Requires-Python: >=3.10
21
21
  Requires-Dist: aiohttp-socks>=0.11.0
22
22
  Requires-Dist: aiohttp<3.14,>=3.13.3
23
- Requires-Dist: eventry<0.4.0,>=0.3.6
23
+ Requires-Dist: eventry<0.8.0,>=0.7.1
24
24
  Requires-Dist: funpayparsers<0.11.0,>=0.10.0
25
- Requires-Dist: pydantic<2.13,>=2.12
25
+ Requires-Dist: pydantic<2.14,>=2.13
26
26
  Provides-Extra: dev
27
27
  Requires-Dist: mypy>=1.10.1; extra == 'dev'
28
28
  Requires-Dist: pre-commit>=4.5.1; extra == 'dev'
@@ -4,15 +4,16 @@ import sys
4
4
  import asyncio
5
5
  import logging
6
6
 
7
- from funpaybotengine import Bot, Dispatcher
7
+ from funpaybotengine import Bot, Router, Dispatcher
8
8
  from funpaybotengine.types import Message
9
9
 
10
10
 
11
11
  bot: Bot = Bot(golden_key='token')
12
- dp: Dispatcher = Dispatcher()
12
+ router = Router(name='my_router')
13
+ dp: Dispatcher = Dispatcher(router)
13
14
 
14
15
 
15
- @dp.on_new_message()
16
+ @router.on_new_message()
16
17
  async def echo(message: Message) -> None:
17
18
  await message.reply(text='echo')
18
19
 
@@ -44,7 +44,7 @@ import logging
44
44
  from contextlib import suppress
45
45
 
46
46
  from redis.asyncio import Redis
47
- from funpaybotengine import Bot, Dispatcher
47
+ from funpaybotengine import Bot, Router, Dispatcher
48
48
  from funpaybotengine.types import Message
49
49
  from funpaybotengine.storage.redis import RedisStorage
50
50
 
@@ -58,10 +58,11 @@ bot: Bot = Bot(
58
58
  golden_key='token',
59
59
  storage=storage,
60
60
  )
61
- dp: Dispatcher = Dispatcher()
61
+ router = Router(name='my_router')
62
+ dp: Dispatcher = Dispatcher(router)
62
63
 
63
64
 
64
- @dp.on_new_message()
65
+ @router.on_new_message()
65
66
  async def echo(message: Message) -> None:
66
67
  await message.reply(text='echo')
67
68
 
@@ -4,8 +4,8 @@ import funpaybotengine.dispatching.events as events
4
4
  import funpaybotengine.dispatching.filters as filters
5
5
  from funpaybotengine.client.bot import Bot
6
6
  from funpaybotengine.client.session import BaseSession, AioHttpSession
7
- from funpaybotengine.dispatching.routers.base import Router
8
- from funpaybotengine.dispatching.routers.dispatcher import Dispatcher
7
+ from funpaybotengine.dispatching.router import Router
8
+ from funpaybotengine.dispatching.dispatcher import Dispatcher
9
9
 
10
10
 
11
11
  __all__ = [
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
 
4
- __all__ = ('BindableObject', 'check_bound')
4
+ __all__ = ['BindableObject']
5
5
 
6
6
 
7
7
  from typing import TYPE_CHECKING, Any, TypeVar
@@ -41,24 +41,6 @@ class BindableObject(BaseModel):
41
41
  return self._bot
42
42
 
43
43
  def get_bound_bot(self) -> Bot:
44
- if not self.bot:
44
+ if self.bot is None:
45
45
  raise BotNotBoundError(self)
46
46
  return self.bot
47
-
48
-
49
- def check_bound(func: F) -> F:
50
- """
51
- Decorator for instance methods to ensure the object is bound to any Bot instance.
52
- """
53
-
54
- def wrapper(*args: Any, **kwargs: Any) -> Any:
55
- if not args:
56
- raise RuntimeError('Can be used only with instance methods.')
57
-
58
- if not isinstance(args[0], BindableObject):
59
- raise ValueError(f'{args[0].__class__.__name__} is not a bindable object.')
60
- if args[0].bot is None:
61
- raise RuntimeError(f'{args[0]} is not bound to any `Bot` instance.')
62
- return func(*args, **kwargs)
63
-
64
- return wrapper # type: ignore
@@ -25,9 +25,9 @@ from funpaybotengine.types import (
25
25
  TransactionFilter,
26
26
  OrderPreviewsBatch,
27
27
  PrivateChatPreview,
28
+ RaiseOffersResponse,
28
29
  TransactionPreviewsBatch,
29
30
  CurrentlyViewingOfferInfo,
30
- RaiseOffersResponse
31
31
  )
32
32
  from funpaybotengine.utils import (
33
33
  random_runner_tag,
@@ -60,13 +60,12 @@ from funpaybotengine.methods import (
60
60
  GetMyChipsPage,
61
61
  GetOfferFields,
62
62
  GetProfilePage,
63
- GetSettingPage,
64
63
  GetMyOffersPage,
64
+ GetSettingsPage,
65
65
  GetSrasInfoPage,
66
66
  GetTransactions,
67
67
  SaveOfferFields,
68
68
  SetOffersHidden,
69
- MethodReturnType,
70
69
  GetSubcategoryPage,
71
70
  GetTransactionsPage,
72
71
  UpdateNoticeChannel,
@@ -114,11 +113,11 @@ from funpaybotengine.client.session.aiohttp_session import AioHttpSession
114
113
 
115
114
  if TYPE_CHECKING:
116
115
  from funpaybotengine.client.session.base import BaseSession
117
- from funpaybotengine.dispatching.routers.dispatcher import Dispatcher
116
+ from funpaybotengine.dispatching.dispatcher import Dispatcher
118
117
 
119
118
 
120
119
  F = TypeVar('F', bound=Callable[..., Any])
121
- R = TypeVar('R', bound=Any)
120
+ R = TypeVar('R')
122
121
 
123
122
 
124
123
  class LocaleMismatchHookProto(Protocol):
@@ -157,16 +156,15 @@ class Bot:
157
156
 
158
157
  self._storage = storage or InMemoryStorage()
159
158
  self._runner = Runner(self)
160
- self._session = session or AioHttpSession(proxy=proxy, default_headers=default_headers)
159
+ self._session = session or AioHttpSession(proxy=proxy, headers=default_headers)
161
160
  self._session_updated_at = 0
162
161
 
163
162
  self._on_locale_mismatch_hook: LocaleMismatchHookProto = force_locale_hook
164
163
  self.update_categories: bool = update_categories
165
164
 
166
165
  self._messages_lock = Lock()
167
- self._listening_lock = Lock()
168
- self._stopping_lock = Lock()
169
166
 
167
+ self._listening_lock = Lock()
170
168
  self._stop_event = Event()
171
169
  self._stopped_event = Event()
172
170
  self._stopped_event.set()
@@ -412,7 +410,7 @@ class Bot:
412
410
  image = (
413
411
  image
414
412
  if isinstance(image, int)
415
- else (await UploadImage(image).execute(self)).response_obj
413
+ else (await UploadImage(file=image).execute(self)).response_obj
416
414
  )
417
415
  elif text is not None:
418
416
  if enforce_whitespaces:
@@ -602,7 +600,8 @@ class Bot:
602
600
 
603
601
  :param args: Tuple of (chat_id, after_message_id)
604
602
 
605
- :returns: A dictionary [chat_id, list] or a list of up to 100 ``Message`` objects, sorted from oldest to newest.
603
+ :returns: A dictionary [chat_id, list] or a list of up to 100 ``Message`` objects,
604
+ sorted from oldest to newest.
606
605
  """
607
606
  if not args and chat_id is None:
608
607
  raise ValueError('Either `chat_id` or `args` must be provided.')
@@ -795,7 +794,7 @@ class Bot:
795
794
  ) -> TransactionPreviewsBatch:
796
795
  return (
797
796
  await GetTransactions(
798
- filter=filter,
797
+ filter=TransactionFilter(filter),
799
798
  from_transaction_id=from_transaction_id,
800
799
  ).execute(self)
801
800
  ).response_obj
@@ -852,7 +851,7 @@ class Bot:
852
851
  return (await GetSrasInfoPage().execute(self)).response_obj
853
852
 
854
853
  async def get_settings_page(self) -> SettingsPage:
855
- return (await GetSettingPage().execute(self)).response_obj
854
+ return (await GetSettingsPage().execute(self)).response_obj
856
855
 
857
856
  async def get_transactions_page(self) -> TransactionsPage:
858
857
  return (await GetTransactionsPage().execute(self)).response_obj
@@ -868,11 +867,11 @@ class Bot:
868
867
 
869
868
  async def make_request(
870
869
  self,
871
- method: FunPayMethod[MethodReturnType],
870
+ method: FunPayMethod[R],
872
871
  skip_update: bool = False,
873
872
  skip_locale_check: bool = False,
874
873
  skip_session_cookies: bool = False,
875
- ) -> Response[MethodReturnType]:
874
+ ) -> Response[R]:
876
875
  if not method.allow_anonymous and self.anonymous:
877
876
  raise RuntimeError(
878
877
  f"Method '{method.__class__.__name__}' cannot be executed anonymously.",
@@ -947,20 +946,16 @@ class Bot:
947
946
  *,
948
947
  config: RunnerConfig | None = None,
949
948
  session_storage: Storage | None = None,
950
- workflow_injection: dict[str, Any] | None = None,
949
+ context_injection: dict[str, Any] | None = None,
951
950
  ) -> None:
952
- workflow_injection = workflow_injection if workflow_injection is not None else {}
951
+ context_injection = context_injection if context_injection is not None else {}
953
952
  try:
954
953
  async with self.session:
955
954
  listener = self._runner.listen(config=config, session_storage=session_storage)
956
- async for event, stack in listener:
957
- await dp.event_entry(
955
+ async for event, pack in listener:
956
+ await dp.propagate_event(
958
957
  event,
959
- event_context_injection={
960
- **workflow_injection,
961
- 'events_stack': stack,
962
- 'bot': self,
963
- },
958
+ additional_context={**context_injection, 'events_pack': pack, 'bot': self},
964
959
  )
965
960
  except KeyboardInterrupt:
966
961
  return
@@ -975,36 +970,47 @@ class Bot:
975
970
  workflow_injection: dict[str, Any] | None = None,
976
971
  ) -> None:
977
972
  if self._listening_lock.locked():
978
- raise RuntimeError('Already listening')
973
+ raise RuntimeError('Already listening.')
979
974
 
980
975
  async with self._listening_lock:
981
976
  self._stop_event.clear()
982
977
  self._stopped_event.clear()
983
978
 
984
- tasks = [
985
- asyncio.create_task(
986
- self._listen_events(
987
- dp,
988
- config=config,
989
- session_storage=session_storage,
990
- workflow_injection=workflow_injection,
991
- ),
992
- ),
993
- asyncio.create_task(self._stop_event.wait()),
994
- ]
979
+ listener_task = asyncio.create_task(
980
+ self._listen_events(
981
+ dp,
982
+ config=config,
983
+ session_storage=session_storage,
984
+ context_injection=workflow_injection,
985
+ )
986
+ )
987
+ stop_task = asyncio.create_task(self._stop_event.wait())
988
+
989
+ try:
990
+ done, pending = await asyncio.wait(
991
+ [listener_task, stop_task], return_when=asyncio.FIRST_COMPLETED
992
+ )
993
+
994
+ # Если таска прослушивания событий упала - райзим исключение наверх.
995
+ if listener_task in done:
996
+ await listener_task
997
+ return
995
998
 
996
- _, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
997
- for task in pending:
999
+ listener_task.cancel()
998
1000
  with suppress(asyncio.CancelledError):
999
- task.cancel()
1000
- self._stopped_event.set()
1001
+ await listener_task
1002
+
1003
+ finally:
1004
+ for task in (listener_task, stop_task):
1005
+ if not task.done():
1006
+ task.cancel()
1007
+
1008
+ await asyncio.gather(listener_task, stop_task, return_exceptions=True)
1009
+ self._stopped_event.set()
1001
1010
 
1002
1011
  async def stop_listening(self) -> None:
1003
1012
  if self._stopped_event.is_set():
1004
- raise RuntimeError('Listening is already stopped.')
1005
- if self._stopping_lock.locked():
1006
- raise RuntimeError('Listening stopping already in progress.')
1013
+ return
1007
1014
 
1008
- async with self._stopping_lock:
1009
- self._stop_event.set()
1010
- await self._stopped_event.wait()
1015
+ self._stop_event.set()
1016
+ await self._stopped_event.wait()
@@ -25,21 +25,17 @@ from funpaybotengine.exceptions.session_exceptions import BannedError
25
25
 
26
26
  if TYPE_CHECKING:
27
27
  from funpaybotengine.client.bot import Bot
28
- from funpaybotengine.methods.base import FunPayMethod, MethodReturnType
28
+ from funpaybotengine.methods.base import MethodR, FunPayMethod
29
29
 
30
30
 
31
31
  class AioHttpSession(BaseSession):
32
- def __init__(
33
- self,
34
- proxy: str | None = None,
35
- default_headers: dict[str, str] | None = None,
36
- ):
32
+ def __init__(self, proxy: str | None = None, headers: dict[str, str] | None = None) -> None:
37
33
  super().__init__()
38
34
 
39
35
  self._proxy = proxy
40
36
  self._default_headers = (
41
- default_headers
42
- if default_headers is not None
37
+ headers
38
+ if headers is not None
43
39
  else {
44
40
  USER_AGENT: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:140.0) '
45
41
  'Gecko/20100101 Firefox/140.0',
@@ -74,10 +70,7 @@ class AioHttpSession(BaseSession):
74
70
  await asyncio.sleep(0.25)
75
71
 
76
72
  def prepare_cookies(
77
- self,
78
- session: ClientSession,
79
- bot: Bot,
80
- skip_session_cookies: bool = False,
73
+ self, session: ClientSession, bot: Bot, skip_session_cookies: bool = False
81
74
  ) -> None:
82
75
  session.cookie_jar.update_cookies({'cookie_prefs': '1'}) # no 3rd-party cookies
83
76
 
@@ -95,11 +88,11 @@ class AioHttpSession(BaseSession):
95
88
 
96
89
  async def make_request(
97
90
  self,
98
- method: FunPayMethod[MethodReturnType],
91
+ method: FunPayMethod[MethodR],
99
92
  bot: Bot,
100
93
  timeout: float | None = None,
101
94
  skip_session_cookies: bool = False,
102
- ) -> Response[MethodReturnType]:
95
+ ) -> Response[MethodR]:
103
96
  session = await self.session()
104
97
 
105
98
  self.prepare_cookies(session, bot, skip_session_cookies=skip_session_cookies)
@@ -22,7 +22,7 @@ from funpaybotengine.exceptions import (
22
22
 
23
23
  if TYPE_CHECKING:
24
24
  from funpaybotengine.client.bot import Bot
25
- from funpaybotengine.methods.base import FunPayMethod, MethodReturnType
25
+ from funpaybotengine.methods.base import MethodR, FunPayMethod
26
26
 
27
27
 
28
28
  _exceptions: dict[int, Any] = {
@@ -82,11 +82,11 @@ class BaseSession(ABC):
82
82
  @abstractmethod
83
83
  async def make_request(
84
84
  self,
85
- method: FunPayMethod[MethodReturnType],
85
+ method: FunPayMethod[MethodR],
86
86
  bot: Bot,
87
87
  timeout: float | None = None,
88
88
  skip_session_cookies: bool = False,
89
- ) -> Response[MethodReturnType]: ...
89
+ ) -> Response[MethodR]: ...
90
90
 
91
91
  def check_status_code(self, method: FunPayMethod[Any], status_code: int | HTTPStatus) -> None:
92
92
  """
@@ -0,0 +1,7 @@
1
+ from __future__ import annotations
2
+
3
+ from .events import *
4
+ from .router import Router as Router
5
+ from .filters import *
6
+ from .dispatcher import Dispatcher as Dispatcher
7
+ from .handler_manager import HandlerManager as HandlerManager
@@ -0,0 +1,47 @@
1
+ from __future__ import annotations
2
+
3
+
4
+ __all__ = ['Dispatcher']
5
+
6
+
7
+ from typing import Any
8
+
9
+ from eventry.asyncio import (
10
+ Dispatcher as BaseDispatcher,
11
+ DispatchingConfig,
12
+ DispatchingContext,
13
+ default_error_callback,
14
+ )
15
+
16
+ from funpaybotengine.loggers import dispatcher_logger as logger
17
+ from funpaybotengine.dispatching import Router, ExceptionEvent
18
+
19
+
20
+ async def on_error_callback(ctx: DispatchingContext, exc: Exception) -> None:
21
+ if isinstance(ctx.event, ExceptionEvent):
22
+ await default_error_callback(ctx, exc)
23
+ return
24
+
25
+ exc_event = ExceptionEvent(object=exc, context=ctx)
26
+
27
+ try:
28
+ await ctx.dispatcher.propagate_event(exc_event)
29
+ except Exception as e:
30
+ logger.error('An error occurred while propagating error event.', exc_info=e)
31
+
32
+
33
+ async def on_handler(ctx: DispatchingContext, result: Any) -> None: ...
34
+
35
+
36
+ # todo: do things depends on a type
37
+
38
+
39
+ class Dispatcher(BaseDispatcher):
40
+ def __init__(
41
+ self, router: Router | None = None, context: dict[str, Any] | None = None
42
+ ) -> None:
43
+ super().__init__(
44
+ config=DispatchingConfig(on_error=on_error_callback, on_handler=on_handler),
45
+ router=router,
46
+ event_context=context,
47
+ )
@@ -14,7 +14,10 @@ from typing import Any, Generic, TypeVar
14
14
  from types import MappingProxyType
15
15
 
16
16
  from pydantic import Field, PrivateAttr
17
- from eventry.asyncio.event import Event as EventryEvent
17
+ from eventry.asyncio import (
18
+ Event as EventryEvent,
19
+ DispatchingContext,
20
+ )
18
21
 
19
22
  from funpaybotengine.base import BindableObject
20
23
 
@@ -32,8 +35,7 @@ class Event(EventryEvent, BindableObject, Generic[EventObject], event_name='even
32
35
  _data: dict[Any, Any] = PrivateAttr(default_factory=dict)
33
36
  _flags: set[Any] = PrivateAttr(default_factory=set)
34
37
 
35
- @property
36
- def event_context_injection(self) -> dict[str, Any]:
38
+ def context_injection(self) -> dict[str, Any]:
37
39
  return {'object': self.object}
38
40
 
39
41
  def __hash__(self) -> int:
@@ -74,36 +76,36 @@ class Event(EventryEvent, BindableObject, Generic[EventObject], event_name='even
74
76
 
75
77
 
76
78
  class RunnerEvent(Event[EventObject], event_name='runner'):
77
- tag: str | None = Field(frozen=True)
79
+ tag: str | None
78
80
 
79
- @property
80
- def event_context_injection(self) -> dict[str, Any]:
81
- injection = super().event_context_injection
82
- injection['tag'] = self.tag
83
- return injection
81
+ def context_injection(self) -> dict[str, Any]:
82
+ return super().context_injection() | {'tag': self.tag}
84
83
 
85
84
 
86
85
  class BotEngineEvent(Event[EventObject], event_name='funpaybotengine'): ...
87
86
 
88
87
 
89
88
  class ExceptionEvent(BotEngineEvent[Exception], event_name='error'):
90
- event: Event[Any] = Field(frozen=True)
89
+ context: DispatchingContext
91
90
 
92
91
  @property
93
- def event_context_injection(self) -> dict[str, Any]:
94
- injection = super().event_context_injection
95
- injection.update({'on_event': self.event, 'exception': self.object})
96
- return injection
92
+ def exception(self) -> Exception:
93
+ return self.object
97
94
 
95
+ def context_injection(self) -> dict[str, Any]:
96
+ return super().context_injection() | {
97
+ 'exception': self.object,
98
+ 'event_context': self.context,
99
+ }
98
100
 
99
- class BotUnauthenticatedEvent(BotEngineEvent[float], event_name='unauthorized'):
100
- delay: float
101
101
 
102
+ class BotUnauthenticatedEvent(BotEngineEvent[float], event_name='unauthorized'):
102
103
  @property
103
- def event_context_injection(self) -> dict[str, Any]:
104
- injection = super().event_context_injection
105
- injection.update({'delay': self.delay})
106
- return injection
104
+ def delay(self) -> float:
105
+ return self.object
106
+
107
+ def context_injection(self) -> dict[str, Any]:
108
+ return super().context_injection() | {'delay': self.delay}
107
109
 
108
110
 
109
111
  class BotAuthenticatedEvent(BotEngineEvent[None], event_name='authorized'): ...