Victor Pasqualini
Todos os projetos

O problema

Pipeline batch tem sempre a mesma forma (ler, transformar, validar, escrever) e mesmo assim cada um é reescrito em código. Responder "o que esse job faz?" vira ler um diff de PySpark, e essa resposta não dá para versionar como contrato, lintar, gerar nem desenhar.

O pipeline é o documento

Um pipeline é um contrato JSON, executado pelo framework e interpretado por mais ninguém. Roda como está pelo Python ou pela CLI, e o mesmo arquivo abre no canvas do Studio como nós conectados.

Um pipeline inteiro: input, transformações, validações, output
{
  "name": "customers_curated",
  "input": { "format": "csv", "path": "/data/landing/customers" },
  "transformations": [
    { "type": "filter", "condition": "status = 'active'" },
    { "type": "cast", "columns": { "created_at": "timestamp" } },
    { "type": "drop_duplicates", "columns": ["id"] }
  ],
  "validations": {
    "on_failure": "warn",
    "rules": [
      { "type": "not_null", "columns": ["id"] },
      { "type": "unique", "columns": ["id"] }
    ],
    "report": { "format": "csv", "path": "/dq/customers", "mode": "append" }
  },
  "output": {
    "format": "parquet",
    "path": "/data/curated/customers",
    "mode": "overwrite",
    "partition_by": ["created_at"]
  }
}
Sparquet Studio: cada template é um pipeline que roda, e compila para esse mesmo JSON

Declarativo onde costuma virar imperativo

As partes em que todo mundo volta para o código têm forma declarativa: parâmetros {param} resolvidos antes do parse, variáveis de runtime {{var}} que empurram um conjunto de chaves coletado para a leitura seguinte como um IN (...) literal (a versão declarativa do truque collect() + isin() que faz o data skipping do Delta funcionar), fragmentos reutilizáveis via $include, e vários destinos numa passada só.

Pushdown de runtime: coleta as chaves e pula dados na leitura seguinte
{ "type": "checkpoint" },
{ "type": "collect", "column": "id_cliente", "as": "clientes_ativos" },
{ "type": "join",
  "input": { "format": "delta", "path": "vendas.bronze_eventos_cliente" },
  "with_transformations": [
    { "type": "filter", "condition": "id_cliente IN ({{clientes_ativos}})" },
    { "type": "distinct" }
  ],
  "on": "id_cliente", "how": "left" }

Duas metades, um contrato

O Studio é um canvas no navegador que lê e escreve exatamente esses documentos: linta enquanto você digita, gera um pipeline com o LLM que você escolher, e executa por um runner local preso em 127.0.0.1: sem conta, sem servidor, sem telemetria. Ele nunca inventa sintaxe que o framework não suporta, e o framework nunca precisa dele para rodar.

Qualidade de dados segue a mesma ideia: é o sparquet-cola, biblioteca separada, declarada como dependência e reexportada em sparquet.validation.*.

Roda pelo Python, ou pela linha de comando
from sparquet import Sparquet

fw = Sparquet(spark={"app_name": "MyJob", "master": "local[*]"})
result = fw.run("pipeline.json", params={"dt_ref": "2026-01-01"})
print(result.summary())
fw.stop()

# or, without writing any Python at all:
# $ sparquet pipeline.json
O canvas edita o contrato; o inspector explica o node selecionado

Onde roda

  • Local, Databricks, EMR, Dataproc ou Synapse: o session manager detecta o ambiente
  • Python 3.9 a 3.14, sobre PySpark 3.4+
  • Extensível: registre seus próprios readers, writers, transformações e validadores
  • Documentado no sparquet.dev em inglês, português e espanhol
Próximo projetoSparquet Cola

Qualidade de dados para Spark como biblioteca, não mais um serviço para operar.