Your First Block
In this guide, you'll create a custom block that reads a CSV file, computes basic summary statistics, and writes the results as JSON. This guide uses Python. If you prefer another language, see the guides for R, TypeScript, Go, and Rust.
Step 1: Create a block collection🔗
A collection is a repository of related blocks that share a language. Create one:
mkdir csv-stats && cd csv-stats
spade init --language pythonThis scaffolds a Python project:
csv-stats/
pyproject.toml # Python package configuration
src/
csv_stats/
__init__.py
blocks/ # Block manifests go hereStep 2: Add a block🔗
spade add summarizeThis creates two files:
blocks/summarize.yaml— The block manifest declaring inputs, outputs, and parameterssrc/csv_stats/summarize.py— The handler function you'll implement
Step 3: Define the block manifest🔗
Edit blocks/summarize.yaml to declare what your block accepts and produces:
id: csv-stats.summarize
version: 0.1.0
kind: standard
network: false
description: Computes summary statistics for a CSV file
inputs:
data:
type: file
format: CSV
description: The input CSV file to analyze
column:
type: string
description: Name of the column to summarize
outputs:
stats:
type: json
description: JSON file containing computed statisticsThis manifest tells Spade that the block:
- Accepts a CSV file input named
data - Accepts a string parameter named
column - Produces a JSON file output named
stats - Does not need network access
- Is a standard (non-map, non-reduce) block
Step 4: Implement the handler🔗
Edit src/csv_stats/summarize.py:
import csv
import json
from spade import run, TabularFile, JsonFile
def handler(data: TabularFile, column: str) -> JsonFile:
"""Compute summary statistics for a column in a CSV file."""
values = []
with open(data.path) as f:
reader = csv.DictReader(f)
for row in reader:
try:
values.append(float(row[column]))
except (ValueError, KeyError):
continue
if not values:
stats = {"error": f"No numeric values found in column '{column}'"}
else:
stats = {
"column": column,
"count": len(values),
"mean": sum(values) / len(values),
"min": min(values),
"max": max(values),
}
output_path = "outputs/stats/summary.json"
with open(output_path, "w") as f:
json.dump(stats, f, indent=2)
return JsonFile(path=output_path)
if __name__ == "__main__":
run(handler)Key points:
- The function signature declares the types.
data: TabularFiletells the Spade library to look for the input nameddataand load it as aTabularFile(which provides a.pathattribute).column: strcomes fromparams.yamlas a scalar parameter. - The return type
JsonFiletells Spade what kind of output to write. - The function writes results to
outputs/stats/— the output directory matching the manifest's output name. - The
run(handler)call at the bottom is the entry point. It handles loading inputs and parameters automatically.
Step 5: Validate🔗
Check that the manifest and source file are valid:
spade checkExpected output:
Collection 'csv-stats' (python) is valid.
1 block found: csv-stats.summarizeStep 6: Install locally🔗
Install the collection from the local directory:
spade install file://.This builds the Python package and registers the block in ~/.spade/blocks/csv-stats/0.1.0/.
Step 7: Use in a pipeline🔗
Now create a pipeline that uses your new block. Create test-pipeline.yaml:
name: csv-stats-test
version: "1.0"
description: Test the summarize block
blocks:
- id: "@summarize"
name: csv-stats.summarize
inputs: []
args:
column: temperatureNext steps🔗
- Your First Block (R) — the same walkthrough for R users
- Learn about block types and the manifest format in detail
- Explore library documentation for your preferred language
- Read the Building a Block tutorial for a comprehensive walkthrough