GABASSI commited on
Commit
4d9d861
·
verified ·
1 Parent(s): 5f6c461

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +116 -0
app.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, StorageContext, load_index_from_storage
4
+ from llama_parse import LlamaParse
5
+ import shutil
6
+
7
+ # --- CONFIGURAÇÃO VISUAL (CSS INDUSTRIAL DARK) ---
8
+ theme_css = """
9
+ body { background-color: #0b0c10; color: #c5c6c7; font-family: 'Roboto', sans-serif; }
10
+ gradio-app { background-color: #0b0c10 !important; }
11
+ /* Cabeçalho */
12
+ .header-container {
13
+ display: flex; align-items: center; justify-content: center; gap: 15px;
14
+ padding: 20px; border-bottom: 1px solid #1f2833; margin-bottom: 20px;
15
+ }
16
+ .logo-img { height: 60px; width: auto; filter: drop-shadow(0 0 10px rgba(102, 252, 241, 0.5)); }
17
+ .brand-name { font-size: 32px; font-weight: bold; color: #66fcf1; letter-spacing: 4px; font-family: 'Impact', sans-serif; }
18
+ /* Chat e Botões */
19
+ .chatbot-area { height: 500px !important; overflow-y: auto; background-color: #1f2833; border: 1px solid #45a29e; border-radius: 10px; }
20
+ button.primary { background-color: #45a29e !important; color: #0b0c10 !important; font-weight: bold; }
21
+ input { background-color: #1f2833 !important; color: white !important; border: 1px solid #45a29e !important; }
22
+ label { color: #66fcf1 !important; }
23
+ """
24
+
25
+ # --- VARIÁVEIS GLOBAIS ---
26
+ INDEX_STORAGE = "./storage"
27
+ global_query_engine = None
28
+
29
+ # --- FUNÇÃO 1: PROCESSAR O PDF ---
30
+ def processar_pdf(files, api_key_llama, api_key_openai):
31
+ global global_query_engine
32
+
33
+ if not files:
34
+ return "⚠️ Por favor, envie um arquivo PDF primeiro."
35
+
36
+ # Configura chaves (Pegando dos inputs ou do sistema)
37
+ os.environ["LLAMA_CLOUD_API_KEY"] = api_key_llama
38
+ os.environ["OPENAI_API_KEY"] = api_key_openai
39
+
40
+ try:
41
+ # Configura o Parser
42
+ parser = LlamaParse(result_type="markdown", language="pt")
43
+ file_extractor = {".pdf": parser}
44
+
45
+ # Lê os arquivos
46
+ documents = SimpleDirectoryReader(input_files=[f.name for f in files], file_extractor=file_extractor).load_data()
47
+
48
+ # Cria o índice
49
+ index = VectorStoreIndex.from_documents(documents)
50
+
51
+ # Salva o motor de busca na memória
52
+ global_query_engine = index.as_query_engine()
53
+
54
+ return f"✅ Sucesso! {len(files)} manual(is) processado(s). O sistema COGNILINE está online."
55
+
56
+ except Exception as e:
57
+ return f"❌ Erro ao processar: {str(e)}"
58
+
59
+ # --- FUNÇÃO 2: CHAT ---
60
+ def responder(message, history):
61
+ global global_query_engine
62
+
63
+ if global_query_engine is None:
64
+ return "⚠️ O sistema está offline. Por favor, faça upload do manual na aba lateral primeiro."
65
+
66
+ try:
67
+ response = global_query_engine.query(message)
68
+ return str(response)
69
+ except Exception as e:
70
+ return f"Erro técnico: {str(e)}"
71
+
72
+ # --- INTERFACE GRÁFICA (GRADIO BLOCKS) ---
73
+ with gr.Blocks(css=theme_css, theme=gr.themes.Soft()) as demo:
74
+
75
+ # 1. Cabeçalho com Logo
76
+ with gr.Row(elem_classes="header-container"):
77
+ # Se você subir o arquivo logo.png junto com o app.py, ele aparece aqui
78
+ if os.path.exists("logo.png"):
79
+ gr.Image("logo.png", elem_classes="logo-img", show_label=False, show_download_button=False, container=False)
80
+ gr.Markdown("<div class='brand-name'>COGNILINE</div>")
81
+
82
+ # 2. Layout Principal
83
+ with gr.Row():
84
+
85
+ # Coluna da Esquerda (Configurações)
86
+ with gr.Column(scale=1, min_width=300):
87
+ gr.Markdown("### ⚙️ Configuração do Sistema")
88
+
89
+ # Inputs de Chave (Para segurança, pedimos aqui ou usamos Secrets)
90
+ txt_llama_key = gr.Textbox(label="LlamaCloud API Key", type="password", placeholder="Cole sua chave llx-...")
91
+ txt_openai_key = gr.Textbox(label="OpenAI API Key", type="password", placeholder="Cole sua chave sk-...")
92
+
93
+ # Upload
94
+ file_upload = gr.File(label="Upload de Manuais (PDF)", file_count="multiple", file_types=[".pdf"])
95
+ btn_process = gr.Button("INICIAR SISTEMA", variant="primary")
96
+ status_output = gr.Textbox(label="Status", interactive=False)
97
+
98
+ # Coluna da Direita (Chat)
99
+ with gr.Column(scale=3):
100
+ chatbot = gr.ChatInterface(
101
+ fn=responder,
102
+ chatbot=gr.Chatbot(elem_classes="chatbot-area", bubble_full_width=False),
103
+ textbox=gr.Textbox(placeholder="Digite sua pergunta técnica aqui...", container=False, scale=7),
104
+ theme="soft",
105
+ submit_btn="ENVIAR",
106
+ retry_btn=None,
107
+ undo_btn=None,
108
+ clear_btn="Limpar"
109
+ )
110
+
111
+ # 3. Ações
112
+ btn_process.click(processar_pdf, inputs=[file_upload, txt_llama_key, txt_openai_key], outputs=status_output)
113
+
114
+ # Lançar
115
+ if __name__ == "__main__":
116
+ demo.launch()