Skip to main content

GovHub Data Lakehouse

Data Lakehouse format-agnostic e infra-agnostic: a mesma camada de orquestração funciona independente de object storage, catálogo de metadados, engine de query e formato de tabela por baixo (Iceberg, Delta Lake, Hudi).

Stack

  • Core: Python, gerenciado com uv
  • Infra como código: Terraform (módulos por ambiente: local, aws, ...)
  • Versões de ferramentas: mise (.mise.toml)

Subindo o ambiente local

mise trust
mise install
cp .env.example .env   # ajuste se necessário — os defaults já batem com a infra local

cd infra/environments/local
terraform init
terraform apply

terraform apply só retorna quando todos os serviços respondem como saudáveis (ver null_resource.wait_for_services em infra/environments/local/main.tf) — não só quando os containers existem. Evita testes/comandos rodando contra um serviço (ex: Trino) que ainda não terminou de subir.

Sobe, via Docker:

Serviço Endpoint Login
MinIO API (S3) http://localhost:9003 lakehouse / lakehouse-dev
MinIO Console http://localhost:9002 lakehouse / lakehouse-dev
Iceberg REST Catalog http://localhost:8181
Airflow (standalone) http://localhost:8082 admin / ver comando abaixo
Trino http://localhost:8083

Senha do Airflow (gerada na primeira subida, persiste no volume):

docker exec govhub-lakehouse-airflow cat /opt/airflow/simple_auth_manager_passwords.json.generated

Bucket warehouse é criado automaticamente no MinIO. Catálogo Iceberg persiste metadados em Postgres (porta 5434).

Para derrubar: terraform destroy dentro de infra/environments/local.

Configuração (.env)

.env.example documenta todas as variáveis GOVHUB_* (storage, catálogo, extractors) com os defaults que já batem com a infra local, mais GOVHUB_ENV (dev | homolog | prod — qual ambiente este checkout está apontando agora; aparece no log de auditoria da CLI). Copie pra .env (gitignorado) e ajuste — mise carrega automaticamente em todo comando rodado via mise exec (.mise.toml), sem depender de nenhuma lib Python.

Rodando o core Python

uv sync
uv run pytest tests/

Testes contra backends reais (s3 em tests/storage/, iceberg_rest em tests/catalog/ e tests/table/, DuckDB + Trino em tests/engines/) precisam do ambiente local do Terraform no ar — caso contrário são pulados automaticamente.

Storage backend

Backend escolhido via GOVHUB_STORAGE_BACKEND (local ou s3). Os demais nomes são genéricos de propósito — os mesmos valerão para os próximos backends (Azure, GCS):

Variável Uso
GOVHUB_STORAGE_BACKEND local | s3
GOVHUB_STORAGE_LOCAL_ROOT raiz no filesystem (backend local)
GOVHUB_STORAGE_CONTAINER bucket/container
GOVHUB_STORAGE_ENDPOINT endpoint do serviço
GOVHUB_STORAGE_ACCESS_KEY credencial de acesso
GOVHUB_STORAGE_SECRET_KEY credencial secreta
GOVHUB_STORAGE_REGION região (quando aplicável)

Catalog backend

Backend escolhido via GOVHUB_CATALOG_BACKEND (iceberg_rest por enquanto):

Variável Uso
GOVHUB_CATALOG_BACKEND iceberg_rest
GOVHUB_CATALOG_URI endpoint do catálogo REST
GOVHUB_CATALOG_WAREHOUSE localização do warehouse (s3://...)
GOVHUB_CATALOG_ENDPOINT endpoint do object storage (S3 FileIO)
GOVHUB_CATALOG_ACCESS_KEY credencial de acesso
GOVHUB_CATALOG_SECRET_KEY credencial secreta
GOVHUB_CATALOG_REGION região (quando aplicável)

Table format backend

Sem variáveis próprias — reaproveita a config do catálogo (GOVHUB_CATALOG_* acima), já que a camada de formato sempre opera sobre uma conexão de catálogo existente. Seleção do formato é por código (TableBackendFactory), iceberg por enquanto.

Extractors e transformers

src/govhub_lakehouse/extractors/ (Strategy + Factory, mesmo padrão de core/) — ApiExtractor, PostgresExtractor, S3Extractor, registrados em ExtractorFactory. src/govhub_lakehouse/transformers/ (Template Method) — IcebergTransformer cuida do passo específico de formato (ajustar o schema solto do extractor para exatamente o que o Iceberg espera) dentro de um algoritmo fixo (transform) compartilhado por qualquer formato futuro.

DAGs (dags/)

Ingestão organizada por domínio de dados (estilo data mesh, mesma lógica do govhub-cidades) — cada domínio tem sua própria pasta/DAG(s) sob dags/<domínio>/, montada em /opt/airflow/dags. Exemplo real: dags/ibge/estados_dag.py — domínio ibge, extract >> transform via TaskFlow API, puxando a lista de estados da API pública do IBGE e carregando em ibge.estados (Iceberg).

docker exec govhub-lakehouse-airflow airflow dags unpause ibge_estados
docker exec govhub-lakehouse-airflow airflow dags trigger ibge_estados
docker exec govhub-lakehouse-airflow airflow dags list-runs ibge_estados

A imagem do Airflow é buildada com o próprio pacote instalado (infra/modules/orchestration/local/docker/airflow/Dockerfile), então qualquer DAG pode importar govhub_lakehouse.extractors/.transformers/ .core.* normalmente.

Lint

uv run black --check src tests dags
uv run isort --check src tests dags

CLI (glh)

uv run glh init
uv run glh create-table --namespace ns --table people --column id:long:required --column name:string
uv run glh ingest --namespace ns --table people --file dados.parquet [--mode append|overwrite]
uv run glh list-tables --namespace ns
uv run glh describe-table --namespace ns --table people

Cada comando lê a config de GOVHUB_STORAGE_*/GOVHUB_CATALOG_* (acima) e emite um log estruturado em JSON por operação em stderr — quem rodou (usuário do SO), quando, quais argumentos, sucesso/erro e duração. O resultado da operação vai pro stdout, também em JSON.

Build e deploy

Pra implantar o glh na infra de um órgão, sem precisar de Python/uv instalado lá:

uv build                                    # wheel + sdist em dist/
docker build -t govhub-lakehouse-cli .      # imagem standalone do CLI
docker run --rm govhub-lakehouse-cli init   # roda contra GOVHUB_STORAGE_*/GOVHUB_CATALOG_* passadas via -e

A imagem não inclui nossa infra local de dev — só o glh e suas dependências. O órgão aponta as variáveis de ambiente pro storage/catálogo deles.

Também publicamos duas imagens no GHCR a cada push na main (CD, ver abaixo):

docker pull ghcr.io/bottinolucas/govhub-lakehouse-cli:latest
docker pull ghcr.io/bottinolucas/govhub-lakehouse-airflow:latest

A -airflow já vem com govhub_lakehouse instalado — é a mesma imagem que infra/modules/orchestration/local builda localmente, só que pronta pra puxar em vez de buildar.

CI/CD

.github/workflows/ci.yml roda em todo push/PR na main:

  • lint: black + isort (src, tests, dags)

  • terraform: fmt -check + validate

  • test: sobe a infra local via Terraform (só retorna com tudo saudável — ver null_resource.wait_for_services), roda pytest, derruba a infra no final, mesmo se os testes falharem

  • build: uv build + build das duas imagens Docker (CLI e Airflow)

  • publish (CD — só em push na main, nunca em PR, só depois que os outros quatro jobs passarem): publica as duas imagens no GHCR (ghcr.io/bottinolucas/govhub-lakehouse-{cli,airflow}), usando o GITHUB_TOKEN nativo — nenhum secret extra a configurar.

  • publish-pypi (CD — só em tag v*, ex: v0.1.0, nunca em push simples): publica o wheel/sdist no PyPI via Trusted Publishing (OIDC — sem token pra guardar). Precisa de um passo manual único, feito uma vez no site do PyPI, antes do primeiro release:

    1. Acesse https://pypi.org/manage/account/publishing/ (logado na conta que vai ser dona do pacote)
    2. Em "Add a new pending publisher", preencha:
      • PyPI project name: govhub-lakehouse (ou o nome que preferir — precisa bater com o name em pyproject.toml)
      • Owner: bottinolucas
      • Repository name: govhub-data-lakehouse
      • Workflow name: ci.yml
      • Environment name: pypi
    3. Pra liberar: git tag v0.1.0 && git push origin v0.1.0 (a versão da tag deve bater com version em pyproject.toml — PyPI rejeita reenviar uma versão já publicada).

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

govhub_lakehouse-0.1.0.tar.gz (18.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

govhub_lakehouse-0.1.0-py3-none-any.whl (38.4 kB view details)

Uploaded Python 3

File details

Details for the file govhub_lakehouse-0.1.0.tar.gz.

File metadata

  • Download URL: govhub_lakehouse-0.1.0.tar.gz
  • Upload date:
  • Size: 18.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for govhub_lakehouse-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f69242caecab50b576451f066da292fcee587ad5708bc74fbc75e0d361c1159e
MD5 7b21ebad0c15100a29312fbf6b19783a
BLAKE2b-256 0ebfe7e899a6ce32c5de3a9acfe3fc63bf04dbc62789313dfda15b5b724a9afd

See more details on using hashes here.

Provenance

The following attestation bundles were made for govhub_lakehouse-0.1.0.tar.gz:

Publisher: ci.yml on bottinolucas/govhub-data-lakehouse

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file govhub_lakehouse-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for govhub_lakehouse-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e494df6c48aac04bb031ff3e632d1469cda194cd55a39b6e55f1c93d844abb45
MD5 e98fdb65e0652d2e8ccbda472e2dc7a2
BLAKE2b-256 a3cd0fe930ce26c3552bebb4817ca4327a5eece176b2c2b7a346b6a0a2f4cc16

See more details on using hashes here.

Provenance

The following attestation bundles were made for govhub_lakehouse-0.1.0-py3-none-any.whl:

Publisher: ci.yml on bottinolucas/govhub-data-lakehouse

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page