Files
aza/AzA march 2026/workforce_planner/api/routes_ai.py

120 lines
3.5 KiB
Python
Raw Normal View History

2026-03-25 22:03:39 +01:00
# -*- coding: utf-8 -*-
"""API-Routen für KI-Services (Transkription, KG-Erstellung, Chat)."""
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form
from pydantic import BaseModel
from ..core.models import Employee
from .auth import get_current_user
from ..ai import service as ai_service
router = APIRouter(prefix="/ai", tags=["KI-Service"])
# ── Transkription ──────────────────────────────
class TranscribeResponse(BaseModel):
text: str
tokens_estimated: int
@router.post("/transcribe", response_model=TranscribeResponse)
async def transcribe(
file: UploadFile = File(...),
language: str = Form("de"),
_user: Employee = Depends(get_current_user),
):
if not file.filename or not file.filename.lower().endswith(".wav"):
raise HTTPException(400, "Nur WAV-Dateien erlaubt")
wav_bytes = await file.read()
if len(wav_bytes) > 50 * 1024 * 1024:
raise HTTPException(413, "Datei zu gross (max 50 MB)")
try:
result = ai_service.transcribe_audio(wav_bytes, language)
return TranscribeResponse(**result)
except RuntimeError as e:
raise HTTPException(503, str(e))
except Exception as e:
raise HTTPException(500, f"Transkription fehlgeschlagen: {e}")
# ── KG-Erstellung ─────────────────────────────
class SummarizeRequest(BaseModel):
transcript: str
system_prompt: str = ""
model: str = "gpt-4o"
class SummarizeResponse(BaseModel):
text: str
tokens_used: int
model: str
@router.post("/summarize", response_model=SummarizeResponse)
def summarize(
data: SummarizeRequest,
_user: Employee = Depends(get_current_user),
):
try:
result = ai_service.summarize_transcript(
data.transcript, data.system_prompt, data.model
)
return SummarizeResponse(**result)
except RuntimeError as e:
raise HTTPException(503, str(e))
except Exception as e:
raise HTTPException(500, f"Zusammenfassung fehlgeschlagen: {e}")
# ── KG-Merge ──────────────────────────────────
class MergeRequest(BaseModel):
existing_kg: str
full_transcript: str
system_prompt: str = ""
model: str = "gpt-4o"
@router.post("/merge", response_model=SummarizeResponse)
def merge_kg(
data: MergeRequest,
_user: Employee = Depends(get_current_user),
):
try:
result = ai_service.merge_kg(
data.existing_kg, data.full_transcript,
data.system_prompt, data.model,
)
return SummarizeResponse(**result)
except RuntimeError as e:
raise HTTPException(503, str(e))
except Exception as e:
raise HTTPException(500, f"Merge fehlgeschlagen: {e}")
# ── Generischer Chat ──────────────────────────
class ChatRequest(BaseModel):
messages: list[dict]
model: str = "gpt-4o"
@router.post("/chat", response_model=SummarizeResponse)
def chat_completion(
data: ChatRequest,
_user: Employee = Depends(get_current_user),
):
try:
result = ai_service.chat_completion(data.messages, data.model)
return SummarizeResponse(**result)
except RuntimeError as e:
raise HTTPException(503, str(e))
except Exception as e:
raise HTTPException(500, f"Chat fehlgeschlagen: {e}")