import io import json import pandas as pd from fastapi import APIRouter, Depends, HTTPException from fastapi.responses import StreamingResponse from sqlalchemy.orm import Session from backend.app.db import get_db from backend.app.repositories.dataset_repo import get_dataset from backend.app.repositories.experiment_repo import get_experiment router = APIRouter(tags=["exports"]) @router.get("/exports/{experiment_id}") def export_experiment(experiment_id: str, db: Session = Depends(get_db)): experiment = get_experiment(db, experiment_id) if not experiment: raise HTTPException(status_code=404, detail="Experiment not found") dataset = get_dataset(db, experiment.dataset_id) if not dataset: raise HTTPException(status_code=404, detail="Dataset not found") if dataset.file_path.endswith(".csv"): df = pd.read_csv(dataset.file_path) else: df = pd.read_excel(dataset.file_path) summary = json.loads(experiment.summary_json) if experiment.summary_json else {} points = summary.get("points", []) export_df = df.copy() if points and len(points) == len(df): export_df["cluster_label"] = [p["cluster_label"] for p in points] export_df["pca_x"] = [p["x"] for p in points] export_df["pca_y"] = [p["y"] for p in points] metrics = json.loads(experiment.metrics_json) if experiment.metrics_json else {} for key, value in metrics.items(): export_df[f"metric_{key}"] = value buffer = io.StringIO() export_df.to_csv(buffer, index=False) buffer.seek(0) return StreamingResponse( iter([buffer.getvalue()]), media_type="text/csv", headers={"Content-Disposition": f"attachment; filename={experiment_id}_export.csv"}, )