Skip to main content

cepx

Fast, offline-capable Brazilian CEP (postal code) lookup for Python, sync and async.

Most CEP libraries are thin HTTP clients: every lookup is a round-trip to Correios/ViaCEP/BrasilAPI, so you inherit their latency, rate limits, and downtime. cepx can resolve CEPs fully offline from a prebuilt database bundled with the package; in microseconds, with no network at all. When you do want the network, it still races the same public providers and returns the first successful answer.

Why cepx

local (offline) network providers
Latency ~12 µs/lookup (~85k/s) one HTTP round-trip (tens–hundreds of ms)
Network none required
Rate limits / outages none subject to both
Works air-gapped ✅ ❌
Coverage ~1.14M CEPs (bundled) whatever the live service returns

The offline path is thousands of times faster than any HTTP lookup and depends on nothing but your own process. Numbers above are the full public API (cepx.cep(...)) against the complete national database, reproducible with make bench-local.

Offline lookups (the local provider)

Install the local extra (it pulls in cepx-data), which ships a prebuilt SQLite database of ~1.14M CEPs:

pip install "cepx[local]"
import cepx

cepx.cep("05010000", providers=["local"])
# Address(cep='05010000', state='SP', city='São Paulo',
#         neighborhood='Perdizes', street='Rua Caiubi', provider='local')
  • Zero network. No requests, no rate limits, no third-party availability to depend on. Ideal for batch jobs, air-gapped environments, and hot paths.
  • Auto-discovered. Once cepx-data is installed, the local provider finds the database automatically; set CEPX_DB to point at your own SQLite file.
  • Opt-in. local is not part of the default provider race; request it explicitly with providers=["local"].

The database

cepx[local] adds one dependency, cepx-data, which bundles the CEP database:

  • ~17 MiB download (the wheel), ~42 MiB on disk once installed — a one-time cost, no runtime downloads.
  • ~1.14 million CEPs: every UF, ~5.4k municipalities, ~31k neighborhoods, ~611k streets.
  • Stored as a normalized SQLite database (one row per CEP keyed on the CEP itself, with UF/city/neighborhood/street deduplicated into lookup tables), so a query is a single indexed primary-key join.
  • Data is derived from CEP Aberto under the Open Database License (ODbL); cepx-data ships it and carries the attribution.

A CEP that isn't in the dataset is a clean miss (provider_error); fall back to the network providers for full coverage if you need it.

Offline-first with network fallback

Prefer the local database and only touch the network when a CEP isn't covered:

def lookup(cep):
    try:
        return cepx.cep(cep, providers=["local"])   # ~microseconds on a hit
    except cepx.CepxError:
        return cepx.cep(cep)                        # network only on a miss

Do this rather than passing providers=["local", ...] in a single call: mixing local with network providers forces the concurrent race path, which spins up a thread pool and fires the network requests on every lookup, even the ones local answers instantly (they're just cancelled once local wins). The two-step form keeps hits fully offline at microsecond speed and only touches the network on genuine misses.

Network lookups

Without the extra (or when you don't request local), cepx queries the live providers concurrently and the first successful response wins. The lookup only fails once every provider fails, aggregating each error.

These are the built-in providers. The first column is the exact string to pass in providers=[...]:

providers= Service Notes
"correios" Correios SIGEP (official postal authority) The official source; SOAP/XML endpoint, so usually the slowest to answer
"correios-alt" Correios address search (the buscacepinter site backend) Same official data through the public site's endpoint
"viacep" ViaCEP Long-running, widely used free API
"widenet" apicep.com (formerly WideNet) Serves CDN-cached JSON
"brasilapi" BrasilAPI Itself an aggregator; fans out to several of the others, so it often wins the race
"opencep" OpenCEP Open, community-maintained database
"awesomeapi" AwesomeAPI Also returns lat/lng, DDD, and IBGE city code (cepx keeps the standard five address fields)
"local" Offline SQLite database (see above) Opt-in, not part of the default race; microsecond lookups with no network

Every provider except local is queried in the default race; pass a subset via providers=[...] to restrict the lookup to just those services.

import cepx

cepx.cep("05010000")
# Address(cep='05010000', ..., provider='brasilapi')

cepx.cep(5010000)                            # ints are left-padded
cepx.cep("05010000", providers=["viacep"])   # restrict providers
cepx.cep("05010000", timeout=5.0)            # per-provider timeout (s)
import asyncio
import cepx

asyncio.run(cepx.acep("05010000"))

Errors

cepx.CepxError is raised with a type of either "validation_error" (bad input, before any request) or "provider_error" (all providers failed). Its errors list holds the underlying cepx.ProviderError entries.

Development

make setup         # create the venv, install deps, install git hooks
make check         # unit tests + coverage + pre-commit (lint, format, types)
make bench-local   # benchmark the local provider against cepx-data

Run make with no target to see everything available.

Credits

cepx began as a Python port of cep-promise and keeps its first-successful-provider model for network lookups.

Metadata

Release files for cepx 0.1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cepx 0.1.5
File Size Uploaded
cepx-0.1.5.tar.gz 62.7 kB Details

Built distribution (wheel)

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

Total release size: 79.9 kB

Release files / cepx-0.1.5.tar.gz

Download URL cepx-0.1.5.tar.gz
Size 62.7 kB
Tags Source
SHA-256 checksum
How to use checksums
4d0209fcfd28d5257f9cd740965267c600fed6dd4fa00928d5d32af47b8e91a8
BLAKE2b-256 checksum
How to use checksums
f14725ead459f45b0798210ae1d9adb1f7a5b8b00c51c81222cc25189b13bb39
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / cepx-0.1.5-py3-none-any.whl

Download URL cepx-0.1.5-py3-none-any.whl
Size 17.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
939608a0c69e11f62c858a0d4b5accb17168e2131cdc7526b32b201df3a97d3b
BLAKE2b-256 checksum
How to use checksums
968c892eb4d1146c1b0773860f3cd88e78da9f8c460ea391a6932ee27e20c7f4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.1.5 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

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