Skip to main content

🪐 jupiter-subtes

jupiter-subtes é uma biblioteca Python para automação dos fluxos de trabalho do Tesouro do Estado do Rio de Janeiro. Ela unifica, em um único pacote, três domínios de automação:

  • SIAFE-Rio2 — geração de documentos contábeis (GR, PDE, PDT, NP, NA, EV) por interface web e por API REST;
  • SEI — controle de processos, análise de documentos, despachos, anexos e marcadores;
  • Microsoft 365 — SharePoint (arquivos e pastas) e Microsoft Graph (Outlook e Teams).

A biblioteca é genérica: não contém regras de negócio codificadas (contas, fontes, UGs). Toda a parametrização contábil é injetada em tempo de execução por dicionários, permitindo que o mesmo código atenda a diferentes setores sem alteração no fonte.

from jupiter import Siafe, SEI, SharePoint, GraphAPI, configurar_log

Índice


Instalação

O módulo apipoint (SharePoint e Graph) depende de uma versão específica do office365-rest-python-client que ainda não foi publicada no PyPI. Instale-a a partir do repositório oficial antes do jupiter:

pip install git+https://github.com/vgrem/office365-rest-python-client.git@630e4e1f7977e28a8354174cc85896421425e4d7
pip install jupiter-subtes

Se você não utilizará o módulo apipoint, a instalação simples é suficiente:

pip install jupiter-subtes

Dependências

Biblioteca Instalação Uso
selenium >= 4.0.0 automática Controle do navegador
automaweb automática Camada base de automação web (interna)
pandas automática Manipulação de DataFrames
requests automática Chamadas às APIs REST (SIAFE, SEI, Teams)
msal automática Suporte à autenticação Microsoft
office365-rest-python-client manual (ver acima) SharePoint e Graph

Requisitos de ambiente: o Edge deve estar instalado e atualizado. O automaweb gerencia o MSEdgeDriver automaticamente. A instalação do office365-rest-python-client via git exige que o git esteja disponível na máquina.


Visão geral dos módulos

Módulo Classes / funções Domínio
siafelibrary Siafe Automação web e API do SIAFE-Rio2
seilibrary SEI Automação web do SEI
apipoint SharePoint, GraphAPI, configurar_log SharePoint, Outlook, Teams e logging

As classes Siafe e SEI herdam de automaweb.Navegador e gerenciam o próprio navegador. SharePoint e GraphAPI operam exclusivamente por API.


Configuração de logging

A biblioteca não registra nenhum handler por conta própria — todos os módulos emitem logs sob o logger jupiter. A função configurar_log centraliza a configuração e deve ser chamada antes de instanciar qualquer classe.

Ela cria até três destinos para os registros:

  1. Arquivo geral — mensagens INFO, WARNING e ERROR;
  2. Arquivo de erros — apenas ERROR;
  3. Interface gráfica — opcional, via callback (para exibir mensagens ao usuário em tempo real).
import logging
from jupiter import configurar_log, Siafe

# Configura os arquivos de log (chame no início do programa)
caminho_geral, caminho_erros = configurar_log(
    nome_programa="Rotina de Contabilização",
    pasta_geral="C:/Logs/geral",
    pasta_erros="C:/Logs/erros",
    callback_interface=None,   # ou uma função que recebe str, ex.: self.log
)

# Loggers do seu programa também são capturados se usarem o prefixo "jupiter."
log = logging.getLogger("jupiter.main")
log.info("Iniciando automação")

siafe = Siafe()   # a partir daqui, todos os logs do Siafe são gravados nos arquivos

Alternativamente, você pode configurar o logger jupiter manualmente com a API padrão do logging, caso precise de um formato ou destino específico.


1. siafelibrary — SIAFE-Rio2

A classe Siafe encapsula toda a interação com o SIAFE-Rio2, tanto pela interface web quanto pela API REST.

1.1. Autenticação

from jupiter import Siafe

siafe = Siafe()

# Login pela interface web (necessário para geração de documentos via navegador)
sucesso = siafe.logar_siafe(versaoSiafe=1, usuario="12345678900", senha="senha")

# Login pela API REST (necessário para métodos *_API e consulta_flexvision)
siafe.logar_siafe_API(versaoSiafe=1, usuario="12345678900", senha="senha")

Ambientes disponíveis (versaoSiafe):

Valor Ambiente Web API
1 Produção ✅ ✅
2 Beta / Testes ✅ ✅
3 Homologação ✅ ✅
4 SIAFE-Rio 1 ✅ —

logar_siafe retorna True/False e trata internamente o pop-up de credenciais inválidas. logar_siafe_API armazena o token em siafe.token e o reutiliza nas chamadas subsequentes.

1.2. Geração de documentos em lote

O método gerar_documento é o ponto de entrada para contabilização em lote. Ele recebe:

  • funcao — o método gerador do documento (gerar_GR, gerar_PDE, gerar_PDT, gerar_NP, gerar_NA, gerar_EV ou gerar_PDT_API);
  • df — um DataFrame com os lançamentos;
  • dict_map — dicionário de regras contábeis por tipo (ver Referência do dict_map);
  • callback_sucesso — função opcional chamada a cada documento contabilizado.
Método Documento
gerar_GR Guia de Recolhimento (orçamentária e extra-orçamentária)
gerar_PDE Programação de Desembolso Extra-orçamentária
gerar_PDT Programação de Desembolso de Transferência
gerar_NP Nota Patrimonial
gerar_NA Nota de Aplicação e Resgate
gerar_EV Nota de Evento (múltiplos itens)
gerar_PDT_API PDT enviada diretamente pela API REST

O DataFrame deve conter, no mínimo, as colunas: id, data, valor, observacao, tipo_id, além de num_documento e tempo_contab inicializadas como None (o robô as preenche).

import pandas as pd
from jupiter import Siafe

df = pd.DataFrame([
    {"id": 1, "data": "01/07/2025", "valor": 1500.00,
     "observacao": "Recolhimento referente a julho/2025",
     "tipo_id": "GR_FUNDO_A", "num_documento": None, "tempo_contab": None},
    {"id": 2, "data": "01/07/2025", "valor": 3200.50,
     "observacao": "Recolhimento referente a julho/2025",
     "tipo_id": "GR_FUNDO_B", "num_documento": None, "tempo_contab": None},
])

regras = {
    "GR_FUNDO_A": { ... },   # ver "Referência do dict_map"
    "GR_FUNDO_B": { ... },
}

def ao_contabilizar(id, num_documento, tempo_contab):
    print(f"[OK] id={id}  doc={num_documento}  tempo={tempo_contab}s")
    # persista o resultado no banco, planilha ou SharePoint aqui

siafe = Siafe()
if siafe.logar_siafe(versaoSiafe=1, usuario="12345678900", senha="senha"):
    siafe.gerar_documento(
        funcao=siafe.gerar_GR,
        df=df,
        dict_map=regras,
        callback_sucesso=ao_contabilizar,
    )

O callback_sucesso é chamado a cada documento gerado, permitindo persistência incremental — se a rotina for interrompida, os documentos já contabilizados estão salvos e o DataFrame reprocessa apenas as linhas com num_documento ainda vazio.

1.3. Nota de Evento (EV) com múltiplos itens

Diferente dos demais, a gerar_EV recebe os itens em um DataFrame aninhado no próprio dicionário, na chave itens (colunas id, evento, credor, valor):

import pandas as pd

regras_ev = {
    "EV_FOLHA": {
        "UG":  "123456",
        "IEF": "1",
        "itens": pd.DataFrame([
            {"id": 1, "evento": "540101", "credor": "12345678000199", "valor": 1000.00},
            {"id": 2, "evento": "540102", "credor": "98765432000155", "valor":  750.50},
        ]),
    },
}

siafe.gerar_documento(funcao=siafe.gerar_EV, df=df, dict_map=regras_ev)

Para duplicar uma Nota de Evento já existente alterando apenas a data e a observação:

siafe.copiar_EV(num_doc="2025EV000123", nova_data="01/08/2025", nova_obs="Reemissão agosto/2025")

1.4. Geração de PDT pela API REST

Para PDTs, além do fluxo web, a biblioteca oferece um caminho por API — mais rápido e sem navegador. O fluxo tem duas etapas: obter a estrutura de uma PDT-modelo com dicionario_PDT e enviá-la com gerar_PDT_API.

from jupiter import Siafe

siafe = Siafe()
siafe.logar_siafe_API(versaoSiafe=1, usuario="12345678900", senha="senha")

# 1. Monta o dicionário-base a partir de uma PDT existente (usada como modelo)
modelo = siafe.dicionario_PDT(exercicio=2025, codigoUG=123456, num_documento="2025PD000045")

# 2a. Envio individual
num_doc, tempo = siafe.gerar_PDT_API(
    exercicio=2025,
    dicionario=modelo,
    data="01/07/2025",
    valor=1500.00,
    observacao="Transferência referente a julho/2025",
)

# 2b. Ou em lote, reutilizando gerar_documento
siafe.gerar_documento(
    funcao=siafe.gerar_PDT_API,
    df=df,
    dict_map={"PDT_MODELO": modelo},
    callback_sucesso=ao_contabilizar,
)

1.5. Consultas e impressão de GR

# Relatório do FlexVision via API (retorna um DataFrame)
df_relatorio = siafe.consulta_flexvision(id="12345", parametros_consulta="2025,123456")

# Imprime em PDF todas as GRs do DataFrame (após gerar_documento preencher num_documento)
siafe.consultar_GR_numDoc(df=df, callback_sucesso=lambda id: print(f"PDF gerado: id={id}"))

# Localiza e imprime uma GR pelo valor (e, opcionalmente, pela data de recolhimento)
num_doc = siafe.consultar_GR_valor(
    valor_pesquisa=1500.00,
    versaoSiafe=1,
    data_pagamento="01/07/2025",
)

2. seilibrary — SEI

A classe SEI automatiza o Sistema Eletrônico de Informações: navegação em processos, análise de documentos, despachos, anexos e gestão de marcadores.

2.1. Login e controle de processos

from jupiter import SEI

sei = SEI()
sei.logar_sei(usuario="joao.silva", senha="senha", orgao="ORGAO")
sei.trocar_unidade("SUPCONC")

# Retorna todos os processos do Controle de Processos, com todas as colunas
# (processo, atribuicao, tipo, marcadores, controle_prazo, etc.)
processos = sei.controlar_processos()

for p in processos:
    print(p["processo"], "|", p["tipo"], "|", p["marcadores"])

2.2. Marcadores

# Lista todos os processos de um marcador específico
todos = sei.visualizar_processos_por_marcador(marcador="Aguardando Despacho")

# Filtra localmente os processos que possuem determinado marcador
pendentes = sei.filtrar_processos_por_marcador(todos, marcador="Aguardando Despacho")

# Move um processo de um marcador para outro
sei.pesquisar_processo("0012345-67.2025.8.19.0000")
sei.remover_marcador("0012345-67.2025.8.19.0000")
sei.adicionar_marcador(marcador="Concluído", processo="0012345-67.2025.8.19.0000", flag_removido=True)

flag_removido=True evita reabrir o processo quando adicionar_marcador é chamado logo após remover_marcador.

2.3. Análise de documentos

analisar_documentos percorre a árvore do processo e retorna um dicionário {nome_documento: texto}. Sobre esse resultado, três métodos aplicam diferentes critérios de busca:

Método Critério Retorno
verificar_despacho OR (qualquer termo) lista de documentos
verificar_despacho_estrito AND (todos os termos) lista de documentos
verificar_despacho_detalhado quais termos por documento {documento: [termos]}
sei.pesquisar_processo("0012345-67.2025.8.19.0000")
sei.expandir_pastas()

# Analisa apenas documentos cujo nome contém "Memorando"
documentos = sei.analisar_documentos(condicao="Memorando")

# Documentos que mencionem "pagamento" E "autorizado"
com_ambos = sei.verificar_despacho_estrito(documentos, termos_busca=["pagamento", "autorizado"])

# Mapa detalhado: quais termos foram achados em cada documento
mapa = sei.verificar_despacho_detalhado(
    documentos, termos_busca=["pagamento", "autorizado", "pendente"]
)
for doc, termos in mapa.items():
    print(f"{doc}: {termos}")

2.4. Download de documentos

baixar_documento localiza um documento pelo nome na árvore e salva o PDF localmente — funciona tanto para documentos externos quanto para documentos natos do SEI.

sei.pesquisar_processo("0012345-67.2025.8.19.0000")
sei.expandir_pastas()

if sei.baixar_documento(nome_documento="Balancete Julho 2025"):
    print("Documento baixado com sucesso.")

2.5. Anexos, despachos e blocos de assinatura

sei.pesquisar_processo("0012345-67.2025.8.19.0000")

# Inclui um arquivo externo como Anexo
sei.incluir_anexo(
    nome_arvore="Balancete Julho 2025",
    caminho_arquivo="C:/Users/joao/Downloads/balancete_jul25.pdf",
    nivel_acesso="publico",   # ou "restrito" (exige hipotese_legal)
)

# Cria um Despacho a partir de um texto padrão cadastrado no SEI.
# Retorna True somente se o despacho for confirmado na árvore do processo.
if sei.incluir_despacho(texto_padrao="Encaminhamento SUPCONC"):

    # Preenche as variáveis do modelo no editor CKEditor5 do SEI
    numero_gr = sei.copiar_informacoes_documento()   # nº do último documento da árvore
    sei.formatar_despacho(
        titulo="Senhor Coordenador,",
        valor="1.500,00",
        valor_por_extenso="um mil e quinhentos reais",
        data="01/07/2025",
        num_documento=numero_gr,
        index_doc=numero_gr,
    )

    # Encaminha o processo para assinatura
    sei.incluir_processo_bloco(bloco="Bloco Assinatura Mensal")

3. apipoint — SharePoint e Microsoft Graph

3.1. SharePoint

A classe SharePoint gerencia arquivos e pastas de um site corporativo, usando a API CSOM do SharePoint via office365-rest-python-client (requer instalação manual antes do jupiter-subtes).

Autenticação. Não usa usuário/senha nem registro de aplicativo no Azure AD — a conexão reaproveita cookies de uma sessão de navegador já autenticada:

  • Na primeira conexão (ou sempre que os cookies expirarem), o construtor abre automaticamente uma janela do Microsoft Edge apontando para o site_url informado. A pessoa precisa fazer o login manualmente nessa janela; feito isso, os cookies são salvos em disco e a janela fecha sozinha.
  • Os cookies ficam salvos, por padrão, em ~/Downloads/cookies_SharePoint.json. Use o parâmetro caminho_cookie do construtor para customizar esse caminho — útil se você usa mais de uma conta/site, ou roda em máquinas diferentes.
  • Automações sem interface gráfica (servidor, serviço do Windows, agendador): se a conexão falhar, o construtor exibe um popup de erro (Tkinter messagebox.showerror), o que pode travar um processo headless em vez de simplesmente lançar uma exceção. Rode a primeira conexão manualmente (com tela) para gerar o arquivo de cookies antes de colocar a rotina para rodar sem interação, e garanta que o arquivo de cookies acompanhe a máquina/usuário que vai executar a automação.
  • Configure o log antes de instanciar SharePoint (veja Configuração de logging): a maioria dos métodos abaixo não lança exceção em caso de falha, então sem log configurado você não terá nenhum rastro do que deu errado.

Caminhos. caminho_sharepoint / pasta_sharepoint usam o caminho relativo ao servidor (server-relative URL), no formato /sites/NomeDoSite/Shared Documents/Pasta/arquivo.txt.

from jupiter import SharePoint

sp = SharePoint(site_url="https://tenant.sharepoint.com/sites/SetorContabil")

# Arquivos — download_arquivo/upload_arquivo retornam bool (True em caso de sucesso)
if not sp.download_arquivo(
    caminho_sharepoint="/sites/SetorContabil/Shared Documents/Relatorios/balancete.xlsx",
    pasta_local="C:/Users/joao/Downloads",
):
    print("Falha ao baixar o balancete — verifique o log.")

if not sp.upload_arquivo(
    caminho_local="C:/Users/joao/Downloads/resultado_julho.xlsx",
    pasta_sharepoint="/sites/SetorContabil/Shared Documents/Resultados",
):
    print("Falha ao enviar o resultado — verifique o log.")

# Pastas (recursivo nos dois sentidos) — também retornam bool
sp.download_pasta("/sites/SetorContabil/Shared Documents/Backup", "C:/Users/joao/Backup_SP")
sp.upload_pasta("C:/Users/joao/Relatorios/2025", "/sites/SetorContabil/Shared Documents/2025")

# Verificações e estrutura
if not sp.existe_pasta("/sites/SetorContabil/Shared Documents/2025/Julho"):
    sp.criar_pasta("/sites/SetorContabil/Shared Documents/2025/Julho")

if sp.existe_arquivo("/sites/SetorContabil/Shared Documents/2025/Junho/temp.xlsx"):
    sp.excluir_arquivo("/sites/SetorContabil/Shared Documents/2025/Junho/temp.xlsx")

sp.excluir_pasta("/sites/SetorContabil/Shared Documents/2025/Rascunhos")
Método Ação Retorno
download_arquivo / upload_arquivo Transferência de arquivo único bool — True em caso de sucesso, False se falhar
download_pasta / upload_pasta Transferência recursiva de pastas bool — True somente se todos os arquivos/subpastas forem transferidos com sucesso
criar_pasta Cria a estrutura de pastas (garante o caminho) bool — True em caso de sucesso, False se falhar
existe_arquivo / existe_pasta Verificação de existência bool — False se não existir; lança ValueError para outros erros (ex.: sem permissão)
excluir_arquivo / excluir_pasta Remoção None — lança a exceção original em caso de falha

Os quatro primeiros métodos nunca lançam exceção: qualquer falha é registrada no log (configurar_log) e sinalizada apenas pelo retorno False. Já excluir_arquivo/excluir_pasta propagam a exceção — envolva-os em try/except se for uma operação crítica.

3.2. Microsoft Graph (Outlook e Teams)

A classe GraphAPI usa autenticação app-only (client credentials) para integrar com Outlook e Teams. Requer registro de aplicativo no Azure AD e autorização da TI para a conta corporativa.

from jupiter import GraphAPI

graph = GraphAPI(
    tenant_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    client_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    client_secret="seu-segredo-aqui",
    conta_corporativa="automacao@orgao.rj.gov.br",
)

# Outlook — envio, resposta e leitura
graph.enviar_email(
    titulo="Rotina de julho concluída",
    mensagem="A contabilização de 47 GRs foi finalizada com sucesso.",
    destinatarios=["joao.silva@orgao.rj.gov.br", "chefia@orgao.rj.gov.br"],
)
mensagens = graph.listar_emails(pasta="Inbox", top=5)
graph.responder_email(id_mensagem="AAMkAGI...", texto_resposta="Recebido, em processamento.")
pastas = graph.listar_pastas()
contatos = graph.obter_contatos()

# Teams — mensagem via webhook
graph.enviar_mensagem(
    webhook_url="https://orgao.webhook.office.com/webhookb2/...",
    mensagem="Contabilização de julho finalizada.",
    destinatarios=["equipe-contabil"],
)

Notificação de erros e envio de logs

GraphAPI também serve como canal de monitoramento das rotinas. notificar_erro reporta exceções e enviar_log despacha o conteúdo de um arquivo de log — ambos por Teams e/ou Outlook.

try:
    siafe.gerar_documento(funcao=siafe.gerar_GR, df=df, dict_map=regras)
except Exception as e:
    graph.notificar_erro(
        excecao=e,
        contexto="Contabilização de GR — lote de julho",
        webhook_url=WEBHOOK,
        destinatarios=["suporte@orgao.rj.gov.br"],
    )

# Ao final da rotina, envia o log de erros gerado por configurar_log
graph.enviar_log(
    caminho_log=caminho_erros,
    titulo="Log de erros — Rotina de julho",
    destinatarios=["suporte@orgao.rj.gov.br"],
)

Referência do dict_map

O dict_map é o mecanismo central de separação entre regras de negócio e automação. Cada chave corresponde ao valor da coluna tipo_id no DataFrame; o valor é um dicionário com os campos que o SIAFE exige para aquele tipo de documento.

regras = {

    # ── GR Orçamentária ──────────────────────────────────────────────────────
    "GR_ORC": {
        "TipoDocumento":             "01 - Arrecadação",         # texto exato do dropdown
        "UG":                        "123456",                    # código da UG emitente
        "DomicilioBancario":         "0001",                      # código para pesquisa
        "DomicilioBancarioCompleto": "0001 - BANCO DO BRASIL",    # texto para validação
        "ExtraOrcamentario":         False,

        "IEF":                       "1",
        "Fonte":                     "100",
        "FonteRJ":                   "100",
        "TipoDetalhamentoFonte":     "0",
        "DetalhamentoFonte":         "0000",                      # opcional
        "Convenio":                  "99999",

        "TipoPatrimonial":           "Ativo",
        "ItemPatrimonial":           "Bancos Conta Movimento",
        "OperacaoPatrimonial":       "Entrada de Recursos",
        "NaturezaReceita":           "11180111",                  # exclusivo da GR orçamentária
    },

    # ── GR Extra-orçamentária ────────────────────────────────────────────────
    "GR_EXTRA": {
        "TipoDocumento":             "02 - Extra-orçamentário",
        "UG":                        "654321",
        "DomicilioBancario":         "0002",
        "DomicilioBancarioCompleto": "0002 - CAIXA ECONÔMICA FEDERAL",
        "ExtraOrcamentario":         True,                        # ativa o caminho extra-orçamentário

        "IEF": "1", "Fonte": "100", "FonteRJ": "100",
        "TipoDetalhamentoFonte": "0", "Convenio": "99999",

        "TipoPatrimonial":           "Passivo",
        "ItemPatrimonial":           "Obrigações a Pagar",
        "OperacaoPatrimonial":       "Saída de Recursos",

        "TipoCredor":                "PJ",                        # PJ | PF | CG | UG (padrão: PJ)
        "Credor":                    "12345678000199",
    },

    # ── PDT (Programação de Desembolso de Transferência) ─────────────────────
    "PDT_01": {
        "UG":                               "123456",
        "UGFavorecida":                     "654321",             # opcional; padrão = UG
        "DomicilioBancarioOrigem":          "0001",
        "DomicilioBancarioOrigemCompleto":  "0001 - BANCO DO BRASIL",
        "DomicilioBancarioDestino":         "0002",
        "DomicilioBancarioDestinoCompleto": "0002 - CAIXA",

        "IEF": "1", "Fonte": "100", "FonteRJ": "100",
        "TipoDetalhamentoFonte": "0", "DetalhamentoFonte": "0000", "Convenio": "99999",

        "TipoPatrimonial":                  "Ativo",
        "ItemPatrimonial":                  "Transferências",
        "OperacaoPatrimonial":              "899991",
        "SelecaoPorValor":                  True,                 # seleciona pelo código, não pelo texto

        "Regularizacao":                    "01 - Tipo A",        # opcional
        "JustificativaRegularizacao":       "Regularização do mês anterior",  # opcional
    },

    # ── NP com Inscrição Genérica ────────────────────────────────────────────
    "NP_IG": {
        "UG":                        "123456",
        "TipoPatrimonial":           "Ativo",
        "ItemPatrimonial":           "Ajustes Patrimoniais",
        "OperacaoPatrimonial":       "Bloqueio",
        "SelecaoPorValor":           True,

        "IEF": "1", "Fonte": "100", "FonteRJ": "100",
        "TipoDetalhamentoFonte": "0", "DetalhamentoFonte": "0000",
        "DomicilioBancario":         "0001",

        "InscricaoGenerica":         "12345",                     # opcional
        "TipoInscricaoGenerica":     "01 - Bloqueio",             # opcional
    },

    # ── NA com Estorno ───────────────────────────────────────────────────────
    "NA_ESTORNO": {
        "UG":                        "123456",
        "Estorno":                   True,                        # marca o documento como estorno

        "TipoPatrimonial":           "Ativo",
        "ItemPatrimonial":           "Aplicações Financeiras",
        "OperacaoPatrimonial":       "Resgate",
        "IEF": "1", "Fonte": "100", "FonteRJ": "100",
        "TipoDetalhamentoFonte": "0", "DetalhamentoFonte": "0000",
        "DomicilioBancario":         "0001 - BANCO DO BRASIL",
    },
}

Boas práticas

  • Os textos dos dropdowns devem ser exatamente iguais aos exibidos no SIAFE (copie diretamente da tela).
  • Use "SelecaoPorValor": True quando o dropdown tem muitas opções e é mais confiável selecionar pelo código numérico.
  • Para PDT via API, o dicionário tem estrutura diferente (JSON de payload) e deve ser obtido com dicionario_PDT, não montado manualmente.

Arquivos de XPath

Os módulos siafelibrary_xpaths.py e seilibrary_xpaths.py centralizam os seletores XPath de cada tela. Quando o SIAFE ou o SEI atualizam a interface, basta ajustar o arquivo _xpaths.py correspondente — a lógica de negócio permanece intacta.

siafelibrary_xpaths.py — por tela do SIAFE:

Classe Tela
siafe_xpaths_login Login
xpaths_menu Menu de navegação
xpaths_gr Guia de Recolhimento
xpaths_pde PD Extra-orçamentária
xpaths_pdt PD de Transferência
xpaths_np Nota Patrimonial
xpaths_na Nota de Aplicação e Resgate
xpaths_ev Nota de Evento
xpaths_consulta Filtros de consulta de GR

seilibrary_xpaths.py — por área do SEI:

Classe Área
sei_xpaths_login Login
xpaths_pagina_inicial Barra de pesquisa e menu da unidade
xpaths_processos Árvore de documentos e iframes
xpaths_documento Formulário de inclusão de documento
xpaths_controle_processos Tabela do Controle de Processos
from jupiter import xpaths_gr, siafe_xpaths_login, sei_xpaths_login

print(xpaths_gr.btn_inserir_gr)      # '//*[@id="pt1:tblGuiaRecolhimento:btnInsert"]'
print(siafe_xpaths_login.usuario)    # '//*[@id="loginBox:itxUsuario::content"]'
print(sei_xpaths_login.btn_acessar)  # '//*[@id="sbmAcessar"]'

Estendendo a biblioteca

from jupiter import Siafe, xpaths_gr

class SiafeCustom(Siafe):
    def verificar_numero_gr(self) -> str | None:
        """Retorna o número da GR exibido na tela atual."""
        if self.verifica_visivel(xpaths_gr.numero_documento):
            return self.obter_texto(xpaths_gr.numero_documento)
        return None

Arquitetura e decisões de design

  • Separação de regras de negócio. Siafe não contém nenhum código de conta, fonte ou UG. Tudo é injetado via dict_map, permitindo que a mesma biblioteca atenda a diferentes sub-setores sem alterações no fonte.
  • Validação antes de prosseguir. Após cada preenchimento crítico, o robô relê o campo do SIAFE para confirmar que o valor foi aceito. Se a validação falhar, ele aborta o documento (clicando em "Voltar") e tenta novamente — até 3 tentativas por lançamento.
  • Resiliência a falhas de DOM. Os métodos de interação têm retry automático para StaleElementReferenceException e aguardam o cursor sair do estado de carregamento antes de prosseguir.
  • Persistência incremental. gerar_documento invoca callback_sucesso a cada documento gerado. Se o processo cair na metade, os documentos já contabilizados estão salvos e apenas os pendentes são reprocessados.
  • Dois caminhos para o SIAFE. Operações podem ser feitas pela interface web (robusta, cobre todos os documentos) ou pela API REST (mais rápida, disponível para PDT e consultas), conforme a necessidade.
  • XPaths centralizados. Os seletores ficam nos arquivos _xpaths.py, isolando a manutenção das mudanças de interface do SIAFE e do SEI.
  • Observabilidade integrada. configurar_log padroniza os logs de todos os módulos, e GraphAPI.notificar_erro / enviar_log levam falhas e relatórios para o Teams e o Outlook.
  • A biblioteca não abre janelas. Nenhum método exibe caixas de diálogo: as falhas vão para o log (e, na API, para siafe.ultimo_erro_API) e o retorno indica o resultado. Quem decide o que mostrar ao usuário é o programa chamador. Isso permite rodar em subprocesso, serviço ou agendador sem travar esperando um clique.
  • Consulta de documentos por filtro. Os métodos dicionario_* pedem ao SIAFE apenas o documento-modelo, via POST com o número no corpo da requisição, em vez de baixar todos os documentos da UG no exercício para filtrar localmente.

Release files for jupiter-subtes 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jupiter-subtes 1.2.0
File Size Uploaded
jupiter_subtes-1.2.0.tar.gz 67.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for jupiter-subtes 1.2.0
File Interpreter ABI Platform
jupiter_subtes-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 126.8 kB

Release files / jupiter_subtes-1.2.0.tar.gz

Download URL jupiter_subtes-1.2.0.tar.gz
Size 67.6 kB
Tags Source
SHA-256 checksum
How to use checksums
04a84c963fd6a7fd58230856aeb145ccb24a6ef24ddeea91af24228479998c8d
BLAKE2b-256 checksum
How to use checksums
eb92862bcd7a97a0d88c0aee71496bf5cfea8bf126c3e6b4c23a1797b6239cf5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / jupiter_subtes-1.2.0-py3-none-any.whl

Download URL jupiter_subtes-1.2.0-py3-none-any.whl
Size 59.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1dafd53ba90f3db386218e3ab536b8d5e4d1bcb566047b3d7fa273da54048d39
BLAKE2b-256 checksum
How to use checksums
e32862f83e9861c2992a9fb55e9524c827c213e953f762624526c94c85a5f714
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release history Release notifications | RSS feed

This release

1.2.0 This release

2 release files

1.1.9

2 release files

1.1.8

2 release files

1.1.7

2 release files

1.1.6

2 release files

1.1.5

2 release files

1.1.4

2 release files

1.1.3

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.9

2 release files

1.0.8

2 release files

1.0.7

2 release files

1.0.6

2 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page