|
| 1 | +# Contribuindo com o hotmart-python |
| 2 | + |
| 3 | +Obrigado pelo interesse em contribuir! Este guia cobre tudo que voce precisa: configuracao do ambiente, execucao de testes, padroes de codigo e como adicionar um novo endpoint da API Hotmart. |
| 4 | + |
| 5 | +**English documentation available at [CONTRIBUTING.md](CONTRIBUTING.md).** |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## Indice |
| 10 | + |
| 11 | +- [Primeiros Passos](#primeiros-passos) |
| 12 | +- [Executando os Testes](#executando-os-testes) |
| 13 | +- [Lint e Formatacao](#lint-e-formatacao) |
| 14 | +- [Verificacao de Tipos](#verificacao-de-tipos) |
| 15 | +- [Estilo de Codigo](#estilo-de-codigo) |
| 16 | +- [Como Adicionar um Novo Endpoint](#como-adicionar-um-novo-endpoint) |
| 17 | +- [Referencia da API](#referencia-da-api) |
| 18 | +- [Checklist de Pull Request](#checklist-de-pull-request) |
| 19 | + |
| 20 | +--- |
| 21 | + |
| 22 | +## Primeiros Passos |
| 23 | + |
| 24 | +Este projeto usa [uv](https://github.com/astral-sh/uv) para gerenciamento de dependencias. |
| 25 | + |
| 26 | +1. Faca o fork e clone o repositorio: |
| 27 | + |
| 28 | +```bash |
| 29 | +git clone https://github.com/im-voracity/hotmart-python.git |
| 30 | +cd hotmart-python |
| 31 | +``` |
| 32 | + |
| 33 | +2. Instale todas as dependencias (incluindo as de desenvolvimento): |
| 34 | + |
| 35 | +```bash |
| 36 | +uv sync |
| 37 | +``` |
| 38 | + |
| 39 | +So isso. O `uv` cria e gerencia o ambiente virtual automaticamente — sem precisar configurar `venv` manualmente. |
| 40 | + |
| 41 | +--- |
| 42 | + |
| 43 | +## Executando os Testes |
| 44 | + |
| 45 | +```bash |
| 46 | +uv run pytest tests/ --ignore=tests/test_integration.py |
| 47 | +``` |
| 48 | + |
| 49 | +Para saida verbosa com tracebacks curtos: |
| 50 | + |
| 51 | +```bash |
| 52 | +uv run pytest tests/ --ignore=tests/test_integration.py -v --tb=short |
| 53 | +``` |
| 54 | + |
| 55 | +Todos os testes unitarios usam `respx` para mockar HTTP — sem chamadas reais a API, sem necessidade de credenciais. |
| 56 | + |
| 57 | +### Testes de integracao |
| 58 | + |
| 59 | +Os testes de integracao rodam contra a API real da Hotmart. Sao pulados automaticamente se as credenciais nao estiverem presentes: |
| 60 | + |
| 61 | +```bash |
| 62 | +# Requer HOTMART_CLIENT_ID, HOTMART_CLIENT_SECRET, HOTMART_BASIC no ambiente |
| 63 | +set -a && source .env && set +a |
| 64 | +uv run pytest tests/test_integration.py -v |
| 65 | +``` |
| 66 | + |
| 67 | +Veja o `.env.example` para as variaveis de ambiente esperadas. |
| 68 | + |
| 69 | +--- |
| 70 | + |
| 71 | +## Lint e Formatacao |
| 72 | + |
| 73 | +```bash |
| 74 | +# Verificar erros de lint |
| 75 | +uv run ruff check src/ tests/ |
| 76 | + |
| 77 | +# Corrigir automaticamente o que for possivel |
| 78 | +uv run ruff check --fix src/ tests/ |
| 79 | + |
| 80 | +# Formatar |
| 81 | +uv run ruff format src/ tests/ |
| 82 | + |
| 83 | +# Verificar formatacao sem modificar arquivos |
| 84 | +uv run ruff format --check src/ tests/ |
| 85 | +``` |
| 86 | + |
| 87 | +--- |
| 88 | + |
| 89 | +## Verificacao de Tipos |
| 90 | + |
| 91 | +```bash |
| 92 | +uv run mypy src/hotmart/ |
| 93 | +``` |
| 94 | + |
| 95 | +O projeto roda `mypy --strict`. Todas as APIs publicas devem ser totalmente anotadas. |
| 96 | + |
| 97 | +--- |
| 98 | + |
| 99 | +## Estilo de Codigo |
| 100 | + |
| 101 | +- **Sem `if` aninhados.** Use early returns e guard clauses. |
| 102 | +- **Early returns primeiro.** Valide entradas e trate casos de erro no inicio da funcao, antes do caminho feliz. |
| 103 | +- **Guard clauses.** Prefira `if not x: return` em vez de `if x: <bloco grande>`. |
| 104 | +- **Docstrings em EN + PT-BR.** Todo metodo publico deve ter uma descricao breve em ingles seguida da traducao em portugues. Veja os metodos de recursos existentes para o padrao. |
| 105 | + |
| 106 | +**Preferido:** |
| 107 | + |
| 108 | +```python |
| 109 | +def meu_metodo(self, valor: str | None) -> str: |
| 110 | + if not valor: |
| 111 | + return "" |
| 112 | + if len(valor) > 100: |
| 113 | + raise ValueError("valor muito longo") |
| 114 | + return valor.strip() |
| 115 | +``` |
| 116 | + |
| 117 | +**Evite:** |
| 118 | + |
| 119 | +```python |
| 120 | +def meu_metodo(self, valor: str | None) -> str: |
| 121 | + if valor: |
| 122 | + if len(valor) <= 100: |
| 123 | + return valor.strip() |
| 124 | + return "" |
| 125 | +``` |
| 126 | + |
| 127 | +--- |
| 128 | + |
| 129 | +## Como Adicionar um Novo Endpoint |
| 130 | + |
| 131 | +### Passo 1 — Identifique o recurso |
| 132 | + |
| 133 | +Determine a qual grupo de recursos o endpoint pertence (`sales`, `subscriptions`, `products`, `coupons`, `club`, `events` ou `negotiation`). Se for um novo grupo, crie um novo arquivo de recurso seguindo os padroes existentes. |
| 134 | + |
| 135 | +### Passo 2 — Adicione ou atualize o modelo Pydantic |
| 136 | + |
| 137 | +Adicione o modelo de resposta em `src/hotmart/models/`. Mantenha um arquivo por grupo de recursos. Use `extra="allow"` em todos os modelos para que novos campos da API nao quebrem o codigo existente: |
| 138 | + |
| 139 | +```python |
| 140 | +# src/hotmart/models/sales.py |
| 141 | +from pydantic import BaseModel, ConfigDict |
| 142 | + |
| 143 | +class MeuNovoModelo(BaseModel): |
| 144 | + model_config = ConfigDict(extra="allow") |
| 145 | + |
| 146 | + campo_um: str |
| 147 | + campo_dois: int | None = None |
| 148 | +``` |
| 149 | + |
| 150 | +Exporte o novo modelo em `src/hotmart/models/__init__.py` e em `src/hotmart/__init__.py`. |
| 151 | + |
| 152 | +### Passo 3 — Adicione o metodo na classe de recurso |
| 153 | + |
| 154 | +Adicione o metodo no arquivo correspondente em `src/hotmart/resources/`: |
| 155 | + |
| 156 | +```python |
| 157 | +# src/hotmart/resources/sales.py |
| 158 | +def meu_novo_metodo( |
| 159 | + self, |
| 160 | + *, |
| 161 | + algum_param: str | None = None, |
| 162 | + **kwargs: Any, |
| 163 | +) -> PaginatedResponse[MeuNovoModelo]: |
| 164 | + """Fetch my new resource. |
| 165 | +
|
| 166 | + Busca o novo recurso. |
| 167 | + """ |
| 168 | + params = _build_params(locals()) |
| 169 | + return self._get("/meu-endpoint", params=params, cast_to=PaginatedResponse[MeuNovoModelo]) # type: ignore[return-value] |
| 170 | +``` |
| 171 | + |
| 172 | +Se o endpoint for paginado, adicione tambem uma variante `*_autopaginate` seguindo o padrao existente. |
| 173 | + |
| 174 | +### Passo 4 — Escreva os testes |
| 175 | + |
| 176 | +Adicione testes em `tests/resources/`. Siga os padroes existentes — mocke `BaseSyncClient._request` e verifique se a URL e os parametros corretos sao passados: |
| 177 | + |
| 178 | +```python |
| 179 | +# tests/resources/test_sales.py |
| 180 | +def test_meu_novo_metodo(client, mock_paginated_response): |
| 181 | + with patch.object(client, "_request", return_value=mock_paginated_response) as mock_req: |
| 182 | + client.sales.meu_novo_metodo(algum_param="valor") |
| 183 | + mock_req.assert_called_once() |
| 184 | + _, kwargs = mock_req.call_args |
| 185 | + assert kwargs["params"]["algum_param"] == "valor" |
| 186 | +``` |
| 187 | + |
| 188 | +### Passo 5 — Atualize a documentacao |
| 189 | + |
| 190 | +Atualize `docs/README.md` e `docs/README-ptBR.md` para documentar o novo metodo na secao de recurso correspondente. |
| 191 | + |
| 192 | +--- |
| 193 | + |
| 194 | +## Referencia da API |
| 195 | + |
| 196 | +O arquivo [`HOTMART-API-REFERENCE.md`](HOTMART-API-REFERENCE.md) contem uma referencia completa e legivel por maquina de todos os endpoints da API Hotmart. Ele existe porque a documentacao oficial da Hotmart e renderizada como uma SPA JavaScript e nao e acessivel por crawlers ou agentes de IA. |
| 197 | + |
| 198 | +Se voce estiver implementando um novo endpoint, este arquivo e a sua referencia principal para parametros de requisicao, formatos de resposta e comportamentos conhecidos. |
| 199 | + |
| 200 | +--- |
| 201 | + |
| 202 | +## Checklist de Pull Request |
| 203 | + |
| 204 | +Antes de enviar um PR, verifique: |
| 205 | + |
| 206 | +- [ ] `uv run pytest tests/ --ignore=tests/test_integration.py` passa sem falhas |
| 207 | +- [ ] `uv run ruff check src/ tests/` nao reporta erros |
| 208 | +- [ ] `uv run ruff format --check src/ tests/` nao reporta alteracoes necessarias |
| 209 | +- [ ] `uv run mypy src/hotmart/` nao reporta erros |
| 210 | +- [ ] Novo endpoint coberto por ao menos um teste |
| 211 | +- [ ] `docs/README.md` e `docs/README-ptBR.md` atualizados se aplicavel |
| 212 | + |
| 213 | +--- |
| 214 | + |
| 215 | +## Licenca |
| 216 | + |
| 217 | +Ao contribuir com este projeto, voce concorda que suas contribuicoes serao licenciadas sob a Apache License 2.0. |
0 commit comments