0

List Devices

by
Published today

List devices filtered by sites, roles, status, tags (slugs), exact name or custom fields ({tier: "edge"} becomes cf_tier=edge). Returns NetBox's count and one page of raw devices, including platform and custom_fields.

Script netbox Verified

The script

Submitted by hugo989 Python3
Verified 3 hours ago
1
# py312
2
# requirements:
3
# pynetbox==7.9.0
4

5

6
from typing import List, Literal, Optional, TypedDict
7

8
import pynetbox
9

10

11
class netbox(TypedDict):
12
    url: str
13
    token: str
14

15

16
DynMultiselect_site = List[str]
17
DynMultiselect_role = List[str]
18

19

20
def api(auth: netbox):
21
    # pynetbox adds /api itself; the resource URL may already end with it.
22
    return pynetbox.api(
23
        auth["url"].rstrip("/").removesuffix("/api"), token=auth["token"]
24
    )
25

26

27
def keep(**fields):
28
    # The run form sends "" / [] / {} for untouched fields: drop them.
29
    return {k: v for k, v in fields.items() if v not in (None, "", [], {})}
30

31

32
def page(records):
33
    # One page (limit/offset), as NetBox's count plus the raw records.
34
    results = [dict(r) for r in records]
35
    return {"count": len(records), "results": results}
36

37

38
def options(endpoint, key="id", **filters):
39
    return [
40
        {"value": str(getattr(r, key)), "label": r.display}
41
        for r in endpoint.filter(brief=1, limit=1000, offset=0, **filters)
42
    ]
43

44

45
# Dropdown of the instance's sites, by slug: the first 1000 (NetBox MAX_PAGE_SIZE); set the value by expression beyond that.
46
def site(auth: netbox):
47
    return options(api(auth).dcim.sites, "slug")
48

49

50
# Dropdown of the instance's device roles, by slug.
51
def role(auth: netbox):
52
    return options(api(auth).dcim.device_roles, "slug")
53

54

55
def main(
56
    auth: netbox,
57
    site: Optional[DynMultiselect_site] = None,
58
    role: Optional[DynMultiselect_role] = None,
59
    status: Optional[
60
        List[
61
            Literal[
62
                "offline",
63
                "active",
64
                "planned",
65
                "staged",
66
                "failed",
67
                "inventory",
68
                "decommissioning",
69
            ]
70
        ]
71
    ] = None,
72
    tag: Optional[List[str]] = None,
73
    name: Optional[str] = None,
74
    custom_field_filters: Optional[dict] = None,
75
    q: Optional[str] = None,
76
    limit: Optional[int] = None,
77
    offset: Optional[int] = None,
78
):
79
    """
80
    List Devices
81
    List devices filtered by sites, roles, status, tags (slugs), exact name or custom fields ({tier: "edge"} becomes cf_tier=edge). Returns NetBox's count and one page of raw devices, including platform and custom_fields.
82
    """
83
    cf = {
84
        k if k.startswith("cf_") else f"cf_{k}": v
85
        for k, v in (custom_field_filters or {}).items()
86
    }
87
    records = api(auth).dcim.devices.filter(
88
        **keep(site=site, role=role, status=status, tag=tag, name=name, q=q, **cf),
89
        # limit=0 means NetBox's MAX_PAGE_SIZE, which also caps an explicit 1000.
90
        limit=50 if limit is None else limit or 1000,
91
        offset=offset or 0,
92
    )
93
    return page(records)
94