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.

Download files

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

Source Distribution

cepx-0.1.4.tar.gz (62.6 kB view details)

Uploaded Source

Built Distribution

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

cepx-0.1.4-py3-none-any.whl (17.2 kB view details)

Uploaded Python 3

File details

Details for the file cepx-0.1.4.tar.gz.

File metadata

  • Download URL: cepx-0.1.4.tar.gz
  • Upload date:
  • Size: 62.6 kB
  • Tags: Source
  • Uploaded using 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}

File hashes

Hashes for cepx-0.1.4.tar.gz
Algorithm Hash digest
SHA256 33d955db70540c739ee038dda6745afe36f661b7a3e09e311f4153dd15de1b9f
MD5 323af54bbd430d345a4cf49134880593
BLAKE2b-256 58c5162414478b9f33aae775baae557eb173023067046070b478d1f16178bcf6

See more details on using hashes here.

File details

Details for the file cepx-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: cepx-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 17.2 kB
  • Tags: Python 3
  • Uploaded using 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}

File hashes

Hashes for cepx-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 439286a1784d15574bbcddd195aeb232e3c403cef1c29219c13b47bd5ff41f97
MD5 18801386d6caff4fbeed25c50875b290
BLAKE2b-256 ca3666c513ab56ccfdc3cc49eeed69ce71b9bdb59b5d4b37c0c940a03521a5d4

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.5

2 files

This release

0.1.4 This release

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

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