mlbench123 commited on
Commit
92db2c3
Β·
verified Β·
1 Parent(s): f477e51

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +38 -14
app.py CHANGED
@@ -444,6 +444,27 @@ def decode_b64_image(b64_str: str) -> Image.Image:
444
  raw = base64.b64decode(b64_str)
445
  return Image.open(io.BytesIO(raw)).convert("RGB")
446
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
447
  # ──────────────────────────────────────────────────────────────────────────────
448
  # JSON EXTRACTION
449
  # ──────────────────────────────────────────────────────────────────────────────
@@ -749,13 +770,16 @@ class ImageInput(BaseModel):
749
  description="One of: front_right, front_left, rear_right, rear_left, inside, door",
750
  example="front_left",
751
  )
752
- image_base64: str = Field(
753
  ...,
754
  description=(
755
- "Base64-encoded image. Can be raw base64 or a data URI "
 
 
756
  "(e.g. 'data:image/jpeg;base64,...'). "
757
  "Supported formats: JPEG, PNG, WEBP."
758
  ),
 
759
  )
760
 
761
 
@@ -766,12 +790,12 @@ class InspectRequest(BaseModel):
766
  max_length=6,
767
  description="List of labeled images. Each label may appear at most once.",
768
  example=[
769
- {"label": "front_left", "image_base64": "<base64>"},
770
- {"label": "front_right", "image_base64": "<base64>"},
771
- {"label": "rear_left", "image_base64": "<base64>"},
772
- {"label": "rear_right", "image_base64": "<base64>"},
773
- {"label": "inside", "image_base64": "<base64>"},
774
- {"label": "door", "image_base64": "<base64>"},
775
  ],
776
  )
777
 
@@ -803,7 +827,7 @@ def inspect(request: InspectRequest):
803
  """
804
  Run full trailer inspection on all submitted images in parallel.
805
 
806
- **Input:** Up to 6 labeled base64 images.
807
  **Output:** Per-label report with component detection results.
808
 
809
  Labels accepted: `front_right`, `front_left`, `rear_right`, `rear_left`, `inside`, `door`
@@ -832,17 +856,17 @@ def inspect(request: InspectRequest):
832
  status_code=422,
833
  detail=f"Duplicate label '{item.label}'. Each label may only appear once.",
834
  )
835
- seen_labels[item.label] = item.image_base64
836
 
837
- # Decode all images
838
  decoded: dict[str, Image.Image] = {}
839
- for label, b64 in seen_labels.items():
840
  try:
841
- decoded[label] = decode_b64_image(b64)
842
  except Exception as e:
843
  raise HTTPException(
844
  status_code=422,
845
- detail=f"Could not decode image for label '{label}': {e}",
846
  )
847
 
848
  # ── Run label analyses in small batches ─────────────────────────────────
 
444
  raw = base64.b64decode(b64_str)
445
  return Image.open(io.BytesIO(raw)).convert("RGB")
446
 
447
+
448
+ def fetch_image_from_url(url: str, timeout: int = 20) -> Image.Image:
449
+ """Download an image from a URL and return it as a PIL Image."""
450
+ resp = requests.get(url, timeout=timeout)
451
+ resp.raise_for_status()
452
+ content_type = resp.headers.get("Content-Type", "")
453
+ if content_type and not content_type.startswith("image/"):
454
+ raise ValueError(f"URL did not return an image (Content-Type: {content_type})")
455
+ return Image.open(io.BytesIO(resp.content)).convert("RGB")
456
+
457
+
458
+ def load_image(image_url: str) -> Image.Image:
459
+ """
460
+ Load an image from either a URL (http/https) or a base64 string / data-URI.
461
+ This is the single entry point for all image loading in the inspect route.
462
+ """
463
+ stripped = image_url.strip()
464
+ if stripped.startswith("http://") or stripped.startswith("https://"):
465
+ return fetch_image_from_url(stripped)
466
+ return decode_b64_image(stripped)
467
+
468
  # ──────────────────────────────────────────────────────────────────────────────
469
  # JSON EXTRACTION
470
  # ──────────────────────────────────────────────────────────────────────────────
 
770
  description="One of: front_right, front_left, rear_right, rear_left, inside, door",
771
  example="front_left",
772
  )
773
+ image_url: str = Field(
774
  ...,
775
  description=(
776
+ "Image source β€” either a public/signed HTTPS URL "
777
+ "(e.g. a Firebase Storage download URL) "
778
+ "OR a base64-encoded string / data-URI "
779
  "(e.g. 'data:image/jpeg;base64,...'). "
780
  "Supported formats: JPEG, PNG, WEBP."
781
  ),
782
+ example="https://firebasestorage.googleapis.com/...",
783
  )
784
 
785
 
 
790
  max_length=6,
791
  description="List of labeled images. Each label may appear at most once.",
792
  example=[
793
+ {"label": "front_left", "image_url": "https://firebasestorage.googleapis.com/..."},
794
+ {"label": "front_right", "image_url": "https://firebasestorage.googleapis.com/..."},
795
+ {"label": "rear_left", "image_url": "https://firebasestorage.googleapis.com/..."},
796
+ {"label": "rear_right", "image_url": "https://firebasestorage.googleapis.com/..."},
797
+ {"label": "inside", "image_url": "https://firebasestorage.googleapis.com/..."},
798
+ {"label": "door", "image_url": "https://firebasestorage.googleapis.com/..."},
799
  ],
800
  )
801
 
 
827
  """
828
  Run full trailer inspection on all submitted images in parallel.
829
 
830
+ **Input:** Up to 6 labeled images β€” each as a signed/public HTTPS URL or base64 string.
831
  **Output:** Per-label report with component detection results.
832
 
833
  Labels accepted: `front_right`, `front_left`, `rear_right`, `rear_left`, `inside`, `door`
 
856
  status_code=422,
857
  detail=f"Duplicate label '{item.label}'. Each label may only appear once.",
858
  )
859
+ seen_labels[item.label] = item.image_url
860
 
861
+ # Load all images (URL download or base64 decode)
862
  decoded: dict[str, Image.Image] = {}
863
+ for label, image_url in seen_labels.items():
864
  try:
865
+ decoded[label] = load_image(image_url)
866
  except Exception as e:
867
  raise HTTPException(
868
  status_code=422,
869
+ detail=f"Could not load image for label '{label}': {e}",
870
  )
871
 
872
  # ── Run label analyses in small batches ─────────────────────────────────