import os import base64 from dotenv import load_dotenv from sqlalchemy import Column, String, Integer from src.ArquitectureLayer.Mapper import Mapper_base from src.ArquitectureLayer.Model import Model_base from src.ArquitectureLayer.Repo import Repo_base from src.ConexionSql.Base_conexion import ConexionBase from src.base import Base from src.Security.Encriptar import Encriptar_fernet from src.Security.GenerarIDs import GeneradorIDUnico from src.Llms.Embedders.Base_Embedder import EmbedderABC from src.TextManager.biblioteca import Biblioteca # Suponiendo que defines la clase lógica Biblioteca aquí # ---------------------- # Cargar clave maestra # ---------------------- from entrypoint import ENV_PATH load_dotenv(ENV_PATH) pssword = os.getenv('MASTER_PASSWORD') if pssword is None: raise ValueError("MASTER_PASSWORD no está definida en el archivo .env") # ---------------------- # MODELO (SQLAlchemy) # ---------------------- class BibliotecaModel(Base, Model_base): __tablename__ = "bibliotecas" id = Column(String, primary_key=True, unique=True) nombre = Column(String, nullable=False, unique=True) descripcion = Column(String, nullable=False, default="") vector_dim = Column(Integer, nullable=False) embedder_info = Column(String, nullable=True) # Nombre de clase, ID de configuración, o info encriptada del embedder # ---------------------- # MAPPER # ---------------------- class BibliotecaMapper(Mapper_base[Biblioteca, BibliotecaModel]): @staticmethod def to_model(obj: Biblioteca) -> BibliotecaModel: return BibliotecaModel( id=obj.id, nombre=obj.nombre, descripcion=obj.descripcion, vector_dim=obj.vector_dim # embedder no se serializa en el modelo, se maneja por separado ) @staticmethod def from_model(model: BibliotecaModel) -> Biblioteca: return Biblioteca( id=model.id, nombre=model.nombre, descripcion=model.descripcion, vector_dim=model.vector_dim, embedder=None # se deja para inyección posterior si es necesario ) @staticmethod def to_dict(obj: Biblioteca) -> dict: embedder_info = type(obj.embedder).__name__ if obj.embedder else None return { "id": obj.id, "nombre": obj.nombre, "descripcion": obj.descripcion, "vector_dim": obj.vector_dim, "embedder_info": embedder_info } @staticmethod def from_dict(data: dict) -> Biblioteca: return Biblioteca( id=data["id"], nombre=data["nombre"], descripcion=data["descripcion"], vector_dim=data["vector_dim"], embedder=None # inyección manual si se desea ) # ---------------------- # REPO # ---------------------- class BibliotecaRepo(Repo_base[BibliotecaModel, Biblioteca]): def __init__(self, conexion: ConexionBase): super().__init__( session=conexion.get_session(), modelo=BibliotecaModel, mapper=BibliotecaMapper ) def add(self, biblioteca: Biblioteca, created_by: str = None, notes: str = None) -> str: # Lógica personalizada: prevenir duplicados por nombre existente = self.session.query(self.Modelo).filter_by(nombre=biblioteca.nombre).first() if existente: raise ValueError(f"Ya existe una biblioteca con el nombre '{biblioteca.nombre}'") return super().add(biblioteca, created_by=created_by, notes=notes) def get_by_nombre(self, nombre: str) -> Biblioteca | None: model = self.session.query(self.Modelo).filter_by(nombre=nombre, sys_deleted_at=None).first() return self.Mapper.from_model(model) if model else None