|
|
|
|
| """
|
| 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
|
|
|