chore: Remove obsolete build and GUI files, and introduce a new Docker Compose setup for microservices architecture. This change streamlines the project structure by eliminating legacy scripts and integrating a PostgreSQL database service alongside extraction and cleaning services.
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
"""Utilidades de texto para parseo de JSON embebido y construcción de schema."""
|
||||
import re
|
||||
import json
|
||||
from typing import Optional, Dict, Any
|
||||
|
||||
|
||||
def extract_json_from_text(text: str) -> Optional[str]:
|
||||
"""Extrae el primer bloque JSON de un texto, con o sin fence ```json.
|
||||
|
||||
Devuelve la cadena JSON o None si no se encuentra.
|
||||
"""
|
||||
# 1. Try markdown fences
|
||||
match = re.search(r"```json\s*(.*?)\s*```", text, flags=re.DOTALL | re.IGNORECASE)
|
||||
if match:
|
||||
return _clean_json_string(match.group(1).strip())
|
||||
|
||||
match = re.search(r"```\s*(\{[\s\S]*?\})\s*```", text, flags=re.DOTALL)
|
||||
if match:
|
||||
return _clean_json_string(match.group(1).strip())
|
||||
|
||||
# 2. Try finding outer braces
|
||||
start = text.find('{')
|
||||
end = text.rfind('}')
|
||||
if start != -1 and end != -1 and end > start:
|
||||
candidate = text[start:end + 1].strip()
|
||||
return _clean_json_string(candidate)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def _clean_json_string(json_str: str) -> str:
|
||||
"""Intenta limpiar errores comunes de JSON generado por LLM."""
|
||||
# Eliminar comas finales en objetos/listas: , } -> } y , ] -> ]
|
||||
# Nota: Esto es una heurística simple y puede fallar en strings que contienen esos patrones.
|
||||
# Usamos regex conservador.
|
||||
json_str = re.sub(r",\s*}", "}", json_str)
|
||||
json_str = re.sub(r",\s*]", "]", json_str)
|
||||
return json_str
|
||||
|
||||
|
||||
def build_schema(data: Dict[str, Any], prefix: str = "") -> Dict[str, str]:
|
||||
"""Construye un mapa ruta->tipo a partir de un dict anidado.
|
||||
|
||||
Para listas de dicts, usa la notación "/*/subcampo".
|
||||
"""
|
||||
schema: Dict[str, str] = {}
|
||||
for k, v in data.items():
|
||||
path = f"{prefix}/{k}" if prefix else k
|
||||
if isinstance(v, dict):
|
||||
schema.update(build_schema(v, path))
|
||||
elif isinstance(v, list) and v and isinstance(v[0], dict):
|
||||
for subkey, subval in v[0].items():
|
||||
schema[f"{path}/*/{subkey}"] = type(subval).__name__
|
||||
else:
|
||||
schema[path] = type(v).__name__
|
||||
return schema
|
||||
Reference in New Issue
Block a user