Spaces:
Running
Running
File size: 2,548 Bytes
267403a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# -*- coding: utf-8 -*-
"""
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
# Zera cache ao trocar ambiente
st.session_state[SESSION_MOD_CACHE_KEY] = {}
def get_env_base() -> str:
base = st.session_state.get(SESSION_ENV_BASE_KEY)
if not base:
# Default: usar a própria pasta onde está o app (Produção)
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):
# fallback: se não achar .py direto, permita subpastas (ex.: envs/test/modulos/operacao.py)
# ajuste conforme sua estrutura real:
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
|