Pular para o conteúdo

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.

Atenção

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:

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.

Atenção

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.

Nota

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:

Antes de conectar num agente

  1. cliente.wsdl.dump() responde e mostra consultarProcesso?
  2. Uma consulta a um processo seu, com movimentos=False e incluirDocumentos=False, devolve sucesso = True?
  3. 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.
  4. O dicionário que a sua Tool devolve tem nome de parte em algum lugar? Imprima-o e leia campo por campo.
  5. MNI_SENHA está só no ambiente — não em config.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.