|
|
|
|
|
|
|
|
"""
|
|
|
module_loader.py — Carregador dinâmico de módulos por ambiente (TESTE/Produção)
|
|
|
Permite importar 'operacao', 'consulta', etc. a partir de um base_path escolhido no login.
|
|
|
"""
|
|
|
|
|
|
import os
|
|
|
import importlib.util
|
|
|
import types
|
|
|
import streamlit as st
|
|
|
|
|
|
SESSION_ENV_BASE_KEY = "__env_base_path__"
|
|
|
SESSION_MOD_CACHE_KEY = "__env_module_cache__"
|
|
|
|
|
|
def set_env_base(base_path: str):
|
|
|
"""Define o caminho base do ambiente (ex.: pasta de produção ou teste)."""
|
|
|
base_path = os.path.abspath(base_path)
|
|
|
if not os.path.isdir(base_path):
|
|
|
raise RuntimeError(f"Caminho do ambiente inválido: {base_path}")
|
|
|
st.session_state[SESSION_ENV_BASE_KEY] = base_path
|
|
|
|
|
|
st.session_state[SESSION_MOD_CACHE_KEY] = {}
|
|
|
|
|
|
def get_env_base() -> str:
|
|
|
base = st.session_state.get(SESSION_ENV_BASE_KEY)
|
|
|
if not base:
|
|
|
|
|
|
base = os.path.abspath(os.getcwd())
|
|
|
st.session_state[SESSION_ENV_BASE_KEY] = base
|
|
|
st.session_state[SESSION_MOD_CACHE_KEY] = {}
|
|
|
return base
|
|
|
|
|
|
def _mod_cache() -> dict:
|
|
|
cache = st.session_state.get(SESSION_MOD_CACHE_KEY)
|
|
|
if cache is None:
|
|
|
cache = {}
|
|
|
st.session_state[SESSION_MOD_CACHE_KEY] = cache
|
|
|
return cache
|
|
|
|
|
|
def load_module(module_name: str) -> types.ModuleType:
|
|
|
"""
|
|
|
Carrega um módulo pelo nome (ex.: 'operacao') a partir do base_path atual.
|
|
|
Mantém cache por ambiente/arquivo para evitar reimportações.
|
|
|
"""
|
|
|
base_path = get_env_base()
|
|
|
mod_path = os.path.join(base_path, f"{module_name}.py")
|
|
|
if not os.path.isfile(mod_path):
|
|
|
|
|
|
|
|
|
mod_path_alt = os.path.join(base_path, "modulos", f"{module_name}.py")
|
|
|
if os.path.isfile(mod_path_alt):
|
|
|
mod_path = mod_path_alt
|
|
|
else:
|
|
|
raise FileNotFoundError(f"Módulo '{module_name}' não encontrado em {base_path}")
|
|
|
|
|
|
cache_key = f"{base_path}::{module_name}"
|
|
|
cache = _mod_cache()
|
|
|
mod = cache.get(cache_key)
|
|
|
if mod:
|
|
|
return mod
|
|
|
|
|
|
spec = importlib.util.spec_from_file_location(module_name, mod_path)
|
|
|
mod = importlib.util.module_from_spec(spec)
|
|
|
assert spec and spec.loader, f"Falha ao preparar spec para {mod_path}"
|
|
|
spec.loader.exec_module(mod)
|
|
|
cache[cache_key] = mod
|
|
|
return mod
|
|
|
|