Pandas & NumPy Academy · Aula

Parametrizando pipelines com dicionários de configuração

Substitua caminhos de arquivos e nomes de colunas definidos diretamente no código por um dicionário de configuração passado em tempo de execução, tornando o pipeline reutilizável.

Aula 2 de 413 etapas

Parametrizando pipelines com dicionários de configuração é uma aula grátis de Pandas & NumPy Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Pandas & NumPy Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Pandas & NumPy Academy inclui 4 aulas no total.

O problema dos valores definidos diretamente no código

Um fluxo com caminhos de arquivos, nomes de colunas e valores-limite definidos diretamente no código deixa de funcionar sempre que o ambiente muda — por exemplo, com outro servidor, uma coluna renomeada ou uma regra de negócio alterada. Cada mudança exige editar o próprio código do fluxo, criando o risco de introduzir erros. A solução é externalizar todos os valores variáveis em um dicionário de configuração, carregado em tempo de execução e passado às funções do fluxo.

import pandas as pd

# BAD: hardcoded values scattered through code
df = pd.read_csv('/data/orders_2024.csv')
df = df.dropna(subset=['revenue', 'quantity'])
df = df[df['revenue'] < 5000]
df.to_parquet('/output/orders_clean.parquet')
print('Hardcoded paths and thresholds are fragile')

Definindo um dicionário de configuração

Substitua cada valor definido diretamente no código por uma entrada em um dicionário de configuração. Agrupe logicamente as configurações relacionadas: caminhos de entrada e saída juntos, limites de limpeza juntos e mapeamentos de nomes de colunas juntos. O dicionário de configuração se torna a única fonte de verdade para todos os parâmetros do fluxo. Alterar um valor na configuração atualiza todas as funções que o utilizam sem modificar o corpo das funções.

CONFIG = {
    'input_path': '/data/orders_2024.csv',
    'output_path': '/output/orders_clean.parquet',
    'required_cols': ['order_id', 'order_date', 'revenue', 'quantity'],
    'date_cols': ['order_date'],
    'revenue_cap': 5000,
    'min_quantity': 1,
    'categorical_cols': ['region', 'category']
}
print('Config loaded:', list(CONFIG.keys()))

Passando a configuração para funções de extração

A função de extração lê todos os seus parâmetros da configuração: o caminho de entrada, as colunas de data a serem interpretadas e quaisquer configurações de codificação ou delimitador. Isso significa que executar o mesmo fluxo com um conjunto de dados de teste ou com o arquivo de outro mês exige apenas uma alteração na configuração — nenhuma alteração no código. Pode manter configurações separadas para os ambientes de desenvolvimento, homologação e produção.

def extract(config):
    return pd.read_csv(
        config['input_path'],
        parse_dates=config.get('date_cols', [])
    )

df = extract(CONFIG)
print('Extracted:', df.shape)

Passando a configuração para funções de transformação

Cada função de transformação recebe a configuração completa e extrai os valores de que precisa. As funções devem usar config.get('key', default) com padrões sensatos para que o fluxo seja robusto mesmo com configurações incompletas. Uma função que exige, por padrão, um limite de 5000, mas pode ser substituída pela configuração, é segura e flexível.

def transform(df, config):
    required = config.get('required_cols', [])
    cap = config.get('revenue_cap', float('inf'))
    min_qty = config.get('min_quantity', 1)

    return (
        df
        .dropna(subset=required)
        .query(f'quantity >= {min_qty}')
        .assign(revenue=lambda d: d['quantity'] * d['unit_price'])
        .assign(revenue_capped=lambda d: d['revenue'].clip(upper=cap))
    )

df_clean = transform(df, CONFIG)
print(df_clean.shape)

Carregando a configuração de um arquivo JSON

Para fluxos de produção, armazene a configuração em um arquivo JSON em vez de usar um dicionário Python definido diretamente no script. Carregue-a com json.load() no início do fluxo. Isso permite que as equipes de operações alterem limites sem acesso ao código Python e possibilita o versionamento da configuração pelo Git — cada alteração na configuração é um commit rastreado, com uma descrição do motivo de negócio para a mudança.

import json

# config.json would contain the same keys as CONFIG above
# with open('config.json') as f:
#     config = json.load(f)

# Example: write and read back
with open('/tmp/pipeline_config.json', 'w') as f:
    json.dump(CONFIG, f, indent=2)

with open('/tmp/pipeline_config.json') as f:
    loaded_config = json.load(f)

print('Loaded config from JSON:', loaded_config['revenue_cap'])

Configurações específicas de cada ambiente

Mantenha arquivos de configuração separados para cada ambiente: config_dev.json, config_staging.json e config_prod.json. Determine qual deles deve ser carregado com base em uma variável de ambiente. Esse padrão evita o uso acidental de caminhos de arquivos de produção durante o desenvolvimento e mantém segredos específicos do ambiente (como credenciais de banco de dados) fora do repositório de código compartilhado.

import os

ENV = os.environ.get('PIPELINE_ENV', 'dev')
CONFIG_PATH = f'config_{ENV}.json'

# In practice:
# with open(CONFIG_PATH) as f:
#     config = json.load(f)

print(f'Using config for environment: {ENV}')
print(f'Config file: {CONFIG_PATH}')

Remapeando nomes de colunas pela configuração

Os dados de origem geralmente têm nomes de colunas diferentes da convenção de nomenclatura interna. Em vez de codificar df.rename(columns={'OrderDate': 'order_date', 'Qty': 'quantity'}) diretamente no corpo do fluxo de dados, armazene o mapeamento de renomeação na configuração. Isso torna o fluxo de dados independente dos nomes das colunas de origem e fácil de adaptar quando o provedor de dados upstream altera o formato da exportação.

CONFIG['column_rename'] = {
    'OrderDate': 'order_date',
    'Qty': 'quantity',
    'UnitPrice': 'unit_price',
    'OrderID': 'order_id'
}

def rename_columns(df, config):
    return df.rename(columns=config.get('column_rename', {}))

print('Column rename mapping stored in config.')

Configuração de agregação: chaves dinâmicas de groupby

A etapa de agregação geralmente agrupa por colunas diferentes conforme o caso de uso. Armazene as chaves de agrupamento e as especificações de agregação na configuração, em vez de codificá-las diretamente. Assim, os analistas podem produzir diferentes tabelas de resumo (por região, categoria ou mês) alterando a configuração, sem modificar a função de agregação. A função se torna um agregador de uso geral, totalmente orientado pela configuração.

CONFIG['agg_spec'] = {
    'group_by': ['region', 'category'],
    'agg_cols': {
        'revenue': ['sum', 'mean'],
        'quantity': ['sum', 'count']
    }
}

def aggregate(df, config):
    spec = config['agg_spec']
    return df.groupby(spec['group_by']).agg(spec['agg_cols'])

result = aggregate(df_clean, CONFIG)
print(result.head())

Validando a configuração na inicialização

Valide a configuração no início do fluxo de dados para identificar chaves ausentes ou inválidas antes que qualquer dado seja carregado. Um fluxo de dados que é executado por 10 minutos e depois falha porque revenue_cap era uma cadeia de caracteres em vez de um número de ponto flutuante desperdiça tempo. Verifique se todas as chaves obrigatórias existem, se os valores têm o tipo correto e se os caminhos estão acessíveis, usando uma função curta de verificação da configuração executada antes de qualquer operação de E/S dispendiosa.

def validate_config(config):
    required_keys = ['input_path', 'output_path', 'required_cols']
    for key in required_keys:
        assert key in config, f'Config missing key: {key}'
    assert isinstance(config['required_cols'], list), 'required_cols must be a list'
    assert isinstance(config.get('revenue_cap', 1), (int, float)), 'revenue_cap must be numeric'
    print('Config validation passed.')

validate_config(CONFIG)

Mesclando a configuração padrão com a configuração do usuário

Permita que os usuários forneçam uma configuração parcial que substitua apenas os valores de seu interesse. Mescle a configuração do usuário sobre uma configuração padrão usando {**defaults, **user_config}. Esse padrão fornece valores padrão sensatos e, ao mesmo tempo, mantém tudo totalmente configurável. É o mesmo padrão usado por bibliotecas populares do Python que aceitam configurações como um dicionário ou argumentos nomeados.

DEFAULT_CONFIG = {
    'revenue_cap': 10000,
    'min_quantity': 1,
    'date_cols': ['order_date'],
    'required_cols': ['order_id', 'revenue']
}

user_config = {'revenue_cap': 5000, 'input_path': '/data/q1.csv'}

final_config = {**DEFAULT_CONFIG, **user_config}
print('Final config revenue_cap:', final_config['revenue_cap'])  # 5000
print('Final config min_quantity:', final_config['min_quantity'])  # 1 (from default)

Armazenando a configuração com a saída

Salve a configuração junto ao arquivo de saída para que qualquer pessoa que o examine possa reproduzir imediatamente a execução do fluxo de dados que o criou. Armazene-a como um arquivo JSON auxiliar, com o mesmo nome da saída, mas com a extensão .config.json. Inclua o carimbo de data e hora da execução do fluxo de dados na configuração salva para garantir a rastreabilidade completa de cada arquivo de saída.

import json
from datetime import datetime

def save_with_config(df, config):
    output_path = config['output_path']
    config_path = output_path.replace('.parquet', '.config.json')

    run_metadata = {**config, 'run_at': datetime.now().isoformat()}
    with open(config_path, 'w') as f:
        json.dump(run_metadata, f, indent=2, default=str)

    df.to_parquet(output_path, index=False)
    print(f'Saved data to {output_path}')
    print(f'Saved config to {config_path}')

Verificação rápida

Teste sua compreensão dos conceitos de Análise de Dados desta lição.

Recapitulação da lição

Nesta lição, você aprendeu a: substituir valores codificados diretamente por um dicionário de configuração carregado de JSON, passar a configuração para as funções de extração, transformação e agregação para obter uma parametrização completa e validar as configurações na inicialização e salvá-las junto aos arquivos de saída para permitir a reprodução. A seguir, exploraremos como testar etapas do fluxo de dados com verificações da quantidade de linhas e proteções baseadas em asserções.

Grátis para começar

Aprenda Python com um tutor de IA — grátis

Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.

Cursos
30
Aulas
120

Perguntas Frequentes

A aula “Parametrizando pipelines com dicionários de configuração” é grátis?

Sim — o texto completo de “Parametrizando pipelines com dicionários de configuração” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Pandas & NumPy Academy, atualize para CoddyKit PRO. O curso de Pandas & NumPy Academy inclui 4 aulas no total.

O que vou aprender em “Parametrizando pipelines com dicionários de configuração”?

Substitua caminhos de arquivos e nomes de colunas definidos diretamente no código por um dicionário de configuração passado em tempo de execução, tornando o pipeline reutilizável. Você pratica Pandas & NumPy Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Pandas & NumPy Academy?

Nenhuma experiência prévia é necessária. Pandas & NumPy Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “Parametrizando pipelines com dicionários de configuração”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Pandas & NumPy Academy?

Sim. Cada aula de Pandas & NumPy Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Estruturando etapas de transformação como funções
  2. Parametrizando pipelines com dicionários de configuração
  3. Testando etapas do pipeline com asserções
  4. Agendando e registrando execuções do pipeline
← Voltar para Pandas & NumPy Academy