|
24 | 24 | """Python gNMI wrapper to ease usage of gNMI."""
|
25 | 25 |
|
26 | 26 | import logging
|
| 27 | +from collections import OrderedDict |
27 | 28 | from xml.etree.ElementPath import xpath_tokenizer_re
|
28 | 29 | from six import string_types
|
29 | 30 |
|
@@ -152,7 +153,9 @@ def get(
|
152 | 153 | "encoding", encoding, "Encoding", proto.gnmi_pb2.Encoding
|
153 | 154 | )
|
154 | 155 | request = proto.gnmi_pb2.GetRequest()
|
155 |
| - if not isinstance(paths, (list, set)): |
| 156 | + try: |
| 157 | + iter(paths) |
| 158 | + except TypeError: |
156 | 159 | raise Exception("paths must be an iterable containing Path(s)!")
|
157 | 160 | request.path.extend(paths)
|
158 | 161 | request.type = data_type
|
@@ -334,3 +337,79 @@ def parse_xpath_to_gnmi_path(self, xpath, origin=None):
|
334 | 337 | raise Exception("Unfinished elements in XPath parsing!")
|
335 | 338 | path.elem.extend(path_elems)
|
336 | 339 | return path
|
| 340 | + |
| 341 | + def xpath_iterator(self, xpath): |
| 342 | + for token in xpath[1:].split('/'): |
| 343 | + #elem = proto.gnmi_pb2.PathElem() |
| 344 | + xpath_so_far += '/' + token |
| 345 | + if '[' in token: |
| 346 | + keys = OrderedDict() |
| 347 | + subtoken = token.replace('[', ',').replace(']', '').split(',') |
| 348 | + for k in subtoken: |
| 349 | + if '=' not in k: |
| 350 | + elem = {'elem': OrderedDict({'name': k})} |
| 351 | + #elem.name = k |
| 352 | + else: |
| 353 | + k, val = tuple(k.replace('"', '').split('=')) |
| 354 | + keys['name'] = k |
| 355 | + keys['value'] = val |
| 356 | + elem['elem'].update({'key': keys}) |
| 357 | + #elem.key.update(keys) |
| 358 | + else: |
| 359 | + elem = {'elem': {'name': token}} |
| 360 | + #elem.name = token |
| 361 | + yield elem |
| 362 | + |
| 363 | + def combine_segments(self, segments): |
| 364 | + xpaths = [seg[0] for seg in segments] |
| 365 | + prev_path = '' |
| 366 | + extentions = [] |
| 367 | + for path in xpaths: |
| 368 | + if not prev_path: |
| 369 | + prev_path = path |
| 370 | + continue |
| 371 | + if len(path) > len(prev_path): |
| 372 | + short_path = prev_path |
| 373 | + long_path = path |
| 374 | + else: |
| 375 | + short_path = path |
| 376 | + long_path = prev_path |
| 377 | + if short_path in long_path: |
| 378 | + end = long_path[:len(short_path)].split() |
| 379 | + extentions.append((short_path, end)) |
| 380 | + removes = [seg for seg in segments if seg[0] == short_path] |
| 381 | + for seg in removes: |
| 382 | + segments.remove(seg) |
| 383 | + import pdb; pdb.set_trace() |
| 384 | + print(segments) |
| 385 | + |
| 386 | + |
| 387 | + |
| 388 | + def resolve_segments(self, segments, required_segments=[]): |
| 389 | + duplicates = [] |
| 390 | + if not segments: |
| 391 | + return required_segments |
| 392 | + xpath, elems, value = segments.pop(0) |
| 393 | + for seg in segments: |
| 394 | + if seg == (xpath, elems, value): |
| 395 | + # Duplicate so move on |
| 396 | + duplicates.append(seg) |
| 397 | + continue |
| 398 | + next_xpath, next_elems, next_value = seg |
| 399 | + |
| 400 | + if xpath in next_xpath: |
| 401 | + # Check if segment is a key |
| 402 | + for seg in segments: |
| 403 | + #for elem in seg[1]: |
| 404 | + if xpath != seg['elem'].get('keybase', ''): |
| 405 | + continue |
| 406 | + else: |
| 407 | + break |
| 408 | + else: |
| 409 | + # This is a key |
| 410 | + return self.resolve_segments( |
| 411 | + segments, |
| 412 | + required_segments |
| 413 | + ) |
| 414 | + required_segments.append((xpath, elems, value)) |
| 415 | + return self.resolve_segments(segments, required_segments) |
0 commit comments