caarleexx commited on
Commit
d19c70e
·
verified ·
1 Parent(s): f504c37

Update api/services/processing_service.py

Browse files
Files changed (1) hide show
  1. api/services/processing_service.py +120 -130
api/services/processing_service.py CHANGED
@@ -1,81 +1,81 @@
1
  """
2
- ProcessingService REAL - Usa LLMManager
3
- Substituição correta usando a API real do projeto.
4
  """
 
5
  import logging
6
  from typing import Dict, Any, List, Optional
7
  from datetime import datetime
8
 
9
- from llm.llm_manager import LLMManager, LLMProvider, ModelType, LLMRequest
10
- from api.processors.processor_metadados_llm import ProcessorMetadadosLLM
11
 
12
  logger = logging.getLogger(__name__)
13
 
14
 
15
  class ProcessingService:
16
  """
17
- Serviço de processamento que usa LLMManager REAL.
18
-
19
- Coordena:
20
- - LLMManager para criar clients LLM
21
- - Processors com LLM integrado
22
- - Logging detalhado
23
  """
24
-
25
  def __init__(
26
  self,
27
  llm_provider: str = "groq",
28
- api_key: Optional[str] = None
 
29
  ):
30
  """
31
  Args:
32
  llm_provider: Provider LLM (groq, openai, anthropic)
33
- api_key: API key para o provider (opcional, usa env vars)
 
34
  """
35
  self.llm_provider = llm_provider
36
  self.api_key = api_key
37
-
38
- # Criar LLMManager
 
 
 
 
 
 
 
39
  self.llm_manager = self._create_llm_manager()
40
-
41
  # Obter client específico do provider
42
  self.llm_client = self._get_provider_client()
43
-
44
- # Inicializar processors (por enquanto só Metadados)
45
- self.processors = {
46
- 1: ProcessorMetadadosLLM(llm_client=self.llm_client)
47
- }
48
-
 
 
49
  logger.info(
50
- f"ProcessingService inicializado "
51
- f"(provider={llm_provider}, processors={len(self.processors)})"
52
  )
53
-
54
  def _create_llm_manager(self) -> Optional[LLMManager]:
55
- """Cria LLMManager e inicializa clients."""
56
  try:
57
- # Se API key fornecida, setar no ambiente
58
- if self.api_key:
59
- import os
60
- env_key = f"{self.llm_provider.upper()}_API_KEY"
61
- os.environ[env_key] = self.api_key
62
- logger.info(f"API key configurada para {env_key}")
63
-
64
- # Criar LLMManager (inicializa todos os clients disponíveis)
65
  manager = LLMManager()
66
- logger.info("LLMManager criado e inicializado")
67
  return manager
68
-
69
  except Exception as e:
70
- logger.error(f"Erro ao criar LLMManager: {e}", exc_info=True)
71
  return None
72
-
73
  def _get_provider_client(self):
74
- """Obtém client específico do provider."""
75
  if not self.llm_manager:
76
- logger.warning("LLMManager não disponível")
77
  return None
78
-
79
  try:
80
  # Mapear string para enum
81
  provider_map = {
@@ -83,126 +83,116 @@ class ProcessingService:
83
  "openai": LLMProvider.OPENAI,
84
  "anthropic": LLMProvider.ANTHROPIC
85
  }
86
-
87
  provider_enum = provider_map.get(self.llm_provider.lower())
88
- if not provider_enum:
89
- logger.error(f"Provider desconhecido: {self.llm_provider}")
90
- return None
91
-
92
- # Obter client do provider
93
- if provider_enum in self.llm_manager.clients:
94
  client = self.llm_manager.clients[provider_enum]
95
- logger.info(f"Client obtido: {type(client).__name__}")
96
  return client
97
  else:
98
  logger.warning(
99
- f"Client para {self.llm_provider} não inicializado. "
100
- "Verifique se a API key está configurada."
101
  )
102
  return None
103
-
104
  except Exception as e:
105
- logger.error(f"Erro ao obter client: {e}", exc_info=True)
106
  return None
107
-
108
- def process_acordao(
109
  self,
110
  acordao_data: Dict[str, Any],
111
- processor_ids: Optional[List[int]] = None
 
112
  ) -> Dict[str, Any]:
113
  """
114
- Processa um acórdão com processors especificados.
115
-
116
  Args:
117
- acordao_data: Dados do acórdão (ementa, integra, etc)
118
- processor_ids: IDs dos processors a executar (default: [1])
119
-
 
120
  Returns:
121
- Resultado consolidado
122
  """
123
- if processor_ids is None:
124
- processor_ids = [1] # Apenas Metadados por enquanto
125
-
126
- start_time = datetime.now()
127
- results = {}
128
- errors = {}
129
-
130
- logger.info(
131
- f"Processando acórdão {acordao_data.get('acordao_id', 'unknown')} "
132
- f"com processors {processor_ids}"
133
- )
134
-
135
- for proc_id in processor_ids:
136
- if proc_id not in self.processors:
137
- error_msg = f"Processor {proc_id} não existe"
138
- errors[proc_id] = error_msg
139
- logger.error(error_msg)
140
- continue
141
-
142
- try:
143
- processor = self.processors[proc_id]
144
- logger.info(f"Executando {processor.specialist_name}...")
145
-
146
- # Processar
147
- result = processor.process(acordao_data)
148
-
149
- # Validar
150
- if processor.validate(result):
151
- results[proc_id] = processor.postprocess(result)
152
- logger.info(
153
- f"{processor.specialist_name} completado "
154
- f"(confidence={processor.confidence_score}%, "
155
- f"time={processor.execution_time:.2f}s)"
156
- )
157
- else:
158
- error_msg = f"Validação falhou para {processor.specialist_name}"
159
- errors[proc_id] = error_msg
160
- logger.error(error_msg)
161
-
162
- except Exception as e:
163
- error_msg = f"Erro ao executar processor {proc_id}: {e}"
164
- errors[proc_id] = error_msg
165
- logger.error(error_msg, exc_info=True)
166
-
167
- elapsed = (datetime.now() - start_time).total_seconds()
168
-
169
- return {
170
- "acordao_id": acordao_data.get("acordao_id", "unknown"),
171
- "status": "completed" if not errors else "completed_with_errors",
172
- "total_processors": len(processor_ids),
173
- "successful": len(results),
174
- "failed": len(errors),
175
- "execution_time": elapsed,
176
- "results": results,
177
- "errors": errors,
178
- "timestamp": datetime.now().isoformat()
179
- }
180
-
181
- def process_batch(
182
  self,
183
  acordaos: List[Dict[str, Any]],
184
- processor_ids: Optional[List[int]] = None
 
185
  ) -> Dict[str, Any]:
186
  """
187
  Processa lote de acórdãos.
188
-
189
  Args:
190
  acordaos: Lista de acórdãos
191
- processor_ids: IDs dos processors
192
-
 
193
  Returns:
194
  Resultados consolidados
195
  """
196
  results = []
197
-
 
198
  for idx, acordao in enumerate(acordaos, 1):
199
- logger.info(f"Processando acórdão {idx}/{len(acordaos)}...")
200
- result = self.process_acordao(acordao, processor_ids)
 
 
 
 
 
201
  results.append(result)
202
-
 
 
 
 
 
203
  return {
204
  "batch_size": len(acordaos),
205
  "processed": len(results),
 
 
 
 
206
  "results": results,
207
  "timestamp": datetime.now().isoformat()
208
- }
 
1
  """
2
+ ProcessingService - Usa ProcessorManager REAL
3
+ Integração correta com os 9 especialistas existentes
4
  """
5
+ import os
6
  import logging
7
  from typing import Dict, Any, List, Optional
8
  from datetime import datetime
9
 
10
+ from llm.llm_manager import LLMManager, LLMProvider
11
+ from processors.processor_menager import ProcessorManager
12
 
13
  logger = logging.getLogger(__name__)
14
 
15
 
16
  class ProcessingService:
17
  """
18
+ Serviço que coordena processamento via ProcessorManager REAL.
19
+
20
+ NÃO cria processors novos - usa os 9 especialistas existentes!
 
 
 
21
  """
22
+
23
  def __init__(
24
  self,
25
  llm_provider: str = "groq",
26
+ api_key: Optional[str] = None,
27
+ max_workers: int = 3
28
  ):
29
  """
30
  Args:
31
  llm_provider: Provider LLM (groq, openai, anthropic)
32
+ api_key: API key (opcional, usa env var se não fornecido)
33
+ max_workers: Workers paralelos
34
  """
35
  self.llm_provider = llm_provider
36
  self.api_key = api_key
37
+ self.max_workers = max_workers
38
+
39
+ # Configurar API key no ambiente se fornecida
40
+ if self.api_key:
41
+ env_key = f"{llm_provider.upper()}_API_KEY"
42
+ os.environ[env_key] = self.api_key
43
+ logger.info(f"✅ API key configurada para {env_key}")
44
+
45
+ # Criar LLMManager (inicializa clients via env vars)
46
  self.llm_manager = self._create_llm_manager()
47
+
48
  # Obter client específico do provider
49
  self.llm_client = self._get_provider_client()
50
+
51
+ # Criar ProcessorManager com LLM client
52
+ # ProcessorManager já inicializa os 9 especialistas!
53
+ self.processor_manager = ProcessorManager(
54
+ llm_model=self.llm_client,
55
+ max_workers=max_workers
56
+ )
57
+
58
  logger.info(
59
+ f"ProcessingService inicializado "
60
+ f"(provider={llm_provider}, 9 especialistas prontos)"
61
  )
62
+
63
  def _create_llm_manager(self) -> Optional[LLMManager]:
64
+ """Cria LLMManager."""
65
  try:
 
 
 
 
 
 
 
 
66
  manager = LLMManager()
67
+ logger.info("LLMManager inicializado")
68
  return manager
 
69
  except Exception as e:
70
+ logger.error(f"Erro ao criar LLMManager: {e}", exc_info=True)
71
  return None
72
+
73
  def _get_provider_client(self):
74
+ """Obtém client do provider selecionado."""
75
  if not self.llm_manager:
76
+ logger.warning("⚠️ LLMManager não disponível")
77
  return None
78
+
79
  try:
80
  # Mapear string para enum
81
  provider_map = {
 
83
  "openai": LLMProvider.OPENAI,
84
  "anthropic": LLMProvider.ANTHROPIC
85
  }
86
+
87
  provider_enum = provider_map.get(self.llm_provider.lower())
88
+
89
+ if provider_enum and provider_enum in self.llm_manager.clients:
 
 
 
 
90
  client = self.llm_manager.clients[provider_enum]
91
+ logger.info(f"Client obtido: {type(client).__name__}")
92
  return client
93
  else:
94
  logger.warning(
95
+ f"⚠️ Client {self.llm_provider} não disponível. "
96
+ "Verifique API key no ambiente."
97
  )
98
  return None
99
+
100
  except Exception as e:
101
+ logger.error(f"Erro ao obter client: {e}", exc_info=True)
102
  return None
103
+
104
+ async def process_acordao(
105
  self,
106
  acordao_data: Dict[str, Any],
107
+ specialist_ids: Optional[List[int]] = None,
108
+ enable_parallel: bool = False
109
  ) -> Dict[str, Any]:
110
  """
111
+ Processa 1 acórdão usando ProcessorManager.
112
+
113
  Args:
114
+ acordao_data: Dados do acórdão
115
+ specialist_ids: IDs dos especialistas (default: todos)
116
+ enable_parallel: Executar em paralelo
117
+
118
  Returns:
119
+ Resultado consolidado dos 9 especialistas
120
  """
121
+ try:
122
+ logger.info(
123
+ f"🚀 Processando acórdão {acordao_data.get('acordao_id', 'unknown')} "
124
+ f"com ProcessorManager"
125
+ )
126
+
127
+ # Usar ProcessorManager REAL para processar
128
+ if enable_parallel:
129
+ result = await self.processor_manager.process_acordao_parallel(
130
+ acordao_data=acordao_data,
131
+ specialist_ids=specialist_ids
132
+ )
133
+ else:
134
+ result = await self.processor_manager.process_acordao_sequential(
135
+ acordao_data=acordao_data,
136
+ specialist_ids=specialist_ids
137
+ )
138
+
139
+ logger.info(
140
+ f"✅ Acórdão processado em {result.get('execution_time', 0):.2f}s"
141
+ )
142
+
143
+ return result
144
+
145
+ except Exception as e:
146
+ logger.error(f"❌ Erro ao processar acórdão: {e}", exc_info=True)
147
+ return {
148
+ "acordao_id": acordao_data.get("acordao_id", "unknown"),
149
+ "status": "error",
150
+ "error": str(e),
151
+ "timestamp": datetime.now().isoformat()
152
+ }
153
+
154
+ async def process_batch(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  self,
156
  acordaos: List[Dict[str, Any]],
157
+ specialist_ids: Optional[List[int]] = None,
158
+ enable_parallel: bool = False
159
  ) -> Dict[str, Any]:
160
  """
161
  Processa lote de acórdãos.
162
+
163
  Args:
164
  acordaos: Lista de acórdãos
165
+ specialist_ids: IDs dos especialistas
166
+ enable_parallel: Processar cada acórdão em paralelo
167
+
168
  Returns:
169
  Resultados consolidados
170
  """
171
  results = []
172
+ start_time = datetime.now()
173
+
174
  for idx, acordao in enumerate(acordaos, 1):
175
+ logger.info(f"📄 Processando acórdão {idx}/{len(acordaos)}...")
176
+
177
+ result = await self.process_acordao(
178
+ acordao_data=acordao,
179
+ specialist_ids=specialist_ids,
180
+ enable_parallel=enable_parallel
181
+ )
182
  results.append(result)
183
+
184
+ elapsed = (datetime.now() - start_time).total_seconds()
185
+
186
+ successful = len([r for r in results if r.get("status") != "error"])
187
+ failed = len(results) - successful
188
+
189
  return {
190
  "batch_size": len(acordaos),
191
  "processed": len(results),
192
+ "successful": successful,
193
+ "failed": failed,
194
+ "total_execution_time": elapsed,
195
+ "avg_time_per_acordao": elapsed / len(acordaos) if acordaos else 0,
196
  "results": results,
197
  "timestamp": datetime.now().isoformat()
198
+ }