Para integrar validação de CPF em um dashboard Streamlit, você precisa chamar a API da CPFHub.io com GET https://api.cpfhub.io/cpf/{CPF} usando o header x-api-key e exibir o retorno diretamente na interface. O Streamlit torna esse processo direto: com poucas linhas de código é possível construir um formulário interativo que consulta dados cadastrais em tempo real. Quando o dashboard envolve dados de pessoas físicas, a validação de CPF garante a qualidade dos dados desde a entrada.
1. Pré-requisitos
-
Python 3.9+ instalado.
-
Pacotes necessários:
pip install streamlit requests pandas. -
Uma conta gratuita na CPFHub.io
2. Configure a chave de API
Crie um arquivo .streamlit/secrets.toml na raiz do projeto para armazenar a chave de forma segura:
[cpfhub]
api_key = "SUA_CHAVE_DE_API"
base_url = "https://api.cpfhub.io"
timeout = 5
O Streamlit carrega automaticamente os secrets desse arquivo, acessíveis via st.secrets.
3. Crie o módulo de serviço
Crie o arquivo cpf_service.py para encapsular a comunicação com a API:
# cpf_service.py
import re
import requests
import streamlit as st
def consultar_cpf(cpf: str) -> dict:
"""
Consulta dados de um CPF na API da CPFHub.io.
Retorna dict com dados ou lança exceção.
"""
cpf_limpo = re.sub(r"\D", "", cpf)
if len(cpf_limpo) != 11:
raise ValueError("CPF deve conter exatamente 11 dígitos.")
url = f"{st.secrets.cpfhub.base_url}/cpf/{cpf_limpo}"
headers = {
"x-api-key": st.secrets.cpfhub.api_key,
"Accept": "application/json",
}
try:
response = requests.get(
url,
headers=headers,
timeout=st.secrets.cpfhub.timeout,
)
except requests.exceptions.Timeout:
raise ConnectionError("Timeout ao consultar a API. Tente novamente.")
except requests.exceptions.RequestException as e:
raise ConnectionError(f"Erro de conexão: {str(e)}")
if response.status_code == 200:
data = response.json()
if data.get("success"):
return data["data"]
raise ValueError("Resposta inesperada da API.")
elif response.status_code == 401:
raise PermissionError("Chave de API inválida.")
elif response.status_code == 404:
raise LookupError("CPF não encontrado na base de dados.")
else:
raise RuntimeError(f"Erro HTTP {response.status_code}")
4. Crie o dashboard principal
Crie o arquivo app.py com a interface do dashboard:
# app.py
import streamlit as st
import pandas as pd
from cpf_service import consultar_cpf
st.set_page_config(
page_title="Dashboard de Validação de CPF",
page_icon="",
layout="wide",
)
st.title("Dashboard de Validacao de CPF")
st.markdown("Consulta de dados cadastrais via API da **CPFHub.io**")
st.markdown("---")
# -- Seção 1: Consulta individual --
st.header("Consulta Individual")
col1, col2 = st.columns([1, 2])
with col1:
cpf_input = st.text_input(
"Digite o CPF",
placeholder="000.000.000-00",
max_chars=14,
)
consultar_btn = st.button("Consultar CPF", type="primary")
with col2:
if consultar_btn and cpf_input:
with st.spinner("Consultando API da CPFHub.io..."):
try:
dados = consultar_cpf(cpf_input)
st.success("CPF encontrado com sucesso!")
metric_col1, metric_col2, metric_col3 = st.columns(3)
metric_col1.metric("Nome", dados.get("name", "N/A"))
metric_col2.metric("Genero", dados.get("gender", "N/A"))
metric_col3.metric("Data de Nascimento", dados.get("birthDate", "N/A"))
with st.expander("Ver dados completos"):
st.json(dados)
except ValueError as e:
st.error(f"Erro de validacao: {str(e)}")
except LookupError as e:
st.warning(str(e))
except (ConnectionError, RuntimeError, PermissionError) as e:
st.error(str(e))
elif consultar_btn:
st.warning("Por favor, digite um CPF.")
5. Adicione consulta em lote
Expanda o dashboard para permitir consultas em lote a partir de um arquivo CSV:
# Continuação do app.py
st.markdown("---")
# -- Seção 2: Consulta em lote --
st.header("Consulta em Lote")
uploaded_file = st.file_uploader(
"Envie um CSV com coluna 'cpf'",
type=["csv"],
)
if uploaded_file is not None:
df = pd.read_csv(uploaded_file, dtype=str)
if "cpf" not in df.columns:
st.error("O arquivo CSV deve conter uma coluna chamada 'cpf'.")
else:
st.dataframe(df.head(), use_container_width=True)
total = len(df)
st.info(f"Total de CPFs no arquivo: {total}")
if st.button("Iniciar consulta em lote"):
resultados = []
progress_bar = st.progress(0)
status_text = st.empty()
for idx, row in df.iterrows():
cpf = str(row["cpf"])
status_text.text(f"Consultando {idx + 1}/{total}: {cpf}")
try:
dados = consultar_cpf(cpf)
resultados.append({
"cpf": cpf,
"nome": dados.get("name"),
"genero": dados.get("gender"),
"nascimento": dados.get("birthDate"),
"status": "Encontrado",
})
except Exception as e:
resultados.append({
"cpf": cpf,
"nome": None,
"genero": None,
"nascimento": None,
"status": str(e),
})
progress_bar.progress((idx + 1) / total)
status_text.text("Consulta finalizada!")
df_resultado = pd.DataFrame(resultados)
st.dataframe(df_resultado, use_container_width=True)
# Métricas de resumo
encontrados = len(df_resultado[df_resultado["status"] == "Encontrado"])
erros = total - encontrados
col_m1, col_m2, col_m3 = st.columns(3)
col_m1.metric("Total consultado", total)
col_m2.metric("Encontrados", encontrados)
col_m3.metric("Erros", erros)
# Download do resultado
csv_result = df_resultado.to_csv(index=False)
st.download_button(
"Baixar resultado (CSV)",
csv_result,
"resultado_cpf.csv",
"text/csv",
)
6. Adicione cache para evitar consultas duplicadas
Use o decorador @st.cache_data para armazenar resultados em cache:
# cpf_service.py (versão com cache)
import re
import requests
import streamlit as st
@st.cache_data(ttl=3600, show_spinner=False)
def consultar_cpf_cached(cpf: str) -> dict:
"""
Consulta CPF com cache de 1 hora para evitar chamadas duplicadas.
"""
cpf_limpo = re.sub(r"\D", "", cpf)
if len(cpf_limpo) != 11:
raise ValueError("CPF deve conter exatamente 11 dígitos.")
url = f"{st.secrets.cpfhub.base_url}/cpf/{cpf_limpo}"
headers = {
"x-api-key": st.secrets.cpfhub.api_key,
"Accept": "application/json",
}
response = requests.get(url, headers=headers, timeout=st.secrets.cpfhub.timeout)
if response.status_code == 200:
data = response.json()
if data.get("success"):
return data["data"]
raise RuntimeError(f"Erro: HTTP {response.status_code}")
7. Execute o dashboard
Inicie a aplicação com o comando:
streamlit run app.py --server.port 8501
Acesse http://localhost:8501 no navegador para interagir com o dashboard.
8. Boas práticas
-
Secrets -- Use
.streamlit/secrets.tomlpara desenvolvimento local e o gerenciador de secrets do Streamlit Cloud para deploy. -
Cache -- O
@st.cache_dataevita consultas duplicadas e economiza sua cota mensal de consultas. -
Feedback visual -- Use
st.spinner,st.progressest.statuspara informar o usuário sobre o andamento das consultas. -
Consultas em lote -- Para consultas em lote, considere adicionar um
time.sleep(0.5)entre requisições. O plano gratuito oferece 50 consultas/mês; consultas extras custam R$0,15 cada — a API não bloqueia, apenas cobra o excedente. -
Timeout -- O timeout de 5 segundos nas requisições evita que o dashboard trave aguardando respostas. A latência típica da API é de ~900ms.
-
LGPD -- A API da CPFHub.io opera em total conformidade com a LGPD. Ao exibir dados pessoais no dashboard, considere mascarar informações sensíveis e restringir o acesso.
Perguntas frequentes
Como a API CPFHub.io é autenticada em um dashboard Streamlit?
A autenticação é feita via header x-api-key em cada requisição GET para https://api.cpfhub.io/cpf/{CPF}. No Streamlit, a prática recomendada é armazenar a chave em .streamlit/secrets.toml e acessá-la via st.secrets, evitando expor credenciais no código-fonte ou em repositórios públicos.
A API CPFHub.io bloqueia requisições quando o limite do plano é atingido?
Não. Quando o limite de consultas do plano é atingido, a API não retorna erro nem bloqueia as requisições — ela simplesmente cobra R$0,15 por cada consulta adicional. O plano gratuito inclui 50 consultas/mês e o plano Pro inclui 1.000 consultas por R$149/mês.
Qual é a latência esperada ao consultar CPFs no Streamlit?
A API da CPFHub.io tem latência média de ~900ms por consulta. Para dashboards com consultas em lote, implemente @st.cache_data para evitar chamadas repetidas ao mesmo CPF e adicione time.sleep(0.5) entre requisições sequenciais para distribuir a carga de forma adequada.
Como garantir conformidade com a LGPD ao exibir dados de CPF em dashboards?
Use o CPF apenas para a finalidade declarada ao titular, armazene apenas o necessário e restrinja o acesso ao dashboard com autenticação. A ANPD orienta que dados de identificação devem ser tratados com o princípio da necessidade — considere mascarar campos sensíveis na visualização para usuários sem permissão de leitura completa.
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.



