Files
siemens_ragas/webapp/api/evaluations.py
wangwei e89695e490 Add RAGAS evaluation web console (FastAPI + vanilla JS)
- webapp/: FastAPI backend with runs/scenarios/evaluations API routers;
  services for run_reader, report_builder, scenario_scanner, task_manager
  (lazy ragas import — server boots even without ragas); Pydantic models
- webapp/static/: single-page console (layout A: left-nav + main area);
  report detail with metric cards, Chart.js distribution histogram,
  grouping table, lowest-score sample review; trigger evaluation + log polling
- webmain.py: uvicorn entry point (alongside existing main.py CLI)
- start.bat: Windows one-click launcher with env checks and auto-browser open
- rag_eval/datasets/: implement missing loader + normalizer modules
  (load_dataset_records, normalize_records) required by evaluator
- scripts/seed_sample_run.py: generate realistic demo run artifacts
- .gitignore: exclude datasets/ data files but keep rag_eval/datasets/ source

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2026-06-15 15:53:57 +08:00

45 lines
1.5 KiB
Python

"""Routes for triggering evaluations and polling background task status."""
from __future__ import annotations
from fastapi import APIRouter, HTTPException
from webapp.models import (
TaskStatus,
TriggerEvaluationRequest,
TriggerEvaluationResponse,
)
from webapp.services import scenario_scanner
from webapp.services.task_manager import task_manager
router = APIRouter(prefix="/api/evaluations", tags=["evaluations"])
@router.post("", response_model=TriggerEvaluationResponse)
def trigger_evaluation(request: TriggerEvaluationRequest) -> TriggerEvaluationResponse:
"""Validate the scenario path and queue a background evaluation task."""
resolved = scenario_scanner.resolve_scenario_path(request.scenario_path)
if resolved is None:
raise HTTPException(
status_code=400,
detail=f"无效或不允许的场景路径: {request.scenario_path}",
)
task_id = task_manager.submit(request.scenario_path)
return TriggerEvaluationResponse(task_id=task_id)
@router.get("/{task_id}", response_model=TaskStatus)
def get_task_status(task_id: str) -> TaskStatus:
"""Return the current status and logs for one evaluation task."""
status = task_manager.get(task_id)
if status is None:
raise HTTPException(status_code=404, detail=f"未找到任务: {task_id}")
return status
@router.get("", response_model=dict)
def list_tasks() -> dict[str, list]:
"""Return all known evaluation tasks for this server session."""
return {"tasks": [task.model_dump() for task in task_manager.list_tasks()]}