🧱 notion-starter
Biblioteca Python resiliente para operar a API oficial do Notion e compartilhar regras de negócio entre interfaces.
📋 Índice
- 📖 Sobre o Projeto
- 📁 Estrutura do Projeto
- 🚀 Funcionalidades
- 🎯 Como Usar
- ⚙️ Configuração
- ✅ Qualidade
- 📄 Licença
- 👤 Autor
- 🤝 Contribuições
📖 Sobre o Projeto
O notion-starter é o núcleo do ecossistema
Automações do Notion.
Ele oferece uma API Python tipada para trabalhar com páginas, databases, tarefas e
conteúdo do Notion com retries, rate limit e erros previsíveis.
Além do cliente base, este repositório concentra a camada compartilhada entre o
notion-tasks-cli e o
notion-workspace-app:
adaptadores GitHub/OpenRouter e notion_starter.services para tarefas, conteúdo,
clonagem, ingestão, inventário GitHub, exportação DOCX e IA. As bordas e a
configuração de ambiente permanecem nos consumidores.
📁 Estrutura do Projeto
notion-starter/
│
├── 📁 src/notion_starter/ # Biblioteca pública e módulos de domínio
│ ├── 📁 services/ # Casos de uso compartilhados
│ ├── client.py # Cliente HTTP resiliente do Notion
│ ├── content.py # Conversão Markdown ↔ blocos
│ ├── properties.py # Builders de propriedades e schemas
│ └── tasks.py # Tarefa e TaskList
│
├── 📁 examples/ # Scripts de uso da biblioteca
├── 📁 tests/ # Suíte automatizada sem rede
├── .github/workflows/ci.yml # Gate em Python 3.10–3.13
├── pyproject.toml # Pacote, dependências e ferramentas
├── QUALIDADE.md # Contrato de qualidade do módulo
├── README.md # Este arquivo
└── LICENSE # Licença MIT
🚀 Funcionalidades
NotionClient— cliente HTTP resiliente com retries, rate limit e erros tipados; incluiobter_paginaeatualizar_paginapara propriedades,obter_bloco/restaurar_blocopara um bloco eler_itens_de_propriedadepara relações com mais de 25 páginas. A regra de retry (deve_retentar) segue a documentação: 429 bloqueado e 503 de escrita não se repetem, e uma escrita que o Notion salvou apesar do 503 viraNotionEscritaSalvaErrorcom os IDs criados.anexar_blocosaceitaapos_bloco_idouno_inicio.- Schema — leitura e comparação de schemas de databases com
comparar_schema. - Tarefas — modelos
TarefaeTaskListpara criar, editar, mover e concluir tarefas; na criação, a coluna de título é descoberta pelo schema para também aceitar databases genéricos. - Conteúdo — leitura e escrita de blocos, incluindo conversão Markdown ↔ blocos
(listas recuadas viram
childrene voltam recuadas na leitura; o código de um blococodevolta com o recuo da primeira linha, como foi gravado). Escritas destrutivas nunca apagam antes de o conteúdo novo estar gravado:escrever_conteudovalida os limites da API antes de tocar na página, anexa em lotes (100 blocos, 1000 elementos, 500 KB) e só então apaga o corpo antigo; aceitaapos_bloco_id/inicioe devolve os IDs criados;limpar_conteudosó apaga o que o Markdown recria (TIPOS_RECRIAVEIS) e preserva, com o motivo, o resto — inclusive blocos que contêm algo não recriável;restaurar_blocosdesfaz pelos IDs;reordenacao.reordenar_blococria a cópia antes de apagar o original, recusa tipos fora da lista branca, blocos com filhos e subpáginas;editar_blocorecusa Markdown de vários blocos e, comconferir_atual, mantém o tipo e recusa perder menção/cor/sublinhado;trocar_trechotroca só um trecho preservando a formatação;ler_bloco,listar_blocos(metadados=True, recursivo=True, contendo=...)eapagar_bloco_verificado(que recusa subpágina/database sem pedido explícito).
- IDs —
utils.normalizar_idaceita UUID com ou sem hífens e links do Notion (ignora?v=, usa?p=e, quando pedido, a âncora#bloco). - Relações —
services.relacoes.relacionarliga os dois sentidos conferindo a outra ponta, lê a lista inteira acima de 25 páginas e recusa passar de 100. - Ingestão de planilhas —
FontePlanilha(chave="Coluna")casa cada linha pelo registro, não pela posição; sem chave, o título é conferido antes de atualizar e divergências vão paraconflitos.ingerir(simular=True)não grava. - Propriedades — builders
properties.*paratitle,rich_text,select,status,number,date,relatione outros tipos; textos acima de 2.000 unidades UTF-16 são fatiados automaticamente. - Inventário — varredura de páginas, databases e árvore do workspace.
- Classificação em lote —
notion_starter.services.classificacaocalcula a distribuição de uma regra sobre linhas já buscadas, lista as linhas sem classificação e só escreve quando o chamador pede explicitamente. - Relatórios DOCX —
notion_starter.services.relatorios_docxexporta um arquivo por data, combinando propriedades e corpo sem arquivos intermediários. - Utilidades — saneamento de texto/JSON,
fatiar_utf16, logging e readers.
Exemplo de fluxo: Markdown → blocos tipados da API do Notion → página atualizada.
🎯 Como Usar
Classificação em lote com dry-run
As linhas são buscadas pelo chamador para que o relatório possa ser conferido
antes da escrita. O padrão é um dry-run; a aplicação pode ocorrer depois, e o
valor é tratado como select por padrão:
from notion_starter.services.classificacao import (
aplicar_classificacoes,
classificar_em_lote,
)
relatorio = classificar_em_lote(linhas, regra_de_classificacao)
print(relatorio.distribuicao)
print(relatorio.ids_sem_classificacao)
aplicar_classificacoes(relatorio, cliente=cliente, coluna="Tipo")
Para outro tipo de coluna, passe um montar_propriedade, como
properties.status. Linhas sem classificação nunca são alteradas.
Instalação
# Instalação pública da biblioteca
python -m pip install "notion-starter>=0.4.0,<0.5.0"
O release 0.4.0 será publicado no PyPI
como wheel e sdist; até lá, o PyPI serve 0.3.1, que ainda não tem as APIs de
escrita segura, IDs e exceções da auditoria de 2026-09-25. Ele não depende de checkout Git e não instala Django, React
ou a CLI. Para operar o produto completo, use
notion-automacoes[app].
Para desenvolvimento, clone o repositório e use python -m pip install -e ".[dev]".
Para desenvolvimento:
# Clone e instale com as dependências de desenvolvimento
git clone https://github.com/Felipe-Alcantara/notion-starter.git
cd notion-starter
python -m pip install -e ".[dev]"
Uso rápido
from notion_starter import NotionClient
client = NotionClient() # lê NOTION_TOKEN do ambiente
Escrever e editar conteúdo sem perder o que já existe
from notion_starter.services import conteudo
# Substitui o corpo recriável: valida, escreve o novo e só então apaga o antigo.
resultado = conteudo.escrever_conteudo(page_id, "# Título\n\n- item", substituir=True,
cliente=client)
print(resultado.criados, resultado.limpeza.apagados_ids, resultado.limpeza.motivos)
# Troca só um trecho, preservando menções, cor e sublinhado do bloco.
conteudo.trocar_trecho(bloco_id, "[20:12]", "[21:40]", cliente=client)
# Desfaz uma limpeza pelos IDs (os blocos voltam no fim da página).
conteudo.restaurar_blocos([bid for bid, _ in resultado.limpeza.apagados_ids], cliente=client)
Todas as recusas desses fluxos acontecem antes de qualquer escrita e
derivam de NotionSyncError (as de entrada inválida também de ValueError).
A pasta examples/ contém scripts completos para listar páginas,
exportar linhas, sincronizar CSV, gerar a árvore HTML do workspace, gerenciar
tarefas e publicar relatórios diários a partir do histórico de um repositório
git (relatorios_do_git.py, com --simular
para conferir antes de escrever).
⚙️ Configuração
| Variável | Descrição |
|---|---|
NOTION_TOKEN |
Token de integração interna do Notion (obrigatório) |
NOTION_DATABASE_ID |
Database padrão de tarefas (opcional) |
NOTION_AUTOMACOES_BACKUP_DIR |
Pasta dos backups em JSON do reordenar_bloco (opcional). Sem ela: ${XDG_STATE_HOME:-~/.local/state}/notion-automacoes/backups ou %LOCALAPPDATA%\notion-automacoes\backups — nunca o diretório corrente |
Use variáveis de ambiente ou um arquivo .env local baseado em .env.example.
Nunca versione tokens ou IDs reais.
✅ Qualidade
O gate local combina lint e testes:
python -m ruff check .
python -m pytest
A CI repete o gate em Python 3.10, 3.11, 3.12 e 3.13. Consulte
QUALIDADE.md para o critério de pronto e a política de
dependências deste pacote.
📄 Licença
Este projeto está sob a licença MIT — veja LICENSE.
👤 Autor
Felipe Alcantara
- GitHub: @Felipe-Alcantara
- Repositório: notion-starter
🤝 Contribuições
Contribuições são bem-vindas. Algumas ideias para quem quiser colaborar:
- ampliar a cobertura de tipos de propriedade do Notion;
- adicionar tipos de bloco ao conversor Markdown;
- expandir a escrita de linhas em data sources;
- melhorar exemplos, testes e documentação.
Leia CONTRIBUTING.md antes de enviar uma mudança.
⭐ Se esta biblioteca foi útil, considere dar uma estrela no GitHub.
Release files for notion-starter 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| notion_starter-0.4.0.tar.gz | 230.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| notion_starter-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 401.7 kB
Release files / notion_starter-0.4.0.tar.gz
| Download URL | notion_starter-0.4.0.tar.gz |
|---|---|
| Size | 230.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8283d12eef7b08f12560b9d330503ed0913c00c828733042657e991f05dd57e4
|
|
BLAKE2b-256 checksum How to use checksums |
020bb05e85d7980fad6e6b29f5dbcd2eac6f0b831dd19f9ac6f00dde9b6c36a8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.
Transparency logRelease files / notion_starter-0.4.0-py3-none-any.whl
| Download URL | notion_starter-0.4.0-py3-none-any.whl |
|---|---|
| Size | 171.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2eb0daf5ed93e9d816e6bc4314302a452627ede949a3aa0b080544dd0a67e631
|
|
BLAKE2b-256 checksum How to use checksums |
b5813239a309312956a99944f3b21f364aba87ecd5689d89246d577e49254660
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.
Transparency log