import { components, operations } from "./types/api"; // Type aliases for better readability export type SpectrumData = components["schemas"]["SpectrumData"]; export type PredictionResult = components["schemas"]["PredictionResult"]; export type BatchPredictionResult = components["schemas"]["BatchPredictionResult"]; export type ComparisonResult = components["schemas"]["ComparisonResult"]; export type ModelInfo = components["schemas"]["ModelInfo"]; export type SystemInfo = components["schemas"]["SystemInfo"]; export type AnalysisRequest = components["schemas"]["AnalysisRequest"]; export type BatchAnalysisRequest = components["schemas"]["BatchAnalysisRequest"]; export type ComparisonRequest = components["schemas"]["ComparisonRequest"]; // API Response types type HealthResponse = { status: string; timestamp: string }; export class ApiClient { private getBaseUrl(): string { // If we're in a browser and on localhost... if (typeof window !== "undefined" && window.location.hostname === "localhost") { // If we're already on port 7860 (Container/Sandbox), use relative paths if (window.location.port === "7860") return ""; // If we're on port 3000 (React Dev Mode), point to the backend dev port if (window.location.port === "3000") return "http://localhost:8000"; } // Default for HF Spaces and all other deployments return ""; } private async request( endpoint: string, options: RequestInit = {} ): Promise { const base = this.getBaseUrl(); const url = endpoint.startsWith("/") ? `${base}${endpoint}` : `${base}/${endpoint}`; const res = await fetch(url, { headers: { "Content-Type": "application/json" }, ...options, }); if (!res.ok) { const text = await res.text(); throw new Error(`HTTP ${res.status}: ${text}`); } return (await res.json()) as T; } // Health endpoints async health(): Promise { return this.request("/api/v1/health"); } // System information async getSystemInfo(): Promise { return this.request("/api/v1/system"); } // Model management async getModels(): Promise { return this.request("/api/v1/models"); } // Spectrum analysis async analyzeSpectrum(request: AnalysisRequest): Promise { return this.request("/api/v1/analyze", { method: "POST", body: JSON.stringify(request), }); } async analyzeBatch( request: BatchAnalysisRequest ): Promise { return this.request("/api/v1/analyze/batch", { method: "POST", body: JSON.stringify(request), }); } async compareModels(request: ComparisonRequest): Promise { return this.request("/api/v1/compare", { method: "POST", body: JSON.stringify(request), }); } // Explainability async explainSpectrum(request: AnalysisRequest): Promise { return this.request("/api/v1/explain", { method: "POST", body: JSON.stringify(request), }); } async explainBatch(request: BatchAnalysisRequest): Promise { return this.request("/api/v1/explain/batch", { method: "POST", body: JSON.stringify(request), }); } // File upload async uploadSpectrum(file: File): Promise { const formData = new FormData(); formData.append("file", file); return this.request("/api/v1/upload", { method: "POST", body: formData, headers: {}, // Remove Content-Type to let browser set it for FormData }); } } // Create and export a default instance export const apiClient = new ApiClient(); export interface FeatureImportance { method: string; top_features: { indices: number[]; values: number[]; }; summary: { max_importance: number; mean_importance: number; important_region_start: number; important_region_end: number; }; importance_scores: number[]; // <-- Add this line } export interface ExplanationResult { prediction: number; // The predicted class index (e.g., 0 or 1) confidence: number; probabilities: number[]; // Array of probabilities for each class class_labels: { [key: number]: string }; // Maps class index to a string name (e.g., {0: 'stable', 1: 'weathered'}) feature_importance: FeatureImportance; model_used: string; spectrum_filename: string; } // Export individual client methods as hooks-ready functions export const useApiClient = () => { return { health: () => apiClient.health(), getSystemInfo: () => apiClient.getSystemInfo(), getModels: () => apiClient.getModels(), analyzeSpectrum: (request: AnalysisRequest) => apiClient.analyzeSpectrum(request), analyzeBatch: (request: BatchAnalysisRequest) => apiClient.analyzeBatch(request), compareModels: (request: ComparisonRequest) => apiClient.compareModels(request), explainSpectrum: (request: AnalysisRequest) => apiClient.explainSpectrum(request), explainBatch: (request: BatchAnalysisRequest) => apiClient.explainBatch(request), uploadSpectrum: (file: File) => apiClient.uploadSpectrum(file), }; };