Skip to main content

CLI zero-dependência para as APIs públicas do PNCP (Portal Nacional de Contratações Públicas)

Project description

pncp-cli

CLI e biblioteca Python para as APIs públicas do PNCP (Portal Nacional de Contratações Públicas). Sem dependências além da stdlib.

Cobre os endpoints GET públicos das duas APIs REST oficiais (specs OpenAPI em /api/consulta/v3/api-docs e /api/pncp/v3/api-docs) e a API de busca do portal. Inclui uma skill de Claude Code para uso assistido.

Instalação

uv tool install pncp-cli        # ou: pipx install pncp-cli
pncp --version

# a partir do código-fonte
git clone https://github.com/AnxietyLab/pncp-cli
cd pncp-cli
uv tool install -e .

Comandos

comando descrição
search busca textual/facetada (editais, atas, contratos)
filtros facetas e tabelas de IDs da busca
consulta contratacoes contratações por período de publicação ou atualização
consulta propostas contratações com propostas em aberto
consulta atas / contratos atas de registro de preço e contratos por período
consulta cobranca instrumentos de cobrança por período
consulta pca Plano de Contratações Anual (geral, por usuário ou atualização)
contratacao / itens / arquivos / historico detalhe de uma contratação
resultados fornecedor vencedor e valores homologados por item
ata atas de uma contratação (detalhe, arquivos, partes, contratos)
contrato contratos e sub-recursos (termos, empenhos, arquivos)
orgao órgãos por CNPJ, id ou razão social; unidades
pca PCA de um órgão (consolidado, itens, valores, CSV)
dominio tabelas de referência (modalidades, amparos legais etc.)
controle decompõe um número de controle PNCP

Exemplos

# descoberta
pncp search "notebook" --tipo edital --status recebendo_proposta --uf SP --table

# coleta por período (NDJSON: um registro por linha, em streaming)
pncp consulta contratacoes --de 2026-01-01 --ate 2026-06-30 \
  --modalidade 6 --all --ndjson > pregoes.ndjson

# da busca ao detalhe
pncp search "ambulância" --tipo edital --all --limit 50 --ndjson \
  | jq -r .numero_controle_pncp \
  | while read c; do pncp itens --controle "$c" --ndjson; done

# documentos de uma contratação
pncp arquivos 07424905000138 2026 212 --baixar ./docs

# quem venceu cada item, por quanto
pncp resultados 80881915000192 2026 44 --ndjson

# demanda futura declarada de um órgão
pncp pca valores 00394452000103 2026

# filtro local com --limit contando após o filtro
pncp consulta contratacoes --de 2026-06-01 --ate 2026-06-30 --all \
  --incluir "armazenamento de dados" --incluir storage --excluir locacao \
  --limit 100 --ndjson --link

Flags globais

flag efeito
--output json|ndjson|table formato de saída (--ndjson/--table são atalhos)
-q, --quiet suprime o progresso no stderr; avisos continuam
--timeout S, --retries N ajustes por requisição (padrão 60s / 5)
--pausa SEG espera entre requisições consecutivas
--version versão instalada

Saída no stdout é sempre JSON válido (seguro para jq); progresso e avisos vão para o stderr.

exit code significado
0 sucesso
1 erro
3 sucesso parcial: stdout válido porém truncado; o stderr indica como retomar

Coletas grandes

Janelas automáticas

A API /consulta rejeita períodos maiores que 365 dias (HTTP 422). Os comandos de período dividem o intervalo em janelas válidas automaticamente.

Streaming

Em NDJSON, cada registro é emitido assim que a página chega. Nada é acumulado em memória, e uma falha no meio preserva o que já saiu: exit code 3, página de retomada indicada no stderr e, no JSON agregado, os campos incompleto/proximaPagina.

Checkpoint

consulta contratacoes --checkpoint arquivo.json grava o progresso após cada página, por unidade de trabalho (modalidade × janela), e retoma coletas interrompidas do ponto exato — inclusive varreduras --modalidade all sobre períodos longos. Regras:

  • exige saída NDJSON (em json/table os registros só saem no fim, e uma interrupção perderia dados já registrados como coletados);
  • o arquivo guarda a identidade da consulta (datas, filtros, --all, --link); reutilizá-lo com parâmetros diferentes é recusado;
  • --limit fica fora da identidade: atingido o limite, o checkpoint é mantido e uma execução posterior com limite maior continua de onde parou;
  • a retomada é at-least-once com granularidade de página: uma interrupção abrupta pode re-emitir registros da página em andamento. Ao carregar em banco, deduplique por numeroControlePNCP (contratações) ou pela chave composta com numeroItem/sequencialDocumento (itens, resultados, arquivos);
  • incompatível com --incluir/--excluir (colete sem filtro e filtre depois).

Filtros locais

search e consulta contratacoes aceitam uma etapa de filtro aplicada localmente sobre os registros:

flag semântica
--incluir TERMO mantém registros que casam (repetível)
--excluir TERMO descarta registros que casam (repetível)
--match any|all --incluir exige qualquer termo (padrão) ou todos
--link acrescenta _link_pncp (URL da contratação no portal)

Um termo de uma palavra casa token inteiro ("rede" não casa "credenciamento"); um termo com espaços casa como frase. A comparação ignora caixa e acentos. Com filtros, --limit conta registros após o filtro.

Comportamentos da API tratados pela CLI

Comportamentos conhecidos dos servidores do PNCP tratados pela CLI:

  • O WAF recusa conexões sem User-Agent de navegador; a API /consulta exige Accept: application/json. A CLI envia ambos.
  • Rate limit se manifesta como HTTP 429 ou como página HTML em resposta 200; os dois casos são retentados com espera (respeitando Retry-After).
  • Endpoints de coleção do pncp-api paginam com tamanhoPagina=10 por padrão e truncam sem qualquer indicação. A CLI sempre pagina até o fim.
  • Coleção vazia é sinalizada como 404 com mensagem descritiva; a CLI converte em lista vazia. O 404 de um recurso de detalhe continua sendo erro.
  • tamanhoPagina máximo varia por endpoint (50 em contratações, 100 em cobrança, 500 em atas/contratos); --tam é validado antes da requisição.
  • Períodos maiores que 365 dias retornam 422; ver janelas automáticas acima.
  • Resposta vazia no meio de uma paginação (após a API indicar páginas restantes) é tratada como truncagem, não como fim normal.
  • Instabilidades do lado do servidor (5xx intermitente) são retentadas; se persistirem, a coleta termina como sucesso parcial (exit 3), sem descartar os registros já obtidos.

Uso como biblioteca

O núcleo não depende de argparse. iter_consulta, iter_cru e iter_envelope são generators com parâmetros explícitos; filtrar e com_link compõem sobre qualquer iterável:

from pncp_cli import iter_consulta, filtrar, CONFIG

CONFIG["pausa"] = 0.5
registros = iter_consulta(
    "/api/consulta/v1/contratacoes/publicacao",
    {"dataInicial": "20260101", "dataFinal": "20260630",
     "codigoModalidadeContratacao": 6},
    seguir=True)
for r in filtrar(registros, incluir=["storage", "armazenamento de dados"]):
    ...

Skill de Claude Code

O pacote embute uma skill para Claude Code que ensina o assistente a operar esta CLI: quando usar busca ou consulta, vocabulário de modalidades e códigos, receitas de coleta e as armadilhas da API. Para instalar:

pncp skill instalar          # copia para ~/.claude/skills/pncp

Respeita CLAUDE_CONFIG_DIR; use --dir para outro destino. A fonte fica em src/pncp_cli/skill/SKILL.md.

Desenvolvimento

uv run --with pytest --no-project pytest tests/ -q

Os testes simulam o transporte HTTP; nenhum toca a rede. A estrutura do pacote separa transporte (client.py), paginação (pagination.py), domínio (filtros.py, controle.py), apresentação (output.py) e comandos (commands/).

Licença

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pncp_cli-2.0.0.tar.gz (41.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pncp_cli-2.0.0-py3-none-any.whl (35.4 kB view details)

Uploaded Python 3

File details

Details for the file pncp_cli-2.0.0.tar.gz.

File metadata

  • Download URL: pncp_cli-2.0.0.tar.gz
  • Upload date:
  • Size: 41.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for pncp_cli-2.0.0.tar.gz
Algorithm Hash digest
SHA256 18885115c43e43b2879a307a80a212b0b778df13a8a4a4fce0bbb237582e120c
MD5 cd5ba46d85bc4e4363180cff53cea665
BLAKE2b-256 20d2cba91f879e79e5ceeac5bc521d80f9012c1aa99b7861459c2ed254307b87

See more details on using hashes here.

File details

Details for the file pncp_cli-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: pncp_cli-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 35.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for pncp_cli-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 59a36f0d80020f0dc7793ad7124c3e21022ae04865019f74db03ddbe21a87f65
MD5 a689e94cba2b7b8c21361b4a0a3ec917
BLAKE2b-256 7ac9475cd5f170725648608da4824fb2202ea8c4df2b9650074ae625573901bc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page