"""Variet Agent — 진입점. FastAPI 서버 + Discord Bot을 동시 실행합니다. """ import asyncio import logging import sys import signal # config를 먼저 import → .env 로드 import config logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(name)s] %(levelname)s: %(message)s", datefmt="%H:%M:%S", handlers=[logging.StreamHandler(sys.stdout)], ) logger = logging.getLogger("variet") async def run_api_server(): """FastAPI 서버를 uvicorn으로 실행.""" import uvicorn uvi_config = uvicorn.Config( "api.server:app", host=config.API_HOST, port=config.API_PORT, log_level="info", reload=False, ) server = uvicorn.Server(uvi_config) await server.serve() async def run_discord_bot(): """Discord Bot 실행.""" from api.discord_bot import start_bot await start_bot() async def main(): """API 서버 + Discord Bot 동시 실행.""" logger.info("=" * 50) logger.info("Variet Agent 시작") logger.info(f" API: http://{config.API_HOST}:{config.API_PORT}") logger.info(f" Discord Bot: {'토큰 설정됨' if config.DISCORD_BOT_TOKEN else '⚠ 토큰 없음'}") logger.info("=" * 50) tasks = [] # API 서버 tasks.append(asyncio.create_task(run_api_server())) # Discord Bot (토큰이 있을 때만) if config.DISCORD_BOT_TOKEN: tasks.append(asyncio.create_task(run_discord_bot())) else: logger.warning("DISCORD_BOT_TOKEN이 없습니다. Bot 없이 API만 실행합니다.") try: await asyncio.gather(*tasks) except KeyboardInterrupt: logger.info("종료 요청...") except Exception as e: logger.error(f"실행 오류: {e}") finally: # 정리 from api.discord_bot import stop_bot await stop_bot() logger.info("Variet Agent 종료") if __name__ == "__main__": try: asyncio.run(main()) except KeyboardInterrupt: pass