O Flask combinado com o sistema de blueprints permite organizar a integração com a API de CPF da CPFHub.io de forma modular — um blueprint para as rotas, um módulo de serviço para a lógica HTTP e um factory pattern para inicializar a aplicação. A API autentica via header x-api-key, retorna dados do titular em ~900ms e cobra R$0,15 por consulta excedente ao plano sem bloquear requisições. A biblioteca requests trata timeout, erros de conexão e a deserialização do JSON em poucas linhas de código.
1. Pré-requisitos
-
Python 3.9+ instalado.
-
Pacotes
flaskerequests:pip install flask requests python-dotenv. -
Uma conta gratuita na CPFHub.io
2. Estrutura do projeto
Organize o projeto com blueprints para manter o código modular:
flask_cpf_app/
├── app/
│ ├── __init__.py
│ ├── config.py
│ ├── cpf/
│ │ ├── __init__.py
│ │ ├── routes.py
│ │ └── services.py
│ └── errors.py
├── .env
├── requirements.txt
└── run.py
3. Configure as variáveis de ambiente
Crie o arquivo .env na raiz do projeto:
FLASK_APP=run.py
FLASK_ENV=development
CPFHUB_API_KEY=SUA_CHAVE_DE_API
CPFHUB_BASE_URL=https://api.cpfhub.io
CPFHUB_TIMEOUT=5
E a classe de configuração em app/config.py:
# app/config.py
import os
from dotenv import load_dotenv
load_dotenv()
class Config:
CPFHUB_API_KEY = os.getenv("CPFHUB_API_KEY")
CPFHUB_BASE_URL = os.getenv("CPFHUB_BASE_URL", "https://api.cpfhub.io")
CPFHUB_TIMEOUT = int(os.getenv("CPFHUB_TIMEOUT", "5"))
4. Crie o serviço de consulta de CPF
O módulo de serviço encapsula toda a lógica de comunicação com a API:
# app/cpf/services.py
import re
import requests
from flask import current_app
class CpfHubError(Exception):
"""Exceção personalizada para erros da API CPFHub."""
def __init__(self, message: str, status_code: int = 500):
self.message = message
self.status_code = status_code
super().__init__(self.message)
def consultar_cpf(cpf: str) -> dict:
"""
Consulta dados de um CPF na API da CPFHub.io.
Retorna o dicionário com os dados do titular.
"""
cpf_limpo = re.sub(r"\D", "", cpf)
if len(cpf_limpo) != 11:
raise CpfHubError("CPF deve conter exatamente 11 dígitos", status_code=400)
config = current_app.config
url = f"{config['CPFHUB_BASE_URL']}/cpf/{cpf_limpo}"
headers = {
"x-api-key": config["CPFHUB_API_KEY"],
"Accept": "application/json",
}
try:
response = requests.get(
url,
headers=headers,
timeout=config["CPFHUB_TIMEOUT"],
)
except requests.exceptions.Timeout:
raise CpfHubError("Timeout ao consultar a API da CPFHub", status_code=504)
except requests.exceptions.ConnectionError:
raise CpfHubError("Erro de conexão com a API da CPFHub", status_code=502)
except requests.exceptions.RequestException as e:
raise CpfHubError(f"Erro na requisição: {str(e)}", status_code=502)
error_map = {
400: "CPF com formato inválido",
401: "Chave de API inválida ou ausente",
404: "CPF não encontrado na base de dados",
}
if response.status_code != 200:
message = error_map.get(
response.status_code,
f"Erro inesperado: HTTP {response.status_code}",
)
raise CpfHubError(message, status_code=response.status_code)
data = response.json()
if not data.get("success"):
raise CpfHubError("Resposta inesperada da API", status_code=500)
return data["data"]
5. Crie o blueprint de CPF
O blueprint organiza todas as rotas relacionadas à consulta de CPF:
# app/cpf/__init__.py
from flask import Blueprint
cpf_bp = Blueprint("cpf", __name__, url_prefix="/api/cpf")
from . import routes # noqa: E402, F401
# app/cpf/routes.py
from flask import jsonify
from . import cpf_bp
from .services import consultar_cpf, CpfHubError
@cpf_bp.route("/<string:cpf>", methods=["GET"])
def consulta_cpf(cpf: str):
"""
Endpoint para consulta de CPF.
GET /api/cpf/<cpf>
"""
try:
dados = consultar_cpf(cpf)
return jsonify({"success": True, "data": dados}), 200
except CpfHubError as e:
return jsonify({"success": False, "error": e.message}), e.status_code
except Exception:
return jsonify({"success": False, "error": "Erro interno do servidor"}), 500
6. Configure o error handler global
Crie handlers globais para erros comuns:
# app/errors.py
from flask import jsonify
def register_error_handlers(app):
@app.errorhandler(404)
def not_found(error):
return jsonify({"success": False, "error": "Recurso não encontrado"}), 404
@app.errorhandler(405)
def method_not_allowed(error):
return jsonify({"success": False, "error": "Método não permitido"}), 405
@app.errorhandler(500)
def internal_error(error):
return jsonify({"success": False, "error": "Erro interno do servidor"}), 500
7. Inicialize a aplicação
Configure o factory pattern para criar a aplicação Flask:
# app/__init__.py
from flask import Flask
from .config import Config
from .cpf import cpf_bp
from .errors import register_error_handlers
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
# Registrar blueprints
app.register_blueprint(cpf_bp)
# Registrar error handlers
register_error_handlers(app)
return app
# run.py
from app import create_app
app = create_app()
if __name__ == "__main__":
app.run(debug=True, port=5000)
8. Teste a integração
Inicie o servidor e faça uma requisição de teste:
python run.py
curl -X GET http://localhost:5000/api/cpf/12345678900
Resposta esperada:
{
"success": true,
"data": {
"cpf": "12345678900",
"name": "João da Silva",
"nameUpper": "JOÃO DA SILVA",
"gender": "M",
"birthDate": "15/06/1990",
"day": 15,
"month": 6,
"year": 1990
}
}
9. Use requests.Session para múltiplas consultas
Se a sua aplicação realiza várias consultas em sequência, use requests.Session para reutilizar conexões TCP:
# app/cpf/services.py (versão com Session)
import re
import requests
from flask import current_app
_session = None
def _get_session() -> requests.Session:
global _session
if _session is None:
_session = requests.Session()
_session.headers.update({
"x-api-key": current_app.config["CPFHUB_API_KEY"],
"Accept": "application/json",
})
return _session
def consultar_cpf_batch(cpfs: list[str]) -> list[dict]:
"""Consulta múltiplos CPFs reutilizando a mesma sessão HTTP."""
session = _get_session()
timeout = current_app.config["CPFHUB_TIMEOUT"]
base_url = current_app.config["CPFHUB_BASE_URL"]
resultados = []
for cpf in cpfs:
cpf_limpo = re.sub(r"\D", "", cpf)
url = f"{base_url}/cpf/{cpf_limpo}"
try:
resp = session.get(url, timeout=timeout)
if resp.status_code == 200:
data = resp.json()
resultados.append({"cpf": cpf_limpo, "data": data.get("data"), "error": None})
else:
resultados.append({"cpf": cpf_limpo, "data": None, "error": f"HTTP {resp.status_code}"})
except requests.exceptions.RequestException as e:
resultados.append({"cpf": cpf_limpo, "data": None, "error": str(e)})
return resultados
10. Boas práticas
-
Timeout — Sempre configure timeout nas requisições. O valor de 5 segundos é seguro considerando o tempo de resposta de ~900ms da API. A documentação da biblioteca requests recomenda sempre definir timeout explícito em chamadas de produção.
-
Blueprints — Use blueprints para separar funcionalidades. Isso facilita a manutenção e o teste isolado de cada módulo.
-
Factory pattern — O
create_app()permite criar múltiplas instâncias com configurações diferentes, ideal para testes. -
Variáveis de ambiente — Nunca hardcode a chave de API. Use
.envpara desenvolvimento e variáveis de ambiente do sistema para produção. -
Logging — Configure o logging do Flask para registrar erros de integração e facilitar o diagnóstico em produção.
-
LGPD — A API da CPFHub.io é compatível com a LGPD. Certifique-se de que sua aplicação também trata dados pessoais conforme a legislação.
Perguntas frequentes
Por que usar blueprints para organizar a integração com a API de CPF no Flask?
Blueprints isolam as rotas e a lógica de negócio de cada funcionalidade em módulos independentes. Quando a integração com CPF cresce — adicionando cache, autenticação ou endpoints de batch — você modifica apenas o blueprint cpf sem tocar no restante da aplicação. Isso facilita os testes unitários e a manutenção a longo prazo.
Como o requests.Session melhora a performance em consultas sequenciais de CPF?
O requests.Session reutiliza a conexão TCP subjacente entre chamadas ao mesmo host, eliminando o handshake TCP e TLS a cada requisição. Em lotes de CPFs, isso pode reduzir o tempo total de forma expressiva — especialmente quando a latência de rede é somada ao tempo de resposta da API (~900ms por consulta).
A API CPFHub.io bloqueia ou retorna erro quando o limite do plano é atingido?
Não. A API não bloqueia nem retorna erro ao atingir o limite mensal do plano. O comportamento é cobrar R$0,15 por consulta excedente automaticamente. O plano gratuito oferece 50 consultas/mês e o Pro inclui 1.000 consultas por R$149/mês. Monitorar o consumo pelo painel em app.cpfhub.io/settings/billing evita cobranças inesperadas.
Como testar o serviço de consulta de CPF sem consumir cota real?
Use o factory pattern create_app() com uma classe de configuração de teste que aponta para um mock local — por exemplo, responses ou httpretty para interceptar chamadas da biblioteca requests. Isso permite testar todos os cenários de erro (timeout, 401, 404) sem fazer nenhuma chamada real à API da CPFHub.io.
Conclusão
Consumir a API da CPFHub.io
Cadastre-se em cpfhub.io
CPFHub.io
Pronto para integrar a API?
50 consultas gratuitas para testar agora. Sem cartão de crédito. Acesso imediato à documentação.
Sobre a redação
Redação CPFHub.io
Time editorial especializado em APIs de CPF, identidade digital e compliance no mercado brasileiro. Produzimos guias técnicos, análises regulatórias e tutoriais sobre LGPD e KYC para desenvolvedores e líderes de produto.



