Spaces:
Sleeping
Sleeping
import gradio as gr | |
import logging | |
# Ipotizziamo che tu abbia queste funzioni nel tuo progetto: | |
# - list_databases(), create_database(), modify_database(), delete_database()... | |
# - list_indexed_files(), upload_and_index(), delete_file_from_database(), etc. | |
# - search_documents(), list_indexed_documents()... | |
# | |
# Se hanno nomi o posizioni diverse, adatta gli import di conseguenza | |
from app.document_handling import ( | |
list_databases, | |
create_database, | |
modify_database, | |
delete_database, | |
upload_and_index, | |
list_indexed_files, | |
delete_file_from_database, | |
list_indexed_documents, | |
search_documents, | |
) | |
from app.llm_handling import answer_question | |
from app.logging_config import configure_logging | |
configure_logging() | |
def update_dropdowns(): | |
"""Aggiorna tutti i dropdown con la lista aggiornata dei database.""" | |
databases = list_databases() | |
# Ritorniamo 6 update() perché nel codice ci sono 6 dropdown da sincronizzare | |
return [gr.update(choices=databases) for _ in range(6)] | |
def extract_text_from_files(files): | |
"""Estrae e concatena il testo da PDF, DOCX e TXT.""" | |
text = "" | |
for file in files: | |
try: | |
if file.name.endswith('.pdf'): | |
text += extract_text_from_pdf(file.name) # Definita in document_handling | |
elif file.name.endswith('.docx'): | |
text += extract_text_from_docx(file.name) # Definita in document_handling | |
else: | |
with open(file.name, 'r', encoding='utf-8') as f: | |
text += f.read() | |
except Exception as e: | |
logging.error(f"Errore durante la lettura del file {file.name}: {e}") | |
return text | |
with gr.Blocks() as rag_chatbot: | |
gr.Markdown("# Chatbot basato su RAG") | |
databases = list_databases() | |
# Questi State() servono per la gestione dei dropdown. | |
# Se non ti servono come stati separati, puoi anche rimuoverli. | |
db_name_upload = gr.State() | |
db_name_list = gr.State() | |
db_name_chat = gr.State() | |
db_name_new = gr.State() | |
modify_db_old_name = gr.State() | |
delete_db_dropdown = gr.State() | |
# ============================================= | |
# TAB: Chatbot | |
# ============================================= | |
with gr.Tab("Chatbot"): | |
with gr.Row(): | |
with gr.Column(scale=2): | |
# Dropdown per selezionare il DB | |
db_name_chat = gr.Dropdown( | |
choices=databases, | |
label="Seleziona Database", | |
value="default_db" | |
) | |
# Chatbot component | |
chatbot = gr.Chatbot(label="Conversazione", type="messages") | |
# Input domanda | |
question_input = gr.Textbox( | |
label="Fai una domanda", | |
placeholder="Scrivi qui la tua domanda...", | |
lines=2 | |
) | |
# Bottoni azione | |
with gr.Row(): | |
ask_button = gr.Button("Invia") | |
clear_button = gr.Button("Pulisci Chat") | |
# File upload con dimensioni ridotte | |
with gr.Row(): | |
file_input = gr.File( | |
label="Carica PDF/Docx/TXT per la conversazione", | |
file_types=[".pdf", ".docx", ".txt"], | |
file_count="multiple", | |
height="100px", # Altezza ridotta | |
scale=3 # Riduce la larghezza relativa | |
) | |
upload_button = gr.Button("Carica Documenti", scale=1) | |
# Stato chat | |
chat_state = gr.State([]) | |
# ---------------------- | |
# FUNZIONI DI CALLBACK | |
# ---------------------- | |
def chat_upload_and_respond(files, chat_history, db_name): | |
# Se chat_history è None, inizializziamo | |
if chat_history is None: | |
chat_history = [] | |
# Estrai il testo dai file | |
text = extract_text_from_files(files) | |
# Aggiungo un messaggio "assistant" che mostra il testo caricato | |
chat_history.append({ | |
"role": "assistant", | |
"content": f"📄 Contenuto dei documenti caricati:\n{text}" | |
}) | |
return chat_history | |
def respond(message, chat_history, db_name): | |
if chat_history is None: | |
chat_history = [] | |
# `answer_question` restituisce due messaggi (user + assistant) in lista | |
new_messages = answer_question(message, db_name) | |
# Li aggiungiamo in coda alla history | |
chat_history.extend(new_messages) | |
# Ritorniamo l'input svuotato (per pulire il Textbox) e la nuova history | |
return "", chat_history | |
def clear_chat(): | |
# Svuota la chat | |
return [], [] | |
# ------------------ | |
# EVENTI BOTTONE | |
# ------------------ | |
upload_button.click( | |
fn=chat_upload_and_respond, | |
inputs=[file_input, chat_state, db_name_chat], | |
outputs=chatbot | |
) | |
ask_button.click( | |
fn=respond, | |
inputs=[question_input, chat_state, db_name_chat], | |
outputs=[question_input, chatbot] | |
) | |
clear_button.click( | |
fn=clear_chat, | |
outputs=[chatbot, chat_state] | |
) | |
# ============================================= | |
# TAB: Gestione Database | |
# ============================================= | |
with gr.Tab("Gestione Database"): | |
gr.Markdown("## Operazioni sui Database") | |
with gr.Row(): | |
with gr.Column(): | |
gr.Markdown("### Crea Database") | |
db_name_input = gr.Textbox(label="Nome Nuovo Database") | |
create_db_button = gr.Button("Crea Database") | |
create_output = gr.Textbox(label="Stato Creazione") | |
with gr.Column(): | |
gr.Markdown("### Rinomina Database") | |
modify_db_old_name = gr.Dropdown(choices=databases, label="Database da Rinominare") | |
modify_db_new_name = gr.Textbox(label="Nuovo Nome") | |
modify_db_button = gr.Button("Rinomina Database") | |
modify_output = gr.Textbox(label="Stato Modifica") | |
with gr.Column(): | |
gr.Markdown("### Elimina Database") | |
delete_db_dropdown = gr.Dropdown(choices=databases, label="Database da Eliminare") | |
delete_db_button = gr.Button("Elimina Database") | |
delete_output = gr.Textbox(label="Stato Eliminazione") | |
# Eventi per i pulsanti di gestione DB | |
create_db_button.click( | |
create_database, # funzione | |
inputs=db_name_input, # input | |
outputs=create_output # output | |
).then( | |
update_dropdowns, | |
outputs=[db_name_upload, db_name_list, db_name_chat, db_name_new, modify_db_old_name, delete_db_dropdown] | |
) | |
modify_db_button.click( | |
modify_database, | |
inputs=[modify_db_old_name, modify_db_new_name], | |
outputs=modify_output | |
).then( | |
update_dropdowns, | |
outputs=[db_name_upload, db_name_list, db_name_chat, db_name_new, modify_db_old_name, delete_db_dropdown] | |
) | |
delete_db_button.click( | |
delete_database, | |
inputs=delete_db_dropdown, | |
outputs=delete_output | |
).then( | |
update_dropdowns, | |
outputs=[db_name_upload, db_name_list, db_name_chat, db_name_new, modify_db_old_name, delete_db_dropdown] | |
) | |
# ============================================= | |
# TAB: Gestione Documenti | |
# ============================================= | |
with gr.Tab("Gestione Documenti"): | |
with gr.Column(): | |
gr.Markdown("### Carica Documenti") | |
with gr.Row(): | |
file_input = gr.File( | |
label="Carica i tuoi documenti", | |
file_types=[".txt", ".pdf", ".docx"], | |
file_count="multiple" | |
) | |
db_name_upload = gr.Dropdown( | |
choices=databases, | |
label="Seleziona Database", | |
value="default_db" | |
) | |
with gr.Row(): | |
title_input = gr.Textbox(label="Titolo del documento") | |
author_input = gr.Textbox(label="Autore") | |
upload_button = gr.Button("Indicizza Documenti") | |
upload_output = gr.Textbox(label="Stato Upload") | |
with gr.Column(): | |
gr.Markdown("### Documenti nel Database") | |
db_name_list = gr.Dropdown( | |
choices=databases, | |
label="Seleziona Database", | |
value="default_db" | |
) | |
list_button = gr.Button("Visualizza Files") | |
list_output = gr.Textbox(label="Files nel Database") | |
delete_file_input = gr.Textbox(label="Nome file da eliminare") | |
delete_file_button = gr.Button("Elimina File") | |
delete_file_output = gr.Textbox(label="Stato Eliminazione") | |
# Eventi | |
upload_button.click( | |
upload_and_index, | |
inputs=[file_input, title_input, author_input, db_name_upload], | |
outputs=upload_output | |
).then( | |
list_indexed_files, | |
inputs=db_name_list, | |
outputs=list_output | |
) | |
list_button.click( | |
list_indexed_files, | |
inputs=db_name_list, | |
outputs=list_output | |
) | |
delete_file_button.click( | |
delete_file_from_database, | |
inputs=[delete_file_input, db_name_list], | |
outputs=delete_file_output | |
).then( | |
list_indexed_files, | |
inputs=db_name_list, | |
outputs=list_output | |
).then( | |
update_dropdowns, | |
outputs=[db_name_upload, db_name_list, db_name_chat, db_name_new, modify_db_old_name, delete_db_dropdown] | |
) | |
# ============================================= | |
# TAB: Visualizza Documenti Indicizzati | |
# ============================================= | |
with gr.Tab("Visualizza Documenti Indicizzati"): | |
with gr.Column(): | |
gr.Markdown("### Documenti nel Database") | |
db_name_list = gr.Dropdown( | |
choices=databases, | |
label="Seleziona Database", | |
value="default_db", | |
interactive=True | |
) | |
list_button = gr.Button("Visualizza Documenti") | |
list_output = gr.Textbox( | |
label="Elenco Documenti", | |
lines=10, | |
interactive=False, | |
value="Clicca 'Visualizza Documenti' per vedere l'elenco" | |
) | |
list_button.click( | |
fn=list_indexed_documents, | |
inputs=[db_name_list], | |
outputs=[list_output], | |
api_name="list_docs" | |
) | |
# ============================================= | |
# TAB: Nuove Funzionalità | |
# ============================================= | |
with gr.Tab("Nuove Funzionalità"): | |
gr.Markdown("## Cerca Documenti e Genera Riassunto") | |
db_name_new = gr.Dropdown(choices=databases, label="Seleziona Database", value="default_db") | |
search_input = gr.Textbox(label="Inserisci Termine di Ricerca") | |
search_button = gr.Button("Cerca Documenti") | |
search_output = gr.Textbox(label="Documenti Trovati") | |
summary_button = gr.Button("Genera Riassunto") | |
summary_output = gr.Textbox(label="Riassunto") | |
search_button.click( | |
search_documents, | |
inputs=[search_input, db_name_new], | |
outputs=search_output | |
) | |
# Esempio di eventuale generazione riassunto | |
# summary_button.click( | |
# generate_summary, | |
# inputs=db_name_new, | |
# outputs=summary_output | |
# ) | |
# Avvio dell'app | |
if __name__ == "__main__": | |
rag_chatbot.launch() | |