Spaces:
Sleeping
Sleeping
import os | |
import gradio as gr | |
from langchain.embeddings import HuggingFaceEmbeddings | |
from langchain.vectorstores import FAISS | |
from googleapiclient.discovery import build | |
from google.oauth2.service_account import Credentials | |
import pickle | |
import time | |
# Initialize embeddings model | |
embeddings = HuggingFaceEmbeddings( | |
model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2" | |
) | |
def load_or_create_vector_store(): | |
"""Load existing vector store or create new one""" | |
if os.path.exists("vector_store.pkl"): | |
with open("vector_store.pkl", "rb") as f: | |
return pickle.load(f) | |
# Google Sheets setup | |
SCOPES = ["https://www.googleapis.com/auth/spreadsheets.readonly"] | |
SPREADSHEET_ID = "13mB_WfOQtOxE1bYO1o-f8aYfh-ooRV1fhOASk9M2DwI" | |
# Load credentials from environment | |
gcp_credentials = os.getenv("GCP_CREDENTIALS") | |
if not gcp_credentials: | |
return None | |
with open("gcp_credentials.json", "w") as f: | |
f.write(gcp_credentials) | |
creds = Credentials.from_service_account_file( | |
"gcp_credentials.json", | |
scopes=SCOPES | |
) | |
service = build("sheets", "v4", credentials=creds) | |
# Load all sheets | |
sheets = [ | |
"geburtstagsinfos", | |
"oeffnungszeiten", | |
"hallenregeln", | |
"hinweise", | |
"kontakt", | |
"attraktionen" | |
] | |
# Prepare documents for embeddings | |
documents = [] | |
for sheet_name in sheets: | |
try: | |
result = service.spreadsheets().values().get( | |
spreadsheetId=SPREADSHEET_ID, | |
range=sheet_name | |
).execute() | |
rows = result.get('values', [])[1:] # Skip header | |
for row in rows: | |
if len(row) >= 2: | |
doc_text = f"Category: {sheet_name}\nQuestion: {row[0]}\nAnswer: {row[1]}" | |
documents.append(doc_text) | |
except Exception as e: | |
print(f"Error loading {sheet_name}: {e}") | |
# Create vector store | |
vector_store = FAISS.from_texts(documents, embeddings) | |
# Save for future use | |
with open("vector_store.pkl", "wb") as f: | |
pickle.dump(vector_store, f) | |
return vector_store | |
# Load or create the vector store | |
vector_store = load_or_create_vector_store() | |
def format_response(results): | |
"""Format search results into a nice response""" | |
if not results: | |
return """Ups! 😅 Dazu habe ich leider keine passende Information gefunden. | |
Aber ich kenne mich super aus mit: | |
- Unseren Öffnungszeiten ⏰ | |
- Den Hallenregeln 📋 | |
- Geburtstagsfeiern 🎂 | |
- Unseren tollen Attraktionen 🎯 | |
- Anfahrt & Kontakt 📍 | |
Frag mich einfach danach!""" | |
# Kategorien prüfen | |
query_text = results[0].page_content.lower() | |
# Adress-/Kontaktanfragen | |
if 'kontakt' in query_text or 'wo finde' in query_text or 'adresse' in query_text: | |
for result in results: | |
if 'contact' in result.metadata.get('source', ''): | |
return f"Cool, dass Du zu uns kommen möchtest! Hier findest Du uns:\n\n{result.page_content}\n\nBis bald! 🚀" | |
# Geburtstagsfragen | |
if 'geburtstag' in query_text or 'feiern' in query_text: | |
birthday_info = [] | |
for result in results: | |
if 'geburtstagsinfos' in result.metadata.get('source', '').lower(): | |
birthday_info.append(result.page_content) | |
if birthday_info: | |
return "Hier sind alle wichtigen Infos zu Kindergeburtstagen:\n\n• " + "\n\n• ".join(birthday_info) | |
# Standardantwort mit dem besten Match | |
return results[0].page_content | |
def chat(message, history): | |
"""Main chat function""" | |
try: | |
if not message.strip(): | |
return "", history | |
if not vector_store: | |
return "Entschuldigung, der Service ist gerade nicht verfügbar. Bitte versuche es später noch einmal.", history | |
# Search for similar content | |
results = vector_store.similarity_search(message, k=1) | |
response = format_response(results) | |
history.append({"role": "user", "content": message}) | |
history.append({"role": "assistant", "content": response}) | |
return "", history | |
except Exception as e: | |
print(f"Error in chat: {e}") | |
return "Entschuldigung, es ist ein Fehler aufgetreten. Bitte versuche es später noch einmal.", history | |
# Gradio Interface | |
with gr.Blocks(css=""" | |
.gradio-container {max-width: 800px !important} | |
.message-wrap {max-width: 800px !important} | |
.message {padding: 15px !important; border-radius: 12px !important; margin: 8px !important} | |
.user-message {background-color: #ff6b00 !important; color: white !important; margin-left: 15% !important} | |
.bot-message {background-color: #f5f5f5 !important; margin-right: 15% !important} | |
.input-row {margin-top: 20px !important} | |
footer {display: none !important} | |
""") as demo: | |
chatbot = gr.Chatbot( | |
value=[], | |
elem_id="chatbot", | |
height=500, | |
avatar_images=("🧑", "🤖"), | |
type="messages" | |
) | |
msg = gr.Textbox( | |
label="Deine Nachricht", | |
placeholder="Was möchtest Du wissen?", | |
lines=2 | |
) | |
submit = gr.Button("Senden", variant="primary") | |
msg.submit(chat, [msg, chatbot], [msg, chatbot]) | |
submit.click(chat, [msg, chatbot], [msg, chatbot]) | |
# Example questions | |
gr.Examples( | |
examples=[ | |
"Was sind die Öffnungszeiten?", | |
"Wie kann ich einen Kindergeburtstag feiern?", | |
"Welche Regeln gibt es?", | |
"Was kostet ein Kindergeburtstag?", | |
"Wo finde ich euch?" | |
], | |
inputs=msg | |
) | |
demo.launch() |