DHEIVER commited on
Commit
322c937
·
verified ·
1 Parent(s): 82a745d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +95 -180
app.py CHANGED
@@ -4,75 +4,91 @@ from huggingface_hub import InferenceClient
4
  from datetime import datetime
5
  import logging
6
  from typing import Dict, List, Optional
 
 
 
 
 
 
7
 
8
  # Configuração do logging
9
- logging.basicConfig(level=logging.INFO)
 
 
 
10
  logger = logging.getLogger(__name__)
11
 
12
- # Substitua com sua chave de API
13
- HF_API_KEY = "hf_seu_token_aqui"
14
-
15
- class DocumentManager:
16
- """Gerencia templates e contextos dos documentos"""
17
-
18
- @staticmethod
19
- def create_prompt_messages(doc_type: str, context: Dict[str, str]) -> List[Dict[str, str]]:
20
- """Cria a sequência de mensagens para o modelo"""
21
-
22
- system_message = {
23
- "role": "system",
24
- "content": """Você é um advogado criminalista brasileiro altamente experiente, especializado em redigir peças processuais.
25
- Gere documentos jurídicos formais, tecnicamente precisos e no formato do direito brasileiro."""
26
- }
27
 
28
- user_message = {
29
- "role": "user",
30
- "content": f"""Por favor, gere um {doc_type} completo e tecnicamente preciso com os seguintes dados:
31
-
32
- QUALIFICAÇÃO:
33
- Cliente: {context.get('client_name')}
34
- Processo: {context.get('process_number')}
35
- Tribunal: {context.get('court')}
36
- Comarca: {context.get('jurisdiction')}
37
-
38
- FATOS:
39
- {context.get('facts')}
40
-
41
- FUNDAMENTOS JURÍDICOS:
42
- {context.get('legal_basis')}
43
 
44
- O documento deve seguir a formatação jurídica padrão, incluindo:
45
- 1. Cabeçalho com endereçamento correto
46
- 2. Qualificação completa das partes
47
- 3. Exposição clara dos fatos
48
- 4. Fundamentação jurídica sólida
49
- 5. Pedidos específicos
50
- 6. Fechamento formal com local, data e espaço para assinatura"""
51
- }
52
-
53
- return [system_message, user_message]
54
 
55
  class DocumentGenerator:
56
- """Gerencia a geração de documentos usando HuggingFace Inference API"""
57
 
58
  def __init__(self, api_key: str):
 
 
 
59
  self.client = InferenceClient(api_key=api_key)
60
  self.model = "mistralai/Mistral-7B-Instruct-v0.2"
61
- self.doc_manager = DocumentManager()
62
 
63
  def generate(self, doc_type: str, context: Dict[str, str]) -> str:
64
  """Gera o documento usando o modelo"""
65
  try:
66
- # Prepara as mensagens
67
- messages = self.doc_manager.create_prompt_messages(doc_type, context)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
  # Faz a chamada à API
70
  completion = self.client.chat.completions.create(
71
  model=self.model,
72
  messages=messages,
73
- temperature=0.3, # Mais conservador para documentos formais
74
- top_p=0.85, # Mantém coerência
75
- max_tokens=2048, # Documento completo
76
  )
77
 
78
  return self._format_output(completion.choices[0].message.content)
@@ -85,18 +101,13 @@ class DocumentGenerator:
85
  """Formata o texto gerado"""
86
  if not text:
87
  return "Erro: Nenhum texto gerado"
88
-
89
- # Remove espaços extras e formata parágrafos
90
- lines = [line.strip() for line in text.split('\n') if line.strip()]
91
- formatted_text = '\n\n'.join(lines)
92
-
93
- return formatted_text.strip()
94
 
95
  class WebInterface:
96
  """Interface Gradio para o gerador de documentos"""
97
 
98
  def __init__(self):
99
- self.generator = DocumentGenerator(api_key=HF_API_KEY)
100
  self.create_interface()
101
 
102
  def create_interface(self):
@@ -104,13 +115,12 @@ class WebInterface:
104
 
105
  with gr.Blocks(theme=gr.themes.Soft()) as self.app:
106
  gr.Markdown("""
107
- # Criminal.ai - Gerador de Peças Processuais
108
- ### Sistema Inteligente de Geração de Documentos Jurídicos
109
  """)
110
 
111
  with gr.Row():
112
  with gr.Column():
113
- # Tipo de documento
114
  doc_type = gr.Dropdown(
115
  choices=[
116
  "Habeas Corpus",
@@ -121,108 +131,48 @@ class WebInterface:
121
  "Apelação Criminal"
122
  ],
123
  label="Tipo de Documento",
124
- value="Habeas Corpus",
125
- info="Selecione o tipo de peça processual"
126
  )
127
 
128
- # Informações do processo
129
  with gr.Group():
130
  gr.Markdown("### Informações do Processo")
131
-
132
  client_name = gr.Textbox(
133
  label="Nome do Cliente",
134
- placeholder="Nome completo do cliente/paciente",
135
- info="Digite o nome completo"
136
  )
137
-
138
  process_number = gr.Textbox(
139
  label="Número do Processo",
140
- placeholder="NNNNNNN-NN.NNNN.N.NN.NNNN",
141
- info="Número CNJ do processo"
142
  )
143
-
144
  court = gr.Textbox(
145
  label="Tribunal",
146
- value="TRIBUNAL DE JUSTIÇA DO ESTADO",
147
- info="Nome completo do tribunal"
148
  )
149
-
150
  jurisdiction = gr.Textbox(
151
- label="Comarca",
152
- placeholder="Nome da comarca",
153
- info="Comarca onde tramita o processo"
154
  )
155
 
156
- # Detalhes do caso
157
  with gr.Group():
158
  gr.Markdown("### Detalhes do Caso")
159
-
160
  facts = gr.Textbox(
161
  label="Fatos",
162
  lines=5,
163
- placeholder="Descreva os fatos relevantes do caso...",
164
- info="Descreva os fatos de forma clara e objetiva"
165
  )
166
-
167
  legal_basis = gr.Textbox(
168
  label="Fundamentos Jurídicos",
169
- lines=3,
170
- placeholder="Indique os fundamentos legais...",
171
- info="Artigos, jurisprudência e doutrina aplicáveis"
172
- )
173
-
174
- # Status e botões
175
- with gr.Row():
176
- generate_btn = gr.Button(
177
- "📝 Gerar Documento",
178
- variant="primary",
179
- scale=2
180
- )
181
-
182
- clear_btn = gr.Button(
183
- "🗑️ Limpar",
184
- variant="secondary",
185
- scale=1
186
  )
187
 
188
- status = gr.Textbox(
189
- label="Status",
190
- interactive=False,
191
- show_label=False
192
- )
193
 
194
- # Coluna de saída
195
  with gr.Column():
196
  output = gr.Textbox(
197
  label="Documento Gerado",
198
  lines=30,
199
- show_copy_button=True,
200
- show_label=True,
201
- container=True
202
  )
203
-
204
- with gr.Row():
205
- copy_btn = gr.Button("📋 Copiar")
206
- download_btn = gr.Button("💾 Salvar como .txt")
207
-
208
- # Exemplos
209
- gr.Examples(
210
- examples=[
211
- [
212
- "Habeas Corpus",
213
- "João da Silva Santos",
214
- "0000123-45.2024.8.26.0000",
215
- "TRIBUNAL DE JUSTIÇA DO ESTADO DE SÃO PAULO",
216
- "São Paulo",
217
- "Paciente preso em flagrante no dia 25/12/2024 por suposto furto simples (art. 155, caput, do CP). Não estão presentes os requisitos da prisão preventiva, sendo o paciente primário, com residência fixa e trabalho lícito.",
218
- "Art. 5º, LXVIII da CF/88; Art. 647 do CPP; Art. 312 do CPP; Súmula 308 do STJ."
219
- ]
220
- ],
221
- inputs=[
222
- doc_type, client_name, process_number,
223
- court, jurisdiction, facts, legal_basis
224
- ]
225
- )
226
 
227
  # Eventos
228
  generate_btn.click(
@@ -233,42 +183,6 @@ class WebInterface:
233
  ],
234
  outputs=[output, status]
235
  )
236
-
237
- def clear_inputs():
238
- return [
239
- gr.update(value="") for _ in range(6)
240
- ] + [gr.update(value="Campos limpos")]
241
-
242
- clear_btn.click(
243
- fn=clear_inputs,
244
- inputs=[],
245
- outputs=[
246
- client_name, process_number, court,
247
- jurisdiction, facts, legal_basis,
248
- status
249
- ]
250
- )
251
-
252
- copy_btn.click(
253
- fn=lambda x: gr.update(value=x),
254
- inputs=[output],
255
- outputs=[output]
256
- )
257
-
258
- def save_document(text):
259
- if not text:
260
- return "Nenhum documento para salvar"
261
-
262
- filename = f"documento_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
263
- with open(filename, 'w', encoding='utf-8') as f:
264
- f.write(text)
265
- return f"Documento salvo como {filename}"
266
-
267
- download_btn.click(
268
- fn=save_document,
269
- inputs=[output],
270
- outputs=[status]
271
- )
272
 
273
  def _generate_document(
274
  self, doc_type: str, client_name: str,
@@ -277,11 +191,9 @@ class WebInterface:
277
  legal_basis: str
278
  ) -> tuple:
279
  """Gera o documento com os parâmetros fornecidos"""
280
-
281
  try:
282
- # Validação básica
283
  if not all([client_name, process_number, facts, legal_basis]):
284
- return "⚠️ Erro: Todos os campos obrigatórios devem ser preenchidos", "⚠️ Preencha todos os campos obrigatórios"
285
 
286
  context = {
287
  "client_name": client_name,
@@ -292,13 +204,8 @@ class WebInterface:
292
  "legal_basis": legal_basis
293
  }
294
 
295
- # Atualiza status
296
- yield "", "⏳ Gerando documento..."
297
-
298
- # Gera documento
299
  result = self.generator.generate(doc_type, context)
300
-
301
- return result, "✅ Documento gerado com sucesso!"
302
 
303
  except Exception as e:
304
  logger.error(f"Erro: {str(e)}")
@@ -309,10 +216,18 @@ class WebInterface:
309
  self.app.launch(share=True)
310
 
311
  if __name__ == "__main__":
312
- # Verificar token
313
- if HF_API_KEY == "hf_seu_token_aqui":
314
- print("⚠️ Atenção: Configure sua API key do Hugging Face antes de executar!")
315
- print("Substitua 'hf_seu_token_aqui' pela sua chave real.")
316
- else:
317
- interface = WebInterface()
318
- interface.launch()
 
 
 
 
 
 
 
 
 
4
  from datetime import datetime
5
  import logging
6
  from typing import Dict, List, Optional
7
+ from pathlib import Path
8
+ import json
9
+ import dotenv
10
+
11
+ # Carrega variáveis de ambiente do arquivo .env se existir
12
+ dotenv.load_dotenv()
13
 
14
  # Configuração do logging
15
+ logging.basicConfig(
16
+ level=logging.INFO,
17
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
18
+ )
19
  logger = logging.getLogger(__name__)
20
 
21
+ def load_token() -> str:
22
+ """Carrega o token HF de várias fontes possíveis"""
23
+ # Prioridade: 1. Variável de ambiente, 2. Arquivo .env, 3. arquivo config.json
24
+
25
+ # Verifica variável de ambiente
26
+ token = os.getenv('HF_TOKEN')
27
+ if token:
28
+ return token
 
 
 
 
 
 
 
29
 
30
+ # Verifica arquivo config.json
31
+ config_file = Path('config.json')
32
+ if config_file.exists():
33
+ try:
34
+ with open(config_file, 'r') as f:
35
+ config = json.load(f)
36
+ return config.get('hf_token', '')
37
+ except Exception as e:
38
+ logger.error(f"Erro ao ler config.json: {e}")
39
+
40
+ return ''
 
 
 
 
41
 
42
+ # Carrega o token
43
+ HF_API_TOKEN = load_token()
 
 
 
 
 
 
 
 
44
 
45
  class DocumentGenerator:
46
+ """Gerencia a geração de documentos usando HF Inference API"""
47
 
48
  def __init__(self, api_key: str):
49
+ if not api_key:
50
+ raise ValueError("API Key não encontrada. Configure HF_TOKEN nas variáveis de ambiente ou no arquivo config.json")
51
+
52
  self.client = InferenceClient(api_key=api_key)
53
  self.model = "mistralai/Mistral-7B-Instruct-v0.2"
 
54
 
55
  def generate(self, doc_type: str, context: Dict[str, str]) -> str:
56
  """Gera o documento usando o modelo"""
57
  try:
58
+ # Prepara as mensagens para o chat
59
+ messages = [
60
+ {
61
+ "role": "system",
62
+ "content": """Você é um advogado criminalista brasileiro experiente.
63
+ Gere documentos jurídicos formais no formato do direito brasileiro."""
64
+ },
65
+ {
66
+ "role": "user",
67
+ "content": f"""Gere um {doc_type} completo com os seguintes dados:
68
+
69
+ QUALIFICAÇÃO:
70
+ Cliente: {context.get('client_name')}
71
+ Processo: {context.get('process_number')}
72
+ Tribunal: {context.get('court')}
73
+ Comarca: {context.get('jurisdiction')}
74
+
75
+ FATOS:
76
+ {context.get('facts')}
77
+
78
+ FUNDAMENTOS JURÍDICOS:
79
+ {context.get('legal_basis')}
80
+
81
+ Use formato jurídico adequado, com todas as partes necessárias."""
82
+ }
83
+ ]
84
 
85
  # Faz a chamada à API
86
  completion = self.client.chat.completions.create(
87
  model=self.model,
88
  messages=messages,
89
+ temperature=0.3,
90
+ top_p=0.85,
91
+ max_tokens=2048,
92
  )
93
 
94
  return self._format_output(completion.choices[0].message.content)
 
101
  """Formata o texto gerado"""
102
  if not text:
103
  return "Erro: Nenhum texto gerado"
104
+ return text.strip()
 
 
 
 
 
105
 
106
  class WebInterface:
107
  """Interface Gradio para o gerador de documentos"""
108
 
109
  def __init__(self):
110
+ self.generator = DocumentGenerator(api_key=HF_API_TOKEN)
111
  self.create_interface()
112
 
113
  def create_interface(self):
 
115
 
116
  with gr.Blocks(theme=gr.themes.Soft()) as self.app:
117
  gr.Markdown("""
118
+ # Criminal.ai - Gerador de Documentos Jurídicos
119
+ Sistema de geração de peças processuais criminais
120
  """)
121
 
122
  with gr.Row():
123
  with gr.Column():
 
124
  doc_type = gr.Dropdown(
125
  choices=[
126
  "Habeas Corpus",
 
131
  "Apelação Criminal"
132
  ],
133
  label="Tipo de Documento",
134
+ value="Habeas Corpus"
 
135
  )
136
 
 
137
  with gr.Group():
138
  gr.Markdown("### Informações do Processo")
 
139
  client_name = gr.Textbox(
140
  label="Nome do Cliente",
141
+ placeholder="Nome completo"
 
142
  )
 
143
  process_number = gr.Textbox(
144
  label="Número do Processo",
145
+ placeholder="NNNNNNN-NN.NNNN.N.NN.NNNN"
 
146
  )
 
147
  court = gr.Textbox(
148
  label="Tribunal",
149
+ value="TRIBUNAL DE JUSTIÇA DO ESTADO"
 
150
  )
 
151
  jurisdiction = gr.Textbox(
152
+ label="Comarca"
 
 
153
  )
154
 
 
155
  with gr.Group():
156
  gr.Markdown("### Detalhes do Caso")
 
157
  facts = gr.Textbox(
158
  label="Fatos",
159
  lines=5,
160
+ placeholder="Descreva os fatos..."
 
161
  )
 
162
  legal_basis = gr.Textbox(
163
  label="Fundamentos Jurídicos",
164
+ lines=3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  )
166
 
167
+ generate_btn = gr.Button("Gerar Documento", variant="primary")
 
 
 
 
168
 
 
169
  with gr.Column():
170
  output = gr.Textbox(
171
  label="Documento Gerado",
172
  lines=30,
173
+ show_copy_button=True
 
 
174
  )
175
+ status = gr.Textbox(label="Status")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
 
177
  # Eventos
178
  generate_btn.click(
 
183
  ],
184
  outputs=[output, status]
185
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
 
187
  def _generate_document(
188
  self, doc_type: str, client_name: str,
 
191
  legal_basis: str
192
  ) -> tuple:
193
  """Gera o documento com os parâmetros fornecidos"""
 
194
  try:
 
195
  if not all([client_name, process_number, facts, legal_basis]):
196
+ return "Erro: Preencha todos os campos obrigatórios", "⚠️ Campos incompletos"
197
 
198
  context = {
199
  "client_name": client_name,
 
204
  "legal_basis": legal_basis
205
  }
206
 
 
 
 
 
207
  result = self.generator.generate(doc_type, context)
208
+ return result, "✅ Documento gerado com sucesso"
 
209
 
210
  except Exception as e:
211
  logger.error(f"Erro: {str(e)}")
 
216
  self.app.launch(share=True)
217
 
218
  if __name__ == "__main__":
219
+ # Verifica se o token está configurado
220
+ if not HF_API_TOKEN:
221
+ print("\n⚠️ Token HF não encontrado!")
222
+ print("\nPara configurar o token:")
223
+ print("1. Crie um arquivo .env com:")
224
+ print(" HF_TOKEN=seu_token_aqui")
225
+ print("\nOu")
226
+ print("2. Crie um arquivo config.json com:")
227
+ print(' {"hf_token": "seu_token_aqui"}')
228
+ print("\nOu")
229
+ print("3. Configure a variável de ambiente HF_TOKEN")
230
+ exit(1)
231
+
232
+ interface = WebInterface()
233
+ interface.launch()