klydekushy's picture
Update app.py
24059db verified
from fastapi import FastAPI
from pydantic import BaseModel
import chromadb
from chromadb.config import Settings
from sentence_transformers import SentenceTransformer
import os
import google.generativeai as genai
import pandas as pd
import numpy as np
# === 1. Configurer le cache dans /tmp/ (accessible en écriture) ===
os.environ['HF_HOME'] = '/tmp/huggingface'
os.environ['TRANSFORMERS_CACHE'] = '/tmp/huggingface'
os.makedirs('/tmp/huggingface', exist_ok=True)
# === 2. Charger le modèle avec gestion des erreurs ===
try:
model = SentenceTransformer('all-MiniLM-L6-v2', cache_folder='/tmp/huggingface')
except Exception as e:
print(f"Erreur de chargement (nom court): {e}")
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2', cache_folder='/tmp/huggingface')
# === 3. Configurer ChromaDB dans /tmp/ ===
client = chromadb.PersistentClient(path="/tmp/chroma_db")
# === 4. Configurer Gemini ===
GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY", "")
genai.configure(api_key=GEMINI_API_KEY)
model_gemini = genai.GenerativeModel("gemini-2.0-flash-lite")
app = FastAPI()
# === Classe Query pour FastAPI ===
class Query(BaseModel):
query: str
# === Fonction d'initialisation de la collection ===
def init_collection():
# Essaie de récupérer la collection, sinon la crée et l'initialise
try:
collection = client.get_collection("Festivals")
print("Collection 'Festivals' chargée")
except Exception:
print("Collection 'Festivals' non trouvée, création et remplissage...")
collection = client.create_collection(name="Festivals", metadata={"hnsw:space": "ip"})
# Ici tu dois récupérer tes données (ex: depuis Airtable)
# Exemple fictif avec dataframe statique, remplace par ta vraie fonction fetch_data()
df = pd.DataFrame([
{
"Festival Name": "Hellfest",
"City": "Clisson",
"Country": "France",
"Dates": "15-18 Juin",
"Genre": "Metal/Rock",
"Ticket Price (EUR)": 200,
"Accommodation option": "Camping",
"Atmosphere": "Festive"
},
{
"Festival Name": "Sziget",
"City": "Budapest",
"Country": "Hongrie",
"Dates": "10-15 Août",
"Genre": "Divers",
"Ticket Price (EUR)": 150,
"Accommodation option": "Tentes",
"Atmosphere": "Jeune et dynamique"
}
])
embeddings, metadatas, ids = [], [], []
for idx, row in df.iterrows():
row_text = "\n".join([f"{col}: {val}" for col, val in row.items() if pd.notna(val)])
embedding = model.encode(row_text)
embedding /= np.linalg.norm(embedding)
embeddings.append(embedding.tolist())
metadatas.append({k: str(v) for k, v in row.items() if pd.notna(v)})
ids.append(f"fest_{idx}")
collection.add(embeddings=embeddings, metadatas=metadatas, ids=ids)
print(f"Collection 'Festivals' initialisée avec {len(ids)} entrées")
return collection
# === Initialisation au démarrage ===
collection = init_collection()
@app.get("/")
async def root():
return {"message": "🎵 GrooveNomad Festivals API est en ligne !"}
@app.post("/api/ask")
async def ask_festival(data: Query):
query_embedding = model.encode(data.query).tolist()
results = collection.query(
query_embeddings=[query_embedding],
n_results=3,
include=["metadatas", "distances"]
)
def get_val(meta, key):
val = meta.get(key)
if not val or str(val).lower() in ["", "nan", "none"]:
return "Non spécifié"
return val
context = "\n".join([
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)')}€"
for m in results["metadatas"][0]
])
prompt = f"""Tu es un expert des festivals. Voici la requête :
\"{data.query}\"
Voici les options :
{context}
Génère une réponse naturelle, enthousiaste, concise, avec des emojis."""
try:
response = model_gemini.generate_content(prompt)
return {"response": response.text}
except Exception as e:
print(f"Erreur lors de la génération : {e}")
return {"error": str(e)}