Skip to content

krbundy/spadelib

Repository files navigation

spadelib

The Go library for authoring Spade blocks. Define a handler function, pass it to Run(), and the library handles parameter loading, input discovery, and output writing.

Installation

go get github.com/krbundy/spadelib
import "github.com/krbundy/spadelib"

The import path is the full module path, but the package identifier stays spadelib, so calls read spadelib.Run(...), spadelib.Input[...], and so on.

Quick Start

package main

import "github.com/krbundy/spadelib"

func handler(args *spadelib.Args) (spadelib.RasterFile, error) {
	source, err := spadelib.Input[spadelib.RasterFile](args, "source")
	if err != nil {
		return spadelib.RasterFile{}, err
	}
	resolution, err := spadelib.Param[float64](args, "resolution")
	if err != nil {
		return spadelib.RasterFile{}, err
	}
	// process source.Path at resolution...
	return spadelib.NewRasterFile("result.tif"), nil
}

func main() {
	spadelib.Run(handler)
}

Run():

  1. Loads scalar parameters from params.yaml
  2. Scans inputs/ for file-based arguments, matched by name
  3. Builds an *Args and calls your handler
  4. Writes the returned value to outputs/

On any error Run() prints it to stderr and exits non-zero.

Reading Arguments

A handler receives an *Args and pulls typed values out of it by name. Because Go generics can't be methods, use the package-level Input and Param functions:

source, err := spadelib.Input[spadelib.RasterFile](args, "source")  // file input
resolution, err := spadelib.Param[float64](args, "resolution")      // scalar

if args.HasInput("mask") {
	mask, err := spadelib.Input[spadelib.VectorFile](args, "mask")  // optional input
}

args.HasInput(name) and args.HasParam(name) test for optional arguments before reading.

Types

Construct file types with the New* helpers (e.g. spadelib.NewRasterFile("path.tif")); the location is on the Path field.

File Types

Type Description
File Generic single file
RasterFile Raster data (e.g., GeoTIFF)
VectorFile Vector data (e.g., GeoJSON)
TabularFile Tabular data (e.g., CSV)
JsonFile JSON data

Directory Type

Type Description
Directory Directory-based input (e.g., shapefiles)

Collection Types

Type Description
FileCollection Collection of files
RasterFileCollection Collection of raster files
VectorFileCollection Collection of vector files
TabularFileCollection Collection of tabular files

Each holds a Paths []string field.

Scalars

string, float64, int, bool, and the other basic types are read directly with spadelib.Param[T].

How Inputs Are Resolved

File-based inputs are discovered from subdirectories in inputs/, where each subdirectory name matches the name you pass to Input:

params.yaml              # scalar args: {resolution: 10, method: "nearest"}
inputs/
  reference/
    data.tif             # -> spadelib.Input[spadelib.RasterFile](args, "reference")
  target/
    data.tif             # -> spadelib.Input[spadelib.RasterFile](args, "target")

The target type determines how each input is constructed:

  • a File type expects a single file in the subdirectory
  • Directory uses the subdirectory path itself
  • a *Collection type gathers all files in the subdirectory

Output Handling

Return a typed value and Run() writes it to outputs/:

func handler(args *spadelib.Args) (spadelib.RasterFile, error) {
	return spadelib.NewRasterFile("result.tif"), nil
}

For multiple named outputs, return an *Outputs:

func handler(args *spadelib.Args) (*spadelib.Outputs, error) {
	out := spadelib.NewOutputs()
	out.Add("raster", spadelib.NewRasterFile("result.tif"))
	out.Add("stats", spadelib.NewJsonFile("stats.json"))
	return out, nil
}

For a handler that produces no output, use spadelib.RunNoOutput, whose handler returns just an error.

Secrets

Named secrets provisioned to the block are read with GetSecret():

token, err := spadelib.GetSecret("api_token")

Run() scrubs the secrets from the environment before your handler runs.

Building a Manifest

Describe a block's inputs and outputs with the manifest builder:

b := spadelib.NewManifestBuilder().Description("Resample a raster.")
spadelib.ManifestInput[spadelib.RasterFile](b, "source")
spadelib.ManifestOutput[spadelib.RasterFile](b, "raster")
manifest := b.Build()

Testing

go test ./...

Learn More

See the Spade homepage for the full system documentation, the block specification, and the other language runtimes (Python, Rust, TypeScript, and R).

About

The Go library for the Spade System

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages