import logging from contextlib import asynccontextmanager from fastapi import Depends, FastAPI, HTTPException, Header from pydantic import BaseModel, Field from app import calling from app.config import settings logging.basicConfig(level=logging.INFO) logger = logging.getLogger("callsvc.main") @asynccontextmanager async def lifespan(_: FastAPI): await calling.start() yield await calling.stop() app = FastAPI(title="Telegram Call Service", lifespan=lifespan) class CallRequest(BaseModel): text: str = Field(..., min_length=1, max_length=2000, description="Текст для озвучки TTS") target: int | str | None = Field( default=None, description=( "Кому звонить: @username или numeric user id. " "Если не задан — берётся CALL_TARGET из .env" ), ) def check_auth(authorization: str | None = Header(default=None)): if not settings.api_token: return expected = f"Bearer {settings.api_token}" if authorization != expected: raise HTTPException(status_code=401, detail="Invalid or missing bearer token") @app.get("/health") async def health(): return {"status": "ok"} @app.post("/call", dependencies=[Depends(check_auth)]) async def call(req: CallRequest): try: result = await calling.make_call(req.text, req.target) except RuntimeError as exc: raise HTTPException(status_code=409, detail=str(exc)) from exc except Exception as exc: # noqa: BLE001 logger.exception("Call failed") raise HTTPException(status_code=500, detail=str(exc)) from exc return {"status": "called", **result}