> For the complete documentation index, see [llms.txt](https://ccie-sp.gitbook.io/ccie-spv5.1-labs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ccie-sp.gitbook.io/ccie-spv5.1-labs/labs/nso/python-service.md).

# Python Service

Create a service that produces the following configuration:

```
router isis 1
 is-type level-2-only
 net 49.0001.0000.0000.<INDEX in hex>.00
 address-family ipv4 unicast
  metric-style wide
  segment-routing mpls
 !
 interface Loopback0
  address-family ipv4 unicast
   prefix-sid absolute <16000 + INDEX>
```

The service should use python code to generate the absolute SID and NET address. The service should take the device name as the key, and an index parameter. Restrict the index to a number from 1-1000.

## Answer <a href="#id-1eff0119-bc91-4b76-8e64-cb69d7e058c9" id="id-1eff0119-bc91-4b76-8e64-cb69d7e058c9"></a>

Generate the skeleton-service

```
ncs-make-package --service-skeleton python-and-template isis-base
```

XML template:

```
<config-template xmlns="http://tail-f.com/ns/config/1.0">
  <devices xmlns="http://tail-f.com/ns/ncs">
    <device>
      <name>{/device}</name>
      <config>
        <router xmlns="http://tail-f.com/ned/cisco-ios-xr">
          <isis>
            <tag>
              <name>1</name>
              <is-type>level-2-only</is-type>
              <net>
                <id>49.0001.0000.0000.{$HEX_INDEX}.00</id>
              </net>
              <address-family>
                <ipv4>
                  <unicast>
                    <metric-style>wide</metric-style>
                    <segment-routing>
                      <mpls/>
                    </segment-routing>
                  </unicast>
                </ipv4>
              </address-family>
              <interface>
                <name>Loopback0</name>
                <address-family>
                  <ipv4>
                    <unicast>
                      <prefix-sid>
                        <absolute>{$ABSOLUTE_INDEX}</absolute>
                      </prefix-sid>
                    </unicast>
                  </ipv4>
                </address-family>
              </interface>
            </tag>
          </isis>
        </router>
      </config>
    </device>
  </devices>
</config-template>
```

Python code (isis-base/python/isis\_base/main.py):

```
class ServiceCallbacks(Service):

    # The create() callback is invoked inside NCS FASTMAP and
    # must always exist.
    @Service.create
    def cb_create(self, tctx, root, service, proplist):
        self.log.info('Service create(service=', service._path, ')')

        vars = ncs.template.Variables()

        vars.add('ABSOLUTE_INDEX', str(service.index + 16000))

        hex_index = hex(service.index).replace('0x', '')
        hex_with_leading_zeros = '0000'
        hex_with_leading_zeros = hex_with_leading_zeros + str(hex_index)
        hex_with_leading_zeros = hex_with_leading_zeros[-4:]
        vars.add('HEX_INDEX', hex_with_leading_zeros)

        template = ncs.template.Template(service)
        template.apply('isis-base-template', vars)
```

YANG module:

```
module isis-base {

  namespace "http://example.com/isis-base";
  prefix isis-base;

  import tailf-ncs {
    prefix ncs;
  }

  revision 2016-01-01 {
    description
      "Initial revision.";
  }

  list isis-base {
    description "Base ISIS config with SR-MPLS enabled";

    key device;

    uses ncs:service-data;
    ncs:servicepoint isis-base-servicepoint;

    leaf device {
      type leafref {
        path "/ncs:devices/ncs:device/ncs:name";
      }
    }

    leaf index {
      mandatory true;
      type uint16 {
        range "1..1000";
      }
    }
  }
}
```

## Explanation <a href="#id-43a169bd-4813-42e7-a4e3-c2d640c0cafb" id="id-43a169bd-4813-42e7-a4e3-c2d640c0cafb"></a>

The XML template is generated by applying the config on a single router, syncing the config in NSO and then using **show running-config devices device xr2 config router isis | display xml**

From there, the variables are inserted. $VAR is used for variables which come from python, and normal XPATH expressions are used for variables coming from the YANG module.

<div align="left"><figure><img src="/files/oLVtno4xhqPZt7So1wLs" alt=""><figcaption></figcaption></figure></div>

Next the YANG module is created. We only need two leafs for this service: device and index. The index is restricted to a value of 1-1000.

<div align="left"><figure><img src="/files/ajWpWTkF9pKSjQmWao7S" alt=""><figcaption></figcaption></figure></div>

Finally, we write the python code. The **main.py** file is already generated automatically. We simply add 16000 to the index to produce the ABSOLUTE\_INDEX variable. We can access our service variables using **service.var**, so **service.index** gives us the index value as entered by the user in NSO.

Obtaining the hex value is a little more complex. We can use python’s builtin hex() function, which returns “0x\<value>”. We can strip away the “0x” and then pad the value with leading zeros using a string slice trick.

<div align="left"><figure><img src="/files/lSDkCnJ6HjomGFvCakqf" alt=""><figcaption></figcaption></figure></div>

You should now be able to apply the service from NSO:

<div align="left"><figure><img src="/files/ZxwP5n1BahtGCngwVPPN" alt=""><figcaption></figcaption></figure></div>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ccie-sp.gitbook.io/ccie-spv5.1-labs/labs/nso/python-service.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
