Spaces:
Sleeping
Sleeping
Add image upload support to bulk JSON import feature
Browse files
app.py
CHANGED
|
@@ -1196,14 +1196,22 @@ with gr.Blocks(
|
|
| 1196 |
|
| 1197 |
with gr.Tab("Bulk Import (JSON)"):
|
| 1198 |
gr.Markdown(
|
| 1199 |
-
"Paste a JSON array like: `[{\"input\": \"...\", \"output\": \"...\"}]`"
|
|
|
|
|
|
|
| 1200 |
elem_classes=["small-note"]
|
| 1201 |
)
|
| 1202 |
bulk_json = gr.Textbox(
|
| 1203 |
show_label=False,
|
| 1204 |
-
placeholder='[{"input": "...", "output": "..."}]',
|
| 1205 |
lines=6
|
| 1206 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1207 |
btn_import = gr.Button(
|
| 1208 |
"Import JSON",
|
| 1209 |
elem_classes=["btn-secondary"]
|
|
@@ -1418,8 +1426,8 @@ with gr.Blocks(
|
|
| 1418 |
)
|
| 1419 |
|
| 1420 |
# Bulk Import
|
| 1421 |
-
def import_bulk_json(json_text, current_dataset):
|
| 1422 |
-
"""Import examples from JSON with comprehensive error handling."""
|
| 1423 |
try:
|
| 1424 |
# Validate inputs
|
| 1425 |
if not json_text or not json_text.strip():
|
|
@@ -1441,6 +1449,34 @@ with gr.Blocks(
|
|
| 1441 |
if len(data) == 0:
|
| 1442 |
raise gr.Error("JSON array is empty. Add at least one example object.")
|
| 1443 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1444 |
# Validate and import items
|
| 1445 |
imported_count = 0
|
| 1446 |
errors = []
|
|
@@ -1466,12 +1502,31 @@ with gr.Blocks(
|
|
| 1466 |
errors.append(f"Item {i+1}: 'input' and 'output' cannot be empty")
|
| 1467 |
continue
|
| 1468 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1469 |
# Add valid item
|
| 1470 |
current_dataset.append({
|
| 1471 |
"input": input_val.strip(),
|
| 1472 |
"output": output_val.strip(),
|
| 1473 |
-
"image":
|
| 1474 |
-
"image_preview": "🖼️ Image" if
|
| 1475 |
})
|
| 1476 |
imported_count += 1
|
| 1477 |
|
|
@@ -1508,7 +1563,7 @@ with gr.Blocks(
|
|
| 1508 |
|
| 1509 |
btn_import.click(
|
| 1510 |
import_bulk_json,
|
| 1511 |
-
inputs=[bulk_json, dataset_state],
|
| 1512 |
outputs=[dataset_state, bulk_json]
|
| 1513 |
).then(
|
| 1514 |
safe_update_table,
|
|
|
|
| 1196 |
|
| 1197 |
with gr.Tab("Bulk Import (JSON)"):
|
| 1198 |
gr.Markdown(
|
| 1199 |
+
"Paste a JSON array like: `[{\"input\": \"...\", \"output\": \"...\"}]`<br>"
|
| 1200 |
+
"**Images**: Upload images below and reference them by index (0-based) in JSON using `\"image_index\": 0`, "
|
| 1201 |
+
"or include base64 directly using `\"image\": \"data:image/...\"`",
|
| 1202 |
elem_classes=["small-note"]
|
| 1203 |
)
|
| 1204 |
bulk_json = gr.Textbox(
|
| 1205 |
show_label=False,
|
| 1206 |
+
placeholder='[{"input": "...", "output": "...", "image_index": 0}]',
|
| 1207 |
lines=6
|
| 1208 |
)
|
| 1209 |
+
bulk_images = gr.File(
|
| 1210 |
+
label="Upload Images (Optional)",
|
| 1211 |
+
file_count="multiple",
|
| 1212 |
+
file_types=["image"],
|
| 1213 |
+
height=100
|
| 1214 |
+
)
|
| 1215 |
btn_import = gr.Button(
|
| 1216 |
"Import JSON",
|
| 1217 |
elem_classes=["btn-secondary"]
|
|
|
|
| 1426 |
)
|
| 1427 |
|
| 1428 |
# Bulk Import
|
| 1429 |
+
def import_bulk_json(json_text, current_dataset, uploaded_images):
|
| 1430 |
+
"""Import examples from JSON with comprehensive error handling and image support."""
|
| 1431 |
try:
|
| 1432 |
# Validate inputs
|
| 1433 |
if not json_text or not json_text.strip():
|
|
|
|
| 1449 |
if len(data) == 0:
|
| 1450 |
raise gr.Error("JSON array is empty. Add at least one example object.")
|
| 1451 |
|
| 1452 |
+
# Process uploaded images into base64 format
|
| 1453 |
+
image_list = []
|
| 1454 |
+
if uploaded_images:
|
| 1455 |
+
for img_file in uploaded_images:
|
| 1456 |
+
try:
|
| 1457 |
+
if img_file is None:
|
| 1458 |
+
continue
|
| 1459 |
+
# Handle different file input formats
|
| 1460 |
+
if isinstance(img_file, str):
|
| 1461 |
+
# File path
|
| 1462 |
+
if os.path.exists(img_file):
|
| 1463 |
+
img_b64 = gradio_image_to_base64(img_file)
|
| 1464 |
+
if img_b64:
|
| 1465 |
+
image_list.append(img_b64)
|
| 1466 |
+
elif hasattr(img_file, 'name'):
|
| 1467 |
+
# File object with name attribute
|
| 1468 |
+
img_b64 = gradio_image_to_base64(img_file.name)
|
| 1469 |
+
if img_b64:
|
| 1470 |
+
image_list.append(img_b64)
|
| 1471 |
+
else:
|
| 1472 |
+
# Try to process as image directly
|
| 1473 |
+
img_b64 = gradio_image_to_base64(img_file)
|
| 1474 |
+
if img_b64:
|
| 1475 |
+
image_list.append(img_b64)
|
| 1476 |
+
except Exception as e:
|
| 1477 |
+
logger.warning(f"Failed to process uploaded image: {str(e)}")
|
| 1478 |
+
continue
|
| 1479 |
+
|
| 1480 |
# Validate and import items
|
| 1481 |
imported_count = 0
|
| 1482 |
errors = []
|
|
|
|
| 1502 |
errors.append(f"Item {i+1}: 'input' and 'output' cannot be empty")
|
| 1503 |
continue
|
| 1504 |
|
| 1505 |
+
# Handle image - check for image_index first, then direct image field
|
| 1506 |
+
img_b64 = None
|
| 1507 |
+
if "image_index" in item:
|
| 1508 |
+
# Reference uploaded image by index
|
| 1509 |
+
img_idx = item["image_index"]
|
| 1510 |
+
if not isinstance(img_idx, int):
|
| 1511 |
+
errors.append(f"Item {i+1}: 'image_index' must be an integer")
|
| 1512 |
+
continue
|
| 1513 |
+
if img_idx < 0 or img_idx >= len(image_list):
|
| 1514 |
+
errors.append(f"Item {i+1}: 'image_index' {img_idx} is out of range (0-{len(image_list)-1})")
|
| 1515 |
+
continue
|
| 1516 |
+
img_b64 = image_list[img_idx]
|
| 1517 |
+
elif "image" in item:
|
| 1518 |
+
# Direct base64 image in JSON
|
| 1519 |
+
img_b64 = item["image"]
|
| 1520 |
+
if img_b64 and not isinstance(img_b64, str):
|
| 1521 |
+
errors.append(f"Item {i+1}: 'image' must be a base64 string")
|
| 1522 |
+
continue
|
| 1523 |
+
|
| 1524 |
# Add valid item
|
| 1525 |
current_dataset.append({
|
| 1526 |
"input": input_val.strip(),
|
| 1527 |
"output": output_val.strip(),
|
| 1528 |
+
"image": img_b64, # Optional - can be None
|
| 1529 |
+
"image_preview": "🖼️ Image" if img_b64 else "-"
|
| 1530 |
})
|
| 1531 |
imported_count += 1
|
| 1532 |
|
|
|
|
| 1563 |
|
| 1564 |
btn_import.click(
|
| 1565 |
import_bulk_json,
|
| 1566 |
+
inputs=[bulk_json, dataset_state, bulk_images],
|
| 1567 |
outputs=[dataset_state, bulk_json]
|
| 1568 |
).then(
|
| 1569 |
safe_update_table,
|