Como integrar validação de CPF em Streamlit para dashboards de dados

Aprenda a integrar validação de CPF em dashboards Streamlit usando a API da CPFHub.io com exemplos visuais e interativos.

Redação CPFHub.io
Redação CPFHub.io
··6 min de leitura
Como integrar validação de CPF em Streamlit para dashboards de dados

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.toml para desenvolvimento local e o gerenciador de secrets do Streamlit Cloud para deploy.

  • Cache -- O @st.cache_data evita consultas duplicadas e economiza sua cota mensal de consultas.

  • Feedback visual -- Use st.spinner, st.progress e st.status para 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.

Redação CPFHub.io

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.

WhatsAppFale conosco via WhatsApp