177 lines
5.0 KiB
Python
177 lines
5.0 KiB
Python
|
|
"""
|
|||
|
|
ERV Insurance Platform - FastAPI Backend
|
|||
|
|
"""
|
|||
|
|
from fastapi import FastAPI
|
|||
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|||
|
|
from fastapi.responses import JSONResponse
|
|||
|
|
from app.config import settings
|
|||
|
|
import redis
|
|||
|
|
import asyncpg
|
|||
|
|
|
|||
|
|
# Создаём FastAPI приложение
|
|||
|
|
app = FastAPI(
|
|||
|
|
title="ERV Insurance Platform API",
|
|||
|
|
description="API для обработки страховых обращений с OCR, AI и интеграциями",
|
|||
|
|
version="1.0.0",
|
|||
|
|
docs_url="/docs",
|
|||
|
|
redoc_url="/redoc"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# CORS middleware
|
|||
|
|
app.add_middleware(
|
|||
|
|
CORSMiddleware,
|
|||
|
|
allow_origins=settings.cors_origins,
|
|||
|
|
allow_credentials=True,
|
|||
|
|
allow_methods=["*"],
|
|||
|
|
allow_headers=["*"],
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ============================================
|
|||
|
|
# HEALTH CHECKS
|
|||
|
|
# ============================================
|
|||
|
|
|
|||
|
|
@app.get("/")
|
|||
|
|
async def root():
|
|||
|
|
"""Главная страница API"""
|
|||
|
|
return {
|
|||
|
|
"message": "🚀 ERV Insurance Platform API",
|
|||
|
|
"version": "1.0.0",
|
|||
|
|
"docs": f"{settings.backend_url}/docs",
|
|||
|
|
"status": "running"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
@app.get("/health")
|
|||
|
|
async def health_check():
|
|||
|
|
"""Проверка здоровья сервисов"""
|
|||
|
|
health_status = {
|
|||
|
|
"api": "ok",
|
|||
|
|
"redis": "checking",
|
|||
|
|
"postgres": "checking",
|
|||
|
|
"ocr": "checking"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# Проверка Redis
|
|||
|
|
try:
|
|||
|
|
r = redis.Redis(
|
|||
|
|
host=settings.redis_host,
|
|||
|
|
port=settings.redis_port,
|
|||
|
|
password=settings.redis_password,
|
|||
|
|
decode_responses=True
|
|||
|
|
)
|
|||
|
|
r.ping()
|
|||
|
|
health_status["redis"] = "ok"
|
|||
|
|
except Exception as e:
|
|||
|
|
health_status["redis"] = f"error: {str(e)}"
|
|||
|
|
|
|||
|
|
# Проверка PostgreSQL
|
|||
|
|
try:
|
|||
|
|
conn = await asyncpg.connect(
|
|||
|
|
host=settings.postgres_host,
|
|||
|
|
port=settings.postgres_port,
|
|||
|
|
database=settings.postgres_db,
|
|||
|
|
user=settings.postgres_user,
|
|||
|
|
password=settings.postgres_password
|
|||
|
|
)
|
|||
|
|
await conn.execute("SELECT 1")
|
|||
|
|
await conn.close()
|
|||
|
|
health_status["postgres"] = "ok"
|
|||
|
|
except Exception as e:
|
|||
|
|
health_status["postgres"] = f"error: {str(e)}"
|
|||
|
|
|
|||
|
|
# Проверка OCR
|
|||
|
|
import httpx
|
|||
|
|
try:
|
|||
|
|
async with httpx.AsyncClient() as client:
|
|||
|
|
response = await client.get(f"{settings.ocr_api_url}/", timeout=5.0)
|
|||
|
|
health_status["ocr"] = "ok" if response.status_code in [200, 404] else "unreachable"
|
|||
|
|
except Exception as e:
|
|||
|
|
health_status["ocr"] = f"error: {str(e)}"
|
|||
|
|
|
|||
|
|
all_ok = all(v == "ok" for v in health_status.values())
|
|||
|
|
|
|||
|
|
return JSONResponse(
|
|||
|
|
status_code=200 if all_ok else 503,
|
|||
|
|
content={
|
|||
|
|
"status": "healthy" if all_ok else "degraded",
|
|||
|
|
"services": health_status
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ============================================
|
|||
|
|
# API V1 ENDPOINTS
|
|||
|
|
# ============================================
|
|||
|
|
|
|||
|
|
@app.get("/api/v1/test")
|
|||
|
|
async def test_endpoint():
|
|||
|
|
"""Тестовый endpoint"""
|
|||
|
|
return {
|
|||
|
|
"message": "✅ API работает!",
|
|||
|
|
"env": settings.app_env,
|
|||
|
|
"debug": settings.debug,
|
|||
|
|
"services": {
|
|||
|
|
"redis": f"{settings.redis_host}:{settings.redis_port}",
|
|||
|
|
"postgres": f"{settings.postgres_host}:{settings.postgres_port}",
|
|||
|
|
"rabbitmq": f"{settings.rabbitmq_host}:{settings.rabbitmq_port}",
|
|||
|
|
"ocr": settings.ocr_api_url
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
@app.get("/api/v1/info")
|
|||
|
|
async def get_info():
|
|||
|
|
"""Информация о платформе"""
|
|||
|
|
return {
|
|||
|
|
"platform": "ERV Insurance Claims",
|
|||
|
|
"version": "1.0.0",
|
|||
|
|
"features": [
|
|||
|
|
"OCR документов (паспорт, билеты)",
|
|||
|
|
"AI автозаполнение (Gemini Vision)",
|
|||
|
|
"Проверка рейсов (FlightAware)",
|
|||
|
|
"СБП выплаты",
|
|||
|
|
"Интеграция с CRM"
|
|||
|
|
],
|
|||
|
|
"tech_stack": {
|
|||
|
|
"backend": "Python FastAPI",
|
|||
|
|
"frontend": "React TypeScript",
|
|||
|
|
"database": "PostgreSQL + MySQL",
|
|||
|
|
"cache": "Redis",
|
|||
|
|
"queue": "RabbitMQ",
|
|||
|
|
"storage": "S3 Timeweb",
|
|||
|
|
"ocr": "Internal Service",
|
|||
|
|
"ai": "OpenRouter Gemini 2.0"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ============================================
|
|||
|
|
# STARTUP/SHUTDOWN
|
|||
|
|
# ============================================
|
|||
|
|
|
|||
|
|
@app.on_event("startup")
|
|||
|
|
async def startup_event():
|
|||
|
|
"""При старте приложения"""
|
|||
|
|
print("🚀 ERV Insurance Platform запускается...")
|
|||
|
|
print(f"📍 Backend URL: {settings.backend_url}")
|
|||
|
|
print(f"📍 API Docs: {settings.backend_url}/docs")
|
|||
|
|
print(f"🔗 Frontend URL: {settings.frontend_url}")
|
|||
|
|
|
|||
|
|
|
|||
|
|
@app.on_event("shutdown")
|
|||
|
|
async def shutdown_event():
|
|||
|
|
"""При остановке приложения"""
|
|||
|
|
print("👋 ERV Insurance Platform остановлен")
|
|||
|
|
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
import uvicorn
|
|||
|
|
uvicorn.run(
|
|||
|
|
"main:app",
|
|||
|
|
host="0.0.0.0",
|
|||
|
|
port=8100,
|
|||
|
|
reload=True
|
|||
|
|
)
|
|||
|
|
|