neops-worker-sdk-py
Python SDK for building network automation function blocks for the neops 2.0 platform. Write small, typed Python units that the workflow engine orchestrates, schedules, and scales.
@register_function_block(Registration(name="show_version", run_on="device", ...))
class ShowVersion(FunctionBlock[ShowVersionParams, ShowVersionResult]):
async def run(self, params, context):
async with ConnectionProxy.connect(context.device) as conn:
output = await conn.send_command("show version")
return FunctionBlockResult(success=True, data=ShowVersionResult(output=output))
Prerequisites
- Python 3.12+
- uv (recommended) or pip
- A running neops-workflow-engine instance (default: http://localhost:3030)
Quick Start
uv sync --group dev --extra test # install all dependencies
cp .env.example .env # configure URL_BLACKBOARD, DIR_FUNCTION_BLOCKS
uv run neops_worker # start worker (polls engine for jobs)
uv run pytest -x -q && uv run ruff format --check neops_worker_sdk && uv run ruff check neops_worker_sdk && uv run pyrefly check # verify
Architecture
Your Function Blocks (@register_function_block)
|
v
Registry (global singleton, discovers FBs from DIR_FUNCTION_BLOCKS dirs)
|
v
Worker Startup
|- Register worker with engine (POST /workers/register -> UUID)
|- Register function blocks (POST /function-blocks/register for each)
|- Start heartbeat task (POST /workers/:uuid/ping every 20s)
\- Start job polling task (POST /blackboard/job every 10s)
|
v
ThreadPoolExecutor (max_workers=1)
|
v
FunctionBlock.acquire() / run() / rollback()
|
v
ConnectionProxy -> ConnectionPlugin -> BaseConnection
| |
v v
WorkflowContext (snapshot + diff) Device (netmiko/napalm/scrapli/ncclient)
|
v
Push result to engine (POST /blackboard/job/result)
Development
Install
uv sync # production deps only
uv sync --group dev # + dev tools (ruff, pyrefly)
uv sync --group dev --extra test # + test deps (pytest, remote-lab)
Run
uv run neops_worker # start worker process
python -m neops_worker_sdk.cli.neops_worker # alternative
Code Quality
uv run ruff format --check neops_worker_sdk examples tests # format check
uv run ruff check neops_worker_sdk examples tests # lint
uv run ruff check --fix neops_worker_sdk examples tests # lint + auto-fix
uv run pyrefly check # type check
make lint # format + lint combined
Testing
Tests are organized in tiers using pytest markers. By default, remote lab tests are excluded.
| Command | What runs |
|---|---|
uv run pytest |
Unit + SDK tests (default) |
uv run pytest -m function_block |
Function block integration tests |
uv run pytest -m remote_lab |
Remote lab tests (needs REMOTE_LAB_URL) |
make test |
Unit tests (uv run pytest -q) |
make test-examples |
Example function block tests |
make test-function-blocks |
Function block + remote lab tests |
make test-all |
Everything |
| Marker | Applied by | Purpose |
|---|---|---|
function_block |
@fb_test_case |
Local function block lifecycle tests |
remote_lab |
@fb_test_case_with_lab |
Tests requiring a provisioned lab topology |
examples |
Auto (conftest.py) | All tests collected from examples/ |
sdk |
– | SDK internal tests |
Configuration
Environment variables loaded via python-dotenv from .env. See .env.example for all options.
| Variable | Default | Purpose |
|---|---|---|
URL_BLACKBOARD |
(required) | Workflow engine base URL |
DIR_FUNCTION_BLOCKS |
(required) | Comma-separated dirs to scan for function blocks |
WORKER_NAME |
(none) | Human-readable worker name |
HEARTBEAT_INTERVAL |
20 |
Seconds between heartbeat pings |
POLL_INTERVAL |
10 |
Seconds between job poll requests |
SHUTDOWN_TIMEOUT |
60 |
Seconds to wait for running job on shutdown |
BLOCKING_DETECTION_THRESHOLD |
0.5 |
Seconds threshold for blocking warnings |
Docker
docker build -t neops-worker-sdk . # production image
docker run --env-file .env neops-worker-sdk # run worker
docker build --target linter -t neops-worker-sdk:lint . # lint stage
docker build --target test -t neops-worker-sdk:test . # test stage
Build stages: base (Python 3.12 + uv + deps), deps-dev (+ dev/test deps), linter (ruff + pyrefly), test (pytest), run-ci (combined results).
Project Structure
neops_worker_sdk/
cli/ Worker entry point, job processing loop
concurrency/ @run_in_thread, run_parallel, BlockingDetector
connection/ 3-tier device connection system
capabilities/ Abstract capability interfaces
plugins/ Platform-specific implementations (netmiko, napalm, scrapli, ncclient)
function_block/ FunctionBlock ABC, result types
logger/ Loguru-based structured logging
registry/ FB discovery, registration decorator, global registry
testing/ Test framework (@fb_test_case, context factories)
workflow/ WorkflowContext, entity wrappers, DB update diffing
worker/ Worker registration with engine
examples/ Example function blocks (getting-started, ping, use-cases)
tests/ Test suites and topologies
Contributing
Default branch: develop. Branch from develop for all changes. Run verification before committing: uv run pytest -x -q && uv run ruff format --check neops_worker_sdk && uv run ruff check neops_worker_sdk && uv run pyrefly check
See Also
- See AGENTS.md for AI agent context, conventions, and gotchas.
- .env.example – environment variable reference


