Skip to content

Repository files navigation

ministack

Wrappers Python ergonômicos sobre o Ministack (emulador local de AWS) para acelerar o desenvolvimento de aplicações de engenharia de dados — pipelines, ETLs, streaming, jobs Spark/Glue, orquestração — sem depender de uma conta AWS real durante o ciclo de desenvolvimento.

Cada classe *Wrapper esconde a complexidade do boto3 por trás de métodos de API enxuta: argumentos primitivos (str, int, bool, dict, list[tuple]) entram, dados úteis saem (ARN, ID, lista, dict). Sem precisar montar dicts aninhados do AWS na mão, sem ler StreamingBody, sem fazer json.dumps em política IAM.

Stack

  • Python 3.13+
  • uv para dependências
  • boto3 para chamar o Ministack
  • Ministack rodando em http://localhost:4566 via Docker Compose
  • pytest + pytest-mock para os testes unitários
  • ruff para lint e formatação
  • commitizen para Conventional Commits + versionamento semver automático

Setup

# 1. Subir o Ministack (e Redis, etc.) via docker compose
docker compose up -d ministack

# 2. Instalar dependências
uv sync

# 3. Instalar git hooks locais (commit-msg + post-commit)
./scripts/install_git_hooks.sh

# 4. Rodar a suíte de testes
uv run pytest

Uso

Cada wrapper se constrói sem argumentos — o Client aponta para o Ministack local por padrão (http://localhost:4566, região us-east-1, credenciais test/test):

from wrappers.s3 import S3Wrapper
from wrappers.kinesis import KinesisWrapper
from wrappers.glue import GlueWrapper

s3 = S3Wrapper()
s3.create_bucket("raw-events")
s3.put_object("raw-events", "events/2026/01/01.json", b'{"id": 1}')
print(s3.list_objects("raw-events"))

kinesis = KinesisWrapper()
kinesis.create_stream("clickstream", shard_count=2)
kinesis.put_record("clickstream", b'{"user_id": 123}', partition_key="123")

glue = GlueWrapper()
glue.create_database({"Name": "analytics"})
glue.create_table("analytics", {"Name": "events", "StorageDescriptor": {}})

Cada operação loga em INFO uma linha de confirmação [ok] <ação>: <identificador> para facilitar o debug.

Serviços implementados

A lista abaixo reflete o estado atual — novos serviços serão adicionados conforme a necessidade de cada aplicação de dados que for sendo construída em cima dessa base.

Serviço Wrapper Operações
CloudWatch CloudWatchWrapper 20
EventBridge EventBridgeWrapper 57
EMR EMRWrapper 22
Firehose FirehoseWrapper 12
Glue GlueWrapper 65
IAM IAMWrapper 67
Kinesis KinesisWrapper 26
S3 S3Wrapper 68
Secrets Manager SecretsManagerWrapper 20
Step Functions StepFunctionsWrapper 33

Todos os métodos cobrem 1:1 as operações suportadas pelo Ministack (verificadas contra o código-fonte do projeto). Próximos serviços previstos conforme demanda: SQS, SNS, Lambda, DynamoDB, Athena, RDS, Redshift, entre outros.

Estrutura

src/
  common/
    utils.py            # Client (dataclass com defaults pro Ministack)
  wrappers/
    cloudwatch.py
    emr.py
    eventbridge.py
    firehose.py
    glue.py
    iam.py
    kinesis.py
    s3.py
    secretsmanager.py
    stepfunctions.py
tests/
  conftest.py           # fixture que mocka boto3 via Client.build_client
  wrappers/
    test_*.py           # 1 teste de happy path por método (~393 testes)
docker-compose.yml      # Ministack + Redis
pyproject.toml          # deps + config do pytest

Convenções dos wrappers

Cada método obedece o mesmo formato:

  1. Argumentos primitivos tipados — nada de dicts aninhados do boto3 vazando para o caller.
  2. dict Python entra para policies/definitions/payloads — serialização para JSON é interna.
  3. Retornos: ARN/ID quando faz sentido (criação), list[dict] para listagens, bytes em downloads.
  4. Uma operação boto3 por método — sem branches, sem helpers internos.
  5. Log [ok] <ação>: <identificador> no fim de cada operação bem-sucedida.

Testes

uv run pytest                              # toda a suíte
uv run pytest tests/wrappers/test_s3.py    # um wrapper específico
uv run pytest -k "create_bucket"           # por nome

Os testes não tocam o Ministack — Client.build_client é substituído por um MagicMock na fixture boto3_client do conftest.py. Cada teste valida o caminho feliz: que o método chama a operação boto3 correta com os kwargs esperados e devolve o dado certo.

Lint e formatação

Configuração do ruff em pyproject.toml (line-length 100, target py313, regras E,W,F,I,B,UP,SIM,C4,N,RUF).

uv run ruff check .                # lint
uv run ruff check . --fix          # lint com auto-fix
uv run ruff format .               # formatar
uv run ruff format . --check       # checar formatação sem alterar

Commits e versionamento

O projeto adota Conventional Commits e versionamento semver gerenciado pelo commitizen. A versão fica em pyproject.toml (campo [project].version) e é atualizada automaticamente a partir do histórico de commits.

Hooks instalados por scripts/install_git_hooks.sh

  • commit-msg — valida que toda mensagem segue Conventional Commits. Commits fora do padrão são rejeitados.
  • post-commit — apenas imprime um lembrete quando há commits acumulados desde a última tag, sugerindo rodar o bump. Não bumpa automaticamente para evitar loops e poluição do histórico.

Formato de commit

<tipo>(<escopo opcional>): <descrição curta>

[corpo opcional]

[footer opcional, ex: BREAKING CHANGE: ...]

Tipos comuns: feat, fix, docs, style, refactor, perf, test, chore, build, ci.

Exemplos:

git commit -m "feat(s3): add presigned_url helper"
git commit -m "fix(kinesis): handle empty shard list"
git commit -m "chore: bump boto3"

Para escrever o commit interativamente seguindo o padrão:

uv run cz commit

Liberar uma nova versão

scripts/bump_version.sh analisa os commits desde a última tag, decide se o bump é MAJOR / MINOR / PATCH (com base nos tipos feat, fix, BREAKING CHANGE), atualiza pyproject.toml, gera/atualiza CHANGELOG.md e cria a tag git vX.Y.Z.

./scripts/bump_version.sh                       # bump automático
./scripts/bump_version.sh --dry-run             # mostra o que seria feito
./scripts/bump_version.sh --increment MINOR     # forçar tipo de bump

# Publicar a tag e o commit de release
git push --follow-tags

Comandos úteis do commitizen direto:

uv run cz version --project        # versão atual
uv run cz changelog                # gerar CHANGELOG sem bumpar
uv run cz check --rev-range HEAD~5..HEAD   # validar últimos commits

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages