diff --git a/src/cript/api/api.py b/src/cript/api/api.py index caeef8c23..e1aa9d3ec 100644 --- a/src/cript/api/api.py +++ b/src/cript/api/api.py @@ -21,6 +21,7 @@ ) from cript.api.paginator import Paginator from cript.api.utils.get_host_token import resolve_host_and_token +from cript.api.utils.helper_functions import _get_node_type_from_json from cript.api.utils.save_helper import ( _fix_node_save, _get_uuid_from_error_message, @@ -477,18 +478,9 @@ def _is_node_schema_valid(self, node_json: str, is_patch: bool = False) -> bool: db_schema = self._get_db_schema() + node_type: str = _get_node_type_from_json(node_json=node_json) + node_dict = json.loads(node_json) - try: - node_list = node_dict["node"] - except KeyError: - raise CRIPTJsonNodeError(node_list=node_dict["node"], json_str=json.dumps(node_dict)) - - # TODO should use the `_is_node_field_valid()` function from utils.py to keep the code DRY - # checking the node field "node": "Material" - if isinstance(node_list, list) and len(node_list) == 1 and isinstance(node_list[0], str): - node_type = node_list[0] - else: - raise CRIPTJsonNodeError(node_list, str(node_list)) # set the schema to test against http POST or PATCH of DB Schema schema_http_method: str diff --git a/src/cript/api/utils/__init__.py b/src/cript/api/utils/__init__.py index 89e714944..50e0528bb 100644 --- a/src/cript/api/utils/__init__.py +++ b/src/cript/api/utils/__init__.py @@ -1,3 +1,4 @@ # trunk-ignore-all(ruff/F401) from .get_host_token import resolve_host_and_token +from .helper_functions import _get_node_type_from_json diff --git a/src/cript/api/utils/helper_functions.py b/src/cript/api/utils/helper_functions.py new file mode 100644 index 000000000..d5f9d4315 --- /dev/null +++ b/src/cript/api/utils/helper_functions.py @@ -0,0 +1,44 @@ +import json +from typing import Dict, List, Union + +from cript.nodes.exceptions import CRIPTJsonNodeError +from cript.nodes.util import _is_node_field_valid + + +def _get_node_type_from_json(node_json: Union[Dict, str]) -> str: + """ + takes a node JSON and output the node_type `Project`, `Material`, etc. + + 1. convert node JSON dict or str to dict + 1. do check the node list to be sure it only has a single type in it + 1. get the node type and return it + + Parameters + ---------- + node_json: [Dict, str] + + Notes + ----- + Takes a str or dict to be more versatile + + Returns + ------- + str: + node type + """ + # convert all JSON node strings to dict for easier handling + if isinstance(node_json, str): + node_json: Dict = json.loads(node_json) + + try: + node_type_list: List[str] = node_json["node"] + except KeyError: + raise CRIPTJsonNodeError(node_list=node_json["node"], json_str=json.dumps(node_json)) + + # check to be sure the node list has a single type "node": ["Material"] + if _is_node_field_valid(node_type_list=node_type_list): + return node_type_list[0] + + # if invalid then raise error + else: + raise CRIPTJsonNodeError(node_list=node_type_list, json_str=str(node_json))