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" |