Como Construí um Pipeline de Dados que Roda Sozinho e Me Faz Parecer Genio

Como Construí um Pipeline de Dados que Roda Sozinho e Me Faz Parecer Genio

Todo desenvolvedor conhece aquele momento: você termina um projeto bacana, dokumenta direitinho, e então descobre que precisa fazer a mesma tarefa manual todos os dias. Eu estava nesse limbo. Toda manhã, eu abria meu laptop, acessava três painéis diferentes, copiáva números, passava pro Excel, e só depois podia começar a trabalhar de verdade.

Isso durou três semanas. Até que um dia, às 11 da noite (porque só nesse horário eu tenho paz mental), decidi que ia resolver isso de uma vez. O resultado? Um pipeline de dados que roda automaticamente e me faz parecer competente demais nas reuniões.

O problema real: Não era só “economizar tempo”. Era sobre transformar dados brutos em informação acionável antes de eu precisar dela. Eu queria chegar no trabalho já com o contexto pronto.

O Cenário Inicial

Eu trabalhava com dados de múltiplas fontes: CRM, banco de dados de vendas, planilha de marketing, e uma API externa de concorrentes. Cada fonte tinha seu próprio formato, sua própria frequência de atualização, e seus próprios probleminhas.

Para fazer qualquer análise, eu precisava:

  • Abrir o CRM (5 minutos)
  • Exportar relatório de vendas (3 minutos)
  • Importar no Google Sheets (2 minutos)
  • Rodar macros de formatação (outros 5 minutos)
  • Atualizar dashboards (8 minutos)

Total: 23 minutos por dia, cinco dias por semana. Em um ano, isso dá quase 100 horas desperdiçadas em tarefas que um script faria em segundos.

A Arquitetura do Pipeline

Decidi usar o que eu já tinha disponível: cron jobs, scripts Bash, e um VPS barato que eu usava só pra hospedar um blog WordPress que ninguém visitava. Nada de ferramentas enterprise, nada de custo adicional.

# Meu primeiro script de extração
#!/bin/bash
DATE=$(date +%Y-%m-%d)

# Exportar do CRM via API
curl -s -H "Authorization: Bearer $CRM_TOKEN"   "https://api.crm.com/v2/reports/daily"   -o /data/raw/crm_${DATE}.json

# Baixar dados de vendas
mysql -h $DB_HOST -u $DB_USER -p$DB_PASS   -e "SELECT * FROM sales WHERE date = CURDATE();"   > /data/raw/sales_${DATE}.csv

# Tudo isso roda as 6:00 todo dia via crontab
# 0 6 * * * /opt/pipeline/extract.sh >> /var/log/pipeline.log 2>&1

Por Que Cron e Não Scheduler Moderno?

Senhores, cron é velho, cron é boring, cron funciona. Eu poderia usar Apache Airflow, Prefect, ou qualquer tool moderna desse hype cycle todo. Mas pra algo pequeno o suficiente pra caber na minha cabeça, cron + scripts shell é mais rápido de debugar, não precisa de interface web pra descobrir por que falhou, e roda em qualquer server sem drama.

Transformação: Onde a Magia Acontece

Extração é só metade do trabalho. Dados brutos são como um quarto de IKEA sem instruções: você sabe que ali tem algo útil, mas precisa montar direito. Aqui entra o script de transformação.

#!/usr/bin/env python3
import json
import csv

def normalize_crm(data):
    normalized = {
        'date': data['report_date'],
        'leads': int(data['new_leads']),
        'conversion_rate': float(data['conversions']) / int(data['leads']),
        'revenue': float(data['total_value'])
    }
    return normalized

def merge_sources(crm_file, sales_file, output_file):
    with open(crm_file) as f:
        crm = json.load(f)
    
    sales = []
    with open(sales_file) as f:
        reader = csv.DictReader(f)
        for row in reader:
            sales.append(row)
    
    merged = []
    crm_normalized = [normalize_crm(c) for c in crm['reports']]
    
    for sale in sales:
        date = sale['date']
        crm_match = next((c for c in crm_normalized if c['date'] == date), None)
        if crm_match:
            merged.append({**sale, **crm_match})
    
    with open(output_file, 'w') as f:
        json.dump(merged, f, indent=2)
    
    return len(merged)

if __name__ == '__main__':
    import sys
    crm_f, sales_f, out_f = sys.argv[1], sys.argv[2], sys.argv[3]
    count = merge_sources(crm_f, sales_f, out_f)
    print(f"Processados {count} registros")

Esse script faz coisas importantes:

  • Normaliza formatos diferentes (CRM usa camelCase, banco usa snake_case)
  • Faz join dos dados via chave de data
  • Calcula métricas derivadas (taxa de conversão, ticket médio)
  • Exporta JSON clean pra quem quiser consumir

O Problema de Dados Falhos

Claro que nada funciona na primeira tentativa. Tive três problemas interessante que me ensinaram mais que qualquer tutorial:

1. Encoding Cretto

O CRM retornava dados com encoding ISO-8859-1 enquanto meu script esperava UTF-8. Resultado: todo mundo com nome não-ASCII virava null no meu JSON. A solução?

# No topo do script Python
import sys
sys.stdout.reconfigure(encoding='utf-8')

# Na hora de ler arquivos
with open(crm_file, encoding='utf-8-sig') as f:
    crm = json.load(f)

Lição: UTF-8-sig detecta BOM automaticamente. Praticamente todo sistema Windows coloca BOM em arquivos. Sempre trate isso.

2. Timestamps em Fusos Errados

Minha planilha de marketing usava horário de São Paulo, o banco usava UTC, e eu estava em Lisboa. Quando fiz o merge, vários registros pareciam duplicados porque o mesmo dado aparecia com 3 horas de diferença.

Resolvi normalizando tudo pra UTC no ponto de extração:

# No extract.sh
export TZ=UTC

3. API Rate Limiting

Descobri que a API do CRM tem limite de 100 requisições por minuto. Quando meu script tentou rodar mais de uma vez ao dia, começou a receber 429 (Too Many Requests).

retry_request() {
    local url=$1
    local max_attempts=5
    local attempt=1
    
    while [ $attempt -le $max_attempts ]; do
        response=$(curl -s -w "
%{http_code}" "$url")
        http_code=$(echo "$response" | tail -n1)
        
        if [ "$http_code" -eq 200 ]; then
            echo "$response" | head -n-1
            return 0
        elif [ "$http_code" -eq 429 ]; then
            sleep $((2 ** attempt))
            attempt=$((attempt + 1))
        else
            return 1
        fi
    done
    return 1
}

Notificações: Saber Quando Algo Quebra

Pipeline sem notificação é como direção sem retrovisor: você só descobre que problema quando já bateu. Eu configurei três níveis de alerta:

# No crontab
0 6 * * * /opt/pipeline/run.sh 2>&1 | tee /var/log/pipeline.log

# run.sh envia notificação em caso de erro
if [ $? -ne 0 ]; then
    curl -s -X POST "https://api.telegram.org/bot$BOT_TOKEN/sendMessage"       -d "chat_id=$CHAT_ID"       -d "text=⚠️ Pipeline falhou! Verificar /var/log/pipeline.log"
fi

Também uso um health check simples: se o arquivo de saída não foi gerado nas últimas 24 horas, recebo alerta.

Dashboard: Transformando Dados em Decisões

Com pipeline rodando, eu precisava visualizar os dados. Solução: Google Sheets + Data Studio (agora Looker Studio). Configurei uma conexão direta ao banco de dados MySQL, criei uma aba com os dados do pipeline, e em 2 horas tinha um dashboard que atualizava automaticamente.

Os KPIs que eu monitoro:

  • Novos leads por dia — early warning de mudanças no funil
  • Taxa de conversão por fonte — onde estou gastando bem meu dinheiro
  • Receita diária vs meta —一目瞭然 se estou no caminho
  • Tempo médio de resposta — indicador de operação, não só resultado

O Resultado Final

Depois de duas semanas de desenvolvimento (e uma de debugging de problemas bem bobos), o pipeline estava funcionando 100%. Os resultados práticos:

  • 23 minutos diários economizados (quase 100 horas por ano)
  • Decisões baseadas em dados atualizados vs planilha desatualizada de três dias
  • Feedback de mercado em tempo real — minha startup parece muito mais profissional do que realmente é

Mas o mais importante: eu não preciso mais pensar em processar dados. Ele simplesmente acontece. Eu chego no trabalho e a informação está lá, pronta pra eu usar.

🛠 O Box Perrengue: Semana passada, o banco de dados ficou down por 4 horas. O pipeline tentou rodar, falhou, e me mandou um alerta. Eu estava em reunião quando recebi. Em 30 segundos, eu sabia que meus dados estavam desatualizados, sem precisar verificar manualmente. Isso, por si só, já valeu cada hora que investi construindo o sistema.

Como Você Pode Começar

Não precisa começar com um pipeline complexo. Meu conselho prático:

  1. Identifique a tarefa manual que você faz todo dia — provavelmente envolve 3 ou mais sistemas diferentes
  2. Automatize o menor passo possível primeiro — extrair dados de uma fonte já ajuda muito
  3. Coloque um alerta simples — um email quando algo falha já muda sua vida
  4. Itere: a cada semana, adicione uma fonte ou transformação nova

O objetivo não é eliminar trabalho. É fazer o trabalho repetitivo sumir pra você poder focar no que realmente importa: resolver problemas interessantes e construir coisas novas.

Este post foi gerado automaticamente pelo sistema de publicação do AutoMente. Eu sou o Olivetto, editor-chefe, e escrevo sobre automação porque literalmente minha vida depende dela.

E você? Qual processo manual você faz todo dia que poderia ser automatizado? Me conta aqui nos comentários.

Posts Similares