Creating Getter Parsers¶
Getter parsers provide normalized, platform-independent output for a logical
data type such as inventory, interfaces, LLDP neighbors, BGP neighbors, or
VLANs. A getter is a wrapper under ttp_templates/get/ that extends one or
more platform templates under ttp_templates/platform/.
Files Involved¶
For a new getter or a new platform implementation of an existing getter, expect to touch these files:
| File or folder | Purpose |
|---|---|
ttp_templates/get/<getter>.txt |
Getter wrapper with <extend> entries |
ttp_templates/platform/<platform>_<command>.txt |
Platform command parser |
ttp_templates/utils/<platform>_process_<command>.py |
Optional normalizer utility |
ttp_templates/utils/models.py |
Pydantic model for normalized records |
test/platform/<platform>/<command_slug>/ |
Raw mock output and expected YAML |
docs/getters_support_matrix.md |
Getter platform support matrix |
Do not manually create or edit generated reference pages under
docs/ttp_templates/. Those pages are generated from template <doc> blocks.
Output Contract¶
Define the normalized record shape before writing the parser. Getter output should be a list of dictionaries with stable keys and predictable types.
For example, the vlans getter returns:
- vid: 100
name: USERS
description: null
Add a Pydantic model in ttp_templates/utils/models.py for each normalized
record type:
class VlanRecord(BaseModel):
vid: StrictInt
name: StrictStr
description: Union[None, StrictStr]
Validate final records in the utility before returning them:
records.append(VlanRecord(**record).model_dump())
Platform Template¶
Platform templates live under ttp_templates/platform/ and use this naming
rule:
<platform>_<command_with_underscores>.txt
Replace spaces and hyphens with _, and replace | with pipe.
Examples:
ttp_templates/platform/cisco_ios_show_running_config_pipe_section_vlan.txt
ttp_templates/platform/juniper_junos_show_configuration_vlans_pipe_display_set.txt
Each platform template should include:
- A
<template name="...">wrapper. - A
<doc>block that names the command and output shape. - An
<input>block with command and platform aliases. - TTP
<group>statements to capture raw values. - A small
<macro>wrapper when Python normalization is needed. - An
<output macro="..."/>tag when a macro is used.
Keep Python inside <macro> minimal. Put parsing cleanup, range expansion,
JSON walking, default values, and validation in ttp_templates/utils/.
Utility Function¶
Create a utility module when the template needs normalization beyond simple TTP captures. Use one utility file per platform template unless an established shared helper already exists.
Utility module checklist:
- Module docstring explains the command being normalized.
Used by:note lists the platform template.- One public transform function is called by the template macro.
- Private helpers are used only for real cleanup, such as VLAN range expansion.
- Final records are validated with the getter Pydantic model.
- The function returns plain Python lists and dictionaries.
Getter utilities should tolerate the TTP macro payload shape used by
results="per_template". In practice this often means accepting both a bare
dictionary and a list of dictionaries:
items = [payload] if isinstance(payload, dict) else payload
Getter Wrapper¶
Getter templates live under ttp_templates/get/.
Add a platform implementation to the getter with an <extend> entry:
<extend template="ttp://platform/cisco_ios_show_running_config_pipe_section_vlan.txt"/>
Also update the getter <doc> block so supported platforms and returned keys
stay accurate.
Mock Data And Expected YAML¶
Use the data-driven platform test layout:
test/platform/<platform>/<command_slug>/<sample>.txt
test/platform/<platform>/<command_slug>/<sample>.yml
The .txt file contains raw command output. The .yml file contains the exact
expected normalized result. Use the same filename stem for both files.
The dynamic test collector automatically discovers these pairs, so do not add a
dedicated test_get_<getter>.py file unless the platform fixtures cannot cover
the behavior.
For commands with important syntax variants, include those variants in mock data. For example, VLAN parsers should cover single IDs and range/list syntax when the platform supports it:
vlan 2,100-105
Support Matrix¶
When adding or removing getter platform support, update
docs/getters_support_matrix.md.
Add the getter row or platform checkmark and list the collection command in the notes section:
### vlans
Collected commands by platform:
- Cisco IOS: `show running-config | section vlan`
Documentation¶
Write useful <doc> blocks in templates. The generated template reference docs
and template navigation are produced from those blocks by:
poetry run inv docs
Static documentation under docs/, including this guide, is edited manually
and should be listed in mkdocs.yml.
Validation¶
Run the dynamic platform tests after adding mock data:
python -m pytest test/test_platform_dynamic.py -q
For a direct getter smoke test:
from pathlib import Path
from ttp_templates import parse_output
data = Path("test/platform/cisco_ios/show_running_config_pipe_section_vlan/show_running_config_pipe_section_vlan.txt").read_text()
result = parse_output(data=data, get="vlans", platform="cisco_ios")
Before finishing, run:
git diff --check
Checklist¶
- Getter output shape is documented and stable.
- Pydantic model exists for normalized records.
- Platform template name matches
get_template()command resolution. <input>command and platform aliases are present.- Utility function validates final records.
- Getter wrapper extends the new platform template.
- Mock
.txtand expected.ymlfiles are present. - Getter support matrix is updated.
- Generated template docs are not hand-edited.
- Focused tests pass.