NetBox Filters in Netpicker (Site/Status/Platform)

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 as None.)
  • 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 (default 25).

Output

  • Collects device names (namedisplayid), sorts case-insensitively.
  • Prints:
    • PREVIEW: name1, name2, ... (up to preview 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" or platform="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: