Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -104,6 +104,7 @@ from fastapi import FastAPI, HTTPException
|
|
104 |
from fastapi.responses import JSONResponse
|
105 |
from pydantic import BaseModel
|
106 |
from huggingface_hub import InferenceClient
|
|
|
107 |
|
108 |
# Set up logging
|
109 |
logging.basicConfig(level=logging.INFO)
|
@@ -138,7 +139,7 @@ def llm_chat_response(text: str, image_url: Optional[str] = None) -> str:
|
|
138 |
api_key=HF_TOKEN
|
139 |
)
|
140 |
|
141 |
-
# Build the messages payload
|
142 |
# For text-only queries, append a default instruction.
|
143 |
message_content = [{
|
144 |
"type": "text",
|
@@ -147,14 +148,14 @@ def llm_chat_response(text: str, image_url: Optional[str] = None) -> str:
|
|
147 |
|
148 |
if image_url:
|
149 |
logger.info("Downloading and converting image to base64 data URI...")
|
150 |
-
# Download the image
|
151 |
image_response = requests.get(image_url)
|
152 |
if image_response.status_code != 200:
|
153 |
logger.error("Failed to download image from URL")
|
154 |
raise HTTPException(status_code=500, detail="Failed to download image from provided URL")
|
155 |
image_bytes = image_response.content
|
156 |
-
|
157 |
-
#
|
158 |
mime_type = image_response.headers.get("Content-Type")
|
159 |
if not mime_type or not mime_type.startswith("image/"):
|
160 |
logger.error("Invalid image MIME type")
|
@@ -163,6 +164,7 @@ def llm_chat_response(text: str, image_url: Optional[str] = None) -> str:
|
|
163 |
# Encode image in base64 and format as a data URI
|
164 |
base64_image = base64.b64encode(image_bytes).decode("utf-8")
|
165 |
data_uri = f"data:{mime_type};base64,{base64_image}"
|
|
|
166 |
|
167 |
message_content.append({
|
168 |
"type": "image_url",
|
@@ -175,19 +177,31 @@ def llm_chat_response(text: str, image_url: Optional[str] = None) -> str:
|
|
175 |
}]
|
176 |
|
177 |
logger.info("Sending request to model...")
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
|
|
|
|
|
|
|
|
|
|
183 |
|
184 |
logger.info(f"Raw model response: {completion}")
|
185 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
if not completion.choices or len(completion.choices) == 0:
|
187 |
logger.error("No choices returned from model.")
|
188 |
raise HTTPException(status_code=500, detail="Model returned no choices.")
|
189 |
|
190 |
-
# Extract the message
|
191 |
choice = completion.choices[0]
|
192 |
response_message = None
|
193 |
if hasattr(choice, "message"):
|
@@ -247,5 +261,3 @@ async def method_not_allowed_handler(request, exc):
|
|
247 |
status_code=405,
|
248 |
content={"error": "Method not allowed. Please check the API documentation."}
|
249 |
)
|
250 |
-
|
251 |
-
|
|
|
104 |
from fastapi.responses import JSONResponse
|
105 |
from pydantic import BaseModel
|
106 |
from huggingface_hub import InferenceClient
|
107 |
+
from requests.exceptions import HTTPError
|
108 |
|
109 |
# Set up logging
|
110 |
logging.basicConfig(level=logging.INFO)
|
|
|
139 |
api_key=HF_TOKEN
|
140 |
)
|
141 |
|
142 |
+
# Build the messages payload.
|
143 |
# For text-only queries, append a default instruction.
|
144 |
message_content = [{
|
145 |
"type": "text",
|
|
|
148 |
|
149 |
if image_url:
|
150 |
logger.info("Downloading and converting image to base64 data URI...")
|
151 |
+
# Download the image
|
152 |
image_response = requests.get(image_url)
|
153 |
if image_response.status_code != 200:
|
154 |
logger.error("Failed to download image from URL")
|
155 |
raise HTTPException(status_code=500, detail="Failed to download image from provided URL")
|
156 |
image_bytes = image_response.content
|
157 |
+
|
158 |
+
# Get the MIME type from the response headers
|
159 |
mime_type = image_response.headers.get("Content-Type")
|
160 |
if not mime_type or not mime_type.startswith("image/"):
|
161 |
logger.error("Invalid image MIME type")
|
|
|
164 |
# Encode image in base64 and format as a data URI
|
165 |
base64_image = base64.b64encode(image_bytes).decode("utf-8")
|
166 |
data_uri = f"data:{mime_type};base64,{base64_image}"
|
167 |
+
logger.info(f"Data URI created: {data_uri[:50]}...") # log first 50 chars for verification
|
168 |
|
169 |
message_content.append({
|
170 |
"type": "image_url",
|
|
|
177 |
}]
|
178 |
|
179 |
logger.info("Sending request to model...")
|
180 |
+
try:
|
181 |
+
completion = client.chat.completions.create(
|
182 |
+
model="meta-llama/Llama-3.2-11B-Vision-Instruct",
|
183 |
+
messages=messages,
|
184 |
+
max_tokens=500
|
185 |
+
)
|
186 |
+
except HTTPError as http_err:
|
187 |
+
# Log HTTP errors from the request
|
188 |
+
logger.error(f"HTTP error occurred: {http_err.response.text}")
|
189 |
+
raise HTTPException(status_code=500, detail=http_err.response.text)
|
190 |
|
191 |
logger.info(f"Raw model response: {completion}")
|
192 |
|
193 |
+
# If the model returned an error field, capture and return that error.
|
194 |
+
if getattr(completion, "error", None):
|
195 |
+
error_details = completion.error
|
196 |
+
error_message = error_details.get("message", "Unknown error")
|
197 |
+
logger.error(f"Model returned error: {error_message}")
|
198 |
+
raise HTTPException(status_code=500, detail=f"Model returned error: {error_message}")
|
199 |
+
|
200 |
if not completion.choices or len(completion.choices) == 0:
|
201 |
logger.error("No choices returned from model.")
|
202 |
raise HTTPException(status_code=500, detail="Model returned no choices.")
|
203 |
|
204 |
+
# Extract the response message from the first choice.
|
205 |
choice = completion.choices[0]
|
206 |
response_message = None
|
207 |
if hasattr(choice, "message"):
|
|
|
261 |
status_code=405,
|
262 |
content={"error": "Method not allowed. Please check the API documentation."}
|
263 |
)
|
|
|
|