LOPs - PY - collect all primvars & usd attrs

import re
import hou
from pxr import Usd, Sdf, UsdGeom, Vt

node = hou.pwd()
stage = node.editableStage()

if stage is None:
raise RuntimeError("USD stage is not available on this node.")

wildcard_pattern = node.parm("collect_primpath").eval()
regex_pattern = "^" + re.sub(r"(\*|\?)", lambda m: ".*" if m.group(0) == "*" else ".", wildcard_pattern) + "
quot;
regex = re.compile(regex_pattern)

matching_primvars = []
matching_usdattrs = []

# Collect all prims first
all_prims = []
def collect_prims(prim):
all_prims.append(prim)
for child in prim.GetChildren():
collect_prims(child)

root = stage.GetPseudoRoot()
collect_prims(root)

# Filter prims that match wildcard, collect attributes only on those prims (no recursion)
for prim in all_prims:
path_str = str(prim.GetPath())
if regex.match(path_str):
# Collect primvars
primvars_api = UsdGeom.PrimvarsAPI(prim)
for pv in primvars_api.GetPrimvars():
matching_primvars.append(pv.GetName())

# Collect USD attributes except primvars
for attr in prim.GetAttributes():
attr_name = attr.GetName()
if attr_name.startswith("primvars:"):
continue
matching_usdattrs.append(attr_name)

# Deduplicate and sort
matching_primvars = sorted(set(matching_primvars))
matching_usdattrs = sorted(set(matching_usdattrs))

metadata_prim_path = Sdf.Path("/metadata")
metadata_prim = stage.GetPrimAtPath(metadata_prim_path)
if not metadata_prim:
metadata_prim = stage.DefinePrim(metadata_prim_path, "")

primvars_vt = Vt.StringArray(matching_primvars)
usdattrs_vt = Vt.StringArray(matching_usdattrs)

metadata_prim.SetCustomDataByKey("primvars_list", primvars_vt)
metadata_prim.SetCustomDataByKey("usdattrs_list", usdattrs_vt)

#print(f"Stored {len(matching_primvars)} primvars and {len(matching_usdattrs)} usd attributes on matching prims")