Contribuindo¶
A contribuição mais útil é uma issue — não um PR
Este SDK é uma superfície pública versionada: cada release publica no PyPI e cada símbolo novo carrega docstring, docs bilíngues e entrada na referência. Por isso o fluxo aqui é issue primeiro: você descreve o problema (ou a ideia), a gente combina o escopo e o formato, e só então alguém escreve código. Um PR que chega antes desse alinhamento quase sempre precisa ser refeito.
Abra uma issue¶
| Necessidade | Onde |
|---|---|
| Bug (algo não funciona como documentado) | Issue: bug report |
| Feature / ideia de API | Issue: feature request |
| Doc confusa, incompleta, exemplo que não roda, typo | Issue: docs |
| Dúvida de uso ("como faço X com o SDK?") | Issue: dúvida |
| Divulgação de segurança | mauricio.benjamin@reloverelations.com (privado, nunca em issue pública) |
O que faz uma issue ser resolvida rápido:
- versão do SDK (
python -c "import tempest_fastapi_sdk as t; print(t.__version__)") e do Python; - snippet mínimo que reproduz — completo, com imports, sem
...; - o que você esperava e o que aconteceu (traceback inteiro, não a última linha);
- para feature: o caso de uso, não a solução já desenhada. O problema costuma ter uma resposta melhor com as peças que o SDK já tem.
Typo na doc também é issue
Antes era "manda PR direto". Não mais: cada página existe duas vezes (docs/<página>.md em PT-BR e docs/<página>.en.md em EN-US) e um PR que corrige só um lado deixa o site inconsistente. Abra a issue apontando a página e o trecho — a correção sai nas duas de uma vez.
Por que issue antes de código¶
Três restrições deste repositório que não aparecem no diff:
- Versionamento e compatibilidade. Todo símbolo público entra em
__all__, na referência renderizada e no contrato SemVer. Renomear ou mudar assinatura depois é breaking change com guia de migração. - Docs no mesmo commit. Mudança de superfície pública sem README,
CHANGELOG.md, receita bilíngue e stub de referência atualizados não passa — é regra do projeto, não preferência do revisor. - Release por feature. Cada fatia sai como sua própria versão (bump em
pyproject.toml,__version__euv.lock, gates completos, tag). Quem conduz esse ciclo é o mantenedor.
Nada disso impede sua contribuição — só significa que combinar o escopo na issue é mais rápido do que descobrir na revisão do PR.
Quero implementar¶
Ótimo — diga isso na issue e espere o "vai". Aí:
- trabalhe num branch
feat/<slug>/fix/<slug>a partir demain; - rode
make check(lint + formato + mypy + testes) — a CI não roda testes (só publica), então é este o gate;make test-matrixcobre 3.12 / 3.13 / 3.14; - atualize a doc PT e EN junto com o código, mais
CHANGELOG.md; - não faça bump de versão nem crie tag — isso é do release;
- um PR por assunto, com o corpo explicando o problema antes da solução.
PR sem issue aceita costuma ser fechado com um pedido pra abrir a issue — não é rejeição do trabalho, é a ordem que mantém a doc e o release coerentes.
Ambiente de desenvolvimento¶
# Clone + sincronize todos os extras e os grupos dev/docs
git clone https://github.com/mauriciobenjamin700/tempest-fastapi-sdk.git
cd tempest-fastapi-sdk
uv sync --all-extras --group dev --group docs
Verificação rápida
make check roda o gate de qualidade completo (lint + checagem de formato + mypy + pytest). A CI não roda testes — só publica a release —, então um make check verde localmente é o que torna um PR mergeável.
Gates de qualidade¶
| Comando | O que faz |
|---|---|
make lint |
ruff check . (sem auto-fix) |
make fix |
ruff check --fix . + ruff format . (escreve) |
make fmt |
ruff format . (escreve) |
make fmt-check |
ruff format --check . (somente leitura) |
make type |
mypy tempest_fastapi_sdk (strict) |
make test |
pytest em paralelo (um worker por núcleo lógico, worksteal, 1 thread de BLAS por worker), sem cobertura |
make test-cov |
pytest em paralelo com o relatório de cobertura |
make test-matrix |
a suíte em 3.12, 3.13 e 3.14, uma venv por versão |
make check |
lint + fmt-check + type + test (para no primeiro erro) |
make ci |
check + build + smoke (gate local completo antes de uma release) |
Os mesmos gates estão disponíveis pela CLI embutida: tempest lint / tempest fix / tempest check funcionam em qualquer projeto consumidor também.
Testes¶
make test # suite padrão em paralelo, sem cobertura (sem model/gpu/docker)
make test-cov # a mesma suite com o relatório de cobertura
uv run pytest tests/admin # só o módulo admin
uv run pytest -k cursor # testes que casam com "cursor"
uv run pytest -x # para no primeiro erro
O make test não roda a suite inteira: o addopts do pyproject.toml passa -m "not model and not gpu and not docker and not network", então os testes que baixam peso de modelo, pedem CUDA, sobem container ou falam com um serviço de terceiro pela internet ficam de fora. Cada grupo tem o seu alvo opt-in: make test-model, make test-gpu, make test-docker e make test-network.
A suite usa SQLite em memória: a fixture db de tests/conftest.py abre um AsyncDatabaseManager("sqlite+aiosqlite:///:memory:") novo por teste, e os testes de repository compartilham a fixture session aberta sobre ele.
Docs¶
make docs-serve # mkdocs serve — live reload em http://127.0.0.1:8000
make docs-build # build do site estático em ./site/
Toda página vive em duas línguas (docs/<página>.md + docs/<página>.en.md) e o build roda com --strict — warning é erro.
A documentação é mantida organizada por regra, não por revisão
Página nova exige: os dois arquivos (PT + .en.md), entrada nos dois navs (o nav: de topo e o nav: do locale en — o plugin i18n traduz rótulo mas não reordena nav compartilhado), na posição alfabética de cada língua, mais a linha na tabela de docs/recipes/index.md/.en.md quando for receita, e o stub em docs/reference.md quando expõe símbolo novo. uv run pytest tests/test_docs_organization.py falha se algo disso faltar ou sair de ordem — e ele roda no make check. Abas de topo, páginas de learning/, a trilha de getting-started/ e o tour da landing seguem ordem didática de propósito. As edições caem no site do Pages no push para main via .github/workflows/docs.yml.
Estilo das mensagens de commit¶
Prefixos de Conventional Commits:
feat:— nova capacidade voltada ao usuáriofix:— correção de bugref:— reestruturação interna sem mudança de comportamentodocs:— só documentaçãotests:— só mudanças de testechore:— tooling, deps, encanamento de release
Adicione ! após o prefixo para mudanças que quebram compatibilidade (feat!: drop class-attr config). Marque na mensagem a versão que entrega a mudança.
Release (mantenedor)¶
make release VERSION=X.Y.Z SUBJECT="assunto" faz o bump nas localizações da versão, roda todos os gates (check + docs-build + smoke), cria o commit + tag e diz o que você deve dar push:
make release VERSION=0.20.0 SUBJECT="assunto da release"
git push origin main
git push origin v0.20.0
O target recusa rodar com a árvore suja ou sem a entrada ## [0.20.0] no CHANGELOG.md — escreva o changelog antes. Sem SUBJECT, a mensagem do commit cai no genérico chore: release v0.20.0 em vez do feat: vX.Y.Z — assunto que o projeto usa.
O workflow de publicação no PyPI dispara no push da tag vX.Y.Z (publicação confiável — sem token de API no repositório).