File size: 4,414 Bytes
88f6e14 f3f8414 88f6e14 |
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 |
# app.py
import gradio as gr
import pandas as pd
import os
import asyncio
from typing import Optional
# Importações de nossos módulos locais
from utils import Historico, setup_font, gerar_pdf_report
from workflow import executar_consulta
from llama_index.core import Settings
from llama_index.llms.groq import Groq
# --- 1. CONFIGURAÇÃO INICIAL ---
# Carrega a chave da API dos Secrets do Hugging Face
API_KEY = os.environ.get("GROQ_API_KEY")
# Prepara a fonte para geração do PDF
FONT_PATH = setup_font()
# Configura o LLM do LlamaIndex
if API_KEY:
Settings.llm = Groq(model="meta-llama/llama-4-scout-17b-16e-instruct", api_key=API_KEY)
print("✅ LLM configurado com sucesso!")
else:
print("❌ AVISO: A chave GROQ_API_KEY não foi encontrada nos Secrets. A aplicação não funcionará.")
# --- 2. FUNÇÕES DE CALLBACK DA INTERFACE ---
def carregar_dados(file, df_estado):
if file is None: return "❌ Nenhum arquivo selecionado", df_estado
try:
df_local = pd.read_csv(file.name)
return f"✅ Arquivo carregado! {df_local.shape[0]} linhas.", df_local
except Exception as e:
return f"❌ Erro ao carregar: {str(e)}", df_estado
def processar_pergunta(pergunta: str, df_local: Optional[pd.DataFrame], historico: Historico):
if df_local is None:
resposta = "❌ Por favor, carregue um arquivo CSV primeiro."
return resposta, historico
if not pergunta.strip():
resposta = "❌ Por favor, digite uma pergunta válida."
return resposta, historico
resultado = asyncio.run(executar_consulta(pergunta, df_local))
resposta = resultado.get("resposta_final", "❌ Erro: a resposta não foi gerada.")
historico.adicionar(pergunta, resposta)
return resposta, historico
def chat_interface(pergunta, chat_history, df_local, historico_obj):
chat_history.append({"role": "user", "content": pergunta})
resposta, historico_obj_atualizado = processar_pergunta(pergunta, df_local, historico_obj)
chat_history.append({"role": "assistant", "content": resposta})
return "", chat_history, historico_obj_atualizado
def gerar_pdf_callback(historico: Historico):
return gerar_pdf_report(historico, FONT_PATH)
def limpar_conversa():
return Historico(), None
# --- 3. DEFINIÇÃO DA INTERFACE GRADIO ---
with gr.Blocks(title="Pandas CSV Analyzer", theme=gr.themes.Soft()) as app:
gr.Markdown(
"""
<div style="text-align: center;">
<h1>🐼 Pandas CSV Analyzer (LlamaIndex)</h1>
<p>Faça upload de um arquivo CSV, faça perguntas em linguagem natural e baixe o relatório!</p>
</div>
"""
)
df_estado = gr.State()
historico_estado = gr.State(value=Historico())
with gr.Row():
with gr.Column(scale=1):
input_arquivo = gr.File(label="1. Faça upload do CSV", file_types=[".csv"])
upload_status = gr.Textbox(label="Status", interactive=False)
botao_gerar_pdf = gr.Button("📄 Gerar e Baixar PDF", variant="secondary")
output_pdf = gr.File(label="Baixar Relatório", interactive=False)
with gr.Column(scale=3):
chatbot = gr.Chatbot(label="Histórico da Conversa", height=550, type='messages')
with gr.Row():
input_pergunta = gr.Textbox(scale=4, show_label=False, placeholder="Ex: Qual o total de vendas por filial?", container=False)
botao_enviar = gr.Button("Enviar", variant="primary", scale=1, min_width=100)
# Conexões dos Eventos
input_arquivo.upload(fn=carregar_dados, inputs=[input_arquivo, df_estado], outputs=[upload_status, df_estado])
botao_enviar.click(fn=chat_interface, inputs=[input_pergunta, chatbot, df_estado, historico_estado], outputs=[input_pergunta, chatbot, historico_estado])
input_pergunta.submit(fn=chat_interface, inputs=[input_pergunta, chatbot, df_estado, historico_estado], outputs=[input_pergunta, chatbot, historico_estado])
botao_gerar_pdf.click(fn=gerar_pdf_callback, inputs=[historico_estado], outputs=[output_pdf])
chatbot.clear(fn=limpar_conversa, inputs=[], outputs=[historico_estado, output_pdf])
# --- 4. LANÇAR A APLICAÇÃO ---
if __name__ == "__main__":
if not API_KEY:
print("A aplicação não pode iniciar sem a chave GROQ_API_KEY. Por favor, configure-a nos secrets do seu Space.")
else:
app.launch() |