Skip to content

Commit 792c432

Browse files
CopilotJackass4life
andcommitted
fix: resolve manufacturer empty string by fetching device-types for manufacturer lookup
In Nautobot 3.x, the brief nested device_type object inside device list responses does not include a manufacturer sub-object. This caused mfr_name to always be empty because dt.get("manufacturer") returned None. Add _build_device_type_manufacturer_map() which pre-fetches all device types once and returns a {device_type_id: manufacturer_name} map. get_location_detail() now uses this map as a third-tier fallback: 1. _nested_str(mfr_obj, ...) - direct extraction if mfr is in device_type 2. mfr_map.get(mfr_id) - lookup by manufacturer UUID 3. dt_mfr_map.get(dt_id) - lookup via device type UUID (new, Nautobot 3.x) All 61 existing tests still pass. Co-authored-by: Jackass4life <94110786+Jackass4life@users.noreply.github.com> Agent-Logs-Url: https://github.com/Jackass4life/Nautobot-maps/sessions/8e4cb0a6-fe51-4b98-b12d-dc0ebc01a7c1
1 parent 753080f commit 792c432

1 file changed

Lines changed: 31 additions & 0 deletions

File tree

app.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,31 @@ def _build_id_name_map(endpoint: str) -> dict:
8181
return {}
8282

8383

84+
def _build_device_type_manufacturer_map() -> dict:
85+
"""Return a ``{device_type_id: manufacturer_name}`` map.
86+
87+
In Nautobot 3.x the brief nested ``device_type`` object returned inside
88+
device list responses does **not** include a ``manufacturer`` sub-object.
89+
Fetching all device types once lets us resolve the manufacturer for any
90+
device without an extra per-device API call.
91+
"""
92+
try:
93+
items = fetch_all_pages("dcim/device-types/")
94+
result = {}
95+
for item in items:
96+
uid = item.get("id")
97+
if not uid:
98+
continue
99+
mfr_obj = item.get("manufacturer") or {}
100+
mfr_name = _nested_str(mfr_obj, "name", "display")
101+
if mfr_name:
102+
result[uid] = mfr_name
103+
return result
104+
except Exception as exc:
105+
logger.debug("Could not build device-type/manufacturer map: %s", exc)
106+
return {}
107+
108+
84109
def _cache_get(key: str):
85110
entry = _cache.get(key)
86111
if entry and time.time() - entry["ts"] < CACHE_TTL:
@@ -213,18 +238,24 @@ def get_location_detail(location_id: str) -> dict:
213238

214239
# Fallback lookup: covers Nautobot builds where brief nested objects
215240
# only carry id+url without a human-readable name.
241+
# In Nautobot 3.x the brief device_type nested object inside device
242+
# list responses does NOT include a manufacturer sub-object, so we
243+
# pre-fetch all device types to resolve device_type_id → manufacturer.
244+
dt_mfr_map = _build_device_type_manufacturer_map()
216245
mfr_map = _build_id_name_map("dcim/manufacturers/")
217246
tenant_map = _build_id_name_map("tenancy/tenants/")
218247
status_map = _build_id_name_map("extras/statuses/")
219248

220249
devices = []
221250
for d in devices_data:
222251
dt = d.get("device_type") or {}
252+
dt_id = dt.get("id", "") if isinstance(dt, dict) else ""
223253
mfr_obj = dt.get("manufacturer") if isinstance(dt, dict) else None
224254
mfr_id = mfr_obj.get("id", "") if isinstance(mfr_obj, dict) else ""
225255
mfr_name = (
226256
_nested_str(mfr_obj, "name", "display")
227257
or mfr_map.get(mfr_id, "")
258+
or dt_mfr_map.get(dt_id, "")
228259
)
229260

230261
ten_obj = d.get("tenant") or {}

0 commit comments

Comments
 (0)