File size: 2,841 Bytes
9a0f04e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
from fastapi import APIRouter
from pydantic import BaseModel
from typing import List
import requests
import json
import os

router = APIRouter(prefix="/outfit", tags=["Outfit"])

WARDROBE_API_URL = "https://wardrobestudio.net/wardrobe/items"
HF_API_URL = "https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.1"
HF_TOKEN = os.getenv("HF_TOKEN")  # Set in Hugging Face Secrets
HEADERS = {"Authorization": f"Bearer {HF_TOKEN}"}

class Item(BaseModel):
    id: str
    label: str
    image_url: str

class OutfitSuggestion(BaseModel):
    day: str
    items: List[Item]

def classify_with_clip(image_url: str) -> str:
    return "jacket" if "jacket" in image_url.lower() else "clothing"

def get_llm_recommendation(items: List[dict], weather_forecast: List[str]) -> List[dict]:
    prompt = f"""
You are a fashion stylist. Here is a user's wardrobe. Each item has a unique ID, label, and image:
{json.dumps(items, indent=2)}
7-day forecast: {', '.join(weather_forecast)}.
Suggest 7 outfits (2–3 item ids per day) for the week. Respond as JSON:
[
  {{"day": "Monday", "items": ["item1", "item3"]}},
  ...
]
""".strip()

    response = requests.post(HF_API_URL, headers=HEADERS, json={"inputs": prompt})
    response.raise_for_status()
    result = response.json()

    if isinstance(result, dict) and "error" in result:
        raise RuntimeError(f"Hugging Face API error: {result['error']}")

    generated_text = result[0].get("generated_text", "")
    return json.loads(generated_text.split("```")[0].strip())

@router.get("/weekly", response_model=List[OutfitSuggestion])
async def generate_outfits():
    try:
        res = requests.get(WARDROBE_API_URL)
        res.raise_for_status()
        wardrobe = res.json()
    except Exception as e:
        return [{"day": "Error", "items": [{"id": "error", "label": "Wardrobe fetch failed", "image_url": ""}]}]

    labeled_items = []
    for idx, item in enumerate(wardrobe):
        image_path = item.get("image_url")
        image_url = f"https://wardrobestudio.net{image_path}"
        label = classify_with_clip(image_url)
        labeled_items.append({
            "id": f"item{idx+1}",
            "label": label,
            "image_url": image_path
        })

    weather = ["sunny", "rainy", "cloudy", "cold", "warm", "hot", "windy"]

    try:
        outfits_raw = get_llm_recommendation(labeled_items, weather)
        result = []
        for entry in outfits_raw:
            matched_items = [item for item in labeled_items if item["id"] in entry.get("items", [])]
            result.append({
                "day": entry.get("day", "Unknown"),
                "items": matched_items
            })
        return result
    except Exception as e:
        return [{"day": "Error", "items": [{"id": "error", "label": f"LLM failed: {e}", "image_url": ""}]}]