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