pymaxgram 4.0.0__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.
- pymaxgram-4.0.0/.gitignore +9 -0
- pymaxgram-4.0.0/PKG-INFO +61 -0
- pymaxgram-4.0.0/README.md +35 -0
- pymaxgram-4.0.0/maxgram/__init__.py +30 -0
- pymaxgram-4.0.0/maxgram/__meta__.py +2 -0
- pymaxgram-4.0.0/maxgram/client/__init__.py +5 -0
- pymaxgram-4.0.0/maxgram/client/bot.py +362 -0
- pymaxgram-4.0.0/maxgram/client/context_controller.py +35 -0
- pymaxgram-4.0.0/maxgram/client/default.py +21 -0
- pymaxgram-4.0.0/maxgram/client/max_api.py +22 -0
- pymaxgram-4.0.0/maxgram/client/session/__init__.py +0 -0
- pymaxgram-4.0.0/maxgram/client/session/aiohttp.py +227 -0
- pymaxgram-4.0.0/maxgram/client/session/base.py +180 -0
- pymaxgram-4.0.0/maxgram/client/session/middlewares/__init__.py +0 -0
- pymaxgram-4.0.0/maxgram/client/session/middlewares/base.py +52 -0
- pymaxgram-4.0.0/maxgram/client/session/middlewares/manager.py +61 -0
- pymaxgram-4.0.0/maxgram/client/session/middlewares/request_logging.py +37 -0
- pymaxgram-4.0.0/maxgram/dispatcher/__init__.py +0 -0
- pymaxgram-4.0.0/maxgram/dispatcher/dispatcher.py +472 -0
- pymaxgram-4.0.0/maxgram/dispatcher/event/__init__.py +0 -0
- pymaxgram-4.0.0/maxgram/dispatcher/event/bases.py +35 -0
- pymaxgram-4.0.0/maxgram/dispatcher/event/event.py +54 -0
- pymaxgram-4.0.0/maxgram/dispatcher/event/handler.py +123 -0
- pymaxgram-4.0.0/maxgram/dispatcher/event/max.py +119 -0
- pymaxgram-4.0.0/maxgram/dispatcher/flags.py +132 -0
- pymaxgram-4.0.0/maxgram/dispatcher/middlewares/__init__.py +0 -0
- pymaxgram-4.0.0/maxgram/dispatcher/middlewares/base.py +20 -0
- pymaxgram-4.0.0/maxgram/dispatcher/middlewares/data.py +82 -0
- pymaxgram-4.0.0/maxgram/dispatcher/middlewares/error.py +38 -0
- pymaxgram-4.0.0/maxgram/dispatcher/middlewares/manager.py +68 -0
- pymaxgram-4.0.0/maxgram/dispatcher/middlewares/user_context.py +64 -0
- pymaxgram-4.0.0/maxgram/dispatcher/router.py +169 -0
- pymaxgram-4.0.0/maxgram/enums/__init__.py +21 -0
- pymaxgram-4.0.0/maxgram/enums/attachment_type.py +13 -0
- pymaxgram-4.0.0/maxgram/enums/button_type.py +11 -0
- pymaxgram-4.0.0/maxgram/enums/chat_action.py +10 -0
- pymaxgram-4.0.0/maxgram/enums/chat_admin_permission.py +15 -0
- pymaxgram-4.0.0/maxgram/enums/chat_status.py +8 -0
- pymaxgram-4.0.0/maxgram/enums/content_type.py +14 -0
- pymaxgram-4.0.0/maxgram/enums/parse_mode.py +6 -0
- pymaxgram-4.0.0/maxgram/enums/update_type.py +7 -0
- pymaxgram-4.0.0/maxgram/enums/upload_type.py +8 -0
- pymaxgram-4.0.0/maxgram/exceptions.py +127 -0
- pymaxgram-4.0.0/maxgram/filters/__init__.py +26 -0
- pymaxgram-4.0.0/maxgram/filters/base.py +54 -0
- pymaxgram-4.0.0/maxgram/filters/callback_data.py +149 -0
- pymaxgram-4.0.0/maxgram/filters/command.py +210 -0
- pymaxgram-4.0.0/maxgram/filters/exception.py +57 -0
- pymaxgram-4.0.0/maxgram/filters/logic.py +77 -0
- pymaxgram-4.0.0/maxgram/filters/magic_data.py +27 -0
- pymaxgram-4.0.0/maxgram/filters/state.py +50 -0
- pymaxgram-4.0.0/maxgram/fsm/__init__.py +0 -0
- pymaxgram-4.0.0/maxgram/fsm/context.py +44 -0
- pymaxgram-4.0.0/maxgram/fsm/middleware.py +104 -0
- pymaxgram-4.0.0/maxgram/fsm/scene.py +980 -0
- pymaxgram-4.0.0/maxgram/fsm/state.py +175 -0
- pymaxgram-4.0.0/maxgram/fsm/storage/__init__.py +0 -0
- pymaxgram-4.0.0/maxgram/fsm/storage/base.py +193 -0
- pymaxgram-4.0.0/maxgram/fsm/storage/memory.py +95 -0
- pymaxgram-4.0.0/maxgram/fsm/strategy.py +36 -0
- pymaxgram-4.0.0/maxgram/handlers/__init__.py +15 -0
- pymaxgram-4.0.0/maxgram/handlers/base.py +47 -0
- pymaxgram-4.0.0/maxgram/handlers/bot_started.py +16 -0
- pymaxgram-4.0.0/maxgram/handlers/callback.py +16 -0
- pymaxgram-4.0.0/maxgram/handlers/error.py +17 -0
- pymaxgram-4.0.0/maxgram/handlers/message.py +26 -0
- pymaxgram-4.0.0/maxgram/loggers.py +7 -0
- pymaxgram-4.0.0/maxgram/methods/__init__.py +65 -0
- pymaxgram-4.0.0/maxgram/methods/add_members.py +16 -0
- pymaxgram-4.0.0/maxgram/methods/answer_callback.py +40 -0
- pymaxgram-4.0.0/maxgram/methods/assign_admins.py +16 -0
- pymaxgram-4.0.0/maxgram/methods/base.py +120 -0
- pymaxgram-4.0.0/maxgram/methods/create_subscription.py +17 -0
- pymaxgram-4.0.0/maxgram/methods/delete_chat.py +15 -0
- pymaxgram-4.0.0/maxgram/methods/delete_message.py +18 -0
- pymaxgram-4.0.0/maxgram/methods/delete_subscription.py +15 -0
- pymaxgram-4.0.0/maxgram/methods/edit_chat.py +20 -0
- pymaxgram-4.0.0/maxgram/methods/edit_message.py +34 -0
- pymaxgram-4.0.0/maxgram/methods/get_admins.py +17 -0
- pymaxgram-4.0.0/maxgram/methods/get_chat.py +16 -0
- pymaxgram-4.0.0/maxgram/methods/get_chats.py +22 -0
- pymaxgram-4.0.0/maxgram/methods/get_me.py +14 -0
- pymaxgram-4.0.0/maxgram/methods/get_members.py +19 -0
- pymaxgram-4.0.0/maxgram/methods/get_message_by_id.py +16 -0
- pymaxgram-4.0.0/maxgram/methods/get_messages.py +18 -0
- pymaxgram-4.0.0/maxgram/methods/get_my_membership.py +16 -0
- pymaxgram-4.0.0/maxgram/methods/get_pinned_message.py +16 -0
- pymaxgram-4.0.0/maxgram/methods/get_subscriptions.py +14 -0
- pymaxgram-4.0.0/maxgram/methods/get_updates.py +19 -0
- pymaxgram-4.0.0/maxgram/methods/get_upload_url.py +16 -0
- pymaxgram-4.0.0/maxgram/methods/get_video_info.py +16 -0
- pymaxgram-4.0.0/maxgram/methods/leave_chat.py +15 -0
- pymaxgram-4.0.0/maxgram/methods/pin_message.py +17 -0
- pymaxgram-4.0.0/maxgram/methods/remove_admin.py +16 -0
- pymaxgram-4.0.0/maxgram/methods/remove_member.py +17 -0
- pymaxgram-4.0.0/maxgram/methods/send_action.py +16 -0
- pymaxgram-4.0.0/maxgram/methods/send_message.py +50 -0
- pymaxgram-4.0.0/maxgram/methods/unpin_message.py +15 -0
- pymaxgram-4.0.0/maxgram/py.typed +0 -0
- pymaxgram-4.0.0/maxgram/types/__init__.py +105 -0
- pymaxgram-4.0.0/maxgram/types/attachment.py +66 -0
- pymaxgram-4.0.0/maxgram/types/attachment_request.py +56 -0
- pymaxgram-4.0.0/maxgram/types/base.py +37 -0
- pymaxgram-4.0.0/maxgram/types/bot_command.py +8 -0
- pymaxgram-4.0.0/maxgram/types/bot_info.py +10 -0
- pymaxgram-4.0.0/maxgram/types/button.py +13 -0
- pymaxgram-4.0.0/maxgram/types/callback.py +38 -0
- pymaxgram-4.0.0/maxgram/types/chat.py +30 -0
- pymaxgram-4.0.0/maxgram/types/chat_admin.py +11 -0
- pymaxgram-4.0.0/maxgram/types/chat_member.py +14 -0
- pymaxgram-4.0.0/maxgram/types/error_event.py +13 -0
- pymaxgram-4.0.0/maxgram/types/image.py +12 -0
- pymaxgram-4.0.0/maxgram/types/inline_keyboard.py +10 -0
- pymaxgram-4.0.0/maxgram/types/input_file.py +150 -0
- pymaxgram-4.0.0/maxgram/types/linked_message.py +18 -0
- pymaxgram-4.0.0/maxgram/types/message.py +106 -0
- pymaxgram-4.0.0/maxgram/types/message_body.py +13 -0
- pymaxgram-4.0.0/maxgram/types/message_stat.py +9 -0
- pymaxgram-4.0.0/maxgram/types/new_message_body.py +15 -0
- pymaxgram-4.0.0/maxgram/types/new_message_link.py +8 -0
- pymaxgram-4.0.0/maxgram/types/recipient.py +11 -0
- pymaxgram-4.0.0/maxgram/types/subscription.py +12 -0
- pymaxgram-4.0.0/maxgram/types/update.py +46 -0
- pymaxgram-4.0.0/maxgram/types/upload_info.py +10 -0
- pymaxgram-4.0.0/maxgram/types/user.py +15 -0
- pymaxgram-4.0.0/maxgram/types/user_with_photo.py +11 -0
- pymaxgram-4.0.0/maxgram/types/video_info.py +22 -0
- pymaxgram-4.0.0/maxgram/utils/__init__.py +0 -0
- pymaxgram-4.0.0/maxgram/utils/backoff.py +85 -0
- pymaxgram-4.0.0/maxgram/utils/callback_answer.py +218 -0
- pymaxgram-4.0.0/maxgram/utils/chat_action.py +179 -0
- pymaxgram-4.0.0/maxgram/utils/chat_member.py +36 -0
- pymaxgram-4.0.0/maxgram/utils/class_attrs_resolver.py +87 -0
- pymaxgram-4.0.0/maxgram/utils/dataclass.py +63 -0
- pymaxgram-4.0.0/maxgram/utils/formatting.py +735 -0
- pymaxgram-4.0.0/maxgram/utils/keyboard.py +91 -0
- pymaxgram-4.0.0/maxgram/utils/link.py +24 -0
- pymaxgram-4.0.0/maxgram/utils/magic_filter.py +23 -0
- pymaxgram-4.0.0/maxgram/utils/markdown.py +59 -0
- pymaxgram-4.0.0/maxgram/utils/mixins.py +98 -0
- pymaxgram-4.0.0/maxgram/utils/mypy_hacks.py +21 -0
- pymaxgram-4.0.0/maxgram/utils/payload.py +114 -0
- pymaxgram-4.0.0/maxgram/utils/serialization.py +89 -0
- pymaxgram-4.0.0/maxgram/utils/text_decorations.py +104 -0
- pymaxgram-4.0.0/maxgram/utils/token.py +15 -0
- pymaxgram-4.0.0/maxgram/utils/warnings.py +6 -0
- pymaxgram-4.0.0/maxgram/webhook/__init__.py +0 -0
- pymaxgram-4.0.0/maxgram/webhook/aiohttp_server.py +152 -0
- pymaxgram-4.0.0/maxgram/webhook/security.py +33 -0
- pymaxgram-4.0.0/pyproject.toml +49 -0
pymaxgram-4.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pymaxgram
|
|
3
|
+
Version: 4.0.0
|
|
4
|
+
Summary: Async framework for MAX Messenger Bot API
|
|
5
|
+
Project-URL: Repository, https://github.com/daeeros/pymaxgram
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Classifier: Development Status :: 4 - Beta
|
|
8
|
+
Classifier: Framework :: AsyncIO
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Topic :: Communications :: Chat
|
|
17
|
+
Classifier: Typing :: Typed
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Requires-Dist: aiofiles<26.0,>=23.2.1
|
|
20
|
+
Requires-Dist: aiohttp<3.14,>=3.9.0
|
|
21
|
+
Requires-Dist: certifi>=2023.7.22
|
|
22
|
+
Requires-Dist: magic-filter<1.1,>=1.0.12
|
|
23
|
+
Requires-Dist: pydantic<2.13,>=2.4.1
|
|
24
|
+
Requires-Dist: typing-extensions<=5.0,>=4.7.0
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# pymaxgram
|
|
28
|
+
|
|
29
|
+
Async framework for MAX Messenger Bot API.
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install pymaxgram
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
import asyncio
|
|
41
|
+
from maxgram import Bot, Dispatcher, Router
|
|
42
|
+
|
|
43
|
+
bot = Bot(token="YOUR_BOT_TOKEN")
|
|
44
|
+
dp = Dispatcher()
|
|
45
|
+
router = Router()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@router.message()
|
|
49
|
+
async def on_message(message, bot):
|
|
50
|
+
await message.answer("Hello!")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
dp.include_router(router)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
async def main():
|
|
57
|
+
await dp.start_polling(bot)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
asyncio.run(main())
|
|
61
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# pymaxgram
|
|
2
|
+
|
|
3
|
+
Async framework for MAX Messenger Bot API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install pymaxgram
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
import asyncio
|
|
15
|
+
from maxgram import Bot, Dispatcher, Router
|
|
16
|
+
|
|
17
|
+
bot = Bot(token="YOUR_BOT_TOKEN")
|
|
18
|
+
dp = Dispatcher()
|
|
19
|
+
router = Router()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@router.message()
|
|
23
|
+
async def on_message(message, bot):
|
|
24
|
+
await message.answer("Hello!")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
dp.include_router(router)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
async def main():
|
|
31
|
+
await dp.start_polling(bot)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
asyncio.run(main())
|
|
35
|
+
```
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from maxgram.dispatcher.flags import FlagGenerator
|
|
2
|
+
|
|
3
|
+
from . import enums, methods, types
|
|
4
|
+
from .__meta__ import __api_version__, __version__
|
|
5
|
+
from .client.bot import Bot
|
|
6
|
+
from .dispatcher.dispatcher import Dispatcher
|
|
7
|
+
from .dispatcher.middlewares.base import BaseMiddleware
|
|
8
|
+
from .dispatcher.router import Router
|
|
9
|
+
from .utils.magic_filter import MagicFilter
|
|
10
|
+
from .utils.text_decorations import html_decoration as html
|
|
11
|
+
from .utils.text_decorations import markdown_decoration as md
|
|
12
|
+
|
|
13
|
+
F = MagicFilter()
|
|
14
|
+
flags = FlagGenerator()
|
|
15
|
+
|
|
16
|
+
__all__ = (
|
|
17
|
+
"BaseMiddleware",
|
|
18
|
+
"Bot",
|
|
19
|
+
"Dispatcher",
|
|
20
|
+
"F",
|
|
21
|
+
"Router",
|
|
22
|
+
"__api_version__",
|
|
23
|
+
"__version__",
|
|
24
|
+
"enums",
|
|
25
|
+
"flags",
|
|
26
|
+
"html",
|
|
27
|
+
"md",
|
|
28
|
+
"methods",
|
|
29
|
+
"types",
|
|
30
|
+
)
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import io
|
|
4
|
+
import pathlib
|
|
5
|
+
from collections.abc import AsyncGenerator
|
|
6
|
+
from contextlib import asynccontextmanager
|
|
7
|
+
from types import TracebackType
|
|
8
|
+
from typing import (
|
|
9
|
+
Any,
|
|
10
|
+
BinaryIO,
|
|
11
|
+
TypeVar,
|
|
12
|
+
cast,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
from ..methods import (
|
|
16
|
+
AddMembers,
|
|
17
|
+
AnswerCallback,
|
|
18
|
+
AssignAdmins,
|
|
19
|
+
CreateSubscription,
|
|
20
|
+
DeleteChat,
|
|
21
|
+
DeleteMessage,
|
|
22
|
+
DeleteSubscription,
|
|
23
|
+
EditChat,
|
|
24
|
+
EditMessage,
|
|
25
|
+
GetAdmins,
|
|
26
|
+
GetChat,
|
|
27
|
+
GetChats,
|
|
28
|
+
GetMe,
|
|
29
|
+
GetMembers,
|
|
30
|
+
GetMessageById,
|
|
31
|
+
GetMessages,
|
|
32
|
+
GetMyMembership,
|
|
33
|
+
GetPinnedMessage,
|
|
34
|
+
GetSubscriptions,
|
|
35
|
+
GetUpdates,
|
|
36
|
+
GetUploadUrl,
|
|
37
|
+
GetVideoInfo,
|
|
38
|
+
LeaveChat,
|
|
39
|
+
MaxMethod,
|
|
40
|
+
PinMessage,
|
|
41
|
+
RemoveAdmin,
|
|
42
|
+
RemoveMember,
|
|
43
|
+
SendAction,
|
|
44
|
+
SendMessage,
|
|
45
|
+
UnpinMessage,
|
|
46
|
+
)
|
|
47
|
+
from ..methods.base import MaxType
|
|
48
|
+
from ..types import (
|
|
49
|
+
BotInfo,
|
|
50
|
+
Chat,
|
|
51
|
+
ChatMember,
|
|
52
|
+
Message,
|
|
53
|
+
Subscription,
|
|
54
|
+
Update,
|
|
55
|
+
UploadInfo,
|
|
56
|
+
User,
|
|
57
|
+
VideoInfo,
|
|
58
|
+
)
|
|
59
|
+
from .context_controller import BotContextController
|
|
60
|
+
from .default import DefaultBotProperties
|
|
61
|
+
|
|
62
|
+
T = TypeVar("T")
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class Bot:
|
|
66
|
+
"""MAX Bot API client."""
|
|
67
|
+
|
|
68
|
+
def __init__(
|
|
69
|
+
self,
|
|
70
|
+
token: str,
|
|
71
|
+
session: Any | None = None,
|
|
72
|
+
default: DefaultBotProperties | None = None,
|
|
73
|
+
) -> None:
|
|
74
|
+
if not token:
|
|
75
|
+
raise ValueError("Token must not be empty")
|
|
76
|
+
|
|
77
|
+
self.__token = token
|
|
78
|
+
self.session = session or self._create_default_session()
|
|
79
|
+
self.default = default or DefaultBotProperties()
|
|
80
|
+
self._me: BotInfo | None = None
|
|
81
|
+
|
|
82
|
+
@staticmethod
|
|
83
|
+
def _create_default_session() -> Any:
|
|
84
|
+
from .session.aiohttp import AiohttpSession
|
|
85
|
+
return AiohttpSession()
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def token(self) -> str:
|
|
89
|
+
return self.__token
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def id(self) -> int | None:
|
|
93
|
+
"""Bot ID. Available after calling get_me()."""
|
|
94
|
+
if self._me:
|
|
95
|
+
return self._me.user_id
|
|
96
|
+
return None
|
|
97
|
+
|
|
98
|
+
async def me(self) -> BotInfo:
|
|
99
|
+
"""Get bot info (cached)."""
|
|
100
|
+
if self._me is None:
|
|
101
|
+
self._me = await self.get_me()
|
|
102
|
+
return self._me
|
|
103
|
+
|
|
104
|
+
async def __call__(
|
|
105
|
+
self,
|
|
106
|
+
method: MaxMethod[MaxType],
|
|
107
|
+
**kwargs: Any,
|
|
108
|
+
) -> MaxType:
|
|
109
|
+
"""Execute an API method."""
|
|
110
|
+
return await self.session(self, method, **kwargs)
|
|
111
|
+
|
|
112
|
+
def __hash__(self) -> int:
|
|
113
|
+
return hash(self.__token)
|
|
114
|
+
|
|
115
|
+
def __eq__(self, other: object) -> bool:
|
|
116
|
+
if not isinstance(other, Bot):
|
|
117
|
+
return NotImplemented
|
|
118
|
+
return self.__token == other.__token
|
|
119
|
+
|
|
120
|
+
async def __aenter__(self) -> Bot:
|
|
121
|
+
return self
|
|
122
|
+
|
|
123
|
+
async def __aexit__(
|
|
124
|
+
self,
|
|
125
|
+
exc_type: type[BaseException] | None,
|
|
126
|
+
exc_val: BaseException | None,
|
|
127
|
+
exc_tb: TracebackType | None,
|
|
128
|
+
) -> None:
|
|
129
|
+
await self.session.close()
|
|
130
|
+
|
|
131
|
+
# ==================== Bot Info ====================
|
|
132
|
+
|
|
133
|
+
async def get_me(self) -> BotInfo:
|
|
134
|
+
return await self(GetMe())
|
|
135
|
+
|
|
136
|
+
# ==================== Chats ====================
|
|
137
|
+
|
|
138
|
+
async def get_chats(
|
|
139
|
+
self,
|
|
140
|
+
count: int | None = None,
|
|
141
|
+
marker: int | None = None,
|
|
142
|
+
) -> list[Chat]:
|
|
143
|
+
return await self(GetChats(count=count, marker=marker))
|
|
144
|
+
|
|
145
|
+
async def get_chat(self, chat_id: int) -> Chat:
|
|
146
|
+
return await self(GetChat(chat_id=chat_id))
|
|
147
|
+
|
|
148
|
+
async def edit_chat(
|
|
149
|
+
self,
|
|
150
|
+
chat_id: int,
|
|
151
|
+
title: str | None = None,
|
|
152
|
+
icon: dict[str, Any] | None = None,
|
|
153
|
+
pin: str | None = None,
|
|
154
|
+
notify: bool | None = None,
|
|
155
|
+
) -> Chat:
|
|
156
|
+
return await self(EditChat(
|
|
157
|
+
chat_id=chat_id, title=title, icon=icon, pin=pin, notify=notify,
|
|
158
|
+
))
|
|
159
|
+
|
|
160
|
+
async def delete_chat(self, chat_id: int) -> bool:
|
|
161
|
+
return await self(DeleteChat(chat_id=chat_id))
|
|
162
|
+
|
|
163
|
+
# ==================== Chat Actions ====================
|
|
164
|
+
|
|
165
|
+
async def send_action(self, chat_id: int, action: str) -> bool:
|
|
166
|
+
return await self(SendAction(chat_id=chat_id, action=action))
|
|
167
|
+
|
|
168
|
+
# ==================== Pinned Messages ====================
|
|
169
|
+
|
|
170
|
+
async def get_pinned_message(self, chat_id: int) -> Message | None:
|
|
171
|
+
return await self(GetPinnedMessage(chat_id=chat_id))
|
|
172
|
+
|
|
173
|
+
async def pin_message(
|
|
174
|
+
self,
|
|
175
|
+
chat_id: int,
|
|
176
|
+
message_id: str,
|
|
177
|
+
notify: bool | None = None,
|
|
178
|
+
) -> bool:
|
|
179
|
+
return await self(PinMessage(chat_id=chat_id, message_id=message_id, notify=notify))
|
|
180
|
+
|
|
181
|
+
async def unpin_message(self, chat_id: int) -> bool:
|
|
182
|
+
return await self(UnpinMessage(chat_id=chat_id))
|
|
183
|
+
|
|
184
|
+
# ==================== Members ====================
|
|
185
|
+
|
|
186
|
+
async def get_my_membership(self, chat_id: int) -> ChatMember:
|
|
187
|
+
return await self(GetMyMembership(chat_id=chat_id))
|
|
188
|
+
|
|
189
|
+
async def leave_chat(self, chat_id: int) -> bool:
|
|
190
|
+
return await self(LeaveChat(chat_id=chat_id))
|
|
191
|
+
|
|
192
|
+
async def get_admins(
|
|
193
|
+
self,
|
|
194
|
+
chat_id: int,
|
|
195
|
+
marker: int | None = None,
|
|
196
|
+
) -> list[ChatMember]:
|
|
197
|
+
return await self(GetAdmins(chat_id=chat_id, marker=marker))
|
|
198
|
+
|
|
199
|
+
async def assign_admins(
|
|
200
|
+
self,
|
|
201
|
+
chat_id: int,
|
|
202
|
+
admins: list[dict[str, Any]],
|
|
203
|
+
) -> bool:
|
|
204
|
+
return await self(AssignAdmins(chat_id=chat_id, admins=admins))
|
|
205
|
+
|
|
206
|
+
async def remove_admin(self, chat_id: int, user_id: int) -> bool:
|
|
207
|
+
return await self(RemoveAdmin(chat_id=chat_id, user_id=user_id))
|
|
208
|
+
|
|
209
|
+
async def get_members(
|
|
210
|
+
self,
|
|
211
|
+
chat_id: int,
|
|
212
|
+
user_ids: list[int] | None = None,
|
|
213
|
+
marker: int | None = None,
|
|
214
|
+
count: int | None = None,
|
|
215
|
+
) -> list[ChatMember]:
|
|
216
|
+
return await self(GetMembers(
|
|
217
|
+
chat_id=chat_id, user_ids=user_ids, marker=marker, count=count,
|
|
218
|
+
))
|
|
219
|
+
|
|
220
|
+
async def add_members(self, chat_id: int, user_ids: list[int]) -> bool:
|
|
221
|
+
return await self(AddMembers(chat_id=chat_id, user_ids=user_ids))
|
|
222
|
+
|
|
223
|
+
async def remove_member(
|
|
224
|
+
self,
|
|
225
|
+
chat_id: int,
|
|
226
|
+
user_id: int,
|
|
227
|
+
block: bool | None = None,
|
|
228
|
+
) -> bool:
|
|
229
|
+
return await self(RemoveMember(chat_id=chat_id, user_id=user_id, block=block))
|
|
230
|
+
|
|
231
|
+
# ==================== Subscriptions (Webhooks) ====================
|
|
232
|
+
|
|
233
|
+
async def get_subscriptions(self) -> list[Subscription]:
|
|
234
|
+
return await self(GetSubscriptions())
|
|
235
|
+
|
|
236
|
+
async def create_subscription(
|
|
237
|
+
self,
|
|
238
|
+
url: str,
|
|
239
|
+
update_types: list[str] | None = None,
|
|
240
|
+
secret: str | None = None,
|
|
241
|
+
) -> bool:
|
|
242
|
+
return await self(CreateSubscription(
|
|
243
|
+
url=url, update_types=update_types, secret=secret,
|
|
244
|
+
))
|
|
245
|
+
|
|
246
|
+
async def delete_subscription(self, url: str) -> bool:
|
|
247
|
+
return await self(DeleteSubscription(url=url))
|
|
248
|
+
|
|
249
|
+
# ==================== Updates ====================
|
|
250
|
+
|
|
251
|
+
async def get_updates(
|
|
252
|
+
self,
|
|
253
|
+
limit: int | None = None,
|
|
254
|
+
timeout: int | None = None,
|
|
255
|
+
marker: int | None = None,
|
|
256
|
+
types: list[str] | None = None,
|
|
257
|
+
) -> list[Update]:
|
|
258
|
+
return await self(GetUpdates(
|
|
259
|
+
limit=limit, timeout=timeout, marker=marker, types=types,
|
|
260
|
+
))
|
|
261
|
+
|
|
262
|
+
# ==================== Messages ====================
|
|
263
|
+
|
|
264
|
+
async def send_message(
|
|
265
|
+
self,
|
|
266
|
+
chat_id: int | None = None,
|
|
267
|
+
user_id: int | None = None,
|
|
268
|
+
text: str | None = None,
|
|
269
|
+
attachments: list[Any] | None = None,
|
|
270
|
+
link: Any | None = None,
|
|
271
|
+
notify: bool | None = None,
|
|
272
|
+
format: str | None = None,
|
|
273
|
+
disable_link_preview: bool | None = None,
|
|
274
|
+
) -> Message:
|
|
275
|
+
return await self(SendMessage(
|
|
276
|
+
chat_id=chat_id,
|
|
277
|
+
user_id=user_id,
|
|
278
|
+
text=text,
|
|
279
|
+
attachments=attachments,
|
|
280
|
+
link=link,
|
|
281
|
+
notify=notify,
|
|
282
|
+
format=format,
|
|
283
|
+
disable_link_preview=disable_link_preview,
|
|
284
|
+
))
|
|
285
|
+
|
|
286
|
+
async def edit_message(
|
|
287
|
+
self,
|
|
288
|
+
message_id: str,
|
|
289
|
+
text: str | None = None,
|
|
290
|
+
attachments: list[Any] | None = None,
|
|
291
|
+
notify: bool | None = None,
|
|
292
|
+
format: str | None = None,
|
|
293
|
+
) -> bool:
|
|
294
|
+
return await self(EditMessage(
|
|
295
|
+
message_id=message_id,
|
|
296
|
+
text=text,
|
|
297
|
+
attachments=attachments,
|
|
298
|
+
notify=notify,
|
|
299
|
+
format=format,
|
|
300
|
+
))
|
|
301
|
+
|
|
302
|
+
async def delete_message(self, message_id: str) -> bool:
|
|
303
|
+
return await self(DeleteMessage(message_id=message_id))
|
|
304
|
+
|
|
305
|
+
async def get_messages(
|
|
306
|
+
self,
|
|
307
|
+
chat_id: int | None = None,
|
|
308
|
+
message_ids: list[str] | None = None,
|
|
309
|
+
count: int | None = None,
|
|
310
|
+
) -> list[Message]:
|
|
311
|
+
return await self(GetMessages(
|
|
312
|
+
chat_id=chat_id, message_ids=message_ids, count=count,
|
|
313
|
+
))
|
|
314
|
+
|
|
315
|
+
async def get_message_by_id(self, message_id: str) -> Message:
|
|
316
|
+
return await self(GetMessageById(message_id=message_id))
|
|
317
|
+
|
|
318
|
+
# ==================== Uploads ====================
|
|
319
|
+
|
|
320
|
+
async def get_upload_url(self, type: str) -> UploadInfo:
|
|
321
|
+
return await self(GetUploadUrl(type=type))
|
|
322
|
+
|
|
323
|
+
async def upload_file(
|
|
324
|
+
self,
|
|
325
|
+
file_type: str,
|
|
326
|
+
file_data: bytes,
|
|
327
|
+
filename: str = "file",
|
|
328
|
+
) -> str:
|
|
329
|
+
"""Two-stage file upload. Returns token for use in attachments."""
|
|
330
|
+
upload_info = await self.get_upload_url(type=file_type)
|
|
331
|
+
result = await self.session.upload_file(
|
|
332
|
+
bot=self,
|
|
333
|
+
upload_url=upload_info.url,
|
|
334
|
+
file_data=file_data,
|
|
335
|
+
filename=filename,
|
|
336
|
+
)
|
|
337
|
+
return result.get("token", upload_info.token or "")
|
|
338
|
+
|
|
339
|
+
# ==================== Video ====================
|
|
340
|
+
|
|
341
|
+
async def get_video_info(self, video_token: str) -> VideoInfo:
|
|
342
|
+
return await self(GetVideoInfo(video_token=video_token))
|
|
343
|
+
|
|
344
|
+
# ==================== Callbacks ====================
|
|
345
|
+
|
|
346
|
+
async def answer_callback(
|
|
347
|
+
self,
|
|
348
|
+
callback_id: str,
|
|
349
|
+
text: str | None = None,
|
|
350
|
+
attachments: list[Any] | None = None,
|
|
351
|
+
notification: str | None = None,
|
|
352
|
+
notify: bool | None = None,
|
|
353
|
+
format: str | None = None,
|
|
354
|
+
) -> bool:
|
|
355
|
+
return await self(AnswerCallback(
|
|
356
|
+
callback_id=callback_id,
|
|
357
|
+
text=text,
|
|
358
|
+
attachments=attachments,
|
|
359
|
+
notification=notification,
|
|
360
|
+
notify=notify,
|
|
361
|
+
format=format,
|
|
362
|
+
))
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, PrivateAttr
|
|
6
|
+
from typing_extensions import Self
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from maxgram.client.bot import Bot
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BotContextController(BaseModel):
|
|
13
|
+
_bot: Bot | None = PrivateAttr()
|
|
14
|
+
|
|
15
|
+
def model_post_init(self, __context: Any) -> None: # noqa: PYI063
|
|
16
|
+
self._bot = __context.get("bot") if __context else None
|
|
17
|
+
|
|
18
|
+
def as_(self, bot: Bot | None) -> Self:
|
|
19
|
+
"""
|
|
20
|
+
Bind object to a bot instance.
|
|
21
|
+
|
|
22
|
+
:param bot: Bot instance
|
|
23
|
+
:return: self
|
|
24
|
+
"""
|
|
25
|
+
self._bot = bot
|
|
26
|
+
return self
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def bot(self) -> Bot | None:
|
|
30
|
+
"""
|
|
31
|
+
Get bot instance.
|
|
32
|
+
|
|
33
|
+
:return: Bot instance
|
|
34
|
+
"""
|
|
35
|
+
return self._bot
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from maxgram.utils.dataclass import dataclass_kwargs
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass(**dataclass_kwargs(slots=True, kw_only=True))
|
|
10
|
+
class DefaultBotProperties:
|
|
11
|
+
"""Default bot properties for MAX API."""
|
|
12
|
+
|
|
13
|
+
parse_mode: str | None = None
|
|
14
|
+
"""Default parse mode for messages (markdown or html)."""
|
|
15
|
+
disable_link_preview: bool | None = None
|
|
16
|
+
"""Disable link preview in messages."""
|
|
17
|
+
notify: bool | None = None
|
|
18
|
+
"""Default notification setting."""
|
|
19
|
+
|
|
20
|
+
def __getitem__(self, item: str) -> Any:
|
|
21
|
+
return getattr(self, item, None)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass(frozen=True)
|
|
7
|
+
class MaxAPIServer:
|
|
8
|
+
"""MAX API server configuration."""
|
|
9
|
+
|
|
10
|
+
base: str = "https://platform-api.max.ru"
|
|
11
|
+
|
|
12
|
+
def api_url(self, path: str) -> str:
|
|
13
|
+
"""Build full API URL from path."""
|
|
14
|
+
return f"{self.base}{path}"
|
|
15
|
+
|
|
16
|
+
@classmethod
|
|
17
|
+
def from_base(cls, base: str) -> MaxAPIServer:
|
|
18
|
+
base = base.rstrip("/")
|
|
19
|
+
return cls(base=base)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
PRODUCTION = MaxAPIServer()
|
|
File without changes
|