google-api-python-client==2.157.0

# PDF generation
weasyprint==62.3
pydyf==0.11.0  # weasyprint 62.3 incompatible with pydyf 0.12+ ('transform' removed)

# Templates / email
jinja2==3.1.5
beautifulsoup4==4.12.3
lxml==5.3.0
bleach==6.2.0

# HTTP / testing
httpx==0.28.1
pytest==8.3.4
pytest-asyncio==0.25.0

# Utility
python-dateutil==2.9.0.post0
slowapi==0.1.9
---main tail---
app.include_router(dashboard.router)
app.include_router(suppression.router)
app.include_router(settings_router.router)
app.include_router(logs.router)
app.include_router(unsub_router.router)

app.mount("/static", StaticFiles(directory="static"), name="static")


@app.get("/api/health")
async def health():
    from app.db.session import check_db_health
    import redis as redis_lib
    db_ok = check_db_health()
    try:
        r = redis_lib.from_url(settings.REDIS_URL, socket_timeout=1)
        r.ping()
        redis_ok = True
    except Exception:
        redis_ok = False
    return {"status": "ok" if db_ok and redis_ok else "degraded",
            "database": "up" if db_ok else "down", "redis": "up" if redis_ok else "down"}


# Frontend SPA-ish pages
@app.get("/", include_in_schema=False)
async def index():
    return FileResponse("static/index.html")


@app.get("/{page}", include_in_schema=False)
async def page(page: str):
    import os
    safe = page.replace("/", "")
    path = f"static/{safe}.html"
    if os.path.exists(path):
