cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
854
Views
0
Helpful
2
Replies

NSO 6.1 Python API: Register two callpoints in same list

JennyW
Level 1
Level 1

Here is my yang module:

 

 

 

module pydp {
  namespace "http://tail-f.com/ns/example/pydp";
  prefix pydp; yang-version 1.1;

  import tailf-common {prefix tailf;}
  import ietf-inet-types {prefix inet;}

  list cont {
    key name;
    leaf name { type string; }
    container brief {
       tailf:callpoint mydp-cp-brief;
       config false;
       leaf status { type string; }
       leaf up-time { type string; }
    }
    container capabilities {
      tailf:callpoint mydp-cp-cap;
      config false;
      leaf test { type string; }
    }
  }
}

 

 

 

and my python:

 

 

 

import ncs 
import _ncs 
from ncs.experimental import DataCallbacks 

def dcb_start(state): 
  dcb = DataCallbacks(state.log)
  dcb.register('/mydp:cont', Handler())
  _ncs.dp.register_data_cb(state.ctx, 'mydp-cp-brief', dcb)
  _ncs.dp.register_data_cb(state.ctx, 'mydp-cp-cap', dcb)
  return state

def dcb_stop(start_state):
    pass

class Handler(object): 
    def get_object(self, tctx, kp, args): 
      cont_name = args.get("cont")
      with ncs.maapi.single_read_trans(tctx.uinfo.username, "passwd") as t: 
        root = ncs.maagic.get_root(t) 
        key = root.cont[device_name] 
        .... 
        return { 
          "brief": { 'status': 'value',  'up-time': 'value' }
        }

    def get_next(self, tctx, kp, args, next): 
      return None 

    def count(self): 
      return 0 

class Main(ncs.application.Application): 
  def setup(self): 
    ...
    self.register_fun(dcb_start, dcb_stop) 

  def teardown(self): 
    pass

 

 

 

I was hoping when get_object() in Handler class gets called, I can use kp to differentiate if it's for brief container or capabilities,  however, the kp was always /mydp:cont when I did "show cont brief" and "show cont capabilities". 

Now I wonder if it is possible to register multiple callpoints with same DataCallbacks instance. 

1 Accepted Solution

Accepted Solutions

tohagber
Cisco Employee
Cisco Employee

The low lever _ncs.X Python API documentation is not well documented. As a general comment i would recommend you to consult the c manual pages for the equivalent API functions https://developer.cisco.com/docs/nso/guides/#!ncs-man-pages-volume-3. The manpage states:
get_object()
...

The purpose of the callback is to return an entire object, i.e. a list entry, in one swoop. If the callback is not implemented, NSO will retrieve the whole object through a series of calls to get_elem().
...

By default, the callback will only be called for list entries - i.e. get_elem() is still needed for leafs that are not defined in a list, but if there are no such leafs in the part of the data model covered by a given callpoint, the get_elem() callback may be omitted when get_object() is registered. This has the drawback that NSO will have to invoke get_object() even if only a single leaf in a list entry is needed though, e.g. for the existence test mentioned for get_elem().

However, if the CONFD_DAEMON_FLAG_BULK_GET_CONTAINER flag is set via confd_set_daemon_flags(), get_object() will also be used for the toplevel ancestor container (if any) when no ancestor list node exists. I.e. in this case, get_elem() is only needed for toplevel leafs - if there are any such leafs in the part of the data model covered by a given callpoint.
...

So try to set the _ncs.dp.DAEMON_FLAG_BULK_GET_CONTAINER flag to verify that your get_object() will be invoked.

-Tommy


View solution in original post

2 Replies 2

tohagber
Cisco Employee
Cisco Employee

The low lever _ncs.X Python API documentation is not well documented. As a general comment i would recommend you to consult the c manual pages for the equivalent API functions https://developer.cisco.com/docs/nso/guides/#!ncs-man-pages-volume-3. The manpage states:
get_object()
...

The purpose of the callback is to return an entire object, i.e. a list entry, in one swoop. If the callback is not implemented, NSO will retrieve the whole object through a series of calls to get_elem().
...

By default, the callback will only be called for list entries - i.e. get_elem() is still needed for leafs that are not defined in a list, but if there are no such leafs in the part of the data model covered by a given callpoint, the get_elem() callback may be omitted when get_object() is registered. This has the drawback that NSO will have to invoke get_object() even if only a single leaf in a list entry is needed though, e.g. for the existence test mentioned for get_elem().

However, if the CONFD_DAEMON_FLAG_BULK_GET_CONTAINER flag is set via confd_set_daemon_flags(), get_object() will also be used for the toplevel ancestor container (if any) when no ancestor list node exists. I.e. in this case, get_elem() is only needed for toplevel leafs - if there are any such leafs in the part of the data model covered by a given callpoint.
...

So try to set the _ncs.dp.DAEMON_FLAG_BULK_GET_CONTAINER flag to verify that your get_object() will be invoked.

-Tommy


Thanks for the clarification. Really hope Cisco can update the Python API documentation.