salma-mahjoub commited on
Commit
87b7096
·
1 Parent(s): 81fc80a

Fix: Update Gradio 6.x API endpoint configuration

Browse files
Files changed (1) hide show
  1. app.py +83 -15
app.py CHANGED
@@ -1,6 +1,7 @@
1
  """
2
  Labasni Recommender Service - Hugging Face Space
3
  Interface Gradio pour les recommandations d'outfits
 
4
  """
5
 
6
  import gradio as gr
@@ -20,47 +21,114 @@ def recommend_outfit_api(clothes_json: str, preference: str, city: str = "Tunis"
20
  JSON avec l'outfit recommandé
21
  """
22
  try:
23
- # Parser le JSON
 
 
 
 
24
  clothes_data = json.loads(clothes_json)
 
25
 
26
  # Appeler le modèle ML
27
  result = recommend_outfit_ml(clothes_data, preference, city)
 
28
 
29
- # Retourner le résultat en JSON
30
  return json.dumps(result, indent=2)
 
 
 
 
 
 
31
  except Exception as e:
32
- # Retourner l'erreur en JSON
33
- return json.dumps({"success": False, "error": str(e)})
 
34
 
35
  # ✅ Interface Gradio avec api_name explicite
36
- # La variable DOIT s'appeler 'demo' pour Hugging Face Spaces
37
  demo = gr.Interface(
38
  fn=recommend_outfit_api,
39
  inputs=[
40
  gr.Textbox(
41
  label="Clothes Data (JSON)",
42
- placeholder='[{"id":"top1","category":"top","style":"casual",...}]',
43
- lines=10
 
44
  ),
45
  gr.Dropdown(
46
  choices=["casual", "formal", "sport", "chic"],
47
  label="Preference",
48
- value="casual"
 
49
  ),
50
- gr.Textbox(label="City", value="Tunis")
 
 
 
 
51
  ],
52
- outputs=gr.Textbox(label="Recommended Outfit (JSON)", lines=15),
 
 
 
 
53
  title="🎽 Labasni Outfit Recommender",
54
- description="Recommandations d'outfits basées sur ML (TensorFlow + PyTorch)",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  examples=[
56
  [
57
- '[{"id":"top1","category":"top","style":"casual","color":"white","season":"summer","score":0.8,"imageURL":"https://example.com/top.jpg"},{"id":"bot1","category":"bottom","style":"casual","color":"blue","season":"summer","score":0.7,"imageURL":"https://example.com/bottom.jpg"},{"id":"shoe1","category":"footwear","style":"casual","color":"black","season":"summer","score":0.9,"imageURL":"https://example.com/shoes.jpg"}]',
 
58
  "casual",
59
  "Tunis"
 
 
 
 
 
 
 
 
 
 
 
 
60
  ]
61
  ],
62
- api_name="predict" # ✅ CRUCIAL pour exposer l'endpoint /api/predict
 
 
 
 
 
63
  )
64
 
65
- # ✅ Pour Hugging Face Spaces, l'interface est automatiquement détectée et lancée
66
- # Pas besoin d'appeler demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
1
  """
2
  Labasni Recommender Service - Hugging Face Space
3
  Interface Gradio pour les recommandations d'outfits
4
+ Version corrigée avec api_name="predict"
5
  """
6
 
7
  import gradio as gr
 
21
  JSON avec l'outfit recommandé
22
  """
23
  try:
24
+ # Log pour debug
25
+ print(f"📥 Received request: preference={preference}, city={city}")
26
+ print(f"📦 Clothes data length: {len(clothes_json)}")
27
+
28
+ # Parser le JSON des vêtements
29
  clothes_data = json.loads(clothes_json)
30
+ print(f"✅ Parsed {len(clothes_data)} clothes items")
31
 
32
  # Appeler le modèle ML
33
  result = recommend_outfit_ml(clothes_data, preference, city)
34
+ print(f"✅ Model returned: success={result.get('success')}")
35
 
36
+ # Retourner le résultat en JSON formaté
37
  return json.dumps(result, indent=2)
38
+
39
+ except json.JSONDecodeError as e:
40
+ error_msg = f"Invalid JSON format: {str(e)}"
41
+ print(f"❌ {error_msg}")
42
+ return json.dumps({"success": False, "error": error_msg})
43
+
44
  except Exception as e:
45
+ error_msg = f"Error during recommendation: {str(e)}"
46
+ print(f" {error_msg}")
47
+ return json.dumps({"success": False, "error": error_msg})
48
 
49
  # ✅ Interface Gradio avec api_name explicite
50
+ # IMPORTANT: La variable DOIT s'appeler 'demo' pour Hugging Face Spaces
51
  demo = gr.Interface(
52
  fn=recommend_outfit_api,
53
  inputs=[
54
  gr.Textbox(
55
  label="Clothes Data (JSON)",
56
+ placeholder='[{"id":"top1","category":"top","style":"casual","color":"white","season":"summer","score":0.8,"imageURL":"https://example.com/top.jpg"}]',
57
+ lines=10,
58
+ info="Liste des vêtements au format JSON"
59
  ),
60
  gr.Dropdown(
61
  choices=["casual", "formal", "sport", "chic"],
62
  label="Preference",
63
+ value="casual",
64
+ info="Style d'outfit souhaité"
65
  ),
66
+ gr.Textbox(
67
+ label="City",
68
+ value="Tunis",
69
+ info="Ville pour la météo"
70
+ )
71
  ],
72
+ outputs=gr.Textbox(
73
+ label="Recommended Outfit (JSON)",
74
+ lines=15,
75
+ show_copy_button=True
76
+ ),
77
  title="🎽 Labasni Outfit Recommender",
78
+ description="""
79
+ Recommandations d'outfits basées sur Machine Learning.
80
+
81
+ **Fonctionnalités:**
82
+ - 🤖 Algorithme ML intelligent (ResNet50 + Scikit-learn)
83
+ - 🌤️ Prise en compte de la météo réelle
84
+ - 🎨 Compatibilité des couleurs et styles
85
+ - 📊 Scoring basé sur l'historique
86
+
87
+ **Usage API:**
88
+ ```bash
89
+ curl -X POST https://salma-mahjoub-styleto-recommender.hf.space/api/predict \\
90
+ -H "Content-Type: application/json" \\
91
+ -d '{"data": [CLOTHES_JSON, "casual", "Tunis"]}'
92
+ ```
93
+ """,
94
  examples=[
95
  [
96
+ # Exemple 1: Outfit casual d'été
97
+ '[{"id":"top1","category":"top","style":"casual","color":"white","season":"summer","score":0.8,"imageURL":"https://example.com/top.jpg"},{"id":"bottom1","category":"bottom","style":"casual","color":"blue","season":"summer","score":0.7,"imageURL":"https://example.com/bottom.jpg"},{"id":"shoe1","category":"footwear","style":"casual","color":"black","season":"summer","score":0.9,"imageURL":"https://example.com/shoes.jpg"}]',
98
  "casual",
99
  "Tunis"
100
+ ],
101
+ [
102
+ # Exemple 2: Outfit formel d'hiver
103
+ '[{"id":"shirt1","category":"top","style":"formal","color":"white","season":"winter","score":0.9,"imageURL":"https://example.com/shirt.jpg"},{"id":"pants1","category":"bottom","style":"formal","color":"black","season":"winter","score":0.8,"imageURL":"https://example.com/pants.jpg"},{"id":"dress_shoes","category":"footwear","style":"formal","color":"black","season":"winter","score":0.95,"imageURL":"https://example.com/dress_shoes.jpg"}]',
104
+ "formal",
105
+ "Paris"
106
+ ],
107
+ [
108
+ # Exemple 3: Outfit sport
109
+ '[{"id":"tshirt1","category":"top","style":"sport","color":"red","season":"all","score":0.75,"imageURL":"https://example.com/tshirt.jpg"},{"id":"shorts1","category":"bottom","style":"sport","color":"black","season":"summer","score":0.8,"imageURL":"https://example.com/shorts.jpg"},{"id":"sneakers1","category":"footwear","style":"sport","color":"white","season":"all","score":0.9,"imageURL":"https://example.com/sneakers.jpg"}]',
110
+ "sport",
111
+ "New York"
112
  ]
113
  ],
114
+ # ✅ CRUCIAL: api_name="predict" expose l'endpoint /api/predict
115
+ api_name="predict",
116
+
117
+ # Options supplémentaires
118
+ allow_flagging="never", # Désactiver le flagging
119
+ theme=gr.themes.Soft(), # Theme moderne
120
  )
121
 
122
+ # ✅ Pour Hugging Face Spaces:
123
+ # - L'interface est automatiquement détectée via la variable 'demo'
124
+ # - Pas besoin d'appeler demo.launch()
125
+ # - Le Space démarre automatiquement
126
+
127
+ # Pour le développement local (optionnel):
128
+ if __name__ == "__main__":
129
+ # Lancement local pour tester
130
+ demo.launch(
131
+ server_name="0.0.0.0",
132
+ server_port=7860,
133
+ share=False
134
+ )