Ваш первый бот

Соберём минимального бота и посмотрим, что Raito берёт на себя.

Структура проекта

Создайте папку для хендлеров рядом с точкой входа:

my_bot/
├── __main__.py
└── handlers/
    └── start.py

Точка входа

__main__.py связывает части aiogram и передаёт папку handlers в Raito:

import asyncio

from aiogram import Bot, Dispatcher
from raito import Raito


async def main() -> None:
    bot = Bot(token="YOUR_TOKEN")
    dispatcher = Dispatcher()

    raito = Raito(dispatcher, "my_bot/handlers", production=False)

    raito.init_logging()
    await raito.setup()
    await dispatcher.start_polling(bot)


if __name__ == "__main__":
    asyncio.run(main())

Всю работу делают два вызова:

  • raito.Raito.setup() просматривает my_bot/handlers и регистрирует каждый найденный роутер. Вызывать dispatcher.include_router вручную не нужно.

  • production=False включает watchdog: сохраните файл хендлера, и Raito перезагрузит его без перезапуска бота.

raito.Raito.init_logging() необязателен: он ставит цветной и удобочитаемый форматтер логов.

Хендлер

Каждый файл в handlers/ содержит объект router. Raito также подхватит роутер под любым именем переменной или единственный роутер в файле, но имя router считается стандартным.

# my_bot/handlers/start.py
from aiogram import Router, filters, types

router = Router(name="start")


@router.message(filters.CommandStart())
async def start(message: types.Message) -> None:
    await message.answer("Hello from Raito! 👋")

Запустите:

python -m my_bot

Отправьте боту /start и получите ответ. Теперь измените текст в start.py и сохраните: правка применится со следующего сообщения, перезапуск не нужен.

Совет

Файлы и папки, чьи имена начинаются с _, загрузчик пропускает, поэтому handlers/_utils.py роутером считаться не будет.

Что произошло

  • Raito рекурсивно обошёл handlers/, импортировал каждый модуль и забрал его роутер.

  • Затем зарегистрировал их в диспетчере в предсказуемом порядке.

  • А в режиме разработки начал следить за изменениями в папке.

Хотите понять, как устроена перезагрузка? Смотрите Архитектура. Готовы к настоящим командам? Переходите к Команды с описаниями и аргументами.