Skip to content

Commit

Permalink
kernelci.api.helper: add get_node_obj function
Browse files Browse the repository at this point in the history
This function is meant to be used by code issuing API requests (such
as a pipeline service) to turn node dicts into objects with resolved
references to linked nodes.

Signed-off-by: Ricardo Cañuelo <[email protected]>
  • Loading branch information
Ricardo Cañuelo committed Feb 21, 2024
1 parent c675e9c commit a434010
Showing 1 changed file with 41 additions and 1 deletion.
42 changes: 41 additions & 1 deletion kernelci/api/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import json
import requests

from . import API
from . import API, models


class APIHelper:
Expand Down Expand Up @@ -220,6 +220,46 @@ def submit_results(self, results, root):
except requests.exceptions.HTTPError as error:
raise RuntimeError(json.loads(error.response.text)) from error

def get_node_obj(self, node_dict, get_linked=False):
"""Takes a dict defining a Node and returns it as a concrete
Node object (or Node subtype object). If get_linked is set to
True, linked nodes are vivified (not recursively).
It will also accept a Node (or subclass) object instead of a
dict. This can be used to fetch and vivify the linked objects if
get_linked is set to True.
"""
# pylint: disable=protected-access
def get_attr(obj, attr):
"""Similar behavior to the builtin getattr, but it can be
used with nested attributes in.dot.notation
"""
fields = attr.split('.')
if len(fields) == 1:
return getattr(obj, fields[0])
return get_attr(getattr(obj, fields[0]), '.'.join(fields[1:]))

def set_attr(obj, attr, value):
"""Similar behavior to the builtin setattr, but it can be
used with nested attributes in.dot.notation
"""
fields = attr.split('.')
if len(fields) == 1:
setattr(obj, fields[0], value)
return
obj = get_attr(obj, '.'.join(fields[:-1]))
setattr(obj, fields[-1], value)

node_obj = models.parse_node_obj(node_dict)
if get_linked:
for linked_node_attr in node_obj._OBJECT_ID_FIELDS:
node_id = get_attr(node_obj, linked_node_attr)
if node_id:
resp = self.api.node.get(node_id)
linked_obj = models.parse_node_obj(resp)
set_attr(node_obj, linked_node_attr, linked_obj)
return node_obj

@classmethod
def load_json(cls, json_path, encoding='utf-8'):
"""Read content from JSON file"""
Expand Down

0 comments on commit a434010

Please sign in to comment.