MNI — a porta que já é sua
O MNI (Modelo Nacional de Interoperabilidade) é o webservice pelo qual os sistemas processuais brasileiros conversam entre si. Ele existe porque o STF precisava receber processo do TJ sem que alguém redigitasse, e virou padrão do CNJ: a versão em uso é a 2.2.2, e PJe e eproc a implementam.
Para você, ele tem uma propriedade que o banco de dados não tem: a credencial é a sua.
Aviso de método, e ele vale o capítulo inteiro.
Eu não testei nada deste capítulo. Chamar o MNI exige a credencial nominal de um magistrado num tribunal, e eu não tenho — nem deveria ter. Tudo aqui vem da documentação pública do CNJ e do WSDL, que são legíveis sem credencial.
Em todo capítulo anterior deste curso os números foram medidos. Neste, não. Quando você rodar, vai encontrar diferenças — nomes de campo, comportamentos, erros que eu não previ. Anote-as. São o material da próxima versão, e valem mais do que qualquer coisa que eu escreva sem a chave na mão.
O que o MNI é, e o que ele não é
Comece pela limitação, porque ela decide se este capítulo serve para a sua pergunta.
A operação central chama-se consultarProcesso, e ela recebe um número de processo. Você já precisa saber qual processo quer. Nas cinco formas da Unidade 3, isso é exclusivamente a forma 5 — Detalhar.
O MNI não conta e não lista. Não existe "quantos processos de tráfico eu tenho" no MNI. Não existe "quais os dez mais antigos".
Isso não é defeito: é o desenho. O MNI foi feito para transportar um processo de um sistema para outro, com fidelidade e com autorização. Estatística nunca foi o objetivo.
A consequência prática, e ela amarra o curso todo:
| Sua pergunta | Onde ela é respondida |
|---|---|
| "quantos?", "quais?", "por órgão?", "cresceu?" | DataJud (Unidade 2) ou o banco interno (capítulo anterior) |
| "e este processo aqui, o que houve nele?" | MNI |
Um agente útil tem as duas coisas: uma Tool que encontra o número, e uma que aprofunda naquele número. As duas vêm de portas diferentes, e é normal que venham.
As três operações, e por onde começar
O CNJ orienta os tribunais a implementar três operações primeiro:
consultarProcesso— os dados de um processo, opcionalmente com movimentos e documentos.consultarAvisosPendentes— as intimações e citações pendentes para aquela identificação.consultarTeorComunicacao— o conteúdo de uma dessas comunicações.
Comece pela primeira. As outras duas são de fluxo de trabalho — mexer nelas é mexer em prazo, e prazo não é lugar de exercício de curso.
O WSDL é a fonte da verdade
Cada tribunal publica o seu endpoint. O CNJ publica o WSDL de referência do serviço de intercomunicação 2.2.2, e o STF publica ambientes separados de teste, homologação e produção — o que é uma boa notícia, porque existe onde errar sem errar em produção.
Peça à sua TI o endereço do endpoint do seu tribunal, e pergunte se há ambiente de homologação. Não adivinhe a URL: o padrão de nome varia, e uma URL adivinhada que responde é pior do que uma que não responde.
Com o endereço na mão, não escreva XML. Deixe a biblioteca ler o contrato:
pip install zeep
from zeep import Client
# O endereço vem da sua TI. O ?wsdl no fim é o que devolve o contrato. {: #o-endereço-vem-da-sua-ti-o-wsdl-no-fim-é-o-que-devolve-o-contrato }
cliente = Client("https://.../intercomunicacao?wsdl")
# Antes de qualquer chamada: leia o que o serviço oferece. {: #antes-de-qualquer-chamada-leia-o-que-o-serviço-oferece }
print(cliente.wsdl.dump())
Esse dump() é o primeiro comando a rodar, e é o equivalente aqui ao WHERE 1=0 do capítulo anterior: ele te mostra o formato — operações, parâmetros, tipos de retorno — sem consultar processo nenhum.
O zeep monta o envelope SOAP, resolve os tipos e devolve objeto Python. Escrever o XML à mão é possível e é como se descobre que um namespace estava errado às onze da noite.
A chamada, e os dois parâmetros que decidem tudo
import os
resposta = cliente.service.consultarProcesso(
idConsultante=os.environ["MNI_ID"],
senhaConsultante=os.environ["MNI_SENHA"],
numeroProcesso=numero,
movimentos=True,
incluirDocumentos=False, # <- leia a próxima seção antes de mudar isto
)
Sua identificação e sua senha vão no corpo da requisição. Isso tem duas consequências imediatas:
A senha é a sua senha do sistema. Vale para ela tudo do capítulo anterior, e um pouco mais: variável de ambiente, nunca em arquivo, nunca em repositório, nunca num print de depuração. Uma senha de banco vazada é um chamado à TI; a sua senha do PJe vazada é a sua assinatura.
A resposta chega com as suas permissões. O sistema do outro lado faz a mesma verificação que faria na tela. Se você não pode ver aquele processo, não vem. Essa é a garantia que o banco não dava — e é o motivo de este capítulo ser mais curto que o anterior.
incluirDocumentos=True traz as peças do processo, em base64, dentro da resposta.
Numa Tool de agente, isso significa a petição inicial, a denúncia, o laudo — inteiros — indo para o contexto do modelo. Não é um vazamento sutil: é o processo inteiro copiado para outro lugar, por causa de um parâmetro booleano.
Deixe False. Se um dia precisar de um documento específico, isso é uma segunda Tool, explícita, que recebe o identificador daquele documento e é chamada de propósito — não um parâmetro ligado por padrão numa Tool de consulta.
O que vem, e o que não pode sair
A resposta do consultarProcesso traz um bloco de dados básicos e, se você pediu, a lista de movimentos.
E traz, nos dados básicos, os polos e as partes: nome, e a depender do sistema, documentos de identificação.
Este é o parágrafo mais importante do capítulo. Você pode ver esses nomes — é o seu processo, e a autorização é legítima. A pergunta não é essa. A pergunta é a da Unidade 4 inteira:
Isto pode ir para o modelo?
Não. E aqui o risco é maior do que no banco, por um motivo mecânico: no banco você escreveu a lista de colunas. Aqui, a resposta chega inteira e pronta, e o caminho de menor esforço — devolver o objeto que veio — é justamente o caminho que entrega tudo.
# Errado. Compila, roda, responde bem, e entrega as partes ao modelo. {: #errado-compila-roda-responde-bem-e-entrega-as-partes-ao-modelo }
def consultar(numero: str) -> dict:
return serialize_object(cliente.service.consultarProcesso(...))
# Certo. A Tool escolhe o que devolver, como na Unidade 3. {: #certo-a-tool-escolhe-o-que-devolver-como-na-unidade-3 }
def consultar_processo(numero_processo: str) -> dict:
"""O andamento de um processo específico, sem dados das partes.
Args:
numero_processo: número no formato CNJ, só dígitos ou com pontuação.
"""
r = cliente.service.consultarProcesso(
idConsultante=os.environ["MNI_ID"],
senhaConsultante=os.environ["MNI_SENHA"],
numeroProcesso=numero_processo,
movimentos=True,
incluirDocumentos=False,
)
if not r.sucesso:
return {"erro": r.mensagem}
basicos = r.processo.dadosBasicos
# Cinto de segurança, igual ao TETO_SIGILO da Unidade 2. Aqui ele não é
# redundante: o MNI devolve o sigiloso porque VOCÊ pode vê-lo.
if int(basicos.nivelSigilo or 0) > 0:
return {"erro": "processo sigiloso; consulte pelo sistema."}
movimentos = [
{"data": str(m.dataHora), "codigo": m.movimentoNacional.codigoNacional}
for m in (r.processo.movimento or [])
][-20:] # os últimos 20 — ver a Unidade 3
return {
"numero_processo": numero_processo,
"classe": basicos.classeProcessual,
"movimentos": movimentos,
}
# Note o que NÃO está no dicionário: polo, parte, nome, documento.
Os nomes exatos dos campos dependem do WSDL do seu tribunal. Confira no dump() antes de copiar — é para isso que ele serve.
O [-20:] e a montagem manual do dicionário são o capítulo Escrever Tool é escolher o que não devolver aplicado. Um processo antigo tem centenas de movimentos, e a resposta do MNI é XML — mais verborrágica que o JSON do DataJud, com a mesma informação.
O problema de tamanho da Unidade 3 volta aqui inteiro, e a solução é a mesma.
Erros que você vai encontrar
Não os medi, mas a forma deles é previsível o bastante para valer o aviso:
sucesso = Falsecom mensagem de credencial. Confira se a identificação é a que o tribunal cadastrou para o serviço — nem sempre é o CPF puro.sucesso = Falseem processo que você vê na tela. Costuma ser autorização por competência: a tela pode consultar em contextos que o serviço não replica. É pergunta para a TI, não bug seu.- Timeout. Vale a lição da Unidade 2: repetir só faz sentido em erro de conexão. Repetir depois de uma recusa de credencial é tentar a senha errada de novo, e algumas vezes seguidas é conta bloqueada.
- SSL. Certificado interno faz o
zeeprecusar. A saída não é desligar a verificação — é pedir o certificado da cadeia interna à TI e apontar para ele.
Antes de conectar num agente
cliente.wsdl.dump()responde e mostraconsultarProcesso?- Uma consulta a um processo seu, com
movimentos=FalseeincluirDocumentos=False, devolvesucesso = True? - Uma consulta a um processo que não é seu devolve recusa? Se devolver dados, a credencial alcança mais que você — pare e fale com a TI.
- O dicionário que a sua Tool devolve tem nome de parte em algum lugar? Imprima-o e leia campo por campo.
MNI_SENHAestá só no ambiente — não emconfig.yaml, não em notebook, não no histórico do PowerShell?
O item 3 é o teste que ninguém faz e é o único que confirma, com medição, a propriedade que abre este capítulo.
Próximo: eproc, o único sistema em que esta porta e a do banco estão abertas ao mesmo tempo.