"""Синхронный запуск пайплайна для одного видео (для длинных видео и плейлистов используйте /jobs — этот эндпоинт держит HTTP-соединение открытым). """ from __future__ import annotations from fastapi import APIRouter, HTTPException from pydantic import BaseModel from api.lib.llm import LLMConfig from api.lib.processing import PipelineError, process_single_video router = APIRouter(prefix="/pipeline", tags=["pipeline"]) class LLMOverride(BaseModel): base_url: str api_key: str = "" model: str timeout: int = 120 max_tokens: int = 1000 temperature: float = 0.3 extra_headers: dict[str, str] = {} system_prompt: str | None = None user_template: str | None = None class ProcessRequest(BaseModel): url: str model_path: str | None = None # None → из настроек summary_max_sentences: int | None = None keep_video: bool | None = None section_id: int | None = None # Если задано — используется этот LLM; иначе сохранённые настройки/env; # иначе встроенная экстрактивная выжимка. llm: LLMOverride | None = None class ProcessResponse(BaseModel): uuid: str title: str source_url: str video_path: str text_full_path: str text_summary_path: str transcription_method: str summary_preview: str @router.post("/process", response_model=ProcessResponse) async def process_video(req: ProcessRequest): llm_cfg = None sys_p = user_t = None if req.llm is not None: llm_cfg = LLMConfig( base_url=req.llm.base_url, api_key=req.llm.api_key, model=req.llm.model, timeout=req.llm.timeout, max_tokens=req.llm.max_tokens, temperature=req.llm.temperature, extra_headers=req.llm.extra_headers, ) sys_p = req.llm.system_prompt user_t = req.llm.user_template try: result = await process_single_video( req.url, model_path=req.model_path, summary_max_sentences=req.summary_max_sentences, keep_video=req.keep_video, section_id=req.section_id, llm_cfg=llm_cfg, system_prompt=sys_p, user_template=user_t, ) except PipelineError as e: raise HTTPException(status_code=e.status, detail=str(e)) return ProcessResponse(**result)