feature/docs - add project docstrings & todos & comments #6

Merged
geekiot merged 4 commits from feature/docs into develop 2025-10-24 02:27:50 +05:00
10 changed files with 139 additions and 1 deletions
Showing only changes of commit 9588856a6a - Show all commits

View file

@ -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)

View file

@ -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")

View file

@ -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):

View file

@ -1 +1,4 @@
__all__ = []
# TODO: Add reply keyboard markups for bot here.

View file

@ -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(

View file

@ -1 +1,4 @@
__all__ = []
# TODO: Add states for FSM Aiogram here.

View file

@ -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"

View file

@ -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]

View file

@ -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.
...

View file

@ -1 +1,5 @@
__all__ = []
# TODO: Add bot business logic
# (working with other service components).