Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -11,7 +11,12 @@ from PIL import Image, ImageFile, UnidentifiedImageError
|
|
| 11 |
import gradio as gr
|
| 12 |
import time
|
| 13 |
import atexit
|
| 14 |
-
from requests.exceptions import RequestException
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
|
| 16 |
# --- Configuration and Globals ---
|
| 17 |
DEFAULT_KEY = os.getenv("MISTRAL_API_KEY", "")
|
|
@@ -36,24 +41,6 @@ Image.MAX_IMAGE_PIXELS = 10000 * 10000
|
|
| 36 |
|
| 37 |
DEFAULT_HEADERS = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}
|
| 38 |
|
| 39 |
-
# Attempt to import Mistral client and its exception.
|
| 40 |
-
# Define a mock exception if the library is not installed, to ensure type hinting and
|
| 41 |
-
# `except MistralAPIException` blocks work correctly.
|
| 42 |
-
try:
|
| 43 |
-
from mistralai import Mistral
|
| 44 |
-
from mistralai.exceptions import MistralAPIException
|
| 45 |
-
except ImportError:
|
| 46 |
-
Mistral = None
|
| 47 |
-
class MistralAPIException(Exception):
|
| 48 |
-
def __init__(self, message, status_code=None, *args, **kwargs):
|
| 49 |
-
super().__init__(message, *args)
|
| 50 |
-
self.status_code = status_code
|
| 51 |
-
self._message = message
|
| 52 |
-
|
| 53 |
-
@property
|
| 54 |
-
def message(self):
|
| 55 |
-
return self._message
|
| 56 |
-
|
| 57 |
# --- Temporary File Cleanup ---
|
| 58 |
_temp_preview_files_to_delete = []
|
| 59 |
|
|
@@ -72,46 +59,19 @@ atexit.register(_cleanup_all_temp_preview_files)
|
|
| 72 |
# --- Mistral Client and API Helpers ---
|
| 73 |
def get_client(key: Optional[str] = None):
|
| 74 |
"""
|
| 75 |
-
Returns a Mistral client instance. If the
|
| 76 |
-
|
| 77 |
-
MistralAPIException with specific messages.
|
| 78 |
"""
|
| 79 |
api_key = (key or "").strip() or DEFAULT_KEY
|
| 80 |
|
| 81 |
-
class DummyMistralService:
|
| 82 |
-
def __init__(self, error_message: str, status_code: Optional[int] = None):
|
| 83 |
-
self._error_message = error_message
|
| 84 |
-
self._status_code = status_code
|
| 85 |
-
|
| 86 |
-
def complete(self, **kwargs):
|
| 87 |
-
raise MistralAPIException(self._error_message, status_code=self._status_code)
|
| 88 |
-
|
| 89 |
-
def upload(self, **kwargs):
|
| 90 |
-
raise MistralAPIException(self._error_message, status_code=self._status_code)
|
| 91 |
-
|
| 92 |
-
class DummyClient:
|
| 93 |
-
def __init__(self, k, library_missing_msg: Optional[str] = None, api_key_missing_msg: Optional[str] = None):
|
| 94 |
-
self.api_key = k
|
| 95 |
-
self.is_real_client = False # Flag for internal diagnostics, not for logic flow control
|
| 96 |
-
|
| 97 |
-
if not k:
|
| 98 |
-
error_msg = api_key_missing_msg or "Mistral API key is not set."
|
| 99 |
-
status_code = 401
|
| 100 |
-
else:
|
| 101 |
-
error_msg = library_missing_msg or "Mistral client library is not installed."
|
| 102 |
-
status_code = 500
|
| 103 |
-
|
| 104 |
-
self.chat = DummyMistralService(error_msg, status_code)
|
| 105 |
-
self.files = DummyMistralService(error_msg, status_code)
|
| 106 |
-
|
| 107 |
if not api_key:
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
|
|
|
|
| 113 |
client = Mistral(api_key=api_key)
|
| 114 |
-
setattr(client, 'is_real_client', True)
|
| 115 |
return client
|
| 116 |
|
| 117 |
def is_remote(src: str) -> bool:
|
|
@@ -539,9 +499,7 @@ def _get_playable_preview_path_from_raw(src_url: str, raw_bytes: bytes, is_image
|
|
| 539 |
jpeg_bytes = convert_to_jpeg_bytes(raw_bytes, base_h=1024)
|
| 540 |
if jpeg_bytes:
|
| 541 |
return _temp_file(jpeg_bytes, suffix=".jpg")
|
| 542 |
-
|
| 543 |
-
print(f"Warning: Could not convert image bytes for {src_url} to JPEG.")
|
| 544 |
-
return "" # Failed image conversion, do not fall through to video logic
|
| 545 |
elif is_video_hint:
|
| 546 |
temp_raw_video_path = _temp_file(raw_bytes, suffix=ext_from_src(src_url) or ".mp4")
|
| 547 |
if not temp_raw_video_path:
|
|
@@ -772,7 +730,7 @@ def create_demo():
|
|
| 772 |
except UnidentifiedImageError:
|
| 773 |
is_actually_video_for_analysis = True
|
| 774 |
except Exception as e:
|
| 775 |
-
print(f"Warning: PIL error during image verification for raw analysis media ({raw_media_path}): {e}.
|
| 776 |
is_actually_video_for_analysis = True
|
| 777 |
|
| 778 |
client = get_client(key)
|
|
|
|
| 11 |
import gradio as gr
|
| 12 |
import time
|
| 13 |
import atexit
|
| 14 |
+
from requests.exceptions import RequestException
|
| 15 |
+
|
| 16 |
+
# Direct import of Mistral client and its exception.
|
| 17 |
+
# An ImportError will now occur at script start if the library is not installed.
|
| 18 |
+
from mistralai import Mistral
|
| 19 |
+
from mistralai.exceptions import MistralAPIException
|
| 20 |
|
| 21 |
# --- Configuration and Globals ---
|
| 22 |
DEFAULT_KEY = os.getenv("MISTRAL_API_KEY", "")
|
|
|
|
| 41 |
|
| 42 |
DEFAULT_HEADERS = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}
|
| 43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
# --- Temporary File Cleanup ---
|
| 45 |
_temp_preview_files_to_delete = []
|
| 46 |
|
|
|
|
| 59 |
# --- Mistral Client and API Helpers ---
|
| 60 |
def get_client(key: Optional[str] = None):
|
| 61 |
"""
|
| 62 |
+
Returns a Mistral client instance. If the API key is missing,
|
| 63 |
+
a MistralAPIException is raised.
|
|
|
|
| 64 |
"""
|
| 65 |
api_key = (key or "").strip() or DEFAULT_KEY
|
| 66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
if not api_key:
|
| 68 |
+
raise MistralAPIException(
|
| 69 |
+
"Mistral API key is not set. Please provide it in the UI or as MISTRAL_API_KEY environment variable.",
|
| 70 |
+
status_code=401 # Unauthorized
|
| 71 |
+
)
|
| 72 |
|
| 73 |
+
# Directly instantiate the real Mistral client
|
| 74 |
client = Mistral(api_key=api_key)
|
|
|
|
| 75 |
return client
|
| 76 |
|
| 77 |
def is_remote(src: str) -> bool:
|
|
|
|
| 499 |
jpeg_bytes = convert_to_jpeg_bytes(raw_bytes, base_h=1024)
|
| 500 |
if jpeg_bytes:
|
| 501 |
return _temp_file(jpeg_bytes, suffix=".jpg")
|
| 502 |
+
return "" # Failed image conversion, do not fall through to video logic
|
|
|
|
|
|
|
| 503 |
elif is_video_hint:
|
| 504 |
temp_raw_video_path = _temp_file(raw_bytes, suffix=ext_from_src(src_url) or ".mp4")
|
| 505 |
if not temp_raw_video_path:
|
|
|
|
| 730 |
except UnidentifiedImageError:
|
| 731 |
is_actually_video_for_analysis = True
|
| 732 |
except Exception as e:
|
| 733 |
+
print(f"Warning: PIL error during image verification for raw analysis media ({raw_media_path}): {e}. Assuming video type for fallback.")
|
| 734 |
is_actually_video_for_analysis = True
|
| 735 |
|
| 736 |
client = get_client(key)
|