Skip to main content

pyjuris

Pacote Python para normalização de processos judiciais brasileiros.

Recebe payloads brutos de fontes externas (Escavador, futuramente Solucionare) e entrega JSON padronizado para consumidores internos do ecossistema LOPS (lops_api, lops_agents).

  • Stateless — funções puras, sem estado interno
  • Idempotente — mesma entrada, mesma saída
  • Sem descartes — dados incompletos entram com flags, nunca são perdidos
  • Sem IA — transformações explícitas e auditáveis por regras

Instalação

# Core (sem dependências externas)
pip install -e .

# Com CLI (flask, pymongo, rich)
pip install -e ".[cli]"

# Com testes
pip install -e ".[dev]"

Requisito: Python 3.11+


Início rápido

from pyjuris import normalizar_processo

with open("processo.json") as f:
    payload = json.load(f)

result = normalizar_processo(payload)
# → dict padronizado pronto para persistir no lops_api

API

normalizar_processo

Ponto de entrada principal. Transforma payload bruto em JSON normalizado.

from pyjuris import normalizar_processo

result = normalizar_processo(payload)

# Explícito (equivalente ao padrão)
result = normalizar_processo(
    payload,
    input_template="escavador",   # fonte dos dados
    output_template="lops_api",   # formato de saída
    enrich_orgaos=True,           # estrutura orgao_julgador automaticamente
)

# Sem enriquecimento de órgão (bulk processing sem necessidade do campo)
result = normalizar_processo(payload, enrich_orgaos=False)

Saída:

{
  "numero_cnj": "1004370-10.2025.8.26.0590",
  "tipo_principal": "RECURSO",
  "fase_atual": "SEGUNDO_GRAU",
  "status_geral": "ATIVO",
  "total_instancias": 2,
  "segredo_justica": false,
  "capa_disponivel": true,
  "tem_audiencia": false,
  "tem_multiplas_instancias_ativas": true,
  "fenomenos_detectados": [
    "inversao_polo:08057867833",
    "multiplas_instancias_ativas"
  ],
  "ano_inicio": 2025,
  "data_inicio": "2025-04-11",
  "data_ultima_movimentacao": "2025-10-02",
  "data_ultima_verificacao": "2025-10-08T12:30:39Z",
  "polo_ativo": "Thial Felix da Silva",
  "polo_passivo": "Banco Agibank S.A",
  "instancias": [ ... ],
  "schema_version": "1.0",
  "_etl": {
    "processado_em": "2026-03-12T21:00:00Z",
    "versao_etl": "1.0.0",
    "fonte_origem": "escavador"
  }
}

resumo

Texto legível para humanos — útil em logs e CLIs.

from pyjuris import resumo

print(resumo(result))
────────────────────────────────────────────────────────
  Processo   1004370-10.2025.8.26.0590
  Tipo       RECURSO
  Fase       SEGUNDO_GRAU
  Status     ATIVO
  Polo ativo   Thial Felix da Silva
  Polo passivo Banco Agibank S.A
  Instâncias 2 ⚠ múltiplas ativas
  Distribuição        2025-04-11
  Última movimentação 2025-10-02

  Alertas:
    ⚠  Polo ativo e passivo invertidos entre graus do processo
    ⚠  Processo ativo simultaneamente em mais de uma instância
────────────────────────────────────────────────────────

should_reprocess

Decide se um processo deve ser reprocessado comparando datas de movimentação.

from pyjuris import should_reprocess

should_reprocess("2025-09-01", "2025-10-02")  # → True  (incoming mais recente)
should_reprocess("2025-10-02", "2025-10-02")  # → False (mesma data)
should_reprocess(None, "2025-10-02")          # → True  (sem dado armazenado)

descrever_fenomeno / descrever_fenomenos

Converte códigos de fenômenos em descrições legíveis em português.

from pyjuris import descrever_fenomeno, descrever_fenomenos

descrever_fenomeno("inversao_polo:12345678900")
# → "Polo ativo e passivo invertidos entre graus do processo"

descrever_fenomenos(result["fenomenos_detectados"])
# → [{"codigo": "inversao_polo:...", "descricao": "..."}, ...]

Fenômenos disponíveis:

Código Descrição
cnj_invalido Número CNJ fora do formato padrão
sem_fontes Nenhuma fonte judicial encontrada
multiplas_instancias_ativas Processo ativo em mais de uma instância
duplicata_ingestao Fonte duplicada detectada na mesma instância
redistribuicao Redistribuição identificada entre fontes do mesmo grau
crawl_duplicado Coleta duplicada da mesma fonte
recursos_distintos Recursos distintos no mesmo grau
inversao_polo:<doc> Polo ativo/passivo invertidos entre graus

CNJParser

Resolve tribunal_sigla, estado e comarca a partir do número CNJ — sem consultas externas.

from pyjuris import CNJParser

parser = CNJParser()

# Resolução básica (tabela estática + 6.797 pares OOOO→comarca)
r = parser.parse("0001234-56.2023.8.26.0536")
# {
#   'tribunal_sigla': 'TJSP',
#   'tribunal_nome':  'TJ de São Paulo',
#   'estado':         'SP',
#   'comarca':        'Santos',
#   'confianca':      'referencia',
#   'segmento':       'Justiça Estadual',
#   'oooo':           '0536',
# }

# Com dados do Escavador (confiança máxima)
r = parser.parse(
    "0001234-56.2023.8.26.0536",
    unidade_origem={"nome": "3ª Vara Cível de Santos", "tribunal_sigla": "TJSP"},
)
# confianca: 'escavador'

Níveis de confiança:

Valor Significado
escavador Dado direto de unidade_origem
referencia OOOO resolvido via tabela com 6.797 pares
tribunal Só tribunal resolvido — comarca desconhecida
none CNJ inválido

Cobertura (sobre 9,5M processos reais): ~68% referencia · ~17% precisa de unidade_origem · ~15% só tribunal.

Também disponível: normalizar_comarca(nome_unidade) — extrai cidade a partir do nome da vara/foro do Escavador.

from pyjuris import normalizar_comarca

normalizar_comarca("17ª Vara do Trabalho de Manaus")  # → "Manaus"
normalizar_comarca("FORO REGIONAL II - SANTO AMARO")  # → "Santo Amaro"
normalizar_comarca("COMARCA DE CAMPINAS")             # → "Campinas"

get_orgaos / parsear_orgao / get_tribunais

Referência de órgãos julgadores brasileiros — 32k+ órgãos de 64 tribunais, bundled com o pacote.

from pyjuris import get_tribunais, get_orgaos, parsear_orgao

# Lista todos os tribunais disponíveis
get_tribunais()
# → ["STJ", "TJSP", "TJRS", "TRF1", "TRT1", ...]  (64 tribunais)

# Órgãos estruturados de um tribunal
get_orgaos("TJRS")[9]
# → {
#     "nome_original": "10ª Vara Criminal do Foro Central - Porto Alegre",
#     "nome_normalizado": "10ª Vara Criminal do Foro Central - Porto Alegre",
#     "encoding_status": "ok",
#     "tipo": "VARA",
#     "numero": 10,
#     "especialidade": "CRIMINAL",
#     "localidade": "Porto Alegre",
#     "cargo": None,
#     "nome_pessoa": None
#   }

# Parsing avulso de qualquer string
parsear_orgao("3ª Vara da Fazenda Pública - Belo Horizonte")
# → {"tipo": "VARA", "numero": 3, "especialidade": "FAZENDA_PUBLICA",
#    "localidade": "Belo Horizonte", "cargo": None, "nome_pessoa": None}

parsear_orgao("GABINETE DA MINISTRA NANCY ANDRIGHI")
# → {"tipo": "GABINETE", "numero": None, "especialidade": None,
#    "localidade": None, "cargo": "Ministra", "nome_pessoa": "Nancy Andrighi"}

O campo orgao_julgador_info é adicionado automaticamente em cada instância pelo normalizar_processo (controlado por enrich_orgaos=True).

Tipos de órgão: VARA, CAMARA, TURMA, TURMA_RECURSAL, GABINETE, JUIZADO_ESPECIAL, JUIZADO_ESPECIAL_FEDERAL, JUIZADO, CEJUSC, UNIDADE_JURISDICIONAL, NUCLEO, GRUPO, SUBSECAO, SECAO, PRESIDENCIA, CORREGEDORIA, DIRETORIA, SECRETARIA, PLENARIO, OUTRO

Especialidades: CIVEL, CRIMINAL, FAZENDA_PUBLICA, EXECUCAO_FISCAL, PREVIDENCIARIO, FAMILIA, ORFAOS_SUCESSOES, INFANCIA_JUVENTUDE, CONSUMIDOR, TRABALHISTA, ACIDENTES_TRABALHO, ELEITORAL, MILITAR, PLANTAO, AMBIENTAL, EMPRESARIAL, PROPRIEDADE_INTELECTUAL, RECUPERACAO_JUDICIAL, AGRARIO, TRIBUTARIO


CLI

# Pipe: stdin → stdout
cat processo.json | pyjuris

# Resumo legível
cat processo.json | pyjuris --resumo

# Arquivo → arquivo
pyjuris -i processo.json -o resultado.json

# Batch: diretório inteiro
pyjuris -i ./jsons/ -o ./output/

# Templates explícitos
pyjuris --input-template escavador --output-template lops_api < processo.json

# Servidor HTTP local (porta 5045)
pyjuris --api

Servidor HTTP (--api):

Endpoint Método Descrição
POST /transform JSON body Normaliza um processo
POST /upload multipart Upload de arquivo JSON
GET / — Health check

Schema de saída

Processo (topo)

Campo Tipo Valores
numero_cnj string | null Formato NNNNNNN-DD.AAAA.J.TT.OOOO
tipo_principal enum ACAO_ORIGINAL, RECURSO, CUMPRIMENTO_SENTENCA, RECURSO_INTERMEDIARIO, DESCONHECIDO
fase_atual enum PRIMEIRO_GRAU, SEGUNDO_GRAU, TERCEIRO_GRAU, ENCERRADO, DESCONHECIDO
status_geral enum ATIVO, INATIVO
total_instancias integer —
segredo_justica boolean —
capa_disponivel boolean —
tem_audiencia boolean —
tem_multiplas_instancias_ativas boolean —
fenomenos_detectados string[] Ver tabela de fenômenos
ano_inicio integer | null —
data_inicio date | null YYYY-MM-DD
data_ultima_movimentacao date | null YYYY-MM-DD
data_ultima_verificacao datetime | null ISO 8601
polo_ativo string | null Nome da parte ativa principal
polo_passivo string | null Nome da parte passiva principal
instancias Instancia[] Ver abaixo
schema_version string "1.0"
_etl object processado_em, versao_etl, fonte_origem

Instância

Campo Tipo Valores
fonte_id integer | null —
grau enum 1, 2, 3
grau_formatado enum Primeiro Grau, Segundo Grau, Terceiro Grau
tipo enum Mesmo que tipo_principal
tribunal object sigla, nome, sistema
classe string | null Classe normalizada pelo ETL
classe_raw string | null Classe original da fonte
assunto_principal string | null —
assunto_path string | null Ex: DIREITO DO CONSUMIDOR > Bancários
assuntos Assunto[] {id, nome, path}
orgao_julgador string | null String original
orgao_julgador_info OrgaoJulgador | null Parsing estruturado (ver acima)
valor_causa number | null Em BRL
moeda enum BRL, null
data_inicio date | null —
data_ultima_movimentacao date | null —
status enum ATIVO, INATIVO
arquivado boolean | null —
capa_disponivel boolean —
partes Parte[] Ver abaixo
audiencias array —

Parte

Campo Tipo Valores
nome string | null —
polo enum ATIVO, PASSIVO, ADVOGADO, DESCONHECIDO
tipo enum FISICA, JURIDICA, DESCONHECIDO, null
tipo_pessoa enum FISICA, JURIDICA, DESCONHECIDO, null
documento string | null CPF ou CNPJ sem formatação
advogados array —

Arquitetura

payload bruto (Escavador | Solucionare)
    ↓ pyjuris/inputs/<template>.parse()
canonical dict          ← formato interno, nunca exposto diretamente
    ↓ pyjuris/outputs/<template>.serialize()
output final (lops_api | solucionare)
    ↓ pipeline.py (enrich_orgaos=True)
+ orgao_julgador_info em cada instância

O pipeline tem 6 camadas internas (aplicadas em inputs/escavador.py):

  1. Sanitização — normaliza strings e datas antes de qualquer lógica
  2. Classificação — mapeia classe processual para tipos canônicos
  3. Deduplicação — remove fontes duplicadas, detecta redistribuições
  4. Normalização — constrói objetos por instância judicial
  5. Detecção de fenômenos — inversão de polo, múltiplas instâncias ativas
  6. Transform — orquestra o pipeline e monta o canonical

Adicionar nova fonte de dados (input)

# 1. Criar pyjuris/inputs/nova_fonte.py
def parse(payload: dict) -> dict:
    """Converte payload bruto para canonical dict."""
    ...

# 2. Registrar em pyjuris/inputs/__init__.py
# 3. Usar: normalizar_processo(payload, input_template="nova_fonte")

Adicionar novo consumidor (output)

# 1. Criar pyjuris/outputs/novo_consumidor.py
def serialize(canonical: dict, etl_version: str) -> dict:
    """Converte canonical para formato do consumidor."""
    ...

# 2. Registrar em pyjuris/outputs/__init__.py
# 3. Usar: normalizar_processo(payload, output_template="novo_consumidor")

Testes

# Suite completa
pytest tests/ -v

# Smoke test com uso real
python scripts/testar_lib.py
python scripts/testar_lib.py --verboso

Scripts utilitários

Script Descrição
scripts/testar_lib.py Smoke test de uso real (não pytest)
scripts/sanear_orgaos.py Gera data/orgaos_julgadores_v2.json para inspeção
scripts/eda_escavador.py Análise exploratória de payloads no MongoDB
scripts/analyze_classe_score.py Análise de cobertura de mapeamento de classes

Migrações de banco

Scripts em migrations/ para evolução do schema MongoDB/PostgreSQL:

python migrations/migration_0001_enums_e_dominios.py
python migrations/migration_0002_rename_e_tipos.py
python migrations/migration_0003_indices.py

Schema SQL completo em docs/schema_banco.sql.

Metadata

Release files for pyjuris 2.0.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 pyjuris 2.0.0
File Size Uploaded
pyjuris-2.0.0.tar.gz 340.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyjuris 2.0.0
File Interpreter ABI Platform
pyjuris-2.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 671.8 kB

Release files / pyjuris-2.0.0.tar.gz

Download URL pyjuris-2.0.0.tar.gz
Size 340.5 kB
Tags Source
SHA-256 checksum
How to use checksums
09120ce1e45f8cf4bd957c35aafcd92c22cce00fb0c149056010cb9ce88139b1
BLAKE2b-256 checksum
How to use checksums
2322ad44da35c1f08b47cc9da0bd4486d165320f64db29ac492f899c1d21b6e7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 6, 2026.

Transparency log

Release files / pyjuris-2.0.0-py3-none-any.whl

Download URL pyjuris-2.0.0-py3-none-any.whl
Size 331.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4a2b4811ca7911bdb927a70566b1bcb3ffef1627508e95dae1ad30cf53d1fa0c
BLAKE2b-256 checksum
How to use checksums
5e7e7c249a42fbea915c4ea29765fc60c19d8fd60da1436626eb6e380db53e7d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 6, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.0.0 This release

2 release files

1.0.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