thlinhares commited on
Commit
c491a68
·
verified ·
1 Parent(s): 7070f0c

Create new_app.py

Browse files
Files changed (1) hide show
  1. new_app.py +200 -0
new_app.py ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from docling.document_converter import DocumentConverter
3
+ import google.generativeai as genai
4
+ import re
5
+ import os
6
+ import logging
7
+ import json
8
+ from typing import Dict, List, Tuple
9
+ from datetime import datetime
10
+ from transformers import AutoModelForTokenClassification, AutoTokenizer
11
+ import torch
12
+ import spacy
13
+
14
+ # Configuração de logging
15
+ logging.basicConfig(
16
+ level=logging.INFO,
17
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
18
+ handlers=[
19
+ logging.FileHandler(f'contract_analyzer_{datetime.now().strftime("%Y%m%d")}.log'),
20
+ logging.StreamHandler()
21
+ ]
22
+ )
23
+ logger = logging.getLogger(__name__)
24
+
25
+ # Configuração da API do Gemini
26
+ GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
27
+ if not GOOGLE_API_KEY:
28
+ logger.error("GOOGLE_API_KEY não encontrada nas variáveis de ambiente")
29
+ raise ValueError("GOOGLE_API_KEY não configurada")
30
+
31
+ genai.configure(api_key=GOOGLE_API_KEY)
32
+ logger.info("API Gemini configurada com sucesso")
33
+
34
+ # Carregar o modelo NER e tokenizador
35
+ model_name = "dominguesm/ner-legal-bert-base-cased-ptbr"
36
+ logger.info(f"Carregando o modelo NER: {model_name}")
37
+ ner_model = AutoModelForTokenClassification.from_pretrained(model_name)
38
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
39
+ logger.info("Modelo NER e tokenizador carregados com sucesso")
40
+
41
+ # Funções do App 1 (Gemini)
42
+ def extract_json_from_response(response_text: str) -> str:
43
+ json_content = response_text.strip()
44
+ if json_content.startswith('```'):
45
+ json_content = json_content.split('\n', 1)[1]
46
+ if json_content.endswith('```'):
47
+ json_content = json_content.rsplit('\n', 1)[0]
48
+ return json_content.strip()
49
+
50
+ def extract_legal_representatives_gemini(contract_text: str) -> Dict:
51
+ logger.info("Iniciando extração de representantes legais com Gemini")
52
+ try:
53
+ model = genai.GenerativeModel('gemini-pro')
54
+ prompt = """
55
+ Analise o seguinte contrato social e extraia:
56
+ 1. Todos os sócios e seus percentuais de participação
57
+ 2. Todos os administradores mencionados
58
+
59
+ Formate a resposta como um dicionário JSON com as seguintes chaves:
60
+ - "socios": lista de dicionários com "nome" e "participacao"
61
+ - "administradores": lista de nomes
62
+
63
+ Contrato Social:
64
+ {contract_text}
65
+ """
66
+
67
+ response = model.generate_content(prompt.format(contract_text=contract_text))
68
+ json_content = extract_json_from_response(response.text)
69
+ result = json.loads(json_content)
70
+
71
+ return result
72
+ except Exception as e:
73
+ logger.error(f"Erro na análise Gemini: {str(e)}")
74
+ return {
75
+ "socios": [],
76
+ "administradores": [],
77
+ "erro": str(e)
78
+ }
79
+
80
+ # Funções do App 2 (NER)
81
+ def extract_entities(text: str) -> List[Tuple[str, str]]:
82
+ logger.debug("Iniciando extração de entidades com NER")
83
+ inputs = tokenizer(text, max_length=512, truncation=True, return_tensors="pt")
84
+ tokens = inputs.tokens()
85
+
86
+ with torch.no_grad():
87
+ outputs = ner_model(**inputs).logits
88
+ predictions = torch.argmax(outputs, dim=2)
89
+
90
+ entities = []
91
+ for token, prediction in zip(tokens, predictions[0].numpy()):
92
+ entity_label = ner_model.config.id2label[prediction]
93
+ if entity_label != "O":
94
+ entities.append((token, entity_label))
95
+
96
+ return entities
97
+
98
+ def extract_representatives_ner(entities: List[Tuple[str, str]]) -> List[str]:
99
+ representatives = []
100
+ current_person = ""
101
+ current_organization = ""
102
+
103
+ for token, label in entities:
104
+ if label in ["B-PESSOA", "I-PESSOA"]:
105
+ current_person += token.replace("##", "")
106
+ else:
107
+ if current_person:
108
+ representatives.append(current_person)
109
+ current_person = ""
110
+
111
+ if label in ["B-ORGANIZACAO", "I-ORGANIZACAO"]:
112
+ current_organization += token.replace("##", "")
113
+ else:
114
+ if current_organization:
115
+ representatives.append(current_organization)
116
+ current_organization = ""
117
+
118
+ if current_person:
119
+ representatives.append(current_person)
120
+ if current_organization:
121
+ representatives.append(current_organization)
122
+
123
+ return representatives
124
+
125
+ def format_output_gemini(analysis_result: Dict) -> str:
126
+ output = "ANÁLISE DO CONTRATO SOCIAL (Gemini)\n\n"
127
+
128
+ output += "SÓCIOS:\n"
129
+ for socio in analysis_result.get("socios", []):
130
+ participacao = socio.get('participacao', 'Não especificada')
131
+ participacao_str = f"{participacao}%" if participacao is not None else "Participação não especificada"
132
+ output += f"- {socio['nome']}: {participacao_str}\n"
133
+
134
+ output += "\nADMINISTRADORES:\n"
135
+ for admin in analysis_result.get("administradores", []):
136
+ output += f"- {admin}\n"
137
+
138
+ if "erro" in analysis_result:
139
+ output += f"\nERRO: {analysis_result['erro']}"
140
+
141
+ return output
142
+
143
+ def format_output_ner(representatives: List[str]) -> str:
144
+ output = "ANÁLISE DO CONTRATO SOCIAL (NER)\n\n"
145
+ output += "REPRESENTANTES IDENTIFICADOS:\n"
146
+ for rep in representatives:
147
+ output += f"- {rep}\n"
148
+ return output
149
+
150
+ # Função principal que processa o documento
151
+ def analyze_contract(file, analysis_type: str):
152
+ logger.info(f"Iniciando análise do arquivo usando {analysis_type}: {file.name}")
153
+
154
+ try:
155
+ converter = DocumentConverter()
156
+ result = converter.convert(file.name)
157
+ document_text = result.document.export_to_text()
158
+
159
+ if analysis_type == "Gemini":
160
+ analysis_result = extract_legal_representatives_gemini(document_text)
161
+ output = format_output_gemini(analysis_result)
162
+ else: # NER
163
+ entities = extract_entities(document_text)
164
+ representatives = extract_representatives_ner(entities)
165
+ output = format_output_ner(representatives)
166
+
167
+ return document_text, output
168
+
169
+ except Exception as e:
170
+ logger.error(f"Erro durante análise do contrato: {str(e)}")
171
+ return "", f"Erro ao processar o arquivo: {str(e)}"
172
+
173
+ # Criar interface Gradio
174
+ try:
175
+ logger.info("Iniciando configuração da interface Gradio")
176
+ iface = gr.Interface(
177
+ fn=analyze_contract,
178
+ inputs=[
179
+ "file",
180
+ gr.Radio(
181
+ choices=["Gemini", "NER"],
182
+ label="Tipo de Análise",
183
+ value="Gemini"
184
+ )
185
+ ],
186
+ outputs=[
187
+ gr.Textbox(label="Texto do Contrato"),
188
+ gr.Textbox(label="Resultado da Análise")
189
+ ],
190
+ title="Analisador de Contratos Sociais",
191
+ description="Este aplicativo analisa contratos sociais usando Gemini ou NER para identificar representantes legais.",
192
+ )
193
+ logger.info("Interface Gradio configurada com sucesso")
194
+ except Exception as e:
195
+ logger.error(f"Erro ao configurar interface Gradio: {str(e)}")
196
+ raise
197
+
198
+ if __name__ == "__main__":
199
+ logger.info("Iniciando aplicação")
200
+ iface.launch()