Metadata-Version: 2.4
Name: snakestack
Version: 0.45.0
Summary: Uma coleção de utilitários para acelerar o desenvolvimento backend em Python com padrões reutilizáveis e produtivos
Author-email: Bruno Segato <brunosegatoit@gmail.com>
Requires-Python: <4.0,>=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.28.1
Requires-Dist: orjson>=3.11.2
Requires-Dist: pydantic>=2.9.2
Requires-Dist: pydantic-settings>=2.10.1
Provides-Extra: mongodb
Requires-Dist: pymongo>=4.16.0; extra == "mongodb"
Provides-Extra: cache
Requires-Dist: redis>=6.4.0; extra == "cache"
Provides-Extra: pubsub
Requires-Dist: google-cloud-pubsub>=2.31.1; extra == "pubsub"
Provides-Extra: telemetry
Requires-Dist: opentelemetry-api>=1.36.0; extra == "telemetry"
Requires-Dist: opentelemetry-exporter-otlp>=1.36.0; extra == "telemetry"
Requires-Dist: opentelemetry-instrumentation-grpc>=0.57b0; extra == "telemetry"
Requires-Dist: opentelemetry-instrumentation-httpx>=0.57b0; extra == "telemetry"
Requires-Dist: opentelemetry-instrumentation-logging>=0.57b0; extra == "telemetry"
Provides-Extra: retry
Requires-Dist: tenacity>=9.1.2; extra == "retry"
Provides-Extra: circuit-breaker
Requires-Dist: pybreaker>=1.4.1; extra == "circuit-breaker"
Dynamic: license-file

# 🐍 SnakeStack

![Python](https://img.shields.io/badge/python->=3.10-blue)
![built with uv](https://img.shields.io/badge/built%20with-uv-blueviolet)
![Pipeline](https://github.com/BrunoSegato/snakestack/actions/workflows/ci.yml/badge.svg)
[![PyPI version](https://badge.fury.io/py/snakestack.svg)](https://pypi.org/project/snakestack/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![codecov](https://codecov.io/gh/BrunoSegato/snakestack/graph/badge.svg)](https://codecov.io/gh/BrunoSegato/snakestack)
![gitleaks badge](https://img.shields.io/badge/protected%20by-gitleaks-blue)

---

## 📦 Visão Geral

O `snakestack` é um pacote modular que oferece uma base robusta para construção de serviços backend com foco em:

- Observabilidade com OpenTelemetry
- Cache assíncrono com Redis
- Integração com Google Pub/Sub
- Acesso assíncrono ao MongoDB
- Client HTTPX com suporte a tracing
- Modelos base com `pydantic` e `pydantic-settings`
- Stack de logging estruturado e configurável
- Circuit breaker para proteção de integrações externas

---

## ⚙️ Instalação

### Base

```bash
pip install snakestack
```

### Extras disponíveis

| Extra     | Comando de instalação               |
| --------- | ----------------------------------- |
| Redis     | `pip install snakestack[redis]`     |
| MongoDB   | `pip install snakestack[mongodb]`   |
| Pub/Sub   | `pip install snakestack[pubsub]`    |
| Telemetry | `pip install snakestack[telemetry]` |
| Retry     | `pip install snakestack[retry]`     |
| Circuit Breaker | `pip install snakestack[circuit-breaker]` |
| Todos     | `pip install snakestack[all]`       |

---

## 📚 Módulos disponíveis

| Módulo                  | Descrição                                                             | Extra        |
| ----------------------- | --------------------------------------------------------------------- | ------------ |
| `snakestack.log`    | Logging estruturado com filtros, formatadores e propagação de request ID | —         |
| `snakestack.cache`      | Cliente Redis assíncrono com TTL, prefixo e serialização via `orjson` | `[redis]`    |
| `snakestack.pubsub`     | Publisher e subscriber para Google Pub/Sub com presets e tracing      | `[pubsub]`   |
| `snakestack.telemetry`  | Setup do OpenTelemetry com auto-instrumentação de HTTPX e logging     | `[telemetry]`|
| `snakestack.mongodb`    | Wrapper assíncrono para PyMongo com singleton de conexão              | `[mongodb]`  |
| `snakestack.healthz`    | Agregador de health checks com medição de latência por check          | —            |
| `snakestack.http_client`      | `AsyncClient` do HTTPX com composição de URL e normalização de erros  | —            |
| `snakestack.model`      | Modelos base Pydantic v2: `StrictModel`, `LenientModel`, `ORMModel`   | —            |
| `snakestack.task`       | Pool de workers assíncrono sobre `asyncio.Queue` com shutdown graceful| —            |
| `snakestack.retry`      | Decorator de retry para APIs externas com backoff exponencial, logging e tracing | `[retry]` |
| `snakestack.circuit_breaker` | Circuit breaker com backends em memória ou Redis, presets para HTTP e banco de dados, logging e tracing | `[circuit-breaker]` |
| `snakestack.config`     | Gerenciamento de settings com `pydantic-settings`                     | —            |

---

## 🧪 Exemplos de Uso

Os exemplos completos estão no diretório [`examples/`](examples/).

### Cache

| Arquivo | Descrição |
| ------- | --------- |
| [`cache/sample_async_service.py`](examples/cache/sample_async_service.py) | Uso básico do `AsyncRedisService` com diferentes tipos de valor |

### Healthz

| Arquivo | Descrição |
| ------- | --------- |
| [`healthz/sample_healthz.py`](examples/healthz/sample_healthz.py) | Health check com callbacks síncronos e assíncronos |
| [`healthz/sample_healthz_with_deps.py`](examples/healthz/sample_healthz_with_deps.py) | Health check verificando Redis e MongoDB |

### Circuit Breaker

| Arquivo | Descrição |
| ------- | --------- |
| [`circuit_breaker/sample_http.py`](examples/circuit_breaker/sample_http.py) | Circuit breaker em chamadas HTTP com preset `circuit_breaker_http` |
| [`circuit_breaker/sample_http_with_telemetry.py`](examples/circuit_breaker/sample_http_with_telemetry.py) | Circuit breaker com tracing via OpenTelemetry |

### HTTPX

| Arquivo                                                                                 | Descrição |
|-----------------------------------------------------------------------------------------| --------- |
| [`http_client/sample_default.py`](examples/http_client/sample_default.py)               | Client HTTPX básico com composição de URL |
| [`http_client/sample_with_telemetry.py`](examples/http_client/sample_with_telemetry.py) | Client HTTPX com tracing via OpenTelemetry |

### Logging

| Arquivo | Descrição |
| ------- | --------- |
| [`log/sample_default.py`](examples/log/sample_default.py) | Formatter padrão |
| [`log/sample_with_request_id.py`](examples/log/sample_with_request_id.py) | Formatter com propagação de request ID |
| [`log/sample_custom_json.py`](examples/log/sample_custom_json.py) | Formatter JSON estruturado |
| [`log/sample_filter_excluded_name.py`](examples/log/sample_filter_excluded_name.py) | Filtro por nome do logger |
| [`log/sample_filter_path.py`](examples/log/sample_filter_path.py) | Filtro por path da requisição |

### MongoDB

| Arquivo | Descrição |
| ------- | --------- |
| [`mongodb/sample_mongodb.py`](examples/mongodb/sample_mongodb.py) | Conexão, consulta e encerramento com PyMongo assíncrono |

### Pub/Sub

| Arquivo                                                                                                       | Descrição                        |
|---------------------------------------------------------------------------------------------------------------|----------------------------------|
| [`pubsub/sample_publisher.py`](examples/pubsub/sample_publisher.py)                                           | Publicação básica de mensagens   |
| [`pubsub/sample_publisher_with_open_telemetry.py`](examples/pubsub/sample_publisher_with_open_telemetry.py)   | Publicação com tracing           |
| [`pubsub/sample_publisher_with_callback.py`](examples/pubsub/sample_publisher_with_open_telemetry.py)         | Publicação com callback          |
| [`pubsub/sample_subscriber.py`](examples/pubsub/sample_subscriber.py)                                         | Subscriber com `SimpleProcessor` |
| [`pubsub/sample_subscriber_with_batch.py`](examples/pubsub/sample_subscriber_with_batch.py)                   | Subscriber com `BatchProcessor`  |
| [`pubsub/sample_subscriber_with_open_telemetry.py`](examples/pubsub/sample_subscriber_with_open_telemetry.py) | Subscriber com tracing           |
| [`pubsub/sample_flow_control.py`](examples/pubsub/sample_flow_control.py)                                     | Configuração de flow control     |

### Task

| Arquivo | Descrição |
| ------- | --------- |
| [`task/sample_task.py`](examples/task/sample_task.py) | Worker pool básico |
| [`task/sample_task_with_sentinel.py`](examples/task/sample_task_with_sentinel.py) | Worker pool com sentinel de encerramento |
| [`task/sample_task_with_callback.py`](examples/task/sample_task_with_callback.py) | Worker pool com callback customizado |

### Retry

| Arquivo | Descrição |
| ------- | --------- |
| [`retry/sample_with_logging.py`](examples/retry/sample_with_logging.py) | Retry com logging estruturado em chamadas a APIs externas |
| [`retry/sample_with_telemetry.py`](examples/retry/sample_with_telemetry.py) | Retry com eventos de tracing via OpenTelemetry |

### Telemetry

| Arquivo | Descrição |
| ------- | --------- |
| [`telemetry/sample_telemetry.py`](examples/telemetry/sample_telemetry.py) | Setup do OpenTelemetry com `instrument_app` |
| [`telemetry/sample_decorator_telemetry.py`](examples/telemetry/sample_decorator_telemetry.py) | Tracing via decorator `@instrumented_span` |

---

## 🛠️ Desenvolvimento Local

### 1. Clone o repositório

```bash
git clone https://github.com/BrunoSegato/snakestack.git
cd snakestack
```

### 2. Instale as dependências

```bash
uv sync --all-groups --all-extras
```

### 3. Instale os hooks de pre-commit

```bash
make hooks
```

### 4. Suba os serviços locais

```bash
docker-compose up -d
```

---

## 🧾 Comandos

| Comando                        | Descrição                                      |
| ------------------------------ | ---------------------------------------------- |
| `make install`                 | Instala apenas dependências de runtime         |
| `make lint`                    | Executa `ruff check`                           |
| `make format`                  | Executa `ruff check --fix`                     |
| `make mypy`                    | Executa `mypy` sem cache incremental           |
| `make check`                   | Executa lint + mypy                            |
| `make pre-commit`              | Executa todos os hooks de pre-commit           |
| `make test`                    | Executa todos os testes                        |
| `make test-unit`               | Executa apenas testes unitários                |
| `make test-matching test=nome` | Executa testes por nome com `-vv -s --pdb`     |
| `make release`                 | Bump de versão + changelog via commitizen      |
| `make publish`                 | Publica no PyPI                                |

---

## 🧪 Testes

O projeto possui cobertura completa de testes unitários organizados por domínio.

```bash
# Todos os testes
make test

# Apenas testes unitários
make test-unit

# Testes de um domínio específico
uv run pytest -m cache
uv run pytest -m pubsub
uv run pytest -m telemetry
uv run pytest -m mongodb
uv run pytest -m retry
uv run pytest -m circuit_breaker

# Teste por nome
make test-matching test='nome_do_teste'
```
