generated from geekiot/python-template
feature/docs - add project docstrings & todos & comments #6
10 changed files with 139 additions and 1 deletions
|
|
@ -1,5 +1,6 @@
|
|||
__all__ = ["start_bot"]
|
||||
|
||||
|
||||
from aiogram import Bot, Dispatcher
|
||||
from redis.asyncio.client import Redis
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
|
@ -13,6 +14,14 @@ async def start_bot(
|
|||
redis_client: Redis,
|
||||
database_session: AsyncSession,
|
||||
) -> None:
|
||||
"""
|
||||
Start Telegram bot.
|
||||
|
||||
Args:
|
||||
bot_token (str): Telegram API bot token.
|
||||
redis_client (Redis): async configured client for redis.
|
||||
database_session (AsyncSession): async database session.
|
||||
"""
|
||||
bot = Bot(bot_token)
|
||||
|
||||
dispatcher = Dispatcher()
|
||||
|
|
@ -20,6 +29,7 @@ async def start_bot(
|
|||
connect_handlers(dispatcher)
|
||||
connect_middlewares(dispatcher)
|
||||
|
||||
# Drop telegram bot updates, add bot menu.
|
||||
await bot.delete_webhook(drop_pending_updates=True)
|
||||
await registry.set_menu(bot)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,10 +7,17 @@ from aiogram import Router
|
|||
|
||||
from .utils.registry import RouterRegistry
|
||||
|
||||
# Main registry router for bot handlers.
|
||||
registry: RouterRegistry = RouterRegistry()
|
||||
|
||||
|
||||
def connect_handlers(dispatcher: Router) -> None:
|
||||
"""
|
||||
Load callbacks and commands modules to register bot handlers.
|
||||
|
||||
Args:
|
||||
dispatcher (Router): Aiogram Dispatcher.
|
||||
"""
|
||||
importlib.import_module("bot.handlers.callbacks")
|
||||
importlib.import_module("bot.handlers.commands")
|
||||
|
||||
|
|
|
|||
|
|
@ -10,10 +10,26 @@ from bot.handlers.utils.types import ChatType
|
|||
|
||||
|
||||
class ChatTypeFilter(BaseFilter):
|
||||
"""
|
||||
Chat type filter for handlers.
|
||||
Only for callbacks and messages.
|
||||
|
||||
Attrs:
|
||||
chat_types (Union[ChatType, list[ChatType]]):
|
||||
Telegram Chat Type from enum ChatType.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
chat_types: Union[ChatType, list[ChatType]],
|
||||
) -> None:
|
||||
"""
|
||||
ChatTypeFilter initialization.
|
||||
|
||||
Args:
|
||||
chat_types (Union[ChatType, list[ChatType]]):
|
||||
telegram chat type from enum ChatType.
|
||||
"""
|
||||
if isinstance(chat_types, ChatType):
|
||||
self.chat_type = [chat_types.value]
|
||||
else:
|
||||
|
|
@ -23,6 +39,17 @@ class ChatTypeFilter(BaseFilter):
|
|||
self,
|
||||
event: Union[Message, CallbackQuery],
|
||||
) -> bool:
|
||||
"""
|
||||
Try checking the event's chat type.
|
||||
Or return False if the event doesn't have the message attr.
|
||||
|
||||
Args:
|
||||
event (Union[Message, CallbackQuery]):
|
||||
a callback or a message event.
|
||||
|
||||
Returns:
|
||||
bool: whether the event's chat type is in the chat_types.
|
||||
"""
|
||||
current_chat_type: str
|
||||
|
||||
if isinstance(event, Message):
|
||||
|
|
|
|||
|
|
@ -1 +1,4 @@
|
|||
__all__ = []
|
||||
|
||||
|
||||
# TODO: Add reply keyboard markups for bot here.
|
||||
|
|
|
|||
|
|
@ -19,12 +19,30 @@ from bot.handlers.utils.types import (
|
|||
|
||||
|
||||
class RouterRegistry:
|
||||
"""
|
||||
Router Registry for Aiogram.
|
||||
Stores the configured router and information about handlers in it.
|
||||
|
||||
Attrs:
|
||||
_router (Router): Aiogram Router.
|
||||
_handlers (list[HandlerMeta]): list of handlers meta info.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""
|
||||
RouterRegistry initialization.
|
||||
"""
|
||||
self._router = Router()
|
||||
self._handlers: list[HandlerMeta] = list()
|
||||
|
||||
@property
|
||||
def router(self) -> Router:
|
||||
"""
|
||||
Getter for the _router attr.
|
||||
|
||||
Returns:
|
||||
Router: _description_
|
||||
"""
|
||||
return self._router
|
||||
|
||||
def register(
|
||||
|
|
@ -36,6 +54,42 @@ class RouterRegistry:
|
|||
command: str,
|
||||
is_callback: bool = False,
|
||||
) -> Callable[[Any], HandlerType]:
|
||||
"""
|
||||
Handler Registration Decorator for handler func.
|
||||
|
||||
Example:
|
||||
```
|
||||
from aiogram.types import Message
|
||||
|
||||
from bot.handlers import registry
|
||||
from bot.handlers.utils.types import ChatType
|
||||
|
||||
|
||||
@registry.register(
|
||||
command="start",
|
||||
chat_types=ChatType.PRIVATE,
|
||||
description="Test Start Function Description",
|
||||
)
|
||||
async def cmd_start(message: Message) -> None:
|
||||
await message.answer(
|
||||
"Test Start Function Answer Text"
|
||||
)
|
||||
```
|
||||
|
||||
Args:
|
||||
description (str):
|
||||
handler description for Telegram bot menu.
|
||||
chat_types (Union[ChatType, list[ChatType]]):
|
||||
list of Telegram chat types.
|
||||
command (str):
|
||||
specifying handler command trigger (data for callback).
|
||||
filters (Union[BaseFilter, list[BaseFilter]], optional):
|
||||
List of a handler's filters.
|
||||
Defaults to [].
|
||||
is_callback (bool, optional):
|
||||
If the func is for callback, then True.
|
||||
Defaults to False.
|
||||
"""
|
||||
if isinstance(chat_types, ChatType):
|
||||
chat_types = [chat_types]
|
||||
|
||||
|
|
@ -70,6 +124,12 @@ class RouterRegistry:
|
|||
return decorator
|
||||
|
||||
async def set_menu(self, bot: Bot) -> None:
|
||||
"""
|
||||
Set the Telegram Bot menu.
|
||||
|
||||
Args:
|
||||
bot (Bot): Aiogram Bot.
|
||||
"""
|
||||
await bot.set_my_commands(
|
||||
[
|
||||
BotCommand(
|
||||
|
|
|
|||
|
|
@ -1 +1,4 @@
|
|||
__all__ = []
|
||||
|
||||
|
||||
# TODO: Add states for FSM Aiogram here.
|
||||
|
|
|
|||
|
|
@ -2,6 +2,11 @@ from enum import Enum
|
|||
|
||||
|
||||
class ChatType(Enum):
|
||||
"""
|
||||
All Telegram Chat Types.
|
||||
Private, group, supergroup, channel.
|
||||
"""
|
||||
|
||||
PRIVATE = "private"
|
||||
GROUP = "group"
|
||||
SUPERGROUP = "supergroup"
|
||||
|
|
|
|||
|
|
@ -10,6 +10,23 @@ HandlerType = TypeVar(
|
|||
|
||||
@dataclass
|
||||
class HandlerMeta:
|
||||
"""
|
||||
Special class for storing useful information about the handler.
|
||||
|
||||
Attrs:
|
||||
func (Callable[[Any], Awaitable[Any]]):
|
||||
aiogram handler func.
|
||||
description (str):
|
||||
handler description for Telegram bot menu.
|
||||
chat_types (list[ChatType]):
|
||||
list of Telegram chat types.
|
||||
command (str):
|
||||
specifying handler command trigger (data for callback).
|
||||
is_callback (bool):
|
||||
If the func is for callback, then True.
|
||||
Defaults to False.
|
||||
"""
|
||||
|
||||
func: Callable[[Any], Awaitable[Any]]
|
||||
description: str
|
||||
chat_types: list[ChatType]
|
||||
|
|
|
|||
|
|
@ -4,4 +4,6 @@ __all__ = ["connect_middlewares"]
|
|||
from aiogram import Router
|
||||
|
||||
|
||||
def connect_middlewares(dispatcher: Router): ...
|
||||
def connect_middlewares(dispatcher: Router):
|
||||
# TODO: Add database and localization middleware and connect them.
|
||||
...
|
||||
|
|
|
|||
|
|
@ -1 +1,5 @@
|
|||
__all__ = []
|
||||
|
||||
|
||||
# TODO: Add bot business logic
|
||||
# (working with other service components).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue