Liyew commited on
Commit
9a0f04e
·
verified ·
1 Parent(s): 85db2ac

Create outfit.py

Browse files
Files changed (1) hide show
  1. outfit.py +82 -0
outfit.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter
2
+ from pydantic import BaseModel
3
+ from typing import List
4
+ import requests
5
+ import json
6
+ import os
7
+
8
+ router = APIRouter(prefix="/outfit", tags=["Outfit"])
9
+
10
+ WARDROBE_API_URL = "https://wardrobestudio.net/wardrobe/items"
11
+ HF_API_URL = "https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.1"
12
+ HF_TOKEN = os.getenv("HF_TOKEN") # Set in Hugging Face Secrets
13
+ HEADERS = {"Authorization": f"Bearer {HF_TOKEN}"}
14
+
15
+ class Item(BaseModel):
16
+ id: str
17
+ label: str
18
+ image_url: str
19
+
20
+ class OutfitSuggestion(BaseModel):
21
+ day: str
22
+ items: List[Item]
23
+
24
+ def classify_with_clip(image_url: str) -> str:
25
+ return "jacket" if "jacket" in image_url.lower() else "clothing"
26
+
27
+ def get_llm_recommendation(items: List[dict], weather_forecast: List[str]) -> List[dict]:
28
+ prompt = f"""
29
+ You are a fashion stylist. Here is a user's wardrobe. Each item has a unique ID, label, and image:
30
+ {json.dumps(items, indent=2)}
31
+ 7-day forecast: {', '.join(weather_forecast)}.
32
+ Suggest 7 outfits (2–3 item ids per day) for the week. Respond as JSON:
33
+ [
34
+ {{"day": "Monday", "items": ["item1", "item3"]}},
35
+ ...
36
+ ]
37
+ """.strip()
38
+
39
+ response = requests.post(HF_API_URL, headers=HEADERS, json={"inputs": prompt})
40
+ response.raise_for_status()
41
+ result = response.json()
42
+
43
+ if isinstance(result, dict) and "error" in result:
44
+ raise RuntimeError(f"Hugging Face API error: {result['error']}")
45
+
46
+ generated_text = result[0].get("generated_text", "")
47
+ return json.loads(generated_text.split("```")[0].strip())
48
+
49
+ @router.get("/weekly", response_model=List[OutfitSuggestion])
50
+ async def generate_outfits():
51
+ try:
52
+ res = requests.get(WARDROBE_API_URL)
53
+ res.raise_for_status()
54
+ wardrobe = res.json()
55
+ except Exception as e:
56
+ return [{"day": "Error", "items": [{"id": "error", "label": "Wardrobe fetch failed", "image_url": ""}]}]
57
+
58
+ labeled_items = []
59
+ for idx, item in enumerate(wardrobe):
60
+ image_path = item.get("image_url")
61
+ image_url = f"https://wardrobestudio.net{image_path}"
62
+ label = classify_with_clip(image_url)
63
+ labeled_items.append({
64
+ "id": f"item{idx+1}",
65
+ "label": label,
66
+ "image_url": image_path
67
+ })
68
+
69
+ weather = ["sunny", "rainy", "cloudy", "cold", "warm", "hot", "windy"]
70
+
71
+ try:
72
+ outfits_raw = get_llm_recommendation(labeled_items, weather)
73
+ result = []
74
+ for entry in outfits_raw:
75
+ matched_items = [item for item in labeled_items if item["id"] in entry.get("items", [])]
76
+ result.append({
77
+ "day": entry.get("day", "Unknown"),
78
+ "items": matched_items
79
+ })
80
+ return result
81
+ except Exception as e:
82
+ return [{"day": "Error", "items": [{"id": "error", "label": f"LLM failed: {e}", "image_url": ""}]}]