Spaces:
Sleeping
Sleeping
import base64 | |
import json | |
import mimetypes | |
import re | |
from langchain.chat_models import init_chat_model | |
from langchain_core.messages import HumanMessage | |
model = init_chat_model("gemini-2.0-flash", model_provider="google_genai") | |
def _encode_file(file_path: str) -> str: | |
with open(file_path, "rb") as f: | |
return base64.b64encode(f.read()).decode("utf-8") | |
def extract_json(response: str) -> dict: | |
# Match inside ```json ... ``` | |
match = re.search(r"```(?:json)?\s*({.*?})\s*```", response, re.DOTALL) | |
if match: | |
json_str = match.group(1) | |
else: | |
# Fallback if no code block | |
json_str = response.strip() | |
try: | |
return json.loads(json_str) | |
except json.JSONDecodeError as e: | |
return {"error": "Failed to parse JSON", "raw": response, "details": str(e)} | |
def analyze_media_structured(file_path: str) -> str: | |
""" | |
Analyze the uploaded image or video of a craft project. | |
Focus the analysis on general craft quality dimensions: | |
- Structure: Alignment, balance, symmetry | |
- Technique: Precision of folds, stitches, lines, etc. | |
- Neatness: Clean execution, absence of wrinkles or gaps | |
- Materials: Appropriate use, clarity, or consistency (if visible) | |
- Areas for improvement: Clear, actionable suggestions | |
Return a structured dictionary with specific observations. | |
Avoid general encouragement or introductions. | |
Do not refer to yourself or the tool. | |
""" | |
mime_type, _ = mimetypes.guess_type(file_path) | |
if not mime_type: | |
return {"error": "Unsupported file type."} | |
encoded = _encode_file(file_path) | |
prompt = f""" | |
You are a craft analysis assistant. The user uploaded a {mime_type} of their craft project. | |
Please return your observations on the following points: | |
- Structure: comment on balance, alignment, or symmetry. | |
- Technique: precision of folds, stitches, or construction. | |
- Neatness: how polished or clean the work appears. | |
- Materials: if visible, comment on appropriateness or consistency. | |
- Recommendations: a list of 2–3 actionable improvements. | |
Return the comments as a string. | |
""" | |
if mime_type.startswith("video"): | |
content = [ | |
{"type": "text", "text": prompt}, | |
{"type": "media", "data": encoded, "mime_type": mime_type}, | |
] | |
elif mime_type.startswith("image"): | |
content = [ | |
{"type": "text", "text": prompt}, | |
{"type": "image_url", "image_url": f"data:{mime_type};base64,{encoded}"}, | |
] | |
else: | |
return {"error": "Unsupported media type."} | |
response = model.invoke([HumanMessage(content=content)]).content | |
try: | |
return response | |
except Exception: | |
return "Failed to load response from media analysis" |