Skip to content

Function Blocks

A function block is a versioned, reusable unit of execution that does one thing: read a config, push a template, collect interface counters, discover devices. Developers write them in Python using the Worker SDK. The workflow engine registers them, resolves them by version, and orchestrates their execution.

What the Engine Knows

When a function block is registered with the engine, it receives:

Property Purpose
package / name / version Identity (e.g., fb.neops.io/ping:1.0.0)
parameterJsonSchema JSON Schema for input validation
resultDataJsonSchema JSON Schema for output validation
runOn Entity type this FB operates on (device, group, interface)
fbType Category: facts, configure, check, execute, none
isPure No side effects -- safe to discard without consequences
isIdempotent Same input produces same output -- safe to re-run

The engine uses this metadata to:

  1. Validate workflow definitions at deployment time (does the referenced FB exist? Are parameters compatible with the schema?)
  2. Resolve version ranges at execution time (find the best matching version)
  3. Determine transaction safety (can this workflow be retried? Is the failure safe?)
  4. Classify failures -- if all executed steps were pure, the failure is FAILED_SAFE

Pure and Idempotent

These two properties are the foundation of the engine's transaction model. Pure means no side effects (read-only). Idempotent means safe to re-run (same input → same result). The engine uses these flags to classify failures and (when implemented) determine retry eligibility.

For the full explanation, decision trees, and best practices, see Types & Safety Semantics.

Why this matters for network automation

In traditional scripting, a failed automation run leaves you wondering: did it apply the config to some devices but not others? Do I need to undo anything? The pure/idempotent model eliminates this ambiguity. The engine tracks exactly what ran, and the safety properties tell you precisely what state you are in.

Function Block Types

The fbType categorizes function blocks for UI organization and filtering:

Type Description Typically pure?
facts Collect data from devices (show commands, SNMP) Yes
configure Push configuration to devices No (but often idempotent)
check Validate compliance or state Yes
execute General-purpose execution Depends
none Utility (data transformation, reporting) Usually yes

Lifecycle in the Engine

  1. Registration -- Workers register their function blocks on startup. The engine stores the metadata and JSON schemas.
  2. Resolution -- When a workflow references fb.neops.io/ping:1, the engine finds the latest 1.x.x version.
  3. Acquire -- The engine creates ACQUIRE jobs on the blackboard. Workers pick them up and run the function block's acquire() method to determine what additional entity data is needed.
  4. Execution -- The engine creates EXECUTE jobs on the blackboard. Workers pick them up and run the function block's run() method.
  5. Result -- The worker pushes the result (success/failure, data, DB updates) back to the blackboard.

Writing function blocks

This page describes function blocks from the engine's perspective. To learn how to implement run(), acquire(), and rollback() in Python, see the Worker SDK's Anatomy of a Function Block.