llm-ready-data / app /api /server.py
light-infer-chat's picture
ok
2ebf97a
Raw
History Blame
3.8 kB
from __future__ import annotations
import asyncio
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.gzip import GZipMiddleware
from app.config import get_settings
from app.core.database import pool_manager
from app.core.logger import get_logger
from app.core.redis_client import create_redis_client, close_redis
from app.core.scripts import load_scripts
from app.services.embeddings_service import EmbeddingService
from app.api.v1.router import api_v1_router
_logger = get_logger(__name__)
_settings = get_settings()
_embedding_service: EmbeddingService = EmbeddingService()
async def _self_ping():
import httpx
health_url = _settings.self_ping_url
while True:
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(health_url)
if response.status_code == 200:
_logger.info("Self-ping successful: %s", health_url)
else:
_logger.warning("Self-ping returned: %s - %s", health_url, response.status_code)
except Exception as exc:
_logger.error("Self-ping error: %s", exc)
await asyncio.sleep(900)
@asynccontextmanager
async def lifespan(app: FastAPI):
_logger.info("Initializing embedding service (loading 384-dim model)...")
loop = asyncio.get_running_loop()
await loop.run_in_executor(None, _embedding_service.load_model, 384)
# await loop.run_in_executor(None, _embedding_service.load_vision_model) # DISABLED (OOM mitigation)
_logger.info("Embedding service initialized with dims: %s", _embedding_service.loaded_dimensions)
redis = create_redis_client(_settings.redis_url) if _settings.redis_url else None
scripts = await load_scripts(redis) if redis else {}
app.state.redis = redis
app.state.scripts = scripts
if redis:
_logger.info("Redis and Lua scripts initialized")
else:
_logger.warning("Redis not configured, running in degraded mode")
asyncio.create_task(_self_ping())
yield
_logger.info("Shutting down...")
await close_redis(redis)
await pool_manager.close_all()
def create_application() -> FastAPI:
app = FastAPI(
title=_settings.app_name,
description="All API Collection - Document extraction, conversion, and database query API.",
version=_settings.app_version,
docs_url="/docs",
redoc_url="/redoc",
openapi_tags=[
{"name": "Convert", "description": "Single-file and single-URL conversion"},
{"name": "Batch", "description": "Bulk conversion of files and URLs"},
{"name": "System", "description": "Health, info, and supported formats"},
{"name": "Embeddings", "description": "Text embedding generation using transformer models"},
{"name": "Verify", "description": "Phone number and identity verification"},
],
lifespan=lifespan,
)
app.add_middleware(GZipMiddleware, minimum_size=1000)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(api_v1_router, prefix="/api/v1")
@app.get("/", include_in_schema=False)
async def root():
return {"message": f"{_settings.app_name} v{_settings.app_version} is running"}
@app.get("/health", include_in_schema=False)
async def root_health():
return {"status": "ok", "version": _settings.app_version}
@app.get("/ping", include_in_schema=False)
async def ping():
return {"name": f"{_settings.app_name}", "version": _settings.app_version}
return app
app = create_application()