Skip to content

Commit

Permalink
working changes
Browse files Browse the repository at this point in the history
  • Loading branch information
duboyal committed Mar 4, 2024
1 parent bababe2 commit b11cc5a
Show file tree
Hide file tree
Showing 4 changed files with 421 additions and 44 deletions.
138 changes: 115 additions & 23 deletions src/cript/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,38 +427,100 @@ def add_to_dict(cls, dictionary, key=None, value=None):
# Key does not exist, create a new list with the value
dictionary[key] = [value]

# ================================== SAVE EXISTING ===================================
def add_existing_node_by_name(
# ================================== ADD EXISTING NODES-NAMES===================================
def add_existing_nodes_by_name(
self,
parent_node: PrimaryBaseNode,
child_node: PrimaryBaseNode,
child_class_type: str,
existing_child_node_names: list, # must be list of strings
):
child_class_name = child_node.node[0]
child_class_object = globals().get(child_class_name.capitalize(), None)
"""
this function will take a list of exact names and add them by uuid
takes in Parent Node, child cass type as a str i.e. "material" or "Material" (either work)
"""

# child_class_type = child_node.node[0]
child_class_object = globals().get(child_class_type.capitalize(), None)

# Check if the class exists
if child_class_object is None:
raise ValueError(f"Class {child_class_name} not found")

existing_node = next(self.search(child_class_object, search_mode=SearchModes.EXACT_NAME, value_to_search=child_node.name))
existing_uuid = str(existing_node.uuid)
raise ValueError(f"Class {child_class_type} not found")

# go through thte list of names and create the payload :
parent_node_type = parent_node.node[0].lower()
url_path = f"/{parent_node_type}/{parent_node.uuid}"

entity_name = f"{child_class_type.lower()}"
uuid_link_payload = {"node": parent_node.node, entity_name: []}

for name in existing_child_node_names:
# print(name.strip())
name = name.strip()

existing_node = next(self.search(child_class_object, search_mode=SearchModes.EXACT_NAME, value_to_search=name.strip()))
existing_uuid = str(existing_node.uuid)

parent_node_type = parent_node.node[0].lower()

API.add_to_dict(uuid_link_payload, key=entity_name, value={"uuid": f"{existing_uuid}"})

patch_response = self._capsule_request(url_path=url_path, method="PATCH", data=json.dumps(uuid_link_payload))

if patch_response.status_code in [200, 201]:
# print("worked")
# print(patch_response.json())
return patch_response
else:
raise ("error in patching existing item")

def remove_nodes_by_name(
self,
parent_node: PrimaryBaseNode,
child_class_type: str,
existing_child_node_names: list,
):
"""
this function will take a list of exact names and add them by uuid
takes in Parent Node, child cass type as a str i.e. "material" or "Material" (either work)
"""

# child_class_type = child_node.node[0]
child_class_object = globals().get(child_class_type.capitalize(), None)

# Check if the class exists
if child_class_object is None:
raise ValueError(f"Class {child_class_type} not found")

# go through thte list of names and create the payload :
parent_node_type = parent_node.node[0].lower()
url_path = f"/{parent_node_type}/{parent_node.uuid}"

payload = {"node": parent_node.node, f"{child_node.node[0].lower()}": [{"uuid": existing_uuid}]}
entity_name = f"{child_class_type.lower()}"
uuid_link_payload = {"node": parent_node.node, entity_name: []}

for name in existing_child_node_names:
# print(name.strip())
name = name.strip().lower()

patch_response = self._capsule_request(url_path=url_path, method="PATCH", data=json.dumps(payload))
existing_node = next(self.search(child_class_object, search_mode=SearchModes.EXACT_NAME, value_to_search=name.strip()))
existing_uuid = str(existing_node.uuid)

if patch_response.status_code in [200, 201]:
print("worked")
parent_node_type = parent_node.node[0].lower()

API.add_to_dict(uuid_link_payload, key=entity_name, value={"uuid": f"{existing_uuid}"})

del_response = self._capsule_request(url_path=url_path, method="DELETE", data=json.dumps(uuid_link_payload))

if del_response.status_code in [200, 201]:
# print("delete worked")
# print(del_response.json())
return del_response
else:
raise ("error in patching existing item")

# ================================== SAVE ===================================

def save_node(self, new_node: PrimaryBaseNode):
def save_node(self, new_node: PrimaryBaseNode, link_existing=True):

# try to create or else fail
try:
Expand Down Expand Up @@ -525,6 +587,10 @@ def save_node(self, new_node: PrimaryBaseNode):
)
diff_dict = diff_.to_dict()

# print("-----diff_dict")
# print(diff_dict)
# quit()

try:

values_changed = diff_dict.get("values_changed", {})
Expand Down Expand Up @@ -559,6 +625,7 @@ def save_node(self, new_node: PrimaryBaseNode):
API.add_to_dict(entities_to_remove_dict, key=entity_name, value={"uuid": f"{uuid_to_remove}"})
else:
print("uuid is None (values changed)")

node_to_add = value["new_value"] # gotta do a search by uuid on the name and node
API.add_to_dict(entities_to_patch_dict, key=entity_name, value=node_to_add)

Expand Down Expand Up @@ -592,7 +659,7 @@ def save_node(self, new_node: PrimaryBaseNode):
print(" 3) DICT ITEMS ADDED ")

for path in dictionary_items_added:
print(path)
# print(path)
# Strip "root" and square brackets, then remove quotes
key_name = path.replace("root[", "").replace("]", "").replace("'", "")
entities_to_patch_dict[key_name] = cleaned_modified[key_name]
Expand Down Expand Up @@ -626,15 +693,42 @@ def save_node(self, new_node: PrimaryBaseNode):

payload_remove = entities_to_remove_dict
payload_patch = entities_to_patch_dict
# print("\n\n____payload_patch")
# print(payload_patch)
# quit()

url_path = f"/project/{new_node.uuid}"

patch_response = self._capsule_request(url_path=url_path, method="PATCH", data=json.dumps(payload_patch))

if patch_response.status_code in [400, 409]:
print("take the materials that exist and link it , then resend the other materials")
print(patch_response.json())
# raise ("error")

"""take the materials that exist and link it , then resend the other materials"""
# print(patch_response.json())

if link_existing == True:

names_list_of_dicts = patch_response.json().get("error").split("item")[1].split("for")[0]
child_class_type = patch_response.json().get("error").split("item")[1].split("for")[1].strip().lower()

eval_names = eval(names_list_of_dicts)
# print(eval_names)
names_list = [name["name"].lower() for name in eval_names]
# print("names_list")

self.add_existing_nodes_by_name(
parent_node=new_node,
child_class_type=child_class_type,
existing_child_node_names=names_list,
)

# need to retry for collection
payload_patch.pop(child_class_type)
patch_response2 = self._capsule_request(url_path=url_path, method="PATCH", data=json.dumps(payload_patch))

# print("\n\n___patch_response2")
# print(patch_response2.json())
# quit()

remove_response = self._capsule_request(url_path=url_path, method="DELETE", data=json.dumps(payload_remove))

Expand All @@ -643,11 +737,9 @@ def save_node(self, new_node: PrimaryBaseNode):
raise (remove_response.json())
# raise ("error")

######################################

print(" - FINALLY WE GET ALL THE WAY TO THE END ")

# ==================================
# ======================================================================================================
def save(self, project: Project) -> None:
"""
This method takes a project node, serializes the class into JSON
Expand Down
119 changes: 119 additions & 0 deletions tests/nodes/primary_nodes/test_material.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
save_integration_node_helper,
)
from tests.utils.util import strip_uid_from_dict
import pytest
import time


def test_create_complex_material(cript_api, simple_material_node, simple_computational_forcefield_node, simple_process_node) -> None:
Expand Down Expand Up @@ -156,3 +158,120 @@ def test_integration_material(cript_api, simple_project_node, simple_material_no

# ========= test delete =========
delete_integration_node_helper(cript_api=cript_api, node_to_delete=simple_material_node)


# @pytest.mark.skip(reason="test is WIP")
# def test_update_material_change_or_reset_children_to_existing_children(cript_api) -> None:
# """
# pytest nodes/primary_nodes/test_project.py::test_update_project_change_or_reset_material_to_existing_materials
# test that a project can be updated and completley reset
# strategy:
# create something with a post/patch
# with a name (we will delete at the end)
# then try to obtain it with load data
# """

# epoch_time = int(time.time())
# name_1 = f"myproj_ali_{epoch_time}"
# mat_1 = f"my_mat__{epoch_time}"
# col_name = f"031o0col__{epoch_time}"

# url_path = f"/project/"
# create_payload = {"node": ["Project"], "name": name_1, "material": [{"uuid": "1809330c-31d2-4a80-af72-77b84070ee1d"}, {"uuid": "ea8f957c-b6e5-4668-b306-e0d6b0d05d9a"}]}

# try:
# create_response = cript_api._capsule_request(url_path=url_path, method="POST", data=json.dumps(create_payload))
# print(create_response)
# except Exception as e:
# print(e)

# cr_res_list = create_response.json()["data"]["result"]

# """
# 1 - get existing material node by uuid - paginator
# - or create material node with a property

# 2 - make an edit to a child node (property or process or component)
# 3 - save the node
# """

# if create_response.json()["code"] in [409, 400, 401]:
# print("---create_response")
# print(create_response)
# raise ValueError(create_response)

# elif create_response.json()["code"] in [201, 200]:

# uuid = None
# for item in cr_res_list:
# if item["node"] == ["Project"]:

# uuid = item["uuid"]
# if uuid == None:
# raise ValueError("no project node")

# get_url = f"/project/{uuid}"

# result = cript_api._capsule_request(url_path=get_url, method="GET")

# result_json_dict = result.json()

# my_project_from_res_data_dict = result_json_dict["data"][0]

# project_list = cript.load_nodes_from_json(nodes_json=json.dumps(my_project_from_res_data_dict))
# project_loaded = project_list

# """
# 1 - get existing material node by uuid - paginator
# - or create material node with a property

# 2 - make an edit to a child node (property or process or component)
# 3 - save the node
# """

# material_001 = cript.Material(name=mat_1, identifier=[])
# toluene = cript.Material(name="toluene", identifier=[{"smiles": "Cc1ccccc1"}]) # , {"pubchem_id": 1140}])
# styrene = cript.Material(name="styrene", identifier=[{"smiles": "Cc1ccccc1"}])

# collection = cript.Collection(name=col_name)

# project_loaded.material = [toluene, styrene]
# project_loaded.collection = [collection]

# print("\n~~~~~~~~~~~~ SAVING NOW ~~~~~~~~~~~")
# print(project_loaded) # material_loaded
# print("~~~~~~~~~~")
# cript_api.save_node(project_loaded) # material_loaded
# print("BASICALLY now WE NEED TO ASSERT ON THE RESPONSE, NOT RELOAD IT INTO A NODE")

# print("\n-- probably need to fix save --\n---project after saved")

# get_url = f"/material/{uuid}" # f"/project/{uuid}"
# edited_result = cript_api._capsule_request(url_path=get_url, method="GET")

# print("\n~~~~~~ saved reflected result")
# print(edited_result.json())

# assert len(edited_result.json()["data"]) == 1

# final = edited_result.json()["data"][0]

# assert len(final["property"]) == 2 # styrene and toluene

# set1 = set([final["property"][0]["name"].lower(), final["property"][1]["name"].lower()])

# set2 = set([json.loads(toluene.property.get_json().json)["name"].lower(), json.loads(styrene.property.get_json().json)["name"].lower()])

# assert set1 == set2 # or material_003toluene.get_json().json)["name"]

# print("\n___final")
# print(final)

# assert final["collection"][0]["name"] == json.loads(collection.get_json().json)["name"]

# print("now deleting proj and eventually 2 mats")
# print("only issue with this test is the toluene")

# del_res = cript_api._capsule_request(url_path=f"/material/{uuid}", method="DELETE")

# assert del_res.json()["code"] == 200
Loading

0 comments on commit b11cc5a

Please sign in to comment.