O Django 4.1+ introduziu suporte nativo a views assíncronas, permitindo que aplicações Python realizem chamadas a APIs externas sem bloquear o servidor. Para integrar a API de CPF da CPFHub.io, você define uma async def view que chama um serviço assíncrono com httpx.AsyncClient — o Django detecta automaticamente que se trata de uma view assíncrona e a executa no event loop. A API responde em ~900ms, autentica via header x-api-key e cobra R$0,15 por consulta excedente ao plano sem bloquear requisições.
1. Pré-requisitos
-
Python 3.10+ e Django 4.2+ instalados.
-
O pacote
httpxpara requisições HTTP assíncronas:pip install httpx. -
Um servidor ASGI como Uvicorn ou Daphne para rodar views assíncronas.
-
Uma conta gratuita na CPFHub.io
2. Configure as variáveis de ambiente
Nunca exponha sua chave de API diretamente no código. Use variáveis de ambiente ou um arquivo .env com o pacote python-decouple:
pip install python-decouple
Crie um arquivo .env na raiz do projeto:
CPFHUB_API_KEY=SUA_CHAVE_DE_API
CPFHUB_BASE_URL=https://api.cpfhub.io
CPFHUB_TIMEOUT=5
No settings.py, importe as configurações:
from decouple import config
CPFHUB_API_KEY = config("CPFHUB_API_KEY")
CPFHUB_BASE_URL = config("CPFHUB_BASE_URL", default="https://api.cpfhub.io")
CPFHUB_TIMEOUT = config("CPFHUB_TIMEOUT", default=5, cast=int)
3. Crie o serviço assíncrono de consulta
Crie um módulo services.py dentro do seu app Django para encapsular a lógica de comunicação com a API:
# myapp/services.py
import httpx
import re
from django.conf import settings
class CpfHubError(Exception):
"""Exceção personalizada para erros da API CPFHub."""
def __init__(self, message: str, status_code: int = None):
self.message = message
self.status_code = status_code
super().__init__(self.message)
async def consultar_cpf(cpf: str) -> dict:
"""
Consulta dados de um CPF na API da CPFHub.io de forma assíncrona.
"""
cpf_limpo = re.sub(r"\D", "", cpf)
if len(cpf_limpo) != 11:
raise CpfHubError("CPF deve conter exatamente 11 dígitos", status_code=400)
url = f"{settings.CPFHUB_BASE_URL}/cpf/{cpf_limpo}"
headers = {
"x-api-key": settings.CPFHUB_API_KEY,
"Accept": "application/json",
}
async with httpx.AsyncClient(timeout=settings.CPFHUB_TIMEOUT) as client:
try:
response = await client.get(url, headers=headers)
except httpx.TimeoutException:
raise CpfHubError("Timeout ao consultar a API da CPFHub", status_code=504)
except httpx.RequestError as e:
raise CpfHubError(f"Erro de conexão: {str(e)}", status_code=502)
if response.status_code == 200:
data = response.json()
if data.get("success"):
return data["data"]
raise CpfHubError("Resposta inesperada da API", status_code=500)
elif response.status_code == 400:
raise CpfHubError("CPF com formato inválido", status_code=400)
elif response.status_code == 401:
raise CpfHubError("Chave de API inválida ou ausente", status_code=401)
elif response.status_code == 404:
raise CpfHubError("CPF não encontrado na base de dados", status_code=404)
else:
raise CpfHubError(f"Erro inesperado: HTTP {response.status_code}", status_code=response.status_code)
4. Crie a view assíncrona
Com Django 4.1+, basta definir a view como uma função async def. O framework detecta automaticamente que se trata de uma view assíncrona:
# myapp/views.py
import json
from django.http import JsonResponse
from .services import consultar_cpf, CpfHubError
async def consulta_cpf_view(request, cpf: str):
"""
View assíncrona para consulta de CPF via API da CPFHub.io.
Método: GET /api/cpf/<cpf>/
"""
if request.method != "GET":
return JsonResponse(
{"error": "Método não permitido"},
status=405,
)
try:
dados = await consultar_cpf(cpf)
return JsonResponse({
"success": True,
"data": dados,
})
except CpfHubError as e:
return JsonResponse(
{"success": False, "error": e.message},
status=e.status_code or 500,
)
except Exception:
return JsonResponse(
{"success": False, "error": "Erro interno do servidor"},
status=500,
)
5. Configure as URLs
Adicione a rota no urls.py do app:
# myapp/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("api/cpf/<str:cpf>/", views.consulta_cpf_view, name="consulta_cpf"),
]
E inclua no urls.py principal do projeto:
# project/urls.py
from django.urls import path, include
urlpatterns = [
path("", include("myapp.urls")),
]
6. Configure o servidor ASGI
Views assíncronas no Django exigem um servidor ASGI. Configure o asgi.py do projeto:
# project/asgi.py
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
application = get_asgi_application()
Inicie o servidor com Uvicorn:
pip install uvicorn
uvicorn project.asgi:application --host 0.0.0.0 --port 8000 --workers 4
7. Teste a integração
Faça uma requisição de teste usando cURL:
curl -X GET http://localhost:8000/api/cpf/12345678900/
A 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
}
}
8. Integração com formulários Django
Se você deseja validar CPF em um formulário HTML, crie um formulário com validação assíncrona no frontend:
# myapp/forms.py
from django import forms
import re
class CpfForm(forms.Form):
cpf = forms.CharField(
max_length=14,
label="CPF",
widget=forms.TextInput(attrs={
"placeholder": "000.000.000-00",
"class": "form-control",
}),
)
def clean_cpf(self):
cpf = self.cleaned_data["cpf"]
cpf_limpo = re.sub(r"\D", "", cpf)
if len(cpf_limpo) != 11:
raise forms.ValidationError("CPF deve conter 11 dígitos.")
return cpf_limpo
# myapp/views.py (view adicional para formulário)
from django.shortcuts import render
from .forms import CpfForm
from .services import consultar_cpf, CpfHubError
async def formulario_cpf_view(request):
resultado = None
erro = None
if request.method == "POST":
form = CpfForm(request.POST)
if form.is_valid():
try:
resultado = await consultar_cpf(form.cleaned_data["cpf"])
except CpfHubError as e:
erro = e.message
else:
form = CpfForm()
return render(request, "myapp/consulta_cpf.html", {
"form": form,
"resultado": resultado,
"erro": erro,
})
9. Boas práticas
-
Timeout — Sempre configure timeout nas requisições HTTP. O valor padrão de 5 segundos é adequado, considerando que a API da CPFHub responde em ~900ms.
-
Servidor ASGI — Views assíncronas só trazem benefício real quando executadas em um servidor ASGI como Uvicorn ou Daphne. Com WSGI, o Django executa a view assíncrona em uma thread separada, anulando o ganho. A documentação oficial do Django detalha o comportamento em cada modo.
-
Reutilização de client — Para alto volume de requisições, considere criar um
httpx.AsyncClientcomo singleton em vez de instanciar um novo a cada chamada. -
Rate limiting local — Implemente um controle de taxa no seu lado para evitar consumir cota desnecessariamente, especialmente no plano gratuito com 50 consultas/mês.
-
Cache — Use o cache do Django para armazenar resultados de consultas recentes e evitar chamadas duplicadas.
-
Segurança — Nunca exponha a chave de API no frontend. Todas as chamadas à CPFHub devem ser feitas pelo backend.
-
LGPD — A API da CPFHub.io opera em conformidade com a LGPD. Garanta que sua aplicação também trate dados pessoais de acordo com a legislação vigente.
Perguntas frequentes
Por que usar views assíncronas no Django para consultar a API de CPF?
Views assíncronas permitem que o servidor Django atenda outras requisições enquanto aguarda a resposta da API externa — que leva ~900ms. Com um servidor ASGI como Uvicorn, isso se traduz em maior throughput sem aumentar o número de workers. Para endpoints de consulta de CPF, onde o gargalo é sempre o I/O de rede, a abordagem assíncrona reduz o tempo ocioso dos processos do servidor.
Qual a diferença entre rodar a view assíncrona com ASGI versus WSGI?
Com ASGI (Uvicorn, Daphne), a view executa no event loop e libera o worker durante a espera pela API — o comportamento esperado. Com WSGI (Gunicorn clássico), o Django detecta a corrotina e a executa em uma thread separada usando asyncio.run(), o que bloqueia o worker e anula o ganho de performance. Para aproveitar views assíncronas de verdade, ASGI não é opcional.
A API CPFHub.io bloqueia quando o limite do plano gratuito é atingido?
Não. Ao atingir as 50 consultas gratuitas do mês, a API continua respondendo normalmente e cobra R$0,15 por consulta excedente — sem retornar erro nem bloquear. Para evitar gastos inesperados, implemente cache no Django para reutilizar resultados recentes e monitore o consumo pelo painel em app.cpfhub.io/settings/billing.
Como garantir conformidade com a LGPD ao consultar CPF via Django?
Use o CPF apenas para a finalidade declarada ao titular, armazene apenas o necessário e implemente controle de acesso aos logs de consulta. A ANPD orienta que dados de identificação devem ser tratados com o princípio da necessidade. Documente a base legal para o tratamento e configure TTL curto no cache para não reter dados além do necessário.
Conclusão
Integrar 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.



