maxapi 0.1__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 (117) hide show
  1. maxapi-0.1/PKG-INFO +49 -0
  2. maxapi-0.1/README.md +28 -0
  3. maxapi-0.1/maxapi/__init__.py +10 -0
  4. maxapi-0.1/maxapi/bot.py +338 -0
  5. maxapi-0.1/maxapi/connection/__init__.py +0 -0
  6. maxapi-0.1/maxapi/connection/base.py +56 -0
  7. maxapi-0.1/maxapi/context/__init__.py +36 -0
  8. maxapi-0.1/maxapi/context/state_machine.py +16 -0
  9. maxapi-0.1/maxapi/dispatcher.py +177 -0
  10. maxapi-0.1/maxapi/enums/__init__.py +0 -0
  11. maxapi-0.1/maxapi/enums/api_path.py +13 -0
  12. maxapi-0.1/maxapi/enums/attachment.py +11 -0
  13. maxapi-0.1/maxapi/enums/button_type.py +9 -0
  14. maxapi-0.1/maxapi/enums/chat_permission.py +10 -0
  15. maxapi-0.1/maxapi/enums/chat_type.py +6 -0
  16. maxapi-0.1/maxapi/enums/http_method.py +9 -0
  17. maxapi-0.1/maxapi/enums/intent.py +6 -0
  18. maxapi-0.1/maxapi/enums/message_link_type.py +6 -0
  19. maxapi-0.1/maxapi/enums/parse_mode.py +5 -0
  20. maxapi-0.1/maxapi/enums/sender_action.py +9 -0
  21. maxapi-0.1/maxapi/enums/text_style.py +13 -0
  22. maxapi-0.1/maxapi/enums/update.py +16 -0
  23. maxapi-0.1/maxapi/filters/__init__.py +53 -0
  24. maxapi-0.1/maxapi/filters/handler.py +31 -0
  25. maxapi-0.1/maxapi/loggers.py +4 -0
  26. maxapi-0.1/maxapi/methods/__init__.py +0 -0
  27. maxapi-0.1/maxapi/methods/add_admin_chat.py +46 -0
  28. maxapi-0.1/maxapi/methods/add_members_chat.py +42 -0
  29. maxapi-0.1/maxapi/methods/change_info.py +46 -0
  30. maxapi-0.1/maxapi/methods/delete_bot_from_chat.py +30 -0
  31. maxapi-0.1/maxapi/methods/delete_chat.py +29 -0
  32. maxapi-0.1/maxapi/methods/delete_message.py +33 -0
  33. maxapi-0.1/maxapi/methods/delete_pin_message.py +29 -0
  34. maxapi-0.1/maxapi/methods/edit_chat.py +68 -0
  35. maxapi-0.1/maxapi/methods/edit_message.py +55 -0
  36. maxapi-0.1/maxapi/methods/get_chat_by_id.py +36 -0
  37. maxapi-0.1/maxapi/methods/get_chat_by_link.py +41 -0
  38. maxapi-0.1/maxapi/methods/get_chats.py +43 -0
  39. maxapi-0.1/maxapi/methods/get_list_admin_chat.py +34 -0
  40. maxapi-0.1/maxapi/methods/get_me.py +29 -0
  41. maxapi-0.1/maxapi/methods/get_me_from_chat.py +34 -0
  42. maxapi-0.1/maxapi/methods/get_members_chat.py +47 -0
  43. maxapi-0.1/maxapi/methods/get_messages.py +60 -0
  44. maxapi-0.1/maxapi/methods/get_pinned_message.py +32 -0
  45. maxapi-0.1/maxapi/methods/get_updates.py +43 -0
  46. maxapi-0.1/maxapi/methods/get_video.py +34 -0
  47. maxapi-0.1/maxapi/methods/pin_message.py +42 -0
  48. maxapi-0.1/maxapi/methods/remove_admin.py +36 -0
  49. maxapi-0.1/maxapi/methods/remove_member_chat.py +42 -0
  50. maxapi-0.1/maxapi/methods/send_action.py +43 -0
  51. maxapi-0.1/maxapi/methods/send_callback.py +53 -0
  52. maxapi-0.1/maxapi/methods/send_message.py +65 -0
  53. maxapi-0.1/maxapi/methods/types/__init__.py +0 -0
  54. maxapi-0.1/maxapi/methods/types/added_admin_chat.py +9 -0
  55. maxapi-0.1/maxapi/methods/types/added_members_chat.py +9 -0
  56. maxapi-0.1/maxapi/methods/types/deleted_bot_from_chat.py +7 -0
  57. maxapi-0.1/maxapi/methods/types/deleted_chat.py +7 -0
  58. maxapi-0.1/maxapi/methods/types/deleted_message.py +7 -0
  59. maxapi-0.1/maxapi/methods/types/deleted_pin_message.py +7 -0
  60. maxapi-0.1/maxapi/methods/types/edited_message.py +7 -0
  61. maxapi-0.1/maxapi/methods/types/getted_list_admin_chat.py +9 -0
  62. maxapi-0.1/maxapi/methods/types/getted_members_chat.py +9 -0
  63. maxapi-0.1/maxapi/methods/types/getted_pineed_message.py +8 -0
  64. maxapi-0.1/maxapi/methods/types/getted_updates.py +75 -0
  65. maxapi-0.1/maxapi/methods/types/pinned_message.py +7 -0
  66. maxapi-0.1/maxapi/methods/types/removed_admin.py +7 -0
  67. maxapi-0.1/maxapi/methods/types/removed_member_chat.py +9 -0
  68. maxapi-0.1/maxapi/methods/types/sended_action.py +7 -0
  69. maxapi-0.1/maxapi/methods/types/sended_callback.py +14 -0
  70. maxapi-0.1/maxapi/methods/types/sended_message.py +8 -0
  71. maxapi-0.1/maxapi/types/__init__.py +49 -0
  72. maxapi-0.1/maxapi/types/attachments/__init__.py +0 -0
  73. maxapi-0.1/maxapi/types/attachments/attachment.py +47 -0
  74. maxapi-0.1/maxapi/types/attachments/audio.py +8 -0
  75. maxapi-0.1/maxapi/types/attachments/buttons/__init__.py +15 -0
  76. maxapi-0.1/maxapi/types/attachments/buttons/attachment_button.py +9 -0
  77. maxapi-0.1/maxapi/types/attachments/buttons/button.py +12 -0
  78. maxapi-0.1/maxapi/types/attachments/buttons/callback_button.py +12 -0
  79. maxapi-0.1/maxapi/types/attachments/buttons/chat_button.py +11 -0
  80. maxapi-0.1/maxapi/types/attachments/buttons/link_button.py +7 -0
  81. maxapi-0.1/maxapi/types/attachments/buttons/request_contact.py +5 -0
  82. maxapi-0.1/maxapi/types/attachments/buttons/request_geo_location_button.py +5 -0
  83. maxapi-0.1/maxapi/types/attachments/contact.py +7 -0
  84. maxapi-0.1/maxapi/types/attachments/file.py +9 -0
  85. maxapi-0.1/maxapi/types/attachments/image.py +14 -0
  86. maxapi-0.1/maxapi/types/attachments/location.py +9 -0
  87. maxapi-0.1/maxapi/types/attachments/share.py +10 -0
  88. maxapi-0.1/maxapi/types/attachments/sticker.py +9 -0
  89. maxapi-0.1/maxapi/types/attachments/video.py +35 -0
  90. maxapi-0.1/maxapi/types/callback.py +13 -0
  91. maxapi-0.1/maxapi/types/chats.py +66 -0
  92. maxapi-0.1/maxapi/types/command.py +9 -0
  93. maxapi-0.1/maxapi/types/errors.py +6 -0
  94. maxapi-0.1/maxapi/types/message.py +154 -0
  95. maxapi-0.1/maxapi/types/updates/__init__.py +27 -0
  96. maxapi-0.1/maxapi/types/updates/bot_added.py +21 -0
  97. maxapi-0.1/maxapi/types/updates/bot_removed.py +21 -0
  98. maxapi-0.1/maxapi/types/updates/bot_started.py +23 -0
  99. maxapi-0.1/maxapi/types/updates/chat_title_changed.py +22 -0
  100. maxapi-0.1/maxapi/types/updates/message_callback.py +76 -0
  101. maxapi-0.1/maxapi/types/updates/message_chat_created.py +24 -0
  102. maxapi-0.1/maxapi/types/updates/message_created.py +22 -0
  103. maxapi-0.1/maxapi/types/updates/message_edited.py +19 -0
  104. maxapi-0.1/maxapi/types/updates/message_removed.py +21 -0
  105. maxapi-0.1/maxapi/types/updates/update.py +11 -0
  106. maxapi-0.1/maxapi/types/updates/user_added.py +23 -0
  107. maxapi-0.1/maxapi/types/updates/user_removed.py +22 -0
  108. maxapi-0.1/maxapi/types/users.py +33 -0
  109. maxapi-0.1/maxapi/utils/__init__.py +0 -0
  110. maxapi-0.1/maxapi/utils/inline_keyboard.py +18 -0
  111. maxapi-0.1/maxapi.egg-info/PKG-INFO +49 -0
  112. maxapi-0.1/maxapi.egg-info/SOURCES.txt +115 -0
  113. maxapi-0.1/maxapi.egg-info/dependency_links.txt +1 -0
  114. maxapi-0.1/maxapi.egg-info/requires.txt +5 -0
  115. maxapi-0.1/maxapi.egg-info/top_level.txt +1 -0
  116. maxapi-0.1/setup.cfg +4 -0
  117. maxapi-0.1/setup.py +20 -0
maxapi-0.1/PKG-INFO ADDED
@@ -0,0 +1,49 @@
1
+ Metadata-Version: 2.4
2
+ Name: maxapi
3
+ Version: 0.1
4
+ Summary: Библиотека для взаимодействия с API мессенджера MAX
5
+ Home-page: https://github.com/love-apples/maxapi/tree/main
6
+ Author: Денис
7
+ Requires-Python: >=3.10
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: aiohttp==3.11.16
10
+ Requires-Dist: fastapi==0.115.13
11
+ Requires-Dist: magic_filter==1.0.12
12
+ Requires-Dist: pydantic==2.11.7
13
+ Requires-Dist: uvicorn==0.34.3
14
+ Dynamic: author
15
+ Dynamic: description
16
+ Dynamic: description-content-type
17
+ Dynamic: home-page
18
+ Dynamic: requires-dist
19
+ Dynamic: requires-python
20
+ Dynamic: summary
21
+
22
+ # maxapi
23
+
24
+ #### Библиотека (like aiogram) для взаимодействия с мессенджером MAX
25
+
26
+ Информация на данный момент:
27
+ * Проект тестируется и активно дорабатывается
28
+ * На данный момент имеется:
29
+ Роутеры
30
+ Билдер инлайн клавиатур
31
+ Этакая машина состояний и контекст к нему
32
+ Поллинг и вебхук методы запуска
33
+ Логгирование
34
+
35
+
36
+ ```bash
37
+ Пример бота описан в example.py
38
+ Перед запуском примера установите зависимости:
39
+
40
+ pip install -r requirements.txt
41
+
42
+ Запуск бота:
43
+
44
+ python example.py
45
+ ```
46
+
47
+
48
+ ### Контакты
49
+ [Группа MAX](https://max.ru/join/IPAok63C3vFqbWTFdutMUtjmrAkGqO56YeAN7iyDfc8)
maxapi-0.1/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # maxapi
2
+
3
+ #### Библиотека (like aiogram) для взаимодействия с мессенджером MAX
4
+
5
+ Информация на данный момент:
6
+ * Проект тестируется и активно дорабатывается
7
+ * На данный момент имеется:
8
+ Роутеры
9
+ Билдер инлайн клавиатур
10
+ Этакая машина состояний и контекст к нему
11
+ Поллинг и вебхук методы запуска
12
+ Логгирование
13
+
14
+
15
+ ```bash
16
+ Пример бота описан в example.py
17
+ Перед запуском примера установите зависимости:
18
+
19
+ pip install -r requirements.txt
20
+
21
+ Запуск бота:
22
+
23
+ python example.py
24
+ ```
25
+
26
+
27
+ ### Контакты
28
+ [Группа MAX](https://max.ru/join/IPAok63C3vFqbWTFdutMUtjmrAkGqO56YeAN7iyDfc8)
@@ -0,0 +1,10 @@
1
+ from .bot import Bot
2
+ from .dispatcher import Dispatcher, Router
3
+ from .filters import F
4
+
5
+ __all__ = [
6
+ Bot,
7
+ Dispatcher,
8
+ F,
9
+ Router
10
+ ]
@@ -0,0 +1,338 @@
1
+ from datetime import datetime
2
+ from typing import Any, Dict, List, TYPE_CHECKING
3
+
4
+ from .methods.get_updates import GetUpdates
5
+ from .methods.remove_member_chat import RemoveMemberChat
6
+ from .methods.add_admin_chat import AddAdminChat
7
+ from .methods.add_members_chat import AddMembersChat
8
+ from .methods.get_members_chat import GetMembersChat
9
+ from .methods.remove_admin import RemoveAdmin
10
+ from .methods.get_list_admin_chat import GetListAdminChat
11
+ from .methods.delete_bot_from_chat import DeleteMeFromMessage
12
+ from .methods.get_me_from_chat import GetMeFromChat
13
+ from .methods.delete_pin_message import DeletePinMessage
14
+ from .methods.get_pinned_message import GetPinnedMessage
15
+ from .methods.pin_message import PinMessage
16
+ from .methods.delete_chat import DeleteChat
17
+ from .methods.send_action import SendAction
18
+ from .methods.edit_chat import EditChat
19
+ from .methods.get_chat_by_id import GetChatById
20
+ from .methods.get_chat_by_link import GetChatByLink
21
+ from .methods.send_callback import SendCallback
22
+ from .methods.get_video import GetVideo
23
+ from .methods.delete_message import DeleteMessage
24
+ from .methods.edit_message import EditMessage
25
+ from .methods.change_info import ChangeInfo
26
+ from .methods.get_me import GetMe
27
+ from .methods.get_messages import GetMessages
28
+ from .methods.get_chats import GetChats
29
+ from .methods.send_message import SendMessage
30
+
31
+ from .enums.parse_mode import ParseMode
32
+ from .enums.sender_action import SenderAction
33
+
34
+ from .types.attachments.attachment import Attachment
35
+ from .types.attachments.image import PhotoAttachmentRequestPayload
36
+ from .types.message import NewMessageLink
37
+ from .types.users import BotCommand, ChatAdmin
38
+
39
+ from .connection.base import BaseConnection
40
+
41
+ if TYPE_CHECKING:
42
+ from .types.message import Message
43
+
44
+
45
+ class Bot(BaseConnection):
46
+
47
+ def __init__(self, token: str):
48
+ super().__init__()
49
+ self.bot = self
50
+
51
+ self.__token = token
52
+ self.params = {
53
+ 'access_token': self.__token
54
+ }
55
+ self.marker_updates = None
56
+
57
+ async def send_message(
58
+ self,
59
+ chat_id: int = None,
60
+ user_id: int = None,
61
+ disable_link_preview: bool = False,
62
+ text: str = None,
63
+ attachments: List[Attachment] = None,
64
+ link: NewMessageLink = None,
65
+ notify: bool = True,
66
+ parse_mode: ParseMode = None
67
+ ):
68
+ return await SendMessage(
69
+ bot=self,
70
+ chat_id=chat_id,
71
+ user_id=user_id,
72
+ disable_link_preview=disable_link_preview,
73
+ text=text,
74
+ attachments=attachments,
75
+ link=link,
76
+ notify=notify,
77
+ parse_mode=parse_mode
78
+ ).request()
79
+
80
+ async def send_action(
81
+ self,
82
+ chat_id: int = None,
83
+ action: SenderAction = SenderAction.TYPING_ON
84
+ ):
85
+ return await SendAction(
86
+ bot=self,
87
+ chat_id=chat_id,
88
+ action=action
89
+ ).request()
90
+
91
+ async def edit_message(
92
+ self,
93
+ message_id: str,
94
+ text: str = None,
95
+ attachments: List[Attachment] = None,
96
+ link: NewMessageLink = None,
97
+ notify: bool = True,
98
+ parse_mode: ParseMode = None
99
+ ):
100
+ return await EditMessage(
101
+ bot=self,
102
+ message_id=message_id,
103
+ text=text,
104
+ attachments=attachments,
105
+ link=link,
106
+ notify=notify,
107
+ parse_mode=parse_mode
108
+ ).request()
109
+
110
+ async def delete_message(
111
+ self,
112
+ message_id: str
113
+ ):
114
+ return await DeleteMessage(
115
+ bot=self,
116
+ message_id=message_id,
117
+ ).request()
118
+
119
+ async def delete_chat(
120
+ self,
121
+ chat_id: int
122
+ ):
123
+ return await DeleteChat(
124
+ bot=self,
125
+ chat_id=chat_id,
126
+ ).request()
127
+
128
+ async def get_messages(
129
+ self,
130
+ chat_id: int = None,
131
+ message_ids: List[str] = None,
132
+ from_time: datetime | int = None,
133
+ to_time: datetime | int = None,
134
+ count: int = 50,
135
+ ):
136
+ return await GetMessages(
137
+ bot=self,
138
+ chat_id=chat_id,
139
+ message_ids=message_ids,
140
+ from_time=from_time,
141
+ to_time=to_time,
142
+ count=count
143
+ ).request()
144
+
145
+ async def get_message(self, message_id: str):
146
+ return await self.get_messages(message_ids=[message_id])
147
+
148
+ async def get_me(self):
149
+ return await GetMe(self).request()
150
+
151
+ async def get_pin_message(self, chat_id: int):
152
+ return await GetPinnedMessage(bot=self, chat_id=chat_id).request()
153
+
154
+ async def change_info(
155
+ self,
156
+ name: str = None,
157
+ description: str = None,
158
+ commands: List[BotCommand] = None,
159
+ photo: Dict[str, Any] = None
160
+ ):
161
+
162
+ return await ChangeInfo(
163
+ bot=self,
164
+ name=name,
165
+ description=description,
166
+ commands=commands,
167
+ photo=photo
168
+ ).request()
169
+
170
+ async def get_chats(
171
+ self,
172
+ count: int = 50,
173
+ marker: int = None
174
+ ):
175
+ return await GetChats(
176
+ bot=self,
177
+ count=count,
178
+ marker=marker
179
+ ).request()
180
+
181
+ async def get_chat_by_link(self, link: str):
182
+ """под вопросом"""
183
+ return await GetChatByLink(bot=self, link=link).request()
184
+
185
+ async def get_chat_by_id(self, id: int):
186
+ return await GetChatById(bot=self, id=id).request()
187
+
188
+ async def edit_chat(
189
+ self,
190
+ chat_id: int,
191
+ icon: PhotoAttachmentRequestPayload = None,
192
+ title: str = None,
193
+ pin: str = None,
194
+ notify: bool = True,
195
+ ):
196
+ return await EditChat(
197
+ bot=self,
198
+ chat_id=chat_id,
199
+ icon=icon,
200
+ title=title,
201
+ pin=pin,
202
+ notify=notify
203
+ ).request()
204
+
205
+ async def get_video(self, video_token: str):
206
+ return await GetVideo(bot=self, video_token=video_token).request()
207
+
208
+ async def send_callback(
209
+ self,
210
+ callback_id: str,
211
+ message: 'Message' = None,
212
+ notification: str = None
213
+ ):
214
+ return await SendCallback(
215
+ bot=self,
216
+ callback_id=callback_id,
217
+ message=message,
218
+ notification=notification
219
+ ).request()
220
+
221
+ async def pin_message(
222
+ self,
223
+ chat_id: int,
224
+ message_id: str,
225
+ notify: bool = True
226
+ ):
227
+ return await PinMessage(
228
+ bot=self,
229
+ chat_id=chat_id,
230
+ message_id=message_id,
231
+ notify=notify
232
+ ).request()
233
+
234
+ async def delete_pin_message(
235
+ self,
236
+ chat_id: int,
237
+ ):
238
+ return await DeletePinMessage(
239
+ bot=self,
240
+ chat_id=chat_id,
241
+ ).request()
242
+
243
+ async def get_me_from_chat(
244
+ self,
245
+ chat_id: int,
246
+ ):
247
+ return await GetMeFromChat(
248
+ bot=self,
249
+ chat_id=chat_id,
250
+ ).request()
251
+
252
+ async def delete_me_from_chat(
253
+ self,
254
+ chat_id: int,
255
+ ):
256
+ return await DeleteMeFromMessage(
257
+ bot=self,
258
+ chat_id=chat_id,
259
+ ).request()
260
+
261
+ async def get_list_admin_chat(
262
+ self,
263
+ chat_id: int,
264
+ ):
265
+ return await GetListAdminChat(
266
+ bot=self,
267
+ chat_id=chat_id,
268
+ ).request()
269
+
270
+ async def add_list_admin_chat(
271
+ self,
272
+ chat_id: int,
273
+ admins: List[ChatAdmin],
274
+ marker: int = None
275
+ ):
276
+ return await AddAdminChat(
277
+ bot=self,
278
+ chat_id=chat_id,
279
+ admins=admins,
280
+ marker=marker,
281
+ ).request()
282
+
283
+ async def remove_admin(
284
+ self,
285
+ chat_id: int,
286
+ user_id: int
287
+ ):
288
+ return await RemoveAdmin(
289
+ bot=self,
290
+ chat_id=chat_id,
291
+ user_id=user_id,
292
+ ).request()
293
+
294
+ async def get_chat_members(
295
+ self,
296
+ chat_id: int,
297
+ user_ids: List[int] = None,
298
+ marker: int = None,
299
+ count: int = None,
300
+ ):
301
+ return await GetMembersChat(
302
+ bot=self,
303
+ chat_id=chat_id,
304
+ user_ids=user_ids,
305
+ marker=marker,
306
+ count=count,
307
+ ).request()
308
+
309
+ async def add_chat_members(
310
+ self,
311
+ chat_id: int,
312
+ user_ids: List[str],
313
+ ):
314
+ return await AddMembersChat(
315
+ bot=self,
316
+ chat_id=chat_id,
317
+ user_ids=user_ids,
318
+ ).request()
319
+
320
+ async def kick_chat_member(
321
+ self,
322
+ chat_id: int,
323
+ user_id: int,
324
+ block: bool = False,
325
+ ):
326
+ return await RemoveMemberChat(
327
+ bot=self,
328
+ chat_id=chat_id,
329
+ user_id=user_id,
330
+ block=block,
331
+ ).request()
332
+
333
+ async def get_updates(
334
+ self,
335
+ ):
336
+ return await GetUpdates(
337
+ bot=self,
338
+ ).request()
File without changes
@@ -0,0 +1,56 @@
1
+ import aiohttp
2
+ from pydantic import BaseModel
3
+
4
+ from ..types.errors import Error
5
+ from ..enums.http_method import HTTPMethod
6
+ from ..enums.api_path import ApiPath
7
+ from ..loggers import logger_bot
8
+
9
+
10
+ class BaseConnection:
11
+
12
+ API_URL = 'https://botapi.max.ru'
13
+
14
+ def __init__(self):
15
+ self.bot = None
16
+ self.session = None
17
+
18
+ async def request(
19
+ self,
20
+ method: HTTPMethod,
21
+ path: ApiPath,
22
+ model: BaseModel,
23
+ is_return_raw: bool = False,
24
+ **kwargs
25
+ ):
26
+
27
+ if not self.bot.session:
28
+ self.bot.session = aiohttp.ClientSession(self.bot.API_URL)
29
+
30
+ r = await self.bot.session.request(
31
+ method=method.value,
32
+ url=path.value if isinstance(path, ApiPath) else path,
33
+ **kwargs
34
+ )
35
+
36
+ if not r.ok:
37
+ raw = await r.text()
38
+ error = Error(code=r.status, text=raw)
39
+ logger_bot.error(error)
40
+ return error
41
+
42
+ raw = await r.json()
43
+
44
+ if is_return_raw: return raw
45
+
46
+ model = model(**raw)
47
+
48
+ if hasattr(model, 'message'):
49
+ attr = getattr(model, 'message')
50
+ if hasattr(attr, 'bot'):
51
+ attr.bot = self.bot
52
+
53
+ if hasattr(model, 'bot'):
54
+ model.bot = self.bot
55
+
56
+ return model
@@ -0,0 +1,36 @@
1
+ import asyncio
2
+
3
+ from typing import Any, Dict
4
+
5
+ from ..context.state_machine import State, StatesGroup
6
+
7
+
8
+ class MemoryContext:
9
+ def __init__(self, chat_id: int, user_id: int):
10
+ self.chat_id = chat_id
11
+ self.user_id = user_id
12
+ self._context: Dict[str, Any] = {}
13
+ self._state: State | None = None
14
+ self._lock = asyncio.Lock()
15
+
16
+ async def get_data(self) -> dict[str, Any]:
17
+ async with self._lock:
18
+ return self._context
19
+
20
+ async def set_data(self, data: dict[str, Any]):
21
+ async with self._lock:
22
+ self._context = data
23
+
24
+ async def update_data(self, **kwargs):
25
+ async with self._lock:
26
+ self._context.update(kwargs)
27
+
28
+ async def set_state(self, state: State | str = None):
29
+ self._state = state
30
+
31
+ async def get_state(self):
32
+ return self._state
33
+
34
+ async def clear(self):
35
+ self._state = None
36
+ self._context = {}
@@ -0,0 +1,16 @@
1
+ class State:
2
+ def __init__(self):
3
+ self.name = None
4
+
5
+ def __set_name__(self, owner, attr_name):
6
+ self.name = f'{owner.__name__}:{attr_name}'
7
+
8
+ def __str__(self):
9
+ return self.name
10
+
11
+
12
+ class StatesGroup:
13
+ @classmethod
14
+ def states(cls) -> list[str]:
15
+ return [str(getattr(cls, attr)) for attr in dir(cls)
16
+ if isinstance(getattr(cls, attr), State)]