#!/usr/bin/env python3 """Local stand-in for the cep.is API, used by the test driver. Behaviour is selected by the first path segment, so a test points the client at a different ``base_url`` to get a different server: ``/fail2`` fails twice then answers, ``/always503`` never answers, and so on. Every prefix counts the requests it saw; ``/_stats//health`` reports that count in the ``ceps`` field so the C driver can assert on it without speaking HTTP itself. """ import json import sys import threading from datetime import datetime, timedelta, timezone from email.utils import format_datetime from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer from urllib.parse import parse_qs, urlparse COLUMNS = [ "cep", "logradouro", "complemento", "unidade", "bairro", "localidade", "uf", "estado", "regiao", "ibge", "gia", "ddd", "siafi", ] DB = { "01001000": { "cep": "01001000", "logradouro": "Praça da Sé", "complemento": "lado ímpar", "unidade": "", "bairro": "Sé", "localidade": "São Paulo", "uf": "SP", "estado": "São Paulo", "regiao": "Sudeste", "ibge": "3550308", "gia": "1004", "ddd": "11", "siafi": "7107", "geo": {"lat": -23.567202, "lon": -46.649659, "raio_m": 1084, "precisao": "logradouro"}, }, "20040020": { "cep": "20040020", "logradouro": "Avenida Rio Branco", "complemento": "", "unidade": "", "bairro": "Centro", "localidade": "Rio de Janeiro", "uf": "RJ", "estado": "Rio de Janeiro", "regiao": "Sudeste", "ibge": "3304557", "gia": "", "ddd": "21", "siafi": "6001", }, "69900000": { "cep": "69900000", "logradouro": "", "complemento": "", "unidade": "", "bairro": "", "localidade": "Rio Branco", "uf": "AC", "estado": "Acre", "regiao": "Norte", "ibge": "1200401", "gia": "", "ddd": "68", "siafi": "0605", "geo": {"lat": -9.97499, "lon": -67.8243, "raio_m": 18420, "precisao": "localidade"}, }, "12345678": { "cep": "12345678", "logradouro": 'Rua A, B "quoted"', "complemento": "até 100", "unidade": "", "bairro": "Vila, Nova", "localidade": "Campinas", "uf": "SP", "estado": "São Paulo", "regiao": "Sudeste", "ibge": "3509502", "gia": "2446", "ddd": "19", "siafi": "6291", }, } for _n in range(600): _c = "%08d" % (70000000 + _n) DB[_c] = { "cep": _c, "logradouro": "Rua %d" % _n, "complemento": "", "unidade": "", "bairro": "Centro", "localidade": "Cidade %d" % _n, "uf": "SP", "estado": "São Paulo", "regiao": "Sudeste", "ibge": "3550308", "gia": "", "ddd": "11", "siafi": "7107", } # Bands the API knows about. A 404 for a CEP inside one carries the owning # municipality in "faixa"; a 404 outside every band omits the key entirely. # cep_ini/cep_fim inside the object are the extreme CEPs that exist, which is # why they differ from the band bounds: 25845000 is in the band, is the DNE's # own start for Areal, and does not exist. FAIXAS = [ ("25845000", "25849999", { "localidade": "Areal", "uf": "RJ", "estado": "Rio de Janeiro", "regiao": "Sudeste", "ibge": "3300225", "cep_ini": "25845001", "cep_fim": "25849899", "ceps": 118, }), ] HITS = {} LOCK = threading.Lock() def not_found(cep=None): body = {"erro": "cep_nao_encontrado", "mensagem": "CEP não existe na base do DNE"} for low, high, faixa in FAIXAS: if cep is not None and low <= cep <= high: body["faixa"] = faixa break return json.dumps(body, ensure_ascii=False) def bump(prefix): with LOCK: HITS[prefix] = HITS.get(prefix, 0) + 1 return HITS[prefix] def csv_escape(value): if any(c in value for c in ',"\r\n'): return '"' + value.replace('"', '""') + '"' return value def csv_row(cep): entry = DB.get(cep) if entry is None: return ",".join([cep] + [""] * (len(COLUMNS) - 1)) return ",".join(csv_escape(entry.get(c, "")) for c in COLUMNS) class Handler(BaseHTTPRequestHandler): protocol_version = "HTTP/1.1" def log_message(self, fmt, *args): pass def send(self, code, body, ctype="application/json; charset=utf-8", headers=None): raw = body.encode("utf-8") if isinstance(body, str) else body self.send_response(code) self.send_header("Content-Type", ctype) self.send_header("Content-Length", str(len(raw))) for key, value in (headers or {}).items(): self.send_header(key, value) self.end_headers() self.wfile.write(raw) def do_GET(self): parsed = urlparse(self.path) parts = [p for p in parsed.path.split("/") if p] if parts and parts[0] == "_stats": name = parts[1] if len(parts) > 1 else "" with LOCK: count = HITS.get(name, 0) self.send(200, json.dumps({ "status": "ok", "dne": "test", "ceps": count, "geo": 0, "base_gerada_em": "2026-07-24T03:48:28Z", })) return prefix = "" if parts and not parts[0].isdigit() and parts[0] not in ("csv", "health"): prefix = parts.pop(0) count = bump(prefix) if prefix == "always503": self.send(503, '{"erro":"interno","mensagem":"falha interna"}') return if prefix == "always429": self.send(429, '{"erro":"limite","mensagem":"devagar"}', headers={"Retry-After": "1"}) return if prefix == "date429": when = datetime.now(timezone.utc) + timedelta(seconds=2) self.send(429, '{"erro":"limite","mensagem":"devagar"}', headers={"Retry-After": format_datetime(when, usegmt=True)}) return if prefix == "hugeretry": self.send(429, '{"erro":"limite","mensagem":"devagar"}', headers={"Retry-After": "3600"}) return if prefix == "fail2" and count <= 2: self.send(503, '{"erro":"interno","mensagem":"falha interna"}') return if prefix == "flaky" and count == 1: self.send(500, '{"erro":"interno","mensagem":"falha interna"}') return if prefix == "always400": self.send(400, '{"erro":"cep_invalido",' '"mensagem":"CEP deve ter 8 dígitos"}') return if prefix == "badjson": self.send(200, "captive portal", ctype="text/html") return if prefix == "badgeo": entry = dict(DB["01001000"]) entry["geo"] = {"lat": "nao-e-numero", "precisao": "logradouro"} entry["campo_novo"] = {"nested": [1, 2, 3]} self.send(200, json.dumps(entry, ensure_ascii=False)) return if prefix == "surrogate": entry = dict(DB["01001000"]) entry["logradouro"] = "Rua \U0001F600 Feliz" self.send(200, json.dumps(entry, ensure_ascii=True)) return if prefix == "escaped": self.send(200, json.dumps(DB["01001000"], ensure_ascii=True)) return if prefix == "faixavazia": self.send(404, json.dumps({ "erro": "cep_nao_encontrado", "mensagem": "CEP não existe na base do DNE", "faixa": {}, }, ensure_ascii=False)) return if prefix == "faixatexto": self.send(404, json.dumps({ "erro": "cep_nao_encontrado", "mensagem": "CEP não existe na base do DNE", "faixa": "Areal", }, ensure_ascii=False)) return if parts and parts[0] == "health": body = {"status": "ok", "dne": "26071", "ceps": 1596168, "geo": 894489, "base_gerada_em": "2026-07-24T03:48:28Z"} if prefix == "degraded": body["status"] = "degraded" self.send(503, json.dumps(body)) return self.send(200, json.dumps(body)) return if parts and parts[0] == "csv": query = parse_qs(parsed.query) ceps = [c for c in query.get("ceps", [""])[0].split(",") if c] if len(ceps) > 500: self.send(400, '{"erro":"limite","mensagem":"máximo 500"}') return if prefix == "short": ceps = ceps[:1] rows = [",".join(COLUMNS)] + [csv_row(c) for c in ceps] body = "\r\n".join(rows) + "\r\n" if prefix == "bom": body = "\ufeff" + body self.send(200, body, ctype="text/csv; charset=utf-8") return if not parts: self.send(404, not_found()) return cep = parts[0] if not (len(cep) == 8 and cep.isdigit()): self.send(400, '{"erro":"cep_invalido",' '"mensagem":"CEP deve ter 8 dígitos"}') return entry = DB.get(cep) if entry is None: self.send(404, not_found(cep)) return self.send(200, json.dumps(entry, ensure_ascii=False)) def main(): port = int(sys.argv[1]) if len(sys.argv) > 1 else 0 server = ThreadingHTTPServer(("127.0.0.1", port), Handler) print(server.server_address[1], flush=True) server.serve_forever() if __name__ == "__main__": main()