fashion_backend / outfit.py
Liyew's picture
Create outfit.py
9a0f04e verified
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": ""}]}]