Spaces:
Runtime error
Runtime error
Add base64 API endpoint for programmatic access
Browse files- digitize_chart now accepts both PIL Image and base64 strings
- Add /api/digitize_base64 endpoint using gr.Textbox inputs
so external clients can send base64 without Gradio file upload
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- api_server.py +35 -2
api_server.py
CHANGED
|
@@ -33,10 +33,12 @@ import cv2
|
|
| 33 |
import numpy as np
|
| 34 |
import json
|
| 35 |
import io
|
|
|
|
| 36 |
import zipfile
|
| 37 |
import urllib.request
|
| 38 |
import ssl
|
| 39 |
import gradio as gr
|
|
|
|
| 40 |
from datetime import datetime, timezone
|
| 41 |
|
| 42 |
# ============================================================
|
|
@@ -323,8 +325,17 @@ def digitize_chart(
|
|
| 323 |
if image is None:
|
| 324 |
return json.dumps({"error": "No image provided"})
|
| 325 |
|
| 326 |
-
#
|
| 327 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 328 |
img_bgr = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2BGR)
|
| 329 |
|
| 330 |
# Extract lines
|
|
@@ -433,6 +444,28 @@ def create_app():
|
|
| 433 |
outputs=[output, file_output],
|
| 434 |
)
|
| 435 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 436 |
return demo
|
| 437 |
|
| 438 |
|
|
|
|
| 33 |
import numpy as np
|
| 34 |
import json
|
| 35 |
import io
|
| 36 |
+
import base64
|
| 37 |
import zipfile
|
| 38 |
import urllib.request
|
| 39 |
import ssl
|
| 40 |
import gradio as gr
|
| 41 |
+
from PIL import Image
|
| 42 |
from datetime import datetime, timezone
|
| 43 |
|
| 44 |
# ============================================================
|
|
|
|
| 325 |
if image is None:
|
| 326 |
return json.dumps({"error": "No image provided"})
|
| 327 |
|
| 328 |
+
# Accept both PIL Image and base64 string
|
| 329 |
+
if isinstance(image, str):
|
| 330 |
+
# Strip data URI prefix if present (e.g. "data:image/png;base64,...")
|
| 331 |
+
if "," in image:
|
| 332 |
+
image = image.split(",", 1)[1]
|
| 333 |
+
img_bytes = base64.b64decode(image)
|
| 334 |
+
pil_img = Image.open(io.BytesIO(img_bytes)).convert("RGB")
|
| 335 |
+
img_rgb = np.array(pil_img)
|
| 336 |
+
else:
|
| 337 |
+
img_rgb = np.array(image)
|
| 338 |
+
|
| 339 |
img_bgr = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2BGR)
|
| 340 |
|
| 341 |
# Extract lines
|
|
|
|
| 444 |
outputs=[output, file_output],
|
| 445 |
)
|
| 446 |
|
| 447 |
+
# Programmatic API endpoint that accepts base64 string directly
|
| 448 |
+
# This avoids Gradio's file upload requirement for gr.Image
|
| 449 |
+
api_image_input = gr.Textbox(visible=False)
|
| 450 |
+
api_auto_axis = gr.Checkbox(value=True, visible=False)
|
| 451 |
+
api_downsample = gr.Textbox(value="arc_length", visible=False)
|
| 452 |
+
api_max_pts = gr.Number(value=20, visible=False)
|
| 453 |
+
api_fixed_stp = gr.Number(value=10, visible=False)
|
| 454 |
+
api_sort = gr.Textbox(value="mean_y_desc", visible=False)
|
| 455 |
+
api_out_fmt = gr.Textbox(value="starry_digitizer_json", visible=False)
|
| 456 |
+
api_output = gr.Textbox(visible=False)
|
| 457 |
+
|
| 458 |
+
def api_digitize(image_base64, auto_axis, downsample, max_pts, fixed_stp, sort, out_fmt):
|
| 459 |
+
return digitize_chart(image_base64, auto_axis, downsample, int(max_pts), int(fixed_stp), sort, out_fmt)
|
| 460 |
+
|
| 461 |
+
api_btn = gr.Button(visible=False, elem_id="api_btn")
|
| 462 |
+
api_btn.click(
|
| 463 |
+
fn=api_digitize,
|
| 464 |
+
inputs=[api_image_input, api_auto_axis, api_downsample, api_max_pts, api_fixed_stp, api_sort, api_out_fmt],
|
| 465 |
+
outputs=[api_output],
|
| 466 |
+
api_name="digitize_base64",
|
| 467 |
+
)
|
| 468 |
+
|
| 469 |
return demo
|
| 470 |
|
| 471 |
|