What are we doing
- A read‑only job that accepts optional filters like Site, Status, Platform
- Prints total count of devices based on the filter
Prerequisites
Refer “Hello Netbox” in Automation article for setting up the environment to access netbox from Netpicker
The Job
In the Netpicker UI, go to Automation → Jobs, create a new job (e.g., netbox_filter_demo), paste the code below, and Save.
from comfy.automate import job
@job()
def netbox_filter_demo(netbox, site=None, status=None, platform=None, preview=25):
if netbox is None:
raise RuntimeError("NetBox integration not available. Check NETBOX_API/NETBOX_TOKEN.")
# Clean params (UI sends "" for blanks)
site = site.strip() if isinstance(site, str) and site.strip() else None
status = status.strip() if isinstance(status, str) and status.strip() else None
platform = platform.strip() if isinstance(platform, str) and platform.strip() else None
try:
preview = int(preview) if str(preview).strip() else 25
except Exception:
preview = 25
# Build filters
filters = {}
if site:
filters["site_id" if site.isdigit() else "site"] = int(site) if site.isdigit() else site
if status:
filters["status"] = status
if platform:
# ID -> platform_id; else try to resolve slug/name to ID; fallback to slug
if platform.isdigit():
filters["platform_id"] = int(platform)
else:
p = netbox.dcim.platforms.get(slug=platform) or netbox.dcim.platforms.get(name=platform)
if p:
filters["platform_id"] = p.id
else:
filters["platform"] = platform # last-resort slug
# Handling based on presence of filters
try:
records = netbox.dcim.devices.filter(**filters) if filters else netbox.dcim.devices.all()
except Exception as e:
print(f"ERROR: NetBox query failed while applying filters={filters}: {e}")
return
names = []
for d in records:
n = getattr(d, "name", None) or getattr(d, "display", None) or getattr(d, "id", None)
if n:
names.append(str(n))
names.sort(key=str.lower)
shown = min(preview, len(names))
if not names:
print("NO DEVICES: No devices matched the provided filter or could be retrieved"
+ (f" | filters: {filters}" if filters else ""))
elif shown:
print("PREVIEW:", ", ".join(names[:shown]))
print(f"Total devices: {len(names)} (showing {shown})" + (f" | filters: {filters}" if filters else ""))
Lists NetBox devices with optional filters (site, status, platform) and prints a capped “preview” plus totals.
Inputs (all optional except netbox
)
netbox
: Initialized NetBox client.site
: Site ID or slug/name. (Blank strings are treated asNone
.)status
: Device status string (e.g.,active
,staged
).platform
: Platform ID, or resolve by slug/name; falls back to using the slug if not resolvable.preview
: Max devices to show in the preview output (default25
).
Output
- Collects device names (
name
→display
→id
), sorts case-insensitively. - Prints:
PREVIEW: name1, name2, ...
(up topreview
items)Total devices: N (showing M) | filters: {...}
- If nothing matched: prints a clear
NO DEVICES
message (with filters if used).
Typical use
- Show all devices: call with just
netbox
. - Filter by site slug:
site="dc1"
. - Filter by platform:
platform="cisco-ios"
orplatform="12"
(ID). - Increase preview:
preview=100
.
Screenshots from the lab setup
Have created a job based on the above code. (Automation -> Create Job -> Python Job)
Select any device (Needed to execute the runner, no action performed on the device)
Set params (optional):
- site -> e.g., 24
- status -> e.g., active

Run and View the Logs:

Data on Netbox:
