Spaces:
Sleeping
Sleeping
Download frontend/src/api/client.ts from junyoung137/image-tool: direct link, hf CLI and curl.
- Browser
- Download file 4.54 kB
-
https://huggingface.co/spaces/junyoung137/image-tool/resolve/main/frontend/src/api/client.ts
- Command line
-
hf download hf://spaces/junyoung137/image-tool/frontend/src/api/client.ts
-
curl -L -o client.ts https://huggingface.co/spaces/junyoung137/image-tool/resolve/main/frontend/src/api/client.ts
4.54 kB
| export const API_BASE = import.meta.env.VITE_API_BASE ?? "http://localhost:8000"; | |
| // --------------------------------------------------------------------------- | |
| // Types | |
| // --------------------------------------------------------------------------- | |
| export interface StepSummary { | |
| step_number: number; | |
| status: "pending" | "processing" | "completed" | "failed"; | |
| original_image_url: string | null; | |
| result_image_url: string | null; | |
| error_message: string | null; | |
| } | |
| // --------------------------------------------------------------------------- | |
| // Upload | |
| // --------------------------------------------------------------------------- | |
| /** | |
| * Upload an image file to the backend. | |
| * POSTs as multipart/form-data; backend applies EXIF rotation, saves step 0, | |
| * and returns the job_id. | |
| */ | |
| export async function uploadImage(file: File): Promise<{ job_id: string }> { | |
| const formData = new FormData(); | |
| formData.append("file", file); | |
| const response = await fetch(`${API_BASE}/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 }>; | |
| } | |
| // --------------------------------------------------------------------------- | |
| // Generate | |
| // --------------------------------------------------------------------------- | |
| /** | |
| * POST /generate — send the mask JSON to the backend and start inpainting. | |
| * | |
| * The backend creates a new step (truncating any forward history if needed), | |
| * starts inference in a BackgroundTask, and returns immediately. | |
| */ | |
| export async function generateMask( | |
| jobId: string, | |
| maskJson: object, | |
| maskSource: "manual" | "ocr" | "mixed" = "manual", | |
| ): Promise<{ job_id: string; step_number: number; status: string }> { | |
| const response = await fetch(`${API_BASE}/generate`, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ | |
| job_id: jobId, | |
| mask_source: maskSource, | |
| mask_json: maskJson, | |
| }), | |
| }); | |
| 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; step_number: number; status: string }>; | |
| } | |
| // --------------------------------------------------------------------------- | |
| // Result polling | |
| // --------------------------------------------------------------------------- | |
| /** | |
| * GET /result/{job_id} — poll current job state. | |
| * | |
| * Returns top-level `status` / `error_message` for the current step | |
| * (backward-compatible with the polling hook), plus the full `steps[]` array | |
| * and `current_step` for the multi-step history navigator. | |
| */ | |
| export async function getJobResult(jobId: string): Promise<{ | |
| job_id: string; | |
| current_step: number; | |
| status: "pending" | "processing" | "completed" | "failed"; | |
| result_image_url: string | null; | |
| original_image_url: string | null; | |
| error_message: string | null; | |
| steps: StepSummary[]; | |
| }> { | |
| const response = await fetch(`${API_BASE}/result/${jobId}`); | |
| if (!response.ok) throw new Error(`HTTP ${response.status}`); | |
| return response.json(); | |
| } | |
| // --------------------------------------------------------------------------- | |
| // Step navigation | |
| // --------------------------------------------------------------------------- | |
| /** | |
| * POST /jobs/{job_id}/goto-step — set job.current_step to stepNumber. | |
| * | |
| * Only completed steps may be navigated to. Truncation of forward history | |
| * happens lazily on the next POST /generate call. | |
| */ | |
| export async function goToStep( | |
| jobId: string, | |
| stepNumber: number, | |
| ): Promise<{ job_id: string; current_step: number }> { | |
| const response = await fetch(`${API_BASE}/jobs/${jobId}/goto-step`, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ step_number: stepNumber }), | |
| }); | |
| 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; current_step: number }>; | |
| } | |