Commit
·
1c42249
1
Parent(s):
0dd809a
feat(api): return image directly from /inpaint; docs: mark download optional for ID-based flow
Browse files- README.md +5 -2
- api/main.py +2 -2
README.md
CHANGED
|
@@ -18,11 +18,14 @@ Endpoints:
|
|
| 18 |
- `GET /health` → {"status":"healthy"}
|
| 19 |
- `POST /upload-image` (form-data: image=file) → {"id":"<image_id>","filename":"name.png"}
|
| 20 |
- `POST /upload-mask` (form-data: mask=file) → {"id":"<mask_id>","filename":"mask.png"}
|
| 21 |
-
- `POST /inpaint` (JSON: {image_id, mask_id}) →
|
| 22 |
- `POST /inpaint-multipart` (form-data: image=file, mask=file) → {"result":"output_xxx.png"}
|
| 23 |
-
- `GET /download/{filename}` → image file
|
| 24 |
- `GET /logs` → recent uploads/results
|
| 25 |
|
|
|
|
|
|
|
|
|
|
| 26 |
Local run:
|
| 27 |
- Install deps: `python3 -m pip install -r requirements.txt`
|
| 28 |
- Run API: `python3 -m uvicorn api.main:app --host 0.0.0.0 --port 7860`
|
|
|
|
| 18 |
- `GET /health` → {"status":"healthy"}
|
| 19 |
- `POST /upload-image` (form-data: image=file) → {"id":"<image_id>","filename":"name.png"}
|
| 20 |
- `POST /upload-mask` (form-data: mask=file) → {"id":"<mask_id>","filename":"mask.png"}
|
| 21 |
+
- `POST /inpaint` (JSON: {image_id, mask_id}) → returns result directly (no download step)
|
| 22 |
- `POST /inpaint-multipart` (form-data: image=file, mask=file) → {"result":"output_xxx.png"}
|
| 23 |
+
- `GET /download/{filename}` → image file (optional; not required when using ID-based inpaint)
|
| 24 |
- `GET /logs` → recent uploads/results
|
| 25 |
|
| 26 |
+
Note:
|
| 27 |
+
- When using the ID-based `POST /inpaint` endpoint, the API responds with the inpainted image directly, so the `GET /download/{filename}` endpoint is not needed.
|
| 28 |
+
|
| 29 |
Local run:
|
| 30 |
- Install deps: `python3 -m pip install -r requirements.txt`
|
| 31 |
- Run API: `python3 -m uvicorn api.main:app --host 0.0.0.0 --port 7860`
|
api/main.py
CHANGED
|
@@ -129,7 +129,7 @@ def _load_rgba_mask_from_image(img: Image.Image) -> np.ndarray:
|
|
| 129 |
|
| 130 |
|
| 131 |
@app.post("/inpaint")
|
| 132 |
-
def inpaint(req: InpaintRequest, _: None = Depends(bearer_auth))
|
| 133 |
if req.image_id not in file_store or file_store[req.image_id]["type"] != "image":
|
| 134 |
raise HTTPException(status_code=404, detail="image_id not found")
|
| 135 |
if req.mask_id not in file_store or file_store[req.mask_id]["type"] != "mask":
|
|
@@ -145,7 +145,7 @@ def inpaint(req: InpaintRequest, _: None = Depends(bearer_auth)) -> Dict[str, st
|
|
| 145 |
Image.fromarray(result).save(result_path)
|
| 146 |
|
| 147 |
logs.append({"result": result_name, "timestamp": datetime.utcnow().isoformat()})
|
| 148 |
-
return
|
| 149 |
|
| 150 |
|
| 151 |
@app.post("/inpaint-multipart")
|
|
|
|
| 129 |
|
| 130 |
|
| 131 |
@app.post("/inpaint")
|
| 132 |
+
def inpaint(req: InpaintRequest, _: None = Depends(bearer_auth)):
|
| 133 |
if req.image_id not in file_store or file_store[req.image_id]["type"] != "image":
|
| 134 |
raise HTTPException(status_code=404, detail="image_id not found")
|
| 135 |
if req.mask_id not in file_store or file_store[req.mask_id]["type"] != "mask":
|
|
|
|
| 145 |
Image.fromarray(result).save(result_path)
|
| 146 |
|
| 147 |
logs.append({"result": result_name, "timestamp": datetime.utcnow().isoformat()})
|
| 148 |
+
return FileResponse(result_path, media_type="image/png", filename=result_name)
|
| 149 |
|
| 150 |
|
| 151 |
@app.post("/inpaint-multipart")
|