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).

Metadata

Release files for govhub-lakehouse 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for govhub-lakehouse 0.1.0
File Size Uploaded Provenance Actions
govhub_lakehouse-0.1.0.tar.gz 18.3 kB With provenance Details for govhub_lakehouse-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for govhub-lakehouse 0.1.0
File Interpreter ABI Platform Actions
govhub_lakehouse-0.1.0-py3-none-any.whl Python 3 none any Details for govhub_lakehouse-0.1.0-py3-none-any.whl

Total release size: 56.8 kB

Release files / govhub_lakehouse-0.1.0.tar.gz

Download URL govhub_lakehouse-0.1.0.tar.gz
Size 18.3 kB
Tags Source
SHA-256 checksum
How to use checksums
f69242caecab50b576451f066da292fcee587ad5708bc74fbc75e0d361c1159e
BLAKE2b-256 checksum
How to use checksums
0ebfe7e899a6ce32c5de3a9acfe3fc63bf04dbc62789313dfda15b5b724a9afd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 26, 2026.

Transparency log

Release files / govhub_lakehouse-0.1.0-py3-none-any.whl

Download URL govhub_lakehouse-0.1.0-py3-none-any.whl
Size 38.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e494df6c48aac04bb031ff3e632d1469cda194cd55a39b6e55f1c93d844abb45
BLAKE2b-256 checksum
How to use checksums
a3cd0fe930ce26c3552bebb4817ca4327a5eece176b2c2b7a346b6a0a2f4cc16
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 26, 2026.

Transparency log

Security for govhub-lakehouse 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for govhub_lakehouse-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 26, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

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