Spaces:
Runtime error
Runtime error
File size: 4,500 Bytes
de3503b 3ae1f10 de97f37 24059db 3ae1f10 de3503b 24059db 3ae1f10 de3503b 24059db de3503b 24059db de3503b 24059db de3503b 24059db f297a4a 3ae1f10 567fe9c 3ae1f10 24059db 3ae1f10 24059db de97f37 3ae1f10 f297a4a 24059db 3ae1f10 f297a4a 24059db 3ae1f10 24059db de97f37 f297a4a 3ae1f10 de97f37 24059db 3ae1f10 f297a4a 24059db |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
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)}
|