"""Bot entrypoint: configure logging, wire the api client, start aiogram polling.""" from __future__ import annotations import asyncio import signal from aiogram import Bot, Dispatcher from ..core.logging import bind_context, configure_logging, get_logger from .client import ApiClient from .config import get_bot_settings from .handlers import router as bot_router log = get_logger(__name__) async def main() -> None: settings = get_bot_settings() configure_logging( settings.log_level, json_output=settings.json_logs, service="bot", env=settings.env, ) bind_context(service="bot", env=settings.env) api = ApiClient(settings) await api.start() bot = Bot(token=settings.bot_token) dp = Dispatcher(api=api, settings=settings) dp.include_router(bot_router) me = await bot.get_me() log.info("bot_started", username=me.username, api_url=settings.api_url) loop = asyncio.get_running_loop() stop_event = asyncio.Event() for sig in (signal.SIGINT, signal.SIGTERM): try: loop.add_signal_handler(sig, stop_event.set) except NotImplementedError: pass polling = asyncio.create_task(dp.start_polling(bot, handle_signals=False, polling_timeout=30)) stopper = asyncio.create_task(stop_event.wait()) try: await asyncio.wait({polling, stopper}, return_when=asyncio.FIRST_COMPLETED) finally: if not polling.done(): polling.cancel() if not stopper.done(): stopper.cancel() await dp.stop_polling() await bot.session.close() await api.aclose() log.info("bot_stopped") if __name__ == "__main__": asyncio.run(main())