From c3a849b2b3667b989706e6523011228fec657946 Mon Sep 17 00:00:00 2001 From: Mikkel Georgsen Date: Fri, 16 Jan 2026 15:36:48 +0000 Subject: [PATCH] feat(02-01): create bot main.py with Application setup - ApplicationBuilder with post_init/post_shutdown hooks - Database lifecycle (init_db, create_tables, close_db) - Config stored in bot_data for handler access - Calls register_handlers before run_polling --- src/moai/bot/main.py | 82 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 src/moai/bot/main.py diff --git a/src/moai/bot/main.py b/src/moai/bot/main.py new file mode 100644 index 0000000..1546731 --- /dev/null +++ b/src/moai/bot/main.py @@ -0,0 +1,82 @@ +"""MoAI Telegram bot entry point. + +Sets up and runs the Telegram bot with database lifecycle hooks. + +Usage: + python -m moai.bot.main +""" + +import logging + +from telegram.ext import Application, ApplicationBuilder + +from moai.bot.config import BotConfig +from moai.bot.handlers import register_handlers +from moai.core.database import close_db, create_tables, init_db + +# Module-level config reference for post_init callback +_config: BotConfig | None = None + + +async def post_init(application: Application) -> None: + """Initialize database after bot application is built. + + Called automatically by python-telegram-bot after Application.build(). + Sets up the database engine and creates tables if needed. + """ + logger = logging.getLogger(__name__) + + if _config is None: + raise RuntimeError("Config not initialized before post_init") + + init_db(_config.database_url) + await create_tables() + logger.info("Database initialized") + + +async def post_shutdown(application: Application) -> None: + """Clean up database on bot shutdown. + + Called automatically by python-telegram-bot during Application shutdown. + Disposes database engine and releases connections. + """ + logger = logging.getLogger(__name__) + await close_db() + logger.info("Database closed") + + +def main() -> None: + """Run the MoAI Telegram bot. + + Loads configuration from environment, sets up the Application with + database lifecycle hooks, registers handlers, and starts polling. + """ + global _config + + _config = BotConfig.from_env() + + logging.basicConfig( + level=getattr(logging, _config.log_level.upper(), logging.INFO), + format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", + ) + logger = logging.getLogger(__name__) + + app = ( + ApplicationBuilder() + .token(_config.bot_token) + .post_init(post_init) + .post_shutdown(post_shutdown) + .build() + ) + + # Store config in bot_data for handler access + app.bot_data["config"] = _config + + register_handlers(app) + + logger.info("Starting MoAI bot...") + app.run_polling() + + +if __name__ == "__main__": + main()