Spaces:
Runtime error
Runtime error
| import type { ModelType, PredictionClass } from "../context/AnalysisContext"; | |
| export interface ConfidenceScores { | |
| Healthy: number; | |
| MCI: number; | |
| AD: number; | |
| } | |
| export interface FoldPrediction { | |
| fold: number; | |
| prediction: PredictionClass; | |
| confidence: number; | |
| confidence_scores: ConfidenceScores; | |
| } | |
| export interface AnalyzeResponse { | |
| id: string; | |
| file_name: string; | |
| model: Exclude<ModelType, null>; | |
| prediction: PredictionClass; | |
| confidence: number; | |
| confidence_scores: ConfidenceScores; | |
| processed_at: string; | |
| spectrogram_image: string | null; | |
| scalogram_montage_image: string | null; | |
| spectrogram_channels: (string | null)[]; | |
| scalogram_channels: (string | null)[]; | |
| channel_0_image: string | null; | |
| channel_1_image: string | null; | |
| mock: boolean; | |
| fold_predictions: FoldPrediction[]; | |
| fold_vote_counts: Partial<Record<PredictionClass, number>>; | |
| ensemble_folds: number; | |
| ensemble_mode: string; | |
| } | |
| export interface TrialAnalysisResult { | |
| id: string; | |
| file_name: string; | |
| trial_no: number | null; | |
| prediction: PredictionClass; | |
| confidence: number; | |
| confidence_scores: ConfidenceScores; | |
| spectrogram_image: string | null; | |
| scalogram_montage_image: string | null; | |
| spectrogram_channels: (string | null)[]; | |
| scalogram_channels: (string | null)[]; | |
| mock: boolean; | |
| fold_predictions: FoldPrediction[]; | |
| fold_vote_counts: Partial<Record<PredictionClass, number>>; | |
| ensemble_folds: number; | |
| ensemble_mode: string; | |
| } | |
| export interface PatientAnalyzeResponse { | |
| id: string; | |
| patient_id: string; | |
| model: Exclude<ModelType, null>; | |
| prediction: PredictionClass; | |
| confidence: number; | |
| confidence_scores: ConfidenceScores; | |
| vote_counts: Partial<Record<PredictionClass, number>>; | |
| trial_count: number; | |
| agreement_ratio: number; | |
| processed_at: string; | |
| trial_results: TrialAnalysisResult[]; | |
| mock: boolean; | |
| } | |
| const API_BASE = import.meta.env.VITE_API_URL ?? ""; | |
| export class AnalysisApiError extends Error { | |
| constructor( | |
| message: string, | |
| public status?: number, | |
| ) { | |
| super(message); | |
| this.name = "AnalysisApiError"; | |
| } | |
| } | |
| export async function analyzeEeg(file: File, model: Exclude<ModelType, null>): Promise<AnalyzeResponse> { | |
| const formData = new FormData(); | |
| formData.append("file", file); | |
| formData.append("model", model); | |
| const response = await fetch(`${API_BASE}/api/analyze`, { | |
| method: "POST", | |
| body: formData, | |
| }); | |
| if (!response.ok) { | |
| let detail = "Analysis request failed."; | |
| try { | |
| const body = await response.json(); | |
| if (typeof body.detail === "string") { | |
| detail = body.detail; | |
| } else if (Array.isArray(body.detail)) { | |
| detail = body.detail.map((d: { msg?: string }) => d.msg).filter(Boolean).join(", ") || detail; | |
| } | |
| } catch { | |
| if (response.status === 500) { | |
| detail = "Server error — ensure the backend is running and USE_MOCK_INFERENCE=true in backend/.env"; | |
| } | |
| } | |
| throw new AnalysisApiError(detail, response.status); | |
| } | |
| return response.json(); | |
| } | |
| export async function analyzePatientEeg( | |
| files: File[], | |
| model: Exclude<ModelType, null>, | |
| ): Promise<PatientAnalyzeResponse> { | |
| const formData = new FormData(); | |
| files.forEach((file) => formData.append("files", file)); | |
| formData.append("model", model); | |
| const response = await fetch(`${API_BASE}/api/analyze/patient`, { | |
| method: "POST", | |
| body: formData, | |
| }); | |
| if (!response.ok) { | |
| let detail = "Patient analysis request failed."; | |
| try { | |
| const body = await response.json(); | |
| if (typeof body.detail === "string") { | |
| detail = body.detail; | |
| } else if (Array.isArray(body.detail)) { | |
| detail = body.detail.map((d: { msg?: string }) => d.msg).filter(Boolean).join(", ") || detail; | |
| } | |
| } catch { | |
| if (response.status === 404) { | |
| detail = "Patient endpoint not found — restart the backend (npm run dev:backend)."; | |
| } else if (response.status === 500) { | |
| detail = "Server error — restart the backend and try again."; | |
| } | |
| } | |
| throw new AnalysisApiError(detail, response.status); | |
| } | |
| return response.json(); | |
| } | |
| export async function checkApiHealth(): Promise<boolean> { | |
| try { | |
| const response = await fetch(`${API_BASE}/api/health`); | |
| return response.ok; | |
| } catch { | |
| return false; | |
| } | |
| } | |
| export interface ModelStatusItem { | |
| name: Exclude<ModelType, null>; | |
| loaded: boolean; | |
| weights_found: boolean; | |
| weights_path: string; | |
| } | |
| export interface ModelsStatusResponse { | |
| models: ModelStatusItem[]; | |
| use_mock_inference: boolean; | |
| fusion_detail: Record<string, unknown> | null; | |
| } | |
| export async function fetchModelsStatus(): Promise<ModelsStatusResponse | null> { | |
| try { | |
| const response = await fetch(`${API_BASE}/api/models/status`); | |
| if (!response.ok) return null; | |
| return response.json(); | |
| } catch { | |
| return null; | |
| } | |
| } | |