import os os.environ['HF_HOME'] = '/tmp/cache' os.environ['TORCH_HOME'] = '/tmp/cache' import json from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from PIL import Image import torch import requests from io import BytesIO # ==================== CRÉATION DE L'APP EN PREMIER ==================== app = FastAPI(title="Fashion Classification API") # ==================== MIDDLEWARE EN SECOND ==================== app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], expose_headers=["*"] ) # ==================== CONFIGURATION DU MODÈLE ==================== print("🔄 Chargement du modèle Fashion CLIP...") model = None processor = None def load_model(): global model, processor try: model_name = "patrickjohncyh/fashion-clip" model = CLIPModel.from_pretrained(model_name) processor = CLIPProcessor.from_pretrained(model_name) print("✅ Modèle chargé avec succès!") except Exception as e: print(f"❌ Erreur de chargement: {e}") # ==================== CATÉGORIES ==================== CATEGORIES_FR = { "haut": ["a t-shirt", "a shirt", "a sweater", "a blouse", "a top"], "pantalon": ["jeans", "pants", "trousers", "leggings"], "robe": ["a dress", "a gown", "a sundress"], "jupe": ["a skirt"], "short": ["shorts", "bermuda shorts"], "veste": ["a jacket", "a blazer", "a leather jacket"], "manteau": ["a coat", "a winter coat", "a parka"], "chaussures": ["sneakers", "high heels", "boots", "sandals"], "sac": ["a handbag", "a purse", "a backpack"], "accessoire": ["a hat", "sunglasses", "a scarf", "a belt"], "autre": ["clothing", "fashion item"] } # ==================== ROUTES ==================== @app.get("/") def read_root(): return {"message": "Fashion Classification API is running!", "status": "OK"} @app.get("/health") def health_check(): return { "model_loaded": model is not None, "status": "ready" if model else "loading" } @app.post("/classify") async def classify_fashion(image_data: dict): """ Endpoint pour Lovable - accepte une URL d'image Format attendu: {"imageUrl": "https://example.com/image.jpg"} """ try: if not model or not processor: raise HTTPException(status_code=503, detail="Model not loaded yet") image_url = image_data.get("imageUrl") if not image_url: raise HTTPException(status_code=400, detail="imageUrl is required") # Télécharger l'image response = requests.get(image_url, timeout=30) response.raise_for_status() # Ouvrir et préparer l'image image = Image.open(BytesIO(response.content)).convert("RGB") image.thumbnail((512, 512)) # SIMULATION - En attendant de régler les problèmes de modèle # Retournez des données factices pour tester return { "success": True, "category": "haut", "confidence": 0.92, "colorHex": "#FF0000", "originalCategory": "a t-shirt", "method": "modli-api-test" } except requests.exceptions.RequestException as e: raise HTTPException(status_code=400, detail=f"Invalid image URL: {str(e)}") except Exception as e: raise HTTPException(status_code=500, detail=f"Classification error: {str(e)}") # ==================== CHARGEMENT AU DÉMARRAGE ==================== # Charger le modèle au démarrage (commenté pour l'instant) # load_model() # ==================== POINT D'ENTRÉE ==================== if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=7860)