Classes and utility functions

This chapter provides descriptions of the classes and utility functions used to write custom show commands.

Formatters

A number of built-in formatters are available or you can create your own using the Format utilities:

ColumnFormatter:

Formats the data using a column-based table, which supports a number of ways to customize the look-and-feel.

ColumnFormatter

+----------+---------+-------------+
| entry-id | source  | destination |
+==========+=========+=============+
| 10       | 1.2.3.4 | 5.6.7.8     |
+----------+---------+-------------+

TagValueFormatter:

Formats the data using a single tag: value pair on each line.

TagValueFormatter

entry-id    : 10
source      : 1.2.3.4
destination : 5.6.7.8

TagValueWithKeyLineFormatter:

Formats the data using:

  • a single line to print the name and keys

  • a line for each field and leaf-list, formatted as a ‟tag: value” pair

TagValueWithKeylineFormatters

Entry 10
  source      : 1.2.3.4
  destination : 5.6.7.8

Built-in decorators are also available to wrap around a formatter to add embellishments to the output. The following table lists the built-in decorators.

Table 1. Built-in decorators

Built-in decorator

Description

Indent

Adds an indentation before every output line.

Border

Adds lines above, below, or between the printed entries.

Header

Adds a header above the first printed entry.

Footer

Adds a footer below the last printed entry.

Whiteline

Adds an empty line above, below, or between the printed entries.

FilteredFormatter

Filters out fields/leaf-lists.

ColumnFormatter

Class srlinux.data.ColumnFormatter(ancestor_keys=True, horizontal_alignment=None, vertical_alignment=None, borders=None

Formats the specific Data object as a column-based table.

Column-based table

+----------+-------------------+--------------------+---------------+
| Entry id |     Ip prefix     |  Origin protocol   |   Next hop    |
+==========+===================+====================+===============+
| 1        | 1.1.2.0/24        | local_aggregate    | None          |
| 2        | 1.1.2.2/32        | directly_connected | None          |
+----------+-------------------+--------------------+---------------+

The output can be customized using the following constructor arguments:

ancestor_keys : bool or list

The bool construct controls whether the ancestor keys are added as columns to the output table:

  • True - (the default) includes all ancestor keys

  • False - does not include any ancestor keys

A list provides more granular control. The list must contain a value for each ancestor key, and can contain:

  • None - suppresses the key

  • A string to specify the column key to use for the ancestor key

List with none value

When passed [None, ‟A”, None], the first and third ancestor key are dropped, and the second is renamed to ‟A”.

horizontal_alignment : dict{str: Alignment}

Dictionary mapping column-names to their horizontal alignment (Alignment.Left/Center/Right). Columns not mentioned are left-aligned.

vertical_alignment : dict{str: Alignment}

Dictionary mapping column-names to their vertical alignment (Alignment.Top/Middle/Bottom). Columns not mentioned are top-aligned.

borders : Borders

Combination of Borders values indicating which borders to print. Defaults to ‟Borders.Outside | Borders.Header | Borders.Columns”.

Class srlinux.data.Alignment

The values used to align data in the table cells. The following table lists the alignment values.

Table 2. Cell alignment values

Alignment value

Description

Left= 1

Horizontally aligns the data to the left

Right= 2

Horizontally aligns the data to the right

Center= 3

Horizontally centers the data

Top= 4

Vertically aligns the data to the top

Middle= 5

Vertically centers the data

Bottom= 6

Vertically aligns the data to the bottom

Class srlinux.data.Borders

Specifies border type when drawing a table. Values can be combined together using the symbol ‛|’. For example: Borders.Outside | Borders.Header draws a border around the table and a line below the header. The following table defines the border values to use when drawing a table.

Table 3. Types of table borders

Table border

Description

Nothing= 0

Draws no borders

Outside= 1

Draws a border around the table

Header= 2

Draws a horizontal line between the header and the first row

Rows= 4

Draws a horizontal line between the rows

Columns= 8

Draws a vertical line between the columns

TagValueFormatter

Class srlinux.data.TagValueFormatter(filter=None)

Formats the specified Data object as a list of ‟tag: value” pairs (one on each line).

key  : <name>
field: <value>

TagValueWithKeyLineFormatter

Class srlinux.data.TagValueWithKeyLineFormatter(filter=None)

Formats the specified Data object as a single line with the name and the keys, followed by a list of ‟tag: value” pairs (one on each line).

node <name> id <id>
 field: <value>

Indent

Class srlinux.data.Indent(formatter, indentation=' ')

Decorator that indents every line printed by the wrapped formatter.

Indent(MyOtherFormatter(), 6)
Indent(MyOtherFormatter(), '      ')

Either of the examples shown above adds six spaces before every line printed by MyOtherFormatter. The following table defines the indent arguments.

Table 4. Indent arguments

Argument

Description

indentation: str or int

The indent string put before every line, or an integer that indicates the amount of spaces to add.

Border

Class srlinux.data.Border(formatter, position=None, character='-')

Decorator that prints a border line above, below, or above and below another formatter.

Border(MyOtherFormatter(), Border.Above | Border.Below, '+')

This example prints a border line of ++++++++++ above and below the output of the other formatter. The following table lists the border line arguments.

Table 5. Border line arguments

Argument

Description

position : Border

Controls where the border lines are drawn. Multiple values can be combined together using the ‟|” symbol.

Border.Above

Prints a line above the first Data entry. Defaults to printing a line above and below.

Border.Below

Prints a line below the last Data entry. Defaults to printing a line above and below.

Border.Between

Prints a line between each Data entry. Defaults to printing a line above and below.

character: char (optional)

Defines the character used to draw the border line. Defaults to ‟-”.

Whiteline

iClass srlinux.data.Whiteline(formatter, position=None)

Decorator that prints an empty line above, below, and between entries of another formatter.

Whiteline(MyOtherFormatter(), Whiteline.Above | Whiteline.Below)

This example prints an empty line above and below the output of the other formatter.

The following table defines the Whiteline arguments.

Table 8. Whiteline arguments

Argument

Description

position : Whiteline

Controls where the empty lines are drawn. Multiple values can be combined together using ‟|”.

Whiteline.Above

Prints a line above the first Data entry. Defaults to printing a line above and below.

Whiteline.Below

Prints a line below the last Data entry. Defaults to printing a line above and below.

Whiteline.Between

Prints a line between each Data entry. Defaults to printing a line above and below.

FilteredFormatter

iClass srlinux.data.FilteredFormatter(formatter, schema, fields=[], leaflists=[])

Decorator that only displays the selected fields and leaf-lists.

FilteredFormatter

FilteredFormatter(
    MyOtherFormatter(),
    schema=data.schema,
    fields=['field-to-keep', 'other-field-to-keep'],
    leaflists=['leaflist-to-keep', 'other-leaflist-to-keep'],
)

A common use case for this decorator is to enhance the format of some fields, but keeps the original field values available for when the output is formatted as JSON.

For the next example, both the original fields and the combined field are added to the Data object, and the original fields are filtered out for formatting.

Both fields added to data object

data = Data(schema)

# The 2 original fields. Added to data so that 'show <snip> | as json' displays them
in a useful fashion.
data.source = '1.2.3.4'
data.destination = '5.6.7.8'

# The combined field we want to show in the show report.
data.flow = f'{data.source} -> {data.destination}'

# Only show the combined field in the show report.
data.formatter = FilteredFormatter(
    TagValueFormatter(),
    schema=data.schema,
    fields=['flow']
)

The following table defines the available FilteredFormatter arguments.

Table 9. FilteredFormatter arguments

Argument

Description

schema : SchemaNode

Defines the schema of the Data object this formatter is applied to

fields : list of str

Defines the names of the fields to display. Any field not mentioned is omitted from the output. The default is to remove all fields.

leaflists : list of str

Defines the names of the leaf-lists to display. Any leaf-list not mentioned is omitted from the output. The default is to remove all leaf-lists.

Format utilities

If the built-in formatters are not sufficient, you can add a summary line or other modifications. The following utilities can be used when writing your own Formatter.

ColumnPrinter

iClass srlinux.data.ColumnPrinter(columns, max_width, horizontal_alignment, vertical_alignment, borders, filter=None)

Utility class to print a set of rows as a column-based table.

+----------+-------------------+
| Entry id |     Ip prefix     |
+==========+===================+
| 1        | 198.51.100.0/24   |
| 2        | 203.0.113.0/32    |
+----------+-------------------+

This output is generated with the following:

printer = ColumnPrinter(['Entry id', 'Ip prefix'], borders=Borders.Outside, max_widt
h=80)

printer.add_row([1, '198.51.100.0/24'])
printer.add_row([2, '203.0.113.0/32'])

printer.iter_format()
# Returns
# (
#    '+----------+-------------------+',
#    '| Entry id |     Ip prefix     |',
#    '+==========+===================+',
#    '| 1        | 198.51.100.0/24   |',
#    '| 2        | 203.0.113.0/32    |',
#    '+----------+-------------------+'
# )

The following table defines the constructor arguments that can be used to customize the output.

Table 10. ColumnPrinter constructor arguments

Constructor argument

Description

horizontal_alignment : dict{str: Alignment}

Dictionary mapping of column-names to their horizontal alignment (Alignment.Left/Center/Right). Columns not mentioned here are left-aligned.

vertical_alignment : dict{str: Alignment}

Dictionary mapping of column-names to their vertical alignment (Alignment.Top/Middle/Bottom). Columns not mentioned here are top-aligned.

borders : Borders

Combining borders values that indicate what borders can be drawn. Defaults to ‟Borders.Outside | Borders.Header | Borders.Columns”.

filter : Filter

Filters out fields from the output. Fields that do not match the filter are not printed.

TagValuePrinter

iClass srlinux.data.TagValuePrinter(tags, max_width, filter=None)

Utility class to print a set of ‟tag: value” pairs.

printer = TagValuePrinter(['first', 'second'], max_width=80)
printer.iter_format(['value', 'other-value'])
# Returns (
#    'first : value',
#    'second: other-value',
# )

If None (or ‛’ or []) is passed in as a value, the item is skipped in the output:

printer.iter_format([None, 'other-value'])
# Returns (
#    'second: other-value',
# )

The following table defines the TagValuePrinter arguments.

Table 11. TagValuePrinter arguments

Argument

Description

filter : Filter

Filters out fields/leaf-lists from the output. Fields that do not match the filter are not printed.

TagValueWithKeyLinePrinter

iClass srlinux.data.TagValueWithKeyLinePrinter(name, keys, tags, max_width, filter=None)

Utility class to print a single line with the name and the keys, followed by a list of ‟tag: value” pairs (one on each line).

node <name> id <id>
 field: <value>

The following is an example of this usage:

printer = TagValueWithKeyLinePrinter(name='node', keys=['key'], tags=['first-
field', 'second-field'], max_width=80)
printer.iter_format(keys=[<name>], values=['value', 'other-value'])
# Returns (
#    'node <name>',
#    '  first-field : value',
#    '  second-field: other-value',
# )

If None (or ‛’ or []) is passed in as a value, the item is skipped in the output:

printer.iter_format(keys=['<name>'], [None, 'other-value'])
# Returns (
#    'node <name>',
#    '  second-field: other-value',
# )

The following table defines theTagValueWithKeyLinePrinter arguments.

Table 12. TagValueWithKeyLinePrinter arguments

Argument

Description

filter : Filter

Filters out fields/leaf-lists from the output. Fields that do not match the filter are not printed.

indent

srlinux.data.indent(values, indentation)

Indents each value with the specified indentation. The indentation can either be a string, or an integer indicating the number of spaces to use for the indentation.

format_value

srlinux.data.format_value(value)

Formats the Data value as a string, which works for key, field, and leaf-list values of all accepted types (number, string, bool), even if the field/leaf-list is absent.

Data

The class used to represent all data; both the data retrieved from the server and the data displayed in the show report.

Class srlinux.data.data.Data(schema, parent=None, **keys)

Allows easy access to a configuration/state instance. When creating a top-level Data object, you must specify an instance of a SchemaNode. The code analyzes the schema, and makes all fields, keys, leaf-lists, and children accessible as attributes.

SchemaNode

Assume that this is the data model:

list interface {
    key 'name';
    field 'admin-state';
    leaflist 'values';
    list subinterface {
        key 'id';
    }
}

You can then:

  • Get the keys:

    value = data.name
    
  • Get and set the fields:

    value = data.admin_state # returns the value or None if unset
    data.admin_state = 'enabled'
    
  • Get and set leaflists:

    value = data.values # returns a list
    data.values = ['a', 'b']
    
  • Access children:

    child = data.subinterface.create(42) # Creates the subinterface with id '42'
    child = data.subinterface.get(42)
    if data.subinterface.exists(42):
        # Returns True/False
    for si in data.subinterface.items():
        # Walks all subinterfaces, ordered by their key
    
Note: Names are changed so that any character that is not a to z, A to Z, or 0 to 9 is replaced by an ‟_”.

Children

When accessing a child (data.subinterface in the preceding example), an instance of DataChildrenOfType is returned. Follow the link to see all the accessors it provides.

Values

All key/field/leaf-list values are of the following types:

  • bool

  • integer

  • string

Formatters

To generate the show report, Formatter objects are used. These can be tied to a specific Data object using two methods:

  • By assigning a formatter to the Data.formatter property.

  • By using Data.set_formatter().

Both methods assign the formatter to all sibling Data objects. Calling the following sets the formatter for all interfaces and not just for subinterface 42.

Formatters

data.subinterface.get(42).formatter = ColumnFormatter()

The following table lists the different types of formatters.

Table 13. Types of formatters

Formatter

Description

parent

Returns the parent Data object, or None if this is the root.

schema

Returns the SchemaNode.

key_names

Returns an iterator over the names of the keys.

key_values

Returns an iterator over the key values. Iterators are returned in the order specified by self.key_names, which is the same as the order that the keys were added to the SchemaNode.

get_key(name)

Returns the value of the key with the specified name.

keys_dict

Returns a ‟name: value” dictionary of the keys.

type_name

Returns the type-name, which is self.schema.name.

field_names

Returns an iterator over the names of the fields.

field_values

Returns an iterator over the field values. Iterators are returned in the order specified by self.field_names, which is the same as the order that the fields were added to the SchemaNode.

set_field(name, value)

Assigns the value to the field with the specified name.

get_field(name, default=None)

Returns the value of the field with the specified name, or the default if the field is unset.

is_field_set(name)

Returns True if the field is set.

leaflist_names

Returns an iterator over the names of the leaf-lists.

leaflist_values

Returns an iterator over the leaf-list values. Iterators are returned in the order specified by self.leaflist_names, which is the same as the order that the leaf-lists were added to the SchemaNode.

get_leaflist(name)

Returns a list containing the values of the leaf-list with the specified name. This list is empty if the leaf-list is unset.

set_leaflist(name, value)

Assigns the value to the leaf-list with the specified name. The value must be a list.

is_leaflist_set(name)

Returns True if the leaf-list is set.

child_names

Returns an iterator over the names of the children.

get_children(name)

Returns the DataChildrenOfType instance that contains all the children of the specified type. This returned object is mutable and can be used to walk/retrieve/add children.

iter_children_by_type(predicate=<function Data.<lambda>>)

Iterates over all DataChildrenOfType instances for which the predicate is True. By default, this returns all children.

iter_children()

Iterates over all child instances.

get(name)

Returns the value of the specified key, field, leaf-list, or child.

get_annotations(name=None)

Returns a list containing the annotations of this node (if called with no arguments) or the field with the specified name.

add_annotation(annotation, name=None)

Adds the specified annotation to this node (when called with a single argument) or to the field with the specified name (when called with two arguments). The annotation must be an instance of Annotation.

formatter

Returns the Formatter that can be used to generate the show report for this Data object.

iter_format(max_width)

Invokes the Formatter of this Data object. Returns an iterator over the formatted output lines.

iter_format_children(max_width)

Invokes the Formatter of all children of this Data object. Returns an iterator over the formatted output lines.

set_formatter(schema, formatter)

Adds a Formatter to the Data object with the specified schema. The schema can be specified as an XPath string (without keys). For example, ‟/interface/subinterface”.

get_schema(path)

Get the SchemaNode of the Data object with the specified path. The path must be an XPath string, for example, ‟/interface/subinterface”.

DataChildrenOfType

Use this class when you need to access children through a Data object. It allows you to retrieve, create, and iterate all children.

Class srlinux.data.data.DataChildrenOfType(schema, parent)

The children of a Data object of a single type.

Returned by Data.get_children() or by accessing the attribute with the child name (for example, Data.interface). Most methods require you to pass a value for each key defined in the schema.

No keys

If the schema has no keys, use:

data.node.get()
data.node.create()
data.node.exists()

Single key

If the schema has a single key, this becomes:

#node has a single key 'name'

data.node.get('abc')
data.node.create('abc')
data.node.exists('abc')

# or

data.node.get(name='abc')
data.node.create(name='abc')
data.node.exists(name='abc')

Multiple keys

If the schema has a multiple keys, specify them all in the correct order:

# node has 2 keys, 'name' and 'id'

data.node.get('abc', 1)
data.node.create('abc', 1)
data.node.exists('abc', 1)

# or

data.node.get(name='abc', id=1)
data.node.create(name='abc', id=1)
data.node.exists(name='abc', id=1)

The following table defines the DataOfChildrenType Attributes.

Table 14. DataOfChildrenType attributes

Attribute

Description

get(*args, **kwargs)

Returns an existing child with the specified keys. Generates an AttributeError if a wrong number of keys is specified, and KeyError if there is the child does not exist.

exists(*args, **kwargs)

Returns True if a child with the specified keys exists. Generates an AttributeError if a wrong number of keys is given.

create(*args, **kwargs)

Creates and returns a child with the specified keys. If this child already exists, the existing child is returned (and no changes are made). Generates an AttributeError if a wrong number of keys is given.

count()

Counts the number of children.

is_empty

Returns True if there are no children of this type.

items()

Iterates over all children of this type and are sorted based on their keys.

clear()

Removes all children of this type.

formatter

Returns the Formatter that can be used to generate the show report for the Data object.

iter_format(max_width)

Invokes the Formatter.iter_format_type() of these Data objects. Returns an iterator over the formatted output lines.

SchemaNode

srlinux.schema.fixed_schema.FixedSchemaNode.add_child(self, child_name, key=None, keys=[], field=None, fields=[], leaflist=None, leaflists=[], importance=<ShowImportance.High: 3>)

Adds a list/container to the current node, which allows you to specify the keys, fields, and leaf-lists of the new child.

The following table defines the SchemaNode arguments.

Table 15. Schema Node arguments

Argument

Description

child_name : str

The name specified for the newly created child.

key : str or None

If not None, a key with the specified name is added.

keys : list of str

The names of the keys to be added.

field : str or None

If not None, a field with the specified name is added.

fields : list of str

The names of the fields that are added.

leaflist : str or None

If not None, a leaf-list with the specified name is added.

leaflists : list of str

The names of the leaf-lists to be added.