VQA / models /hf_boss_api.py
VigneshVS2005's picture
Major Project Finalization: Renamed Models, Implemented SQLite DB Auth, User Tracking, and adjusted model restraints per request.
1b2c3a0
Raw
History Blame
4.44 kB
import os
import io
import base64
import requests
import re
def hf_boss_answer(image, question, lang="en"):
token = os.getenv("HF_TOKEN")
if not token:
return "Setup Required", "HF Token is missing.", "Please set HF_TOKEN."
# Using Qwen 2.5 VL as requested
model_id = "Qwen/Qwen2.5-VL-7B-Instruct:hyperbolic"
try:
api_url = "https://router.huggingface.co/v1/chat/completions"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
if image.mode != 'RGB':
image = image.convert('RGB')
# Consistent resizing for vision models
image.thumbnail((1024, 1024))
buffered = io.BytesIO()
image.save(buffered, format="JPEG", quality=85)
img_b64 = base64.b64encode(buffered.getvalue()).decode("utf-8")
img_data_url = f"data:image/jpeg;base64,{img_b64}"
prompt = f"""Analyze this image and answer the question.
Question: {question}
CRITICAL FORMATTING RULES:
1. All output must be in language: {lang}.
2. You MUST use exactly these THREE labels: "Caption:", "Final Answer:", and "Explanation:".
3. Do not use any markdown formatting like **bold** in the labels.
4. "Caption:" must be 1 line.
5. "Final Answer:" must be 1 line.
6. "Explanation:" must be 2-3 sentences.
Output Format:
Caption: [1 line]
Final Answer: [1 line]
Explanation: [2-3 sentences]"""
payload = {
"model": model_id,
"messages": [
{
"role": "system",
"content": "You are a professional VQA assistant. You follow formatting instructions perfectly."
},
{
"role": "user",
"content": [
{"type": "text", "text": prompt},
{"type": "image_url", "image_url": {"url": img_data_url}}
]
}
],
"max_tokens": 1024,
"temperature": 0.1
}
response = requests.post(api_url, headers=headers, json=payload, timeout=90)
# Fallback system
if response.status_code != 200:
model_id = "google/gemma-3-12b-it:featherless"
payload["model"] = model_id
response = requests.post(api_url, headers=headers, json=payload, timeout=90)
if response.status_code != 200:
model_id = "zai-org/GLM-4.5V:novita"
payload["model"] = model_id
response = requests.post(api_url, headers=headers, json=payload, timeout=90)
if response.status_code != 200:
return "HF Boss API Error", f"HTTP {response.status_code}", response.text
data = response.json()
raw_text = data["choices"][0]["message"]["content"]
# AGGRESSIVE EXTRACTION LOGIC
# This regex handles cases with or without bolding, and different spacings
def extract(label, text):
# Look for **Label**, Label:, etc.
pattern = rf'(?:\*\*|#)?{label}(?:\*\*|#)?\s*[:\-]?\s*(.*?)(?=\s*(?:\n(?:\*\*|#)?[A-Z][a-z]+ [A-Z][a-z]+:?|\n(?:\*\*|#)?[A-Z][a-z]+:?)|$)'
match = re.search(pattern, text, re.IGNORECASE | re.DOTALL)
return match.group(1).strip() if match else None
caption = extract("Caption", raw_text)
answer = extract("Final Answer", raw_text)
explanation = extract("Explanation", raw_text)
# Emergency Fallback: If regex fails, use the raw text split by lines
if not caption or not answer:
lines = [l.strip() for l in raw_text.split('\n') if l.strip()]
caption = caption or (lines[0] if len(lines) > 0 else "Analysis failed to parse.")
answer = answer or (lines[1] if len(lines) > 1 else "No answer found in output.")
explanation = explanation or (" ".join(lines[2:]) if len(lines) > 2 else raw_text)
# Cleanup
caption = caption.replace("**", "").replace("\n", " ").strip()
answer = answer.replace("**", "").replace("\n", " ").strip()
explanation = explanation.replace("**", "").strip()
return caption, answer, explanation
except Exception as e:
return "HF Boss Internal Crash", "Parsing Error", f"Raw: {locals().get('raw_text', 'No text')} | Error: {repr(e)}"