Spaces:
Sleeping
Sleeping
File size: 5,481 Bytes
4a0e21d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | 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<T>(
endpoint: string,
options: RequestInit = {}
): Promise<T> {
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<HealthResponse> {
return this.request<HealthResponse>("/api/v1/health");
}
// System information
async getSystemInfo(): Promise<SystemInfo> {
return this.request<SystemInfo>("/api/v1/system");
}
// Model management
async getModels(): Promise<ModelInfo[]> {
return this.request<ModelInfo[]>("/api/v1/models");
}
// Spectrum analysis
async analyzeSpectrum(request: AnalysisRequest): Promise<PredictionResult> {
return this.request<PredictionResult>("/api/v1/analyze", {
method: "POST",
body: JSON.stringify(request),
});
}
async analyzeBatch(
request: BatchAnalysisRequest
): Promise<BatchPredictionResult> {
return this.request<BatchPredictionResult>("/api/v1/analyze/batch", {
method: "POST",
body: JSON.stringify(request),
});
}
async compareModels(request: ComparisonRequest): Promise<ComparisonResult> {
return this.request<ComparisonResult>("/api/v1/compare", {
method: "POST",
body: JSON.stringify(request),
});
}
// Explainability
async explainSpectrum(request: AnalysisRequest): Promise<any> {
return this.request<any>("/api/v1/explain", {
method: "POST",
body: JSON.stringify(request),
});
}
async explainBatch(request: BatchAnalysisRequest): Promise<any> {
return this.request<any>("/api/v1/explain/batch", {
method: "POST",
body: JSON.stringify(request),
});
}
// File upload
async uploadSpectrum(file: File): Promise<SpectrumData> {
const formData = new FormData();
formData.append("file", file);
return this.request<SpectrumData>("/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),
};
};
|