Input References
When a block needs data from an upstream block, you list the upstream block's invocation ID in the inputs field. Spade supports two reference styles: bare references and explicit references. You can mix both styles in the same inputs list.
Bare references🔗
A bare reference is the simplest form. You provide only the invocation ID of the upstream block:
inputs:
- "@upstream"When Spade encounters a bare reference, it uses type matching to determine which output from the upstream block connects to which input on the current block. This works well when the connection is unambiguous -- for example, when the upstream block produces a single raster output and the current block expects a single raster input.
Example: unambiguous bare reference🔗
Consider two blocks:
data.sentinel2produces one output:image(type:file, format:GeoTIFF)raster.reprojectexpects one file input:raster(type:file, format:GeoTIFF)
The pipeline:
blocks:
- id: "@source"
name: data.sentinel2
inputs: []
args:
region: "POLYGON((-122.5 37.5, -122.0 37.5, -122.0 38.0, -122.5 38.0, -122.5 37.5))"
- id: "@reproject"
name: raster.reproject
inputs:
- "@source"
args:
target_crs: "EPSG:4326"Spade sees that data.sentinel2 produces a GeoTIFF output and raster.reproject expects a GeoTIFF input. There is exactly one way to match them, so the bare reference is sufficient.
Explicit references🔗
An explicit reference is an object with up to three keys:
| Key | Required | Description |
|---|---|---|
block | Yes | The invocation ID of the upstream block |
output | Yes | The name of the specific output to use |
as | No | The name of the input on the downstream block to connect to. If omitted, Spade type-matches the named output against the current block's remaining unmatched inputs. |
inputs:
- block: "@classify"
output: classified_rasterExplicit references are necessary when a bare reference would be ambiguous. This happens when the upstream block produces multiple outputs of the same type, or when there are multiple upstream blocks whose outputs could match the same input.
as is necessary on top of block+output in a further, more specific case: when two or more explicit references in the same inputs list target outputs that share a type, and the current block has two or more unmatched inputs of that same type. Naming the output alone doesn't tell Spade which of those same-typed inputs to wire it to -- see the raster.band-ratio example below.
Example: explicit reference needed🔗
Consider a block called raster.split-bands that produces two outputs:
red(type:file, format:GeoTIFF)nir(type:file, format:GeoTIFF)
And a downstream block raster.band-ratio that expects two inputs:
numerator(type:file, format:GeoTIFF)denominator(type:file, format:GeoTIFF)
Using bare references here would be ambiguous -- Spade cannot determine which output (red or nir) maps to which input (numerator or denominator). Naming the output with block+output alone is not enough either: both numerator and denominator are GeoTIFF, so after fixing nir and red as the two outputs, there would still be two equally valid ways to pair them with the two remaining GeoTIFF inputs. You need as to pin each one directly:
blocks:
- id: "@split"
name: raster.split-bands
inputs:
- "@source"
args:
red_band: 4
nir_band: 8
- id: "@ratio"
name: raster.band-ratio
inputs:
- block: "@split"
output: nir
as: numerator
- block: "@split"
output: red
as: denominator
args: {}Here, as wires the nir output directly to the numerator input and the red output directly to the denominator input -- no type matching is needed for either reference, so there's no ambiguity to resolve.
Mixed references🔗
You can combine bare and explicit references in the same inputs list. This is useful when some connections are unambiguous and others are not.
blocks:
- id: "@combine"
name: analysis.combine
inputs:
# Bare reference: the upstream block has one output that
# matches one of this block's inputs by type.
- "@imagery"
# Explicit reference: this upstream block has multiple
# outputs, so we name the specific one we want.
- block: "@stats"
output: summary_statsSpade resolves explicit references first, then resolves the remaining bare references against the unmatched inputs.
Type-matching algorithm🔗
When Spade processes a block's inputs list, it runs the following algorithm to wire upstream outputs to the current block's declared inputs:
Step 1: Gather declared inputs. Read the current block's manifest to find all declared inputs and their types. Separate file-type inputs (which come from upstream blocks) from scalar inputs (which come from args).
Step 2: Resolve explicit references. For each explicit reference in the inputs list:
- Look up the upstream block invocation by its
blockID. - Look up the named
outputin that upstream block's manifest. - If the reference has an
askey, wire the output directly to the named input and mark both as resolved -- skip to the next reference. No type matching needed. - Otherwise, find the declared input on the current block whose type is compatible with the output's type.
- If exactly one input matches, wire them together and mark both the output and the input as resolved.
- If no input matches, report a type-mismatch error.
- If multiple inputs match, report an ambiguity error and suggest adding
asto pin the target input explicitly.
Step 3: Resolve bare references. For each bare reference in the inputs list:
- Look up the upstream block invocation by its ID.
- Collect all of that block's outputs that have not yet been resolved.
- For each unresolved output, find all unresolved inputs on the current block with a compatible type.
- If there is exactly one way to pair all unresolved outputs to unresolved inputs, wire them and mark them as resolved.
- If multiple pairings are possible, report an ambiguity error and suggest using explicit references.
- If an output has no compatible unresolved input, report a type-mismatch error.
Step 4: Verify completeness. After resolving all references, check that every required file-type input on the current block has been wired to an upstream output. If any required input remains unwired, report a missing-input error.
Walkthrough: unambiguous resolution🔗
Suppose Block A produces:
image(type:file, format:GeoTIFF)
And Block B expects:
raster(type:file, format:GeoTIFF)threshold(type:number, from args)
Block B's pipeline entry:
- id: "@classify"
name: raster.classify
inputs:
- "@source"
args:
threshold: 0.5Resolution proceeds as:
- Declared file-type inputs:
raster(GeoTIFF). Scalar inputs:threshold(from args). - No explicit references.
- Bare reference to Block A. Block A has one unresolved output:
image(GeoTIFF). Block B has one unresolved file-type input:raster(GeoTIFF). Types are compatible. Exactly one pairing exists. Wireimagetoraster. - All required inputs are satisfied.
Walkthrough: ambiguous resolution🔗
Suppose Block A produces:
red(type:file, format:GeoTIFF)nir(type:file, format:GeoTIFF)
And Block B expects:
band_a(type:file, format:GeoTIFF)band_b(type:file, format:GeoTIFF)
Block B's pipeline entry using bare references:
- id: "@difference"
name: raster.difference
inputs:
- "@split"
args: {}Resolution proceeds as:
- Declared file-type inputs:
band_a(GeoTIFF),band_b(GeoTIFF). - No explicit references.
- Bare reference to Block A. Unresolved outputs:
red(GeoTIFF),nir(GeoTIFF). Unresolved inputs:band_a(GeoTIFF),band_b(GeoTIFF). Both outputs are compatible with both inputs. Two possible pairings exist: (red->band_a,nir->band_b) or (red->band_b,nir->band_a). - Ambiguity error. Spade reports the conflict and suggests using explicit references.
The fix is to use explicit references:
- id: "@difference"
name: raster.difference
inputs:
- block: "@split"
output: nir
- block: "@split"
output: red
args: {}When to use each style🔗
| Situation | Recommended style |
|---|---|
| Upstream block has one output and downstream block has one matching input | Bare reference |
| Upstream block has multiple outputs of different types | Bare reference (types are still distinguishable) |
| Upstream block has multiple outputs of the same type | Explicit reference |
| Multiple upstream blocks produce outputs of the same type for a multi-input block | Explicit reference |
| You want maximum clarity regardless of ambiguity | Explicit reference |
As a general rule: start with bare references for simplicity. If spade check reports an ambiguity error, switch to explicit references for the affected connections.