Estrutura de Notebooks
Versão: 1.1.0 | Data: 2026-08-26 | Domínio: code-quality | Autor: Pedro O. Silva
Formato de Arquivo
REGRA OBRIGATÓRIA: Notebooks devem ser SEMPRE criados no formato .py (Python Source / Databricks format), salvo solicitacao explicita do usuario por .ipynb ou formato Jupyter Notebook JSON.
Justificativa - Versionamento Git Limpo:
- Diff legível: Formato texto puro, linha por linha, ideal para code review em Pull Requests
- Sem noise de metadata:
.ipynb (JSON) reescreve execution_count e outputs a cada save, poluindo diffs mesmo sem mudança lógica
- Padrão de mercado: Times que usam Databricks Repos + CI/CD geralmente padronizam em
.py exatamente por isso
- Histórico git como narrativa: Para projetos de portfólio onde commits incrementais contam a história técnica,
.py trabalha a favor
- Menos conflitos de merge: Metadados JSON são fonte clássica de conflitos chatos em colaboração
Observação - Metadados do Workspace:
- Data de criação, histórico de execução, execution_count: metadados internos do Databricks Workspace
- Não aparecem no GitHub/portfólio - audiência externa só vê o código commitado
- Para portfólio técnico, o que importa é o histórico git (commits, PRs, evolução do código)
PROIBIDO: Criar notebooks em formato .ipynb (Jupyter Notebook), exceto quando houver solicitacao explicita para aquela tarefa.
Limitação Técnica Importante
CÉLULAS MARKDOWN NÃO TÊM CAMPO DE TÍTULO
- Apenas células de código (Python, SQL, Scala, R) possuem campo editável de título ao lado da numeração
- Células de Markdown não suportam títulos por limitação técnica da ferramenta Databricks
- Esta é uma característica da plataforma, não uma escolha de padrão
- Portanto: NUNCA cobrar ou esperar títulos em células markdown
Células Iniciais
Célula 1 - Documentação
- Tipo: Markdown
- Conteúdo: Explicação do objetivo, conteúdo e função do notebook
- Título: Não aplicável - células markdown não têm campo de título
Célula 2 - Carregar Configurações
- Tipo: Código (Python/Scala/R)
- Título: "Carregar configurações"
- Conteúdo: SOMENTE o
%run do módulo de configuração compartilhado — nada mais
- SEM linha de comentário explicativo: o
%run já é autoexplicativo, não repetir em comentário o que o título já diz
Carregamento de Módulos Compartilhados
- Padrão obrigatório:
%run ./nome_do_modulo (caminho relativo)
- PROIBIDO: Usar caminho absoluto (
/Workspace/Users/...) ou open() + exec()
- Motivo: Caminhos absolutos quebram portabilidade entre workspaces/contas e expõem e-mail/usuário no código
- Exemplos:
- Notebook em
01_bronze/ carregando 05_apoio/config_parametros.py: %run ../05_apoio/config_parametros
- Notebook em
05_apoio/ carregando módulo na mesma pasta: %run ./config_parametros
Célula 3 - Inicializar Anos a Processar
- Tipo: Código (Python/Scala/R)
- Título: "Inicializar Anos a Processar"
- Conteúdo: capturar
ANOS_PROCESSAR explicitamente do retorno de inicializar_anos_processar(), com guardrail (raise se vazio)
- Comentário permitido: aqui, diferente da Célula 2 e da Célula 4, uma linha de comentário explicando a captura explícita do retorno é esperada (não é autoexplicativo como um
%run ou um import)
Célula 4 - Imports
- Tipo: Código (Python/Scala/R)
- Título: "Imports"
- Regra: Todos os imports do notebook devem estar concentrados aqui
- NUNCA: Espalhar imports pelo notebook
- SEM linha de comentário explicativo: imports são autoexplicativos, não comentar o óbvio
Ordem obrigatória e fixa das células iniciais: Documentação → Carregar Configurações → Inicializar Anos a Processar → Imports, quando todas essas etapas forem aplicáveis. Não criar uma célula artificial para uma etapa que não exista no notebook.
Demais Células
Estrutura Padrão
Cada célula deve:
- Linha 1:
# df_[nome]: [descrição do que a célula faz]
- Linha 2:
# [explicação técnica/de negócio do motivo/abordagem]
- Ler de um ou mais dataframes/tabelas
- Aplicar transformação
- Gerar um novo dataframe de saída
- Nomenclatura de saída: CARREGUE a skill naming-conventions para regras de nomenclatura de DataFrames
Separação de Responsabilidades
CRÍTICO: Uma célula não deve fazer muitas coisas.
Separar transformações em células distintas:
- Células que leem dados (de tabelas ou outros dataframes)
- Células que transformam (filtros, limpezas, conversões)
- Células que consultam (queries analíticas)
- Células que fazem cálculos (métricas, KPIs)
- Células que agregam (GROUP BY, sumarizações)
- Células que gravam (geralmente as últimas) - salvam dataframes resultantes em tabelas
Resiliência e Estrutura de Células
IMPORTANTE: um try/except não pode atravessar células (cada célula é compilada isoladamente — um try: sem except na mesma célula é SyntaxError). Ao adicionar tratamento de erros/retry/logging a um pipeline:
Cada etapa (extração, transformação, gravação) continua sendo uma função, definida na sua própria célula
O loop com try/except que chama essas funções fica inteiro em uma única célula de orquestração — não se abre em uma célula e fecha em outra
Isso preserva a separação de responsabilidades por célula E mantém o código executável
Padrão completo e exemplo: CARREGUE a skill data-quality-guardrails, seção 3 (Resiliência Operacional).
Comentários e Documentação
- Orientação sobre comentários: CARREGUE a skill technical-writing para orientação sobre como escrever comentários de código (tom, estrutura, foco no porquê, exemplos)
Ao implementar mudanças, consulte docs-sync/SKILL.md para atualizar documentações afetadas.
1---2name: notebook-structure3description: Use ao criar, desenvolver, estruturar ou montar notebooks NOVOS do zero -- ordem fixa de celulas iniciais (DOCUMENTACAO, CARREGAR CONFIGURACOES, INICIALIZAR ANOS A PROCESSAR, IMPORTS), separacao de responsabilidades por celula, formato de arquivo (.py vs .ipynb). NAO use para documentar ou revisar o conteudo tecnico e a logica de notebooks existentes; para alteracao estrutural de notebook existente, use esta skill.4---56# Estrutura de Notebooks78**Versão:** 1.1.0 | **Data:** 2026-08-26 | **Domínio:** code-quality | **Autor:** Pedro O. Silva910## Formato de Arquivo1112**REGRA OBRIGATÓRIA**: Notebooks devem ser SEMPRE criados no formato `.py` (Python Source / Databricks format), salvo solicitacao explicita do usuario por `.ipynb` ou formato Jupyter Notebook JSON.1314**Justificativa - Versionamento Git Limpo**:15* **Diff legível**: Formato texto puro, linha por linha, ideal para code review em Pull Requests16* **Sem noise de metadata**: `.ipynb` (JSON) reescreve `execution_count` e outputs a cada save, poluindo diffs mesmo sem mudança lógica17* **Padrão de mercado**: Times que usam Databricks Repos + CI/CD geralmente padronizam em `.py` exatamente por isso18* **Histórico git como narrativa**: Para projetos de portfólio onde commits incrementais contam a história técnica, `.py` trabalha a favor19* **Menos conflitos de merge**: Metadados JSON são fonte clássica de conflitos chatos em colaboração2021**Observação - Metadados do Workspace**:22* Data de criação, histórico de execução, execution_count: metadados internos do Databricks Workspace23* **Não aparecem no GitHub/portfólio** - audiência externa só vê o código commitado24* Para portfólio técnico, o que importa é o histórico git (commits, PRs, evolução do código)2526**PROIBIDO**: Criar notebooks em formato `.ipynb` (Jupyter Notebook), exceto quando houver solicitacao explicita para aquela tarefa.2728---2930## Limitação Técnica Importante3132**CÉLULAS MARKDOWN NÃO TÊM CAMPO DE TÍTULO**3334* Apenas células de **código** (Python, SQL, Scala, R) possuem campo editável de título ao lado da numeração35* Células de **Markdown** não suportam títulos por limitação técnica da ferramenta Databricks36* Esta é uma característica da plataforma, não uma escolha de padrão37* Portanto: NUNCA cobrar ou esperar títulos em células markdown3839## Células Iniciais4041### Célula 1 - Documentação42* **Tipo**: Markdown43* **Conteúdo**: Explicação do objetivo, conteúdo e função do notebook44* **Título**: Não aplicável - células markdown não têm campo de título4546### Célula 2 - Carregar Configurações47* **Tipo**: Código (Python/Scala/R)48* **Título**: "Carregar configurações"49* **Conteúdo**: SOMENTE o `%run` do módulo de configuração compartilhado — nada mais50* **SEM linha de comentário explicativo**: o `%run` já é autoexplicativo, não repetir em comentário o que o título já diz5152#### Carregamento de Módulos Compartilhados53* **Padrão obrigatório**: `%run ./nome_do_modulo` (caminho relativo)54* **PROIBIDO**: Usar caminho absoluto (`/Workspace/Users/...`) ou `open()` + `exec()`55* **Motivo**: Caminhos absolutos quebram portabilidade entre workspaces/contas e expõem e-mail/usuário no código56* **Exemplos**:57 - Notebook em `01_bronze/` carregando `05_apoio/config_parametros.py`: `%run ../05_apoio/config_parametros`58 - Notebook em `05_apoio/` carregando módulo na mesma pasta: `%run ./config_parametros`5960### Célula 3 - Inicializar Anos a Processar61* **Tipo**: Código (Python/Scala/R)62* **Título**: "Inicializar Anos a Processar"63* **Conteúdo**: capturar `ANOS_PROCESSAR` explicitamente do retorno de `inicializar_anos_processar()`, com guardrail (`raise` se vazio)64* **Comentário permitido**: aqui, diferente da Célula 2 e da Célula 4, uma linha de comentário explicando a captura explícita do retorno é esperada (não é autoexplicativo como um `%run` ou um `import`)6566### Célula 4 - Imports67* **Tipo**: Código (Python/Scala/R)68* **Título**: "Imports"69* **Regra**: Todos os imports do notebook devem estar concentrados aqui70* **NUNCA**: Espalhar imports pelo notebook71* **SEM linha de comentário explicativo**: imports são autoexplicativos, não comentar o óbvio7273**Ordem obrigatória e fixa das células iniciais**: Documentação → Carregar Configurações → Inicializar Anos a Processar → Imports, quando todas essas etapas forem aplicáveis. Não criar uma célula artificial para uma etapa que não exista no notebook.7475## Demais Células7677### Estrutura Padrão7879Cada célula deve:8081* **Ter título em MAIÚSCULO**8283* **Seguir padrão de 2 linhas de cabeçalho**:84 - Linha 1: `# df_[nome]: [descrição do que a célula faz]`85 - Linha 2: `# [explicação técnica/de negócio do motivo/abordagem]`8687* **Fluxo de dados**:88 - Ler de um ou mais dataframes/tabelas89 - Aplicar transformação90 - Gerar um novo dataframe de saída9192* **Nomenclatura de saída**: CARREGUE a skill naming-conventions para regras de nomenclatura de DataFrames9394## Separação de Responsabilidades9596**CRÍTICO**: Uma célula não deve fazer muitas coisas.9798### Separar transformações em células distintas:99100* **Células que leem dados** (de tabelas ou outros dataframes)101* **Células que transformam** (filtros, limpezas, conversões)102* **Células que consultam** (queries analíticas)103* **Células que fazem cálculos** (métricas, KPIs)104* **Células que agregam** (GROUP BY, sumarizações)105* **Células que gravam** (geralmente as últimas) - salvam dataframes resultantes em tabelas106107### Resiliência e Estrutura de Células108109**IMPORTANTE**: um `try/except` não pode atravessar células (cada célula é compilada isoladamente — um `try:` sem `except` na mesma célula é `SyntaxError`). Ao adicionar tratamento de erros/retry/logging a um pipeline:110* Cada etapa (extração, transformação, gravação) continua sendo uma **função**, definida na sua própria célula111* O loop com `try/except` que chama essas funções fica **inteiro em uma única célula de orquestração** — não se abre em uma célula e fecha em outra112* Isso preserva a separação de responsabilidades por célula E mantém o código executável113114* Padrão completo e exemplo: CARREGUE a skill data-quality-guardrails, seção 3 (Resiliência Operacional).115116## Comentários e Documentação117118* **Orientação sobre comentários**: CARREGUE a skill technical-writing para orientação sobre como escrever comentários de código (tom, estrutura, foco no porquê, exemplos)119120---121122**Ao implementar mudanças, consulte `docs-sync/SKILL.md` para atualizar documentações afetadas.**