Quickstart
This guide walks you through creating a Spade block in Go. By the end you will have a working block that reads a raster file, applies a resolution parameter, and writes the result.
Prerequisites🔗
- Go 1.25 or later
- The Spade CLI installed (Installation guide)
Step 1: Create a block collection🔗
mkdir raster-tools && cd raster-tools
spade init --language goThis scaffolds the project:
raster-tools/
go.mod
main.go
blocks/Add the Spade library:
go get github.com/spade-dev/spadeStep 2: Add a block🔗
spade add reprojectThis creates:
blocks/reproject.yaml-- the block manifestreproject.go-- the handler entrypoint
Step 3: Define the manifest🔗
Edit blocks/reproject.yaml:
id: raster-tools.reproject
version: 0.1.0
kind: standard
network: false
description: Reprojects a raster to a target resolution
inputs:
source:
type: file
format: GeoTIFF
resolution:
type: number
outputs:
raster:
type: file
format: GeoTIFFStep 4: Write the handler🔗
Edit reproject.go:
package main
import (
"fmt"
"os/exec"
spade "github.com/spade-dev/spade"
)
func main() {
spade.Run(reproject)
}
func reproject(args *spade.Args) (*spade.RasterFile, error) {
source, err := spade.Input[*spade.RasterFile](args, "source")
if err != nil {
return nil, err
}
resolution, err := spade.Param[float64](args, "resolution")
if err != nil {
return nil, err
}
outputPath := "reprojected.tif"
cmd := exec.Command("gdalwarp",
"-tr", fmt.Sprintf("%f", resolution), fmt.Sprintf("%f", resolution),
source.Path, outputPath,
)
if err := cmd.Run(); err != nil {
return nil, fmt.Errorf("gdalwarp failed: %w", err)
}
result := spade.NewRasterFile(outputPath)
return &result, nil
}Key concepts:
spade.Run[O IntoOutput](handler)is the generic entry point. The type parameterOis the handler's return type. The library infers it from your handler's signature.spade.Input[T](args, name)retrieves a typed file input by name.Tmust be a pointer to a type implementingFromInput.spade.Param[T](args, name)retrieves a typed scalar parameter fromparams.yaml.- The handler receives an
*Argsstruct and returns(O, error).
Step 5: Validate and install🔗
spade check
spade install file://.Step 6: Use in a pipeline🔗
blocks:
- id: "@reproject"
name: raster-tools.reproject
inputs: []
args:
resolution: 10No-output handlers🔗
If your block performs a side effect without producing output, use RunNoOutput:
func main() {
spade.RunNoOutput(validate)
}
func validate(args *spade.Args) error {
source, err := spade.Input[*spade.RasterFile](args, "source")
if err != nil {
return err
}
fmt.Printf("Validated: %s\n", source.Path)
return nil
}Next steps🔗
- Types -- all available Spade types
- Handler Functions -- handler patterns and multiple outputs
- Manifest Generation -- generating manifests with the builder API
- Examples -- complete worked examples