import os import tempfile from abc import ABC from functools import cached_property from app.schemas import HolmesCliente from app.services.holmes import HolmesAPI from pydantic import BaseModel class ClienteConfig(BaseModel): nome: str razao_social: str cnpj: str holmes: HolmesCliente # Chave publica (PEM) da API do cliente. Ciframos com ela; so a privada, # que fica com eles, abre. chave_publica: str class ClienteBase(ABC): # A subclasse atribui direto: config = ClienteConfig(...) config: ClienteConfig def __init_subclass__(cls, **kwargs): super().__init_subclass__(**kwargs) if not hasattr(cls, "config"): raise TypeError(f"{cls.__name__} precisa definir `config`") # --- comum a todos: ninguem sobrescreve --- @property def nome(self) -> str: return self.config.nome @cached_property def holmes(self) -> HolmesAPI: """ API do Holmes ja amarrada nas credenciais deste cliente. cached_property e nao property: uma instancia por cliente, criada no primeiro uso. Com @property comum sairia uma HolmesAPI nova a cada acesso, e qualquer estado em memoria (token) se perderia. """ return HolmesAPI( credenciais=self.config.holmes, cache_token=self.cache_token_holmes, ) @property def cache_token_holmes(self) -> str: """ Arquivo de cache do token do Holmes, um por cliente. Sem isso dois clientes com contas diferentes sobrescreveriam o token um do outro — era o caso quando isso era uma constante de modulo. """ return os.path.join( tempfile.gettempdir(), f"holmes_token_{self.nome}.json" ) def __repr__(self) -> str: return f""