models + refactor
This commit is contained in:
81
aiws.py
81
aiws.py
@@ -23,6 +23,8 @@ from api.service.album_service import AlbumService
|
||||
from middlewares.album import AlbumMiddleware
|
||||
from middlewares.auth import AuthMiddleware
|
||||
from middlewares.dao import DaoMiddleware
|
||||
from scheduler.daily_scheduler import DailyScheduler
|
||||
from scheduler.telegram_admin_handler import create_daily_scheduler_router
|
||||
|
||||
# Репозитории и DAO
|
||||
from repos.char_repo import CharacterRepo
|
||||
@@ -108,7 +110,7 @@ dp["gemini"] = gemini
|
||||
# 1. Роутеры без мидлварей (например, auth)
|
||||
dp.include_router(auth_router)
|
||||
|
||||
# 2. Основные роутеры
|
||||
# 2. Основные роутеры (daily_scheduler router добавляется в lifespan)
|
||||
main_router = Router()
|
||||
dp.include_router(main_router)
|
||||
dp.include_router(assets_router)
|
||||
@@ -141,6 +143,34 @@ async def start_scheduler(service: GenerationService):
|
||||
logger.error(f"Scheduler error: {e}")
|
||||
await asyncio.sleep(60) # Check every 60 seconds
|
||||
|
||||
|
||||
def _build_daily_scheduler() -> DailyScheduler:
|
||||
"""Construct DailyScheduler; MetaAdapter is optional (needs env vars)."""
|
||||
meta_adapter = None
|
||||
if settings.META_ACCESS_TOKEN and settings.META_INSTAGRAM_ACCOUNT_ID:
|
||||
from adapters.meta_adapter import MetaAdapter
|
||||
meta_adapter = MetaAdapter(
|
||||
access_token=settings.META_ACCESS_TOKEN,
|
||||
instagram_account_id=settings.META_INSTAGRAM_ACCOUNT_ID,
|
||||
)
|
||||
logger.info("MetaAdapter initialized")
|
||||
else:
|
||||
logger.warning("META_ACCESS_TOKEN / META_INSTAGRAM_ACCOUNT_ID not set — Instagram publishing disabled")
|
||||
|
||||
if not settings.SCHEDULER_CHARACTER_ID:
|
||||
logger.warning("SCHEDULER_CHARACTER_ID not set — daily scheduler will error at runtime")
|
||||
|
||||
return DailyScheduler(
|
||||
dao=dao,
|
||||
gemini=gemini,
|
||||
s3_adapter=s3_adapter,
|
||||
generation_service=generation_service,
|
||||
bot=bot,
|
||||
admin_id=ADMIN_ID,
|
||||
character_id=settings.SCHEDULER_CHARACTER_ID or "",
|
||||
meta_adapter=meta_adapter,
|
||||
)
|
||||
|
||||
# --- LIFESPAN (Запуск FastAPI + Bot) ---
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
@@ -164,36 +194,39 @@ async def lifespan(app: FastAPI):
|
||||
|
||||
print("✅ DB & DAO initialized")
|
||||
|
||||
# 2. ЗАПУСК БОТА (в фоне)
|
||||
# Важно: handle_signals=False, чтобы бот не перехватывал сигналы остановки у uvicorn
|
||||
# Мы НЕ передаем сюда dao=..., так как он уже подключен через Middleware выше
|
||||
# polling_task = asyncio.create_task(
|
||||
# dp.start_polling(bot, handle_signals=False)
|
||||
# )
|
||||
# print("🤖 Bot polling started")
|
||||
# 2. Инициализация и регистрация daily_scheduler роутера
|
||||
daily_scheduler = _build_daily_scheduler()
|
||||
dp.include_router(create_daily_scheduler_router(daily_scheduler))
|
||||
print("📅 Daily scheduler router registered")
|
||||
|
||||
# 3. ЗАПУСК ШЕДУЛЕРА
|
||||
# 3. ЗАПУСК БОТА (в фоне)
|
||||
# handle_signals=False — бот не перехватывает сигналы остановки у uvicorn
|
||||
polling_task = asyncio.create_task(
|
||||
dp.start_polling(bot, handle_signals=False)
|
||||
)
|
||||
print("🤖 Bot polling started")
|
||||
|
||||
# 4. ЗАПУСК ШЕДУЛЕРОВ
|
||||
scheduler_task = asyncio.create_task(start_scheduler(generation_service))
|
||||
print("⏰ Scheduler started")
|
||||
daily_scheduler_task = asyncio.create_task(daily_scheduler.run_loop())
|
||||
print("⏰ Schedulers started")
|
||||
|
||||
yield
|
||||
|
||||
# --- SHUTDOWN ---
|
||||
print("🛑 Shutting down...")
|
||||
|
||||
# 4. Остановка шедулера
|
||||
scheduler_task.cancel()
|
||||
try:
|
||||
await scheduler_task
|
||||
except asyncio.CancelledError:
|
||||
print("⏰ Scheduler stopped")
|
||||
|
||||
# 3. Остановка бота
|
||||
# polling_task.cancel()
|
||||
# try:
|
||||
# await polling_task
|
||||
# except asyncio.CancelledError:
|
||||
# print("🤖 Bot polling stopped")
|
||||
|
||||
# Останавливаем все фоновые задачи
|
||||
for task, name in [
|
||||
(polling_task, "Bot polling"),
|
||||
(scheduler_task, "Stale-gen scheduler"),
|
||||
(daily_scheduler_task, "Daily scheduler"),
|
||||
]:
|
||||
task.cancel()
|
||||
try:
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
print(f"⏹ {name} stopped")
|
||||
|
||||
# 4. Отключение БД
|
||||
# Обычно Motor закрывать не обязательно при выходе, но хорошим тоном считается
|
||||
|
||||
Reference in New Issue
Block a user