pypncp — Cliente Python assíncrono para a API de Consulta do PNCP
Project description
pypncp
Cliente Python assíncrono para a API de Consulta do PNCP — Portal Nacional de Contratações Públicas.
Como usar
Adicionar ao projeto
Com uv (recomendado):
uv add pypncp
Com pip:
pip install pypncp
Ou direto no pyproject.toml:
[project]
dependencies = [
"pypncp>=0.1",
]
Criar o cliente
O cliente é a entrada única para a API. Use async with pra gerenciar o ciclo de vida:
from pypncp import PNCPClient
async def buscar_dados():
async with PNCPClient() as client:
# client está pronto — usa os resources abaixo
...
# Fora de async def, use asyncio.run():
# asyncio.run(buscar_dados())
Exemplos por recurso
Contratos — busque contratos por período de publicação:
async with PNCPClient() as client:
# Uma página
page = await client.contratos.list(
data_inicial="2025-01-01",
data_final="2025-03-31",
)
for contrato in page.data:
print(contrato.numero_contrato_empenho, contrato.valor_global)
# Todas as páginas (paginação automática)
async for contrato in client.contratos.list_all(
data_inicial="2025-01-01",
data_final="2025-03-31",
):
print(contrato.objeto_contrato)
Contratações (licitações) — filtre por modalidade (código 1 = pregão):
async with PNCPClient() as client:
async for compra in client.contratacoes.list_all_publicacao(
data_inicial="2025-01-01",
data_final="2025-03-31",
codigo_modalidade=1, # 1 = Pregão
):
print(compra.objeto_compra, compra.orgao_nome)
# Com propostas abertas (apenas data_final)
async for compra in client.contratacoes.list_all_com_proposta(
data_final="2025-12-31",
):
print(compra.objeto_compra, compra.data_abertura_proposta)
Atas de registro de preço:
async with PNCPClient() as client:
async for ata in client.atas.list_all(
data_inicial="2025-01-01",
data_final="2025-12-31",
):
print(ata.objeto_contratacao, ata.orgao_nome)
Paginação
# Automática — use list_all*() (async generator)
async for contrato in client.contratos.list_all(
data_inicial="2025-01-01",
data_final="2025-12-31",
):
...
# Manual — use list() e controle a página
page = await client.contratos.list(
data_inicial="2025-01-01",
data_final="2025-12-31",
pagina=1,
)
print(f"Página {page.numero_pagina} de {page.total_paginas}")
print(f"Itens nesta página: {len(page.data)}")
# Propriedades úteis de Page[T]:
# page.data → list[T]
# page.numero_pagina
# page.total_paginas
# page.has_more → True se há mais páginas
Tratamento de erros
Todas as exceções herdam de PNCPError — nunca vazam exceções de transporte:
from pypncp import PNCPError, NotFoundError, RateLimitError
try:
page = await client.contratos.list(
data_inicial="2025-01-01",
data_final="2025-12-31",
)
except NotFoundError:
print("Recurso não encontrado (HTTP 404)")
except RateLimitError:
print("Muitas requisições (HTTP 429)")
except PNCPError as e:
print(f"Erro na API: {e}")
Exemplo completo com FastAPI
from fastapi import FastAPI, HTTPException
from pypncp import PNCPClient, NotFoundError
app = FastAPI()
@app.get("/contratos")
async def listar_contratos(
data_inicial: str,
data_final: str,
pagina: int = 1,
):
async with PNCPClient() as client:
page = await client.contratos.list(
data_inicial=data_inicial,
data_final=data_final,
pagina=pagina,
)
return {
"contratos": [c.model_dump() for c in page.data],
"pagina": page.numero_pagina,
"total_paginas": page.total_paginas,
"total_registros": page.total_registros,
}
@app.get("/contratos/{orgao_cnpj}/{ano}/{sequencial}")
async def get_contrato(orgao_cnpj: str, ano: int, sequencial: int):
async with PNCPClient() as client:
try:
contrato = await client.contratos.get(
orgao_cnpj=orgao_cnpj,
ano=ano,
sequencial=sequencial,
)
return contrato.model_dump()
except NotFoundError:
raise HTTPException(status_code=404, detail="Contrato não encontrado")
Para contribuir
Requisitos
- Python 3.12+
- uv — gerenciador de projetos e pacotes
uv sync
Rodar verificações
git clone https://github.com/gabrielgz0/pypncp
cd pypncp
uv sync # instala tudo — dev deps inclusas
uv run pytest -v # tests
uv run ruff check src/ tests/
uv run mypy src/
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
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 pypncp-0.1.1.tar.gz.
File metadata
- Download URL: pypncp-0.1.1.tar.gz
- Upload date:
- Size: 15.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
62468d2f599c3d335c104b4df77c502d0ba5724fa21944b4ed09aeb173260fec
|
|
| MD5 |
c95de9f922090c90858a4700052f0f7f
|
|
| BLAKE2b-256 |
791cf8a36a53ac60f6080e0891596cf026968dc17cb05b86047741224e11c751
|
Provenance
The following attestation bundles were made for pypncp-0.1.1.tar.gz:
Publisher:
ci.yml on gabrielgz0/pypncp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pypncp-0.1.1.tar.gz -
Subject digest:
62468d2f599c3d335c104b4df77c502d0ba5724fa21944b4ed09aeb173260fec - Sigstore transparency entry: 1524972333
- Sigstore integration time:
-
Permalink:
gabrielgz0/pypncp@fa1fc780a7878adb87c2363787ed0ad85085c578 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/gabrielgz0
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@fa1fc780a7878adb87c2363787ed0ad85085c578 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pypncp-0.1.1-py3-none-any.whl.
File metadata
- Download URL: pypncp-0.1.1-py3-none-any.whl
- Upload date:
- Size: 13.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d08984481df7c9e004a7f718caa02fbf3cd776fd04d6fdad88da2a5f496a8a45
|
|
| MD5 |
3a9c58587e72e1aa29883797ecb821ec
|
|
| BLAKE2b-256 |
2a675669ed5d094e02373f01e7dabd10f8101578b24a4f9effaafe682e90957a
|
Provenance
The following attestation bundles were made for pypncp-0.1.1-py3-none-any.whl:
Publisher:
ci.yml on gabrielgz0/pypncp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pypncp-0.1.1-py3-none-any.whl -
Subject digest:
d08984481df7c9e004a7f718caa02fbf3cd776fd04d6fdad88da2a5f496a8a45 - Sigstore transparency entry: 1524972339
- Sigstore integration time:
-
Permalink:
gabrielgz0/pypncp@fa1fc780a7878adb87c2363787ed0ad85085c578 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/gabrielgz0
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@fa1fc780a7878adb87c2363787ed0ad85085c578 -
Trigger Event:
release
-
Statement type: