Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -97,6 +97,8 @@
|
|
97 |
# app.py
|
98 |
import os
|
99 |
import logging
|
|
|
|
|
100 |
from typing import Optional
|
101 |
from fastapi import FastAPI, HTTPException
|
102 |
from fastapi.responses import JSONResponse
|
@@ -137,16 +139,34 @@ def llm_chat_response(text: str, image_url: Optional[str] = None) -> str:
|
|
137 |
)
|
138 |
|
139 |
# Build the messages payload dynamically.
|
140 |
-
#
|
141 |
message_content = [{
|
142 |
"type": "text",
|
143 |
"text": text + ("" if image_url else " describe in one line only")
|
144 |
}]
|
145 |
|
146 |
if image_url:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
message_content.append({
|
148 |
"type": "image_url",
|
149 |
-
"image_url": {"url":
|
150 |
})
|
151 |
|
152 |
messages = [{
|
@@ -161,18 +181,15 @@ def llm_chat_response(text: str, image_url: Optional[str] = None) -> str:
|
|
161 |
max_tokens=500
|
162 |
)
|
163 |
|
164 |
-
# Debug log the raw response for troubleshooting.
|
165 |
logger.info(f"Raw model response: {completion}")
|
166 |
|
167 |
-
# Ensure we have a valid response.
|
168 |
if not completion.choices or len(completion.choices) == 0:
|
169 |
logger.error("No choices returned from model.")
|
170 |
raise HTTPException(status_code=500, detail="Model returned no choices.")
|
171 |
|
172 |
-
# Extract the message
|
173 |
-
response_message = None
|
174 |
-
# Some responses may be dicts or objects; try both approaches.
|
175 |
choice = completion.choices[0]
|
|
|
176 |
if hasattr(choice, "message"):
|
177 |
response_message = choice.message
|
178 |
elif isinstance(choice, dict):
|
@@ -182,11 +199,9 @@ def llm_chat_response(text: str, image_url: Optional[str] = None) -> str:
|
|
182 |
logger.error(f"Response message is empty: {choice}")
|
183 |
raise HTTPException(status_code=500, detail="Model response did not include a message.")
|
184 |
|
185 |
-
# Extract the content from the message.
|
186 |
content = None
|
187 |
if isinstance(response_message, dict):
|
188 |
content = response_message.get("content")
|
189 |
-
# If for some reason it's not a dict, try attribute access.
|
190 |
if content is None and hasattr(response_message, "content"):
|
191 |
content = response_message.content
|
192 |
|
@@ -233,3 +248,4 @@ async def method_not_allowed_handler(request, exc):
|
|
233 |
content={"error": "Method not allowed. Please check the API documentation."}
|
234 |
)
|
235 |
|
|
|
|
97 |
# app.py
|
98 |
import os
|
99 |
import logging
|
100 |
+
import base64
|
101 |
+
import requests
|
102 |
from typing import Optional
|
103 |
from fastapi import FastAPI, HTTPException
|
104 |
from fastapi.responses import JSONResponse
|
|
|
139 |
)
|
140 |
|
141 |
# Build the messages payload dynamically.
|
142 |
+
# For text-only queries, append a default instruction.
|
143 |
message_content = [{
|
144 |
"type": "text",
|
145 |
"text": text + ("" if image_url else " describe in one line only")
|
146 |
}]
|
147 |
|
148 |
if image_url:
|
149 |
+
logger.info("Downloading and converting image to base64 data URI...")
|
150 |
+
# Download the image from the URL
|
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 |
+
# Determine the MIME type
|
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")
|
161 |
+
raise HTTPException(status_code=500, detail="Invalid image MIME type")
|
162 |
+
|
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",
|
169 |
+
"image_url": {"url": data_uri}
|
170 |
})
|
171 |
|
172 |
messages = [{
|
|
|
181 |
max_tokens=500
|
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 content from the first choice.
|
|
|
|
|
191 |
choice = completion.choices[0]
|
192 |
+
response_message = None
|
193 |
if hasattr(choice, "message"):
|
194 |
response_message = choice.message
|
195 |
elif isinstance(choice, dict):
|
|
|
199 |
logger.error(f"Response message is empty: {choice}")
|
200 |
raise HTTPException(status_code=500, detail="Model response did not include a message.")
|
201 |
|
|
|
202 |
content = None
|
203 |
if isinstance(response_message, dict):
|
204 |
content = response_message.get("content")
|
|
|
205 |
if content is None and hasattr(response_message, "content"):
|
206 |
content = response_message.content
|
207 |
|
|
|
248 |
content={"error": "Method not allowed. Please check the API documentation."}
|
249 |
)
|
250 |
|
251 |
+
|