1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
"""Python client for the public CEP API at `cep.is <https://cep.is>`_.
Quick use — for a script, the module-level functions are enough::
import cepis
address = cepis.lookup("01001-000")
print(address.localidade, address.uf) # São Paulo SP
In an application — build a :class:`Client` once and reuse it::
from cepis import Client
client = Client(timeout=5.0, total_timeout=15.0)
address = client.lookup("01001000")
Pointing at a local instance (the API repo brings one up with ``just up``)::
client = Client(base_url="http://localhost:8080")
Errors are explicit and split by decision — whether retrying helps or not::
from cepis import CEPNotFound, CepisError
try:
address = cepis.lookup(cep_from_form)
except CEPNotFound:
... # the CEP does not exist: ask the user for another
except CepisError:
... # network, server, rate limit: retry later
Note on field names: the API surface is English, but the **data fields keep
the API's own Portuguese names** (``logradouro``, ``bairro``, ``localidade``).
What you read in the JSON is what you access on the object.
The module-level functions share one default client. It is built once because
:class:`Client` keeps no state between calls and is thread-safe. Do not mutate
it: it applies process-wide, including to third-party libraries that also use
this module. Anyone needing different settings should build their own.
"""
from __future__ import annotations
__version__ = "0.1.0"
from .client import DEFAULT_URL, MAX_BATCH, Client, normalize_cep
from .errors import (
CepisError,
CEPNotFound,
InvalidCEP,
InvalidResponse,
NetworkError,
RateLimited,
ServerError,
)
from .models import Address, Geo, Health
__all__ = [
"DEFAULT_URL",
"MAX_BATCH",
"Address",
"CEPNotFound",
"CepisError",
"Client",
"Geo",
"Health",
"InvalidCEP",
"InvalidResponse",
"NetworkError",
"RateLimited",
"ServerError",
"__version__",
"health",
"lookup",
"lookup_many",
"normalize_cep",
]
_default = Client()
def lookup(cep: str) -> Address:
"""Look up a CEP using the default configuration.
Shorthand for ``Client().lookup(cep)``. See :meth:`Client.lookup`.
"""
return _default.lookup(cep)
def lookup_many(ceps: list[str]) -> list[Address | None]:
"""Look up many CEPs in one batch, using the default configuration.
Shorthand for :meth:`Client.lookup_many` — read that one, especially the
warning that batches carry no coordinate.
"""
return _default.lookup_many(ceps)
def health() -> Health:
"""Query the API's health using the default configuration.
Shorthand for :meth:`Client.health`.
"""
return _default.health()
|