Spaces:
Sleeping
Sleeping
| """Wizara Vision API endpoint handlers.""" | |
| from __future__ import annotations | |
| import os | |
| from typing import Any, Callable | |
| from PIL import Image | |
| from .responses import ( | |
| detections_to_objects, | |
| error_response, | |
| parse_advanced_settings, | |
| success_response, | |
| unsupported_response, | |
| ) | |
| def resolve_image_path(image_file: Any, base_dir: str) -> str | None: | |
| if isinstance(image_file, str): | |
| candidate = image_file | |
| if not os.path.isabs(candidate): | |
| candidate = os.path.join(base_dir, candidate) | |
| return candidate if os.path.exists(candidate) else None | |
| if isinstance(image_file, dict): | |
| path = image_file.get("path") | |
| return path if path and os.path.exists(path) else None | |
| path = getattr(image_file, "path", None) | |
| return path if path and os.path.exists(path) else None | |
| def merge_settings( | |
| *, | |
| model_mode: str, | |
| temp: float, | |
| top_p: float, | |
| top_k: int, | |
| short_size: int | None, | |
| advanced_settings: str | None, | |
| ) -> dict[str, Any]: | |
| settings = { | |
| "model_mode": model_mode, | |
| "temp": temp, | |
| "top_p": top_p, | |
| "top_k": top_k, | |
| "short_size": short_size, | |
| } | |
| settings.update(parse_advanced_settings(advanced_settings)) | |
| return settings | |
| def handle_detect( | |
| *, | |
| image_file: Any, | |
| categories: str, | |
| task_type: str, | |
| model_mode: str, | |
| temp: float, | |
| top_p: float, | |
| top_k: int, | |
| short_size: int | None, | |
| advanced_settings: str | None, | |
| base_dir: str, | |
| run_image_gpu: Callable[..., tuple], | |
| generate_prompt: Callable[[str, str], str], | |
| parse_results: Callable[[str, str], list[dict[str, Any]]], | |
| ) -> dict[str, Any]: | |
| if not image_file: | |
| return error_response("Image is required.", code="MISSING_IMAGE") | |
| image_path = resolve_image_path(image_file, base_dir) | |
| if not image_path: | |
| return error_response("Invalid image file path.", code="INVALID_IMAGE") | |
| settings = merge_settings( | |
| model_mode=model_mode, | |
| temp=temp, | |
| top_p=top_p, | |
| top_k=top_k, | |
| short_size=short_size, | |
| advanced_settings=advanced_settings, | |
| ) | |
| category = categories.strip() or "objects" | |
| task = task_type.strip() or "Detection" | |
| question_override = settings.get("question_override") | |
| if not question_override: | |
| question_override = generate_prompt(task, category) | |
| try: | |
| image = Image.open(image_path).convert("RGB") | |
| width, height = image.size | |
| _, stats, raw_text, _, _ = run_image_gpu( | |
| image_path, | |
| category, | |
| settings.get("model_mode", model_mode), | |
| float(settings.get("temp", temp)), | |
| float(settings.get("top_p", top_p)), | |
| int(settings.get("top_k", top_k)), | |
| settings.get("short_size", short_size), | |
| question_override, | |
| ) | |
| category_str = " ".join(part.strip() for part in category.split(",") if part.strip()) | |
| detections = parse_results(raw_text, category_str) | |
| objects = detections_to_objects(detections) | |
| return success_response( | |
| image_width=width, | |
| image_height=height, | |
| objects=objects, | |
| task=task.lower(), | |
| extra={ | |
| "stats": stats, | |
| "raw_text": raw_text, | |
| "prompt": question_override, | |
| }, | |
| ) | |
| except Exception as exc: # noqa: BLE001 | |
| return error_response(str(exc), code="INFERENCE_FAILED") | |
| def handle_ocr( | |
| *, | |
| image_file: Any, | |
| model_mode: str, | |
| temp: float, | |
| top_p: float, | |
| top_k: int, | |
| short_size: int | None, | |
| advanced_settings: str | None, | |
| base_dir: str, | |
| run_image_gpu: Callable[..., tuple], | |
| generate_prompt: Callable[[str, str], str], | |
| parse_results: Callable[[str, str], list[dict[str, Any]]], | |
| ) -> dict[str, Any]: | |
| return handle_detect( | |
| image_file=image_file, | |
| categories="text", | |
| task_type="OCR", | |
| model_mode=model_mode, | |
| temp=temp, | |
| top_p=top_p, | |
| top_k=top_k, | |
| short_size=short_size, | |
| advanced_settings=advanced_settings, | |
| base_dir=base_dir, | |
| run_image_gpu=run_image_gpu, | |
| generate_prompt=generate_prompt, | |
| parse_results=parse_results, | |
| ) | |
| def handle_unsupported(task: str) -> dict[str, Any]: | |
| return unsupported_response(task) | |