File size: 2,032 Bytes
fbf73ff
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import type { CasesResponse, SegmentResponse } from '../types'

function getApiBase(): string {
  const url = import.meta.env.VITE_API_URL

  // In production, VITE_API_URL must be set - fail fast with clear error
  if (import.meta.env.PROD && !url) {
    throw new Error(
      'VITE_API_URL environment variable is required in production. ' +
        'Set it to the backend API URL (e.g., https://your-app.hf.space).'
    )
  }

  // In development, fall back to localhost
  return url || 'http://localhost:7860'
}

const API_BASE = getApiBase()

export class ApiError extends Error {
  status: number
  detail?: string

  constructor(message: string, status: number, detail?: string) {
    super(message)
    this.name = 'ApiError'
    this.status = status
    this.detail = detail
  }
}

class ApiClient {
  private baseUrl: string

  constructor(baseUrl: string) {
    this.baseUrl = baseUrl
  }

  async getCases(signal?: AbortSignal): Promise<CasesResponse> {
    const response = await fetch(`${this.baseUrl}/api/cases`, { signal })

    if (!response.ok) {
      const error = await response.json().catch(() => ({}))
      throw new ApiError(
        `Failed to fetch cases: ${response.statusText}`,
        response.status,
        error.detail
      )
    }

    return response.json()
  }

  async runSegmentation(
    caseId: string,
    fastMode: boolean = true,
    signal?: AbortSignal
  ): Promise<SegmentResponse> {
    const response = await fetch(`${this.baseUrl}/api/segment`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        case_id: caseId,
        fast_mode: fastMode,
      }),
      signal,
    })

    if (!response.ok) {
      const error = await response.json().catch(() => ({}))
      throw new ApiError(
        `Segmentation failed: ${error.detail || response.statusText}`,
        response.status,
        error.detail
      )
    }

    return response.json()
  }
}

export const apiClient = new ApiClient(API_BASE)