File size: 2,802 Bytes
a3953cb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
/**
 * bgremoveClient.ts — API client for the Background Removal feature.
 *
 * Completely independent of client.ts, upscaleClient.ts, and objectRemovalClient.ts.
 * Do not import from or share state with any other feature's client.
 *
 * URL note
 * --------
 * The backend stores result paths relative to STORAGE_DIR (e.g. "/bgremove/{id}/result.png").
 * The FastAPI StaticFiles mount is at /storage, so the full URL is:
 *   http://localhost:8000/storage/bgremove/{id}/result.png
 * Use buildBgRemoveUrl() to convert a stored relative path to a usable URL.
 */

export const BGREMOVE_API_BASE = import.meta.env.VITE_API_BASE ?? "http://localhost:8000";

/**
 * Convert a relative result path (e.g. "/bgremove/{id}/result.png") to the
 * full URL served by the FastAPI /storage StaticFiles mount.
 */
export function buildBgRemoveUrl(relPath: string): string {
  return `${BGREMOVE_API_BASE}/storage${relPath}`;
}

// ---------------------------------------------------------------------------
// Upload
// ---------------------------------------------------------------------------

/**
 * POST /bgremove/upload — submit an image for background removal.
 *
 * The backend applies EXIF correction, persists the image, and immediately
 * kicks off background inference.  Returns job_id; poll getBgRemoveResult()
 * to track progress.
 *
 * No options — background removal is always a single output: transparent PNG.
 */
export async function uploadForBgRemove(
  file: File,
): Promise<{ job_id: string }> {
  const formData = new FormData();
  formData.append("file", file);

  const response = await fetch(`${BGREMOVE_API_BASE}/bgremove/upload`, {
    method: "POST",
    body:   formData,
  });

  if (!response.ok) {
    let detail = `HTTP ${response.status}`;
    try {
      const json = await response.json();
      if (json?.detail) detail = json.detail;
    } catch { /* ignore */ }
    throw new Error(detail);
  }

  return response.json() as Promise<{ job_id: string }>;
}

// ---------------------------------------------------------------------------
// Result polling
// ---------------------------------------------------------------------------

export interface BgRemoveResult {
  job_id:           string;
  status:           "pending" | "processing" | "completed" | "failed";
  result_image_url: string | null;  // relative path, use buildBgRemoveUrl() for full URL
  error_message:    string | null;
}

/**
 * GET /bgremove/result/{job_id} — poll the current status of a bgremove job.
 */
export async function getBgRemoveResult(jobId: string): Promise<BgRemoveResult> {
  const response = await fetch(`${BGREMOVE_API_BASE}/bgremove/result/${jobId}`);
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return response.json() as Promise<BgRemoveResult>;
}