File size: 1,528 Bytes
abdafa3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
/**
 * API client for ChestAI backend.
 * Uses axios with typed responses matching the FastAPI Pydantic schemas.
 */

import axios from "axios";

const API_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:7860";

export interface FindingResult {
  name: string;
  probability: number;
  uncertainty: number;
  present: boolean;
  high_uncertainty: boolean;
}

export interface PredictionResponse {
  findings: FindingResult[];
  entropy: number;
  report: string;
  gradcam_available: boolean;
  gradcam_classes: string[];
  inference_time_ms: number;
  model_version: string;
}

export async function analyzeXray(
  file: File,
  patientAge?: number,
  patientGender?: string
): Promise<PredictionResponse> {
  const formData = new FormData();
  formData.append("file", file);
  if (patientAge !== undefined) formData.append("patient_age", String(patientAge));
  if (patientGender) formData.append("patient_gender", patientGender);

  const { data } = await axios.post<PredictionResponse>(
    `${API_URL}/api/v1/predict`,
    formData,
    { headers: { "Content-Type": "multipart/form-data" }, timeout: 60000 }
  );
  return data;
}

export function getGradCAMUrl(sessionId: string, className: string): string {
  return `${API_URL}/api/v1/gradcam/${sessionId}/${encodeURIComponent(className)}`;
}

export async function checkHealth(): Promise<boolean> {
  try {
    const { data } = await axios.get(`${API_URL}/health`, { timeout: 5000 });
    return data.model_loaded === true;
  } catch {
    return false;
  }
}