Files
openrouter-watcher/src/openrouter_monitor/tasks/cleanup.py
Luca Sacchi Ricciardi 3ae5d736ce feat(tasks): T55-T58 implement background tasks for OpenRouter sync
- T55: Setup APScheduler with AsyncIOScheduler and @scheduled_job decorator
- T56: Implement hourly usage stats sync from OpenRouter API
- T57: Implement daily API key validation job
- T58: Implement weekly cleanup job for old usage stats
- Add usage_stats_retention_days config option
- Integrate scheduler with FastAPI lifespan events
- Add 26 unit tests for scheduler, sync, and cleanup tasks
- Add apscheduler to requirements.txt

The background tasks now automatically:
- Sync usage stats every hour from OpenRouter
- Validate API keys daily at 2 AM UTC
- Clean up old data weekly on Sunday at 3 AM UTC
2026-04-07 17:41:24 +02:00

60 lines
1.9 KiB
Python

"""Cleanup tasks for old data.
T58: Task to clean up old usage stats data.
"""
import logging
from datetime import datetime, timedelta
from apscheduler.triggers.cron import CronTrigger
from sqlalchemy import delete
from openrouter_monitor.database import SessionLocal
from openrouter_monitor.models.usage_stats import UsageStats
from openrouter_monitor.config import get_settings
from openrouter_monitor.tasks.scheduler import scheduled_job
logger = logging.getLogger(__name__)
settings = get_settings()
@scheduled_job(
CronTrigger(day_of_week='sun', hour=3, minute=0),
id='cleanup_old_usage_stats',
replace_existing=True
)
async def cleanup_old_usage_stats():
"""Clean up usage stats older than retention period.
Runs weekly on Sunday at 3:00 AM UTC.
Removes UsageStats records older than usage_stats_retention_days
(default: 365 days).
The retention period is configurable via the
USAGE_STATS_RETENTION_DAYS environment variable.
"""
logger.info("Starting cleanup of old usage stats")
try:
with SessionLocal() as db:
# Calculate cutoff date
retention_days = settings.usage_stats_retention_days
cutoff_date = datetime.utcnow().date() - timedelta(days=retention_days)
logger.info(f"Removing usage stats older than {cutoff_date}")
# Delete old records
stmt = delete(UsageStats).where(UsageStats.date < cutoff_date)
result = db.execute(stmt)
deleted_count = result.rowcount
db.commit()
logger.info(
f"Cleanup completed. Deleted {deleted_count} old usage stats records "
f"(retention: {retention_days} days)"
)
except Exception as e:
logger.error(f"Error in cleanup_old_usage_stats job: {e}")