klydekushy commited on
Commit
24059db
·
verified ·
1 Parent(s): de3503b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +69 -28
app.py CHANGED
@@ -1,85 +1,126 @@
1
  from fastapi import FastAPI
2
  from pydantic import BaseModel
3
  import chromadb
 
4
  from sentence_transformers import SentenceTransformer
5
  import os
6
  import google.generativeai as genai
 
 
7
 
8
  # === 1. Configurer le cache dans /tmp/ (accessible en écriture) ===
9
- os.environ['HF_HOME'] = '/tmp/huggingface' # Dossier pour les modèles Hugging Face
10
- os.environ['TRANSFORMERS_CACHE'] = '/tmp/huggingface' # Dossier pour Transformers
11
- os.makedirs('/tmp/huggingface', exist_ok=True) # Crée le dossier si inexistant
12
 
13
  # === 2. Charger le modèle avec gestion des erreurs ===
14
  try:
15
- # Essayer avec le nom court
16
- model = SentenceTransformer(
17
- 'all-MiniLM-L6-v2',
18
- cache_folder='/tmp/huggingface'
19
- )
20
  except Exception as e:
21
  print(f"Erreur de chargement (nom court): {e}")
22
- # Fallback: utiliser le nom complet du modèle
23
- model = SentenceTransformer(
24
- 'sentence-transformers/all-MiniLM-L6-v2',
25
- cache_folder='/tmp/huggingface'
26
- )
27
 
28
  # === 3. Configurer ChromaDB dans /tmp/ ===
29
  client = chromadb.PersistentClient(path="/tmp/chroma_db")
30
 
31
- # === 4. Configurer Gemini (existant) ===
32
  GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY", "")
33
  genai.configure(api_key=GEMINI_API_KEY)
34
  model_gemini = genai.GenerativeModel("gemini-2.0-flash-lite")
35
 
36
  app = FastAPI()
37
 
38
- # ... (le reste de votre code reste inchangé) ...
39
-
40
  class Query(BaseModel):
41
  query: str
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  @app.get("/")
44
  async def root():
45
  return {"message": "🎵 GrooveNomad Festivals API est en ligne !"}
46
 
47
  @app.post("/api/ask")
48
  async def ask_festival(data: Query):
49
- try:
50
- collection = client.get_collection("Festivals")
51
- except Exception:
52
- return {"error": "Collection 'Festivals' non trouvée."}
53
-
54
  query_embedding = model.encode(data.query).tolist()
55
  results = collection.query(
56
  query_embeddings=[query_embedding],
57
  n_results=3,
58
  include=["metadatas", "distances"]
59
  )
60
-
61
  def get_val(meta, key):
62
  val = meta.get(key)
63
  if not val or str(val).lower() in ["", "nan", "none"]:
64
  return "Non spécifié"
65
  return val
66
-
67
  context = "\n".join([
68
  f"{get_val(m, 'Festival Name')} à {get_val(m, 'City')} ({get_val(m, 'Country')}) le {get_val(m, 'Dates')} 🎶 {get_val(m, 'Genre')} – {get_val(m, 'Ticket Price (EUR)')}€"
69
  for m in results["metadatas"][0]
70
  ])
71
-
72
  prompt = f"""Tu es un expert des festivals. Voici la requête :
73
  \"{data.query}\"
74
-
75
  Voici les options :
76
  {context}
77
-
78
  Génère une réponse naturelle, enthousiaste, concise, avec des emojis."""
79
-
80
  try:
81
  response = model_gemini.generate_content(prompt)
82
  return {"response": response.text}
83
  except Exception as e:
84
  print(f"Erreur lors de la génération : {e}")
85
- return {"error": str(e)}
 
1
  from fastapi import FastAPI
2
  from pydantic import BaseModel
3
  import chromadb
4
+ from chromadb.config import Settings
5
  from sentence_transformers import SentenceTransformer
6
  import os
7
  import google.generativeai as genai
8
+ import pandas as pd
9
+ import numpy as np
10
 
11
  # === 1. Configurer le cache dans /tmp/ (accessible en écriture) ===
12
+ os.environ['HF_HOME'] = '/tmp/huggingface'
13
+ os.environ['TRANSFORMERS_CACHE'] = '/tmp/huggingface'
14
+ os.makedirs('/tmp/huggingface', exist_ok=True)
15
 
16
  # === 2. Charger le modèle avec gestion des erreurs ===
17
  try:
18
+ model = SentenceTransformer('all-MiniLM-L6-v2', cache_folder='/tmp/huggingface')
 
 
 
 
19
  except Exception as e:
20
  print(f"Erreur de chargement (nom court): {e}")
21
+ model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2', cache_folder='/tmp/huggingface')
 
 
 
 
22
 
23
  # === 3. Configurer ChromaDB dans /tmp/ ===
24
  client = chromadb.PersistentClient(path="/tmp/chroma_db")
25
 
26
+ # === 4. Configurer Gemini ===
27
  GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY", "")
28
  genai.configure(api_key=GEMINI_API_KEY)
29
  model_gemini = genai.GenerativeModel("gemini-2.0-flash-lite")
30
 
31
  app = FastAPI()
32
 
33
+ # === Classe Query pour FastAPI ===
 
34
  class Query(BaseModel):
35
  query: str
36
 
37
+ # === Fonction d'initialisation de la collection ===
38
+ def init_collection():
39
+ # Essaie de récupérer la collection, sinon la crée et l'initialise
40
+ try:
41
+ collection = client.get_collection("Festivals")
42
+ print("Collection 'Festivals' chargée")
43
+ except Exception:
44
+ print("Collection 'Festivals' non trouvée, création et remplissage...")
45
+ collection = client.create_collection(name="Festivals", metadata={"hnsw:space": "ip"})
46
+
47
+ # Ici tu dois récupérer tes données (ex: depuis Airtable)
48
+ # Exemple fictif avec dataframe statique, remplace par ta vraie fonction fetch_data()
49
+ df = pd.DataFrame([
50
+ {
51
+ "Festival Name": "Hellfest",
52
+ "City": "Clisson",
53
+ "Country": "France",
54
+ "Dates": "15-18 Juin",
55
+ "Genre": "Metal/Rock",
56
+ "Ticket Price (EUR)": 200,
57
+ "Accommodation option": "Camping",
58
+ "Atmosphere": "Festive"
59
+ },
60
+ {
61
+ "Festival Name": "Sziget",
62
+ "City": "Budapest",
63
+ "Country": "Hongrie",
64
+ "Dates": "10-15 Août",
65
+ "Genre": "Divers",
66
+ "Ticket Price (EUR)": 150,
67
+ "Accommodation option": "Tentes",
68
+ "Atmosphere": "Jeune et dynamique"
69
+ }
70
+ ])
71
+
72
+ embeddings, metadatas, ids = [], [], []
73
+ for idx, row in df.iterrows():
74
+ row_text = "\n".join([f"{col}: {val}" for col, val in row.items() if pd.notna(val)])
75
+ embedding = model.encode(row_text)
76
+ embedding /= np.linalg.norm(embedding)
77
+ embeddings.append(embedding.tolist())
78
+ metadatas.append({k: str(v) for k, v in row.items() if pd.notna(v)})
79
+ ids.append(f"fest_{idx}")
80
+
81
+ collection.add(embeddings=embeddings, metadatas=metadatas, ids=ids)
82
+ print(f"Collection 'Festivals' initialisée avec {len(ids)} entrées")
83
+
84
+ return collection
85
+
86
+
87
+ # === Initialisation au démarrage ===
88
+ collection = init_collection()
89
+
90
+
91
  @app.get("/")
92
  async def root():
93
  return {"message": "🎵 GrooveNomad Festivals API est en ligne !"}
94
 
95
  @app.post("/api/ask")
96
  async def ask_festival(data: Query):
 
 
 
 
 
97
  query_embedding = model.encode(data.query).tolist()
98
  results = collection.query(
99
  query_embeddings=[query_embedding],
100
  n_results=3,
101
  include=["metadatas", "distances"]
102
  )
103
+
104
  def get_val(meta, key):
105
  val = meta.get(key)
106
  if not val or str(val).lower() in ["", "nan", "none"]:
107
  return "Non spécifié"
108
  return val
109
+
110
  context = "\n".join([
111
  f"{get_val(m, 'Festival Name')} à {get_val(m, 'City')} ({get_val(m, 'Country')}) le {get_val(m, 'Dates')} 🎶 {get_val(m, 'Genre')} – {get_val(m, 'Ticket Price (EUR)')}€"
112
  for m in results["metadatas"][0]
113
  ])
114
+
115
  prompt = f"""Tu es un expert des festivals. Voici la requête :
116
  \"{data.query}\"
 
117
  Voici les options :
118
  {context}
 
119
  Génère une réponse naturelle, enthousiaste, concise, avec des emojis."""
120
+
121
  try:
122
  response = model_gemini.generate_content(prompt)
123
  return {"response": response.text}
124
  except Exception as e:
125
  print(f"Erreur lors de la génération : {e}")
126
+ return {"error": str(e)}