Discovery — the read catalogue

Discover and describe any readable Cisco ACI class — offline.

The read catalogue ships with the package: metadata for all ~15,300 readable ACI classes (not just the ~2,200 with generated models), opened lazily on first use. This module is the public door to it — search for a class by name or label, describe its properties/faults/subclasses, or find which class carries a given property — with no APIC connection required.

Nothing here runs at import niwaki; the catalogue loads only when you import niwaki.catalog and call one of these functions.

Example:

from niwaki import catalog

catalog.search("bridge domain")        # → ['fvBD', ...]  (ranked)
doc = catalog.describe("fvCEp")         # label, properties, faults, subclasses
for prop in doc.props:
    print(prop.readable, prop.kind)     # readable field names + coercion kinds
catalog.find_prop("mac")                # → [('fvCEp', 'mac'), ...]
catalog.concrete_subclasses("fvEPg")    # → every concrete EPG class
catalog.fault_name("F0467")             # → 'fltFvNwIssuesConfig-failed'

Functions

niwaki.catalog.search(term, *, limit=50)[source]

Class names whose wire name or GUI label matches term.

Ranked by the full-text index where the runtime’s sqlite provides it, or a (broader, unranked) substring scan otherwise.

Parameters:
  • term (str) – The text to match, e.g. "bridge domain".

  • limit (int) – Maximum number of class names to return.

Returns:

Matching wire class names.

Return type:

list[str]

niwaki.catalog.describe(class_name)[source]

Describe a class: its label, comment, properties, faults, and subclasses.

Parameters:

class_name (str) – The wire class name, e.g. "fvCEp".

Returns:

A ClassDocname, label, comment, is_abstract, is_observable (informational only — not a subscribability gate, see the field’s own docstring), a tuple of PropDoc, a {code: name} fault map, and (for an abstract class) its concrete subclasses.

Raises:

KeyError – No such class in the catalogue.

Return type:

ClassDoc

niwaki.catalog.prop_meta(class_name, name)[source]

Describe one property of a class, addressed by its readable or wire name.

Parameters:
  • class_name (str) – The wire class name, e.g. "fvBD".

  • name (str) – The property’s readable ("arp_flooding") or wire ("arpFlood") name.

Returns:

A PropDoc.

Raises:

KeyError – The class or property is unknown.

Return type:

PropDoc

niwaki.catalog.find_prop(term, *, limit=50)[source]

(class, wire property) pairs whose property name or label matches term.

Answers “which class carries a MAC?” — the complement to search().

Parameters:
  • term (str) – The property text to match, e.g. "mac".

  • limit (int) – Maximum number of pairs to return.

Returns:

(wire_class_name, wire_property_name) pairs.

Return type:

list[tuple[str, str]]

niwaki.catalog.concrete_subclasses(class_name)[source]

Every concrete descendant of a class, walked transitively.

The set an abstract-class query (e.g. aci.query("fvEPg")) fans out to.

Parameters:

class_name (str) – The (usually abstract) wire class name.

Returns:

Concrete descendant wire class names, sorted.

Return type:

list[str]

niwaki.catalog.class_meta(class_name)[source]

A class’s readable↔wire name maps and per-property coercion kinds.

Lower-level than describe(); the same metadata the result objects use to expose readable field names on non-generated classes. Also carries is_stat — whether the APIC can ever push for this class (a stats class, e.g. a granularity variant like eqptEgrBytes5min, never can).

Parameters:

class_name (str) – The wire class name.

Returns:

A ClassMeta.

Raises:

KeyError – No such class in the catalogue.

Return type:

ClassMeta

niwaki.catalog.fault_name(code)[source]

The rule name behind a fault code, e.g. "F0467""fltFvNwIssuesConfig-failed".

This is a global lookup — it does not require knowing which class raised the fault. That complements describe(), whose faults mapping is scoped to one class (the faults that class can raise): a ManagedObject read back from faultInst carries a code but not the class that raised it, so this is the function that turns it into a human-readable name.

Parameters:

code (str) – The fault code, e.g. "F0467".

Returns:

The fault’s rule name, or None if the code is not in the catalogue — this is expected for threshold-crossing alerts (tca-* rules), whose codes are minted at runtime from an operator’s statsThresholdPolicy rather than defined statically in the class schema.

Return type:

str | None

Example:

faults = aci.query("faultInst").fetch()
for f in faults:
    print(f["code"], catalog.fault_name(f["code"]))

Result types

class niwaki.catalog.ClassDoc(
name,
label,
comment,
is_abstract,
is_observable,
props,
faults,
concrete_subclasses,
)[source]

Bases: object

A class, as describe presents it: identity, properties, faults, kin.

is_observable

APIC schema metadata, informational only — do not treat this as a gate on whether the class can be subscribed to. Empirically falsified live: a class with is_observable=False (faultInst) was subscribed to successfully and delivered real push notifications. The flag that actually governs subscribability is isStat (see ClassMeta.is_stat).

Type:

bool

class niwaki.catalog.PropDoc(readable, wire, kind, is_naming, label, default, comment, enum_values)[source]

Bases: object

One property, as describe presents it.

class niwaki.catalog.ClassMeta(class_name, readable_to_wire, wire_to_readable, wire_to_kind, naming, is_stat)[source]

Bases: object

The read metadata for one ACI class, assembled once and memoised.

class_name

The wire class name (e.g. "fvCEp").

Type:

str

readable_to_wire

{python_name: wire_name} — the readable field names.

Type:

dict[str, str]

wire_to_readable

{wire_name: python_name} — the inverse.

Type:

dict[str, str]

wire_to_kind

{wire_name: FieldKind value | None} — how to coerce a wire value on read (None = read as a plain string).

Type:

dict[str, str | None]

naming

The wire names of the identifying properties.

Type:

frozenset[str]

is_stat

The class is a statistics class (a granularity variant of a stats family, e.g. eqptEgrBytes5min). Cisco’s own docs state stats updates bypass the APIC’s event manager entirely — architecturally incapable of ever pushing — so this is what gates StatsClassNotSubscribableError, not isObservable (see ClassDoc.is_observable).

Type:

bool