59 lines
1.7 KiB
Python
59 lines
1.7 KiB
Python
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}
|