Biblioteca para modernização do fluxo de trabalho do Tesouro do Estado do Rio de Janeiro
Project description
🪐 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
- Visão geral dos módulos
- Configuração de logging
- 1. siafelibrary — SIAFE-Rio2
- 2. seilibrary — SEI
- 3. apipoint — SharePoint e Microsoft Graph
- Referência do
dict_map - Arquivos de XPath
- Arquitetura e decisões de design
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
automawebgerencia o MSEdgeDriver automaticamente. A instalação dooffice365-rest-python-clientvia git exige que ogitesteja 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:
- Arquivo geral — mensagens
INFO,WARNINGeERROR; - Arquivo de erros — apenas
ERROR; - 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_EVougerar_PDT_API);df— um DataFrame com os lançamentos;dict_map— dicionário de regras contábeis por tipo (ver Referência dodict_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=Trueevita reabrir o processo quandoadicionar_marcadoré chamado logo apósremover_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. A autenticação usa cookies do navegador, coletados automaticamente via automaweb na primeira conexão e persistidos em disco.
from jupiter import SharePoint
sp = SharePoint(site_url="https://tenant.sharepoint.com/sites/SetorContabil")
# Arquivos
sp.download_arquivo(
caminho_sharepoint="/sites/SetorContabil/Shared Documents/Relatorios/balancete.xlsx",
pasta_local="C:/Users/joao/Downloads",
)
sp.upload_arquivo(
caminho_local="C:/Users/joao/Downloads/resultado_julho.xlsx",
pasta_sharepoint="/sites/SetorContabil/Shared Documents/Resultados",
)
# Pastas (recursivo nos dois sentidos)
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 |
|---|---|
download_arquivo / upload_arquivo |
Transferência de arquivo único |
download_pasta / upload_pasta |
Transferência recursiva de pastas |
criar_pasta |
Cria a estrutura de pastas (garante o caminho) |
existe_arquivo / existe_pasta |
Verificação de existência |
excluir_arquivo / excluir_pasta |
Remoção |
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": Truequando 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.
Siafenão contém nenhum código de conta, fonte ou UG. Tudo é injetado viadict_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
StaleElementReferenceExceptione aguardam o cursor sair do estado de carregamento antes de prosseguir. - Persistência incremental.
gerar_documentoinvocacallback_sucessoa 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_logpadroniza os logs de todos os módulos, eGraphAPI.notificar_erro/enviar_loglevam falhas e relatórios para o Teams e o Outlook.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jupiter_subtes-1.1.5.tar.gz.
File metadata
- Download URL: jupiter_subtes-1.1.5.tar.gz
- Upload date:
- Size: 52.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6af7ba9fb9995c2dc212c3cc6e29fb770ed5008d466796ea631cf7cb11924afb
|
|
| MD5 |
5bcae4de449a3dff378617096365650c
|
|
| BLAKE2b-256 |
18eccff1a8c9623b19ee4a1fbe3e21b1613f19fe94355e241b332adc9dcc23f8
|
File details
Details for the file jupiter_subtes-1.1.5-py3-none-any.whl.
File metadata
- Download URL: jupiter_subtes-1.1.5-py3-none-any.whl
- Upload date:
- Size: 44.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
67ded321506d9e7195f28d7be2ddae52e93fb09fd58e85306a5ceb78a60ae461
|
|
| MD5 |
2af000327a659ca21df4e25c90202a2f
|
|
| BLAKE2b-256 |
0c5f037171274a435fec717426bdb0807ffc5f1cda6c06e2f845e877248f77d9
|