39474-vm/backend/app/main.py
2026-04-04 22:08:49 +05:00

127 lines
3.8 KiB
Python

import json
import os
from urllib.error import URLError
from urllib.request import Request, urlopen
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.routers import (
agencies,
analytics,
applications,
auth,
bank,
benefits,
chat,
complaints,
documents,
family,
forms,
legal,
tson,
voice,
)
app = FastAPI(title="SuperGov API")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # In prod, restrict to frontend URL
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(auth.router)
app.include_router(chat.router)
app.include_router(forms.router)
app.include_router(applications.router)
app.include_router(benefits.router)
app.include_router(complaints.router)
app.include_router(documents.router)
app.include_router(agencies.router)
app.include_router(voice.router)
app.include_router(analytics.router)
app.include_router(family.router)
app.include_router(bank.router)
app.include_router(tson.router)
app.include_router(legal.router)
@app.get("/health")
def health_check():
return {
"status": "ok",
"version": "1.0",
"agents": [
"OrchestratorAgent",
"NLPAgent",
"DocumentAgent",
"GuideAgent",
"RefusalAgent",
"BenefitsAgent",
"LawyerAgent"
]
}
@app.get("/health/integrations")
def health_integrations():
"""Локальная сводка: какие переменные заданы и отвечают ли внешние URL (без секретов)."""
stack_jwks_url = os.getenv("STACK_AUTH_JWKS_URL")
stack_jwks_ok = False
if stack_jwks_url:
try:
req = Request(stack_jwks_url, headers={"User-Agent": "SuperGov-health/1"})
with urlopen(req, timeout=8.0) as resp:
body = json.loads(resp.read().decode())
stack_jwks_ok = bool(body.get("keys"))
except (URLError, TimeoutError, OSError, ValueError, TypeError):
stack_jwks_ok = False
supabase_rest = "skipped"
if os.getenv("SUPABASE_URL") and os.getenv("SUPABASE_SERVICE_KEY"):
try:
from app.database import get_db
db = get_db()
db.table("users").select("id").limit(1).execute()
supabase_rest = "ok"
except Exception as e:
supabase_rest = f"error:{type(e).__name__}"
sendgrid_ready = bool(os.getenv("SENDGRID_API_KEY") and os.getenv("SENDGRID_FROM_EMAIL"))
twilio_ready = bool(
os.getenv("TWILIO_ACCOUNT_SID")
and os.getenv("TWILIO_AUTH_TOKEN")
and os.getenv("TWILIO_FROM_NUMBER")
)
return {
"supabase": {
"env_url": bool(os.getenv("SUPABASE_URL")),
"env_service_key": bool(os.getenv("SUPABASE_SERVICE_KEY")),
"rest_probe": supabase_rest,
},
"stack_auth": {
"env_project_id": bool(os.getenv("STACK_PROJECT_ID")),
"env_jwks_url": bool(stack_jwks_url),
"jwks_reachable": stack_jwks_ok,
},
"sendgrid": {
"env_api_key": bool(os.getenv("SENDGRID_API_KEY")),
"env_from_email": bool(os.getenv("SENDGRID_FROM_EMAIL")),
"otp_email_ready": sendgrid_ready,
},
"telegram": {
"env_bot_token": bool(os.getenv("TELEGRAM_BOT_TOKEN")),
"note": "Call NotificationService.send_telegram(chat_id, message) from your code; no route uses it yet.",
},
"twilio": {
"env_account_sid": bool(os.getenv("TWILIO_ACCOUNT_SID")),
"env_auth_token": bool(os.getenv("TWILIO_AUTH_TOKEN")),
"env_from_number": bool(os.getenv("TWILIO_FROM_NUMBER")),
"sms_ready": twilio_ready,
},
}