From a56e818641b107ee9444db6bbd16330654213ac3 Mon Sep 17 00:00:00 2001
From: Alexander Schlemmer <alexander@mail-schlemmer.de>
Date: Fri, 4 Mar 2022 21:20:41 +0100
Subject: [PATCH] ENH: refactored multiple methods needed for parameter
 management of simulations

---
 src/caosdb/apiutils.py       | 23 ++++++++++++++++
 src/caosdb/high_level_api.py | 52 +++++++++++++++++++++++++++++-------
 2 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/src/caosdb/apiutils.py b/src/caosdb/apiutils.py
index 5558f649..e6bd80fb 100644
--- a/src/caosdb/apiutils.py
+++ b/src/caosdb/apiutils.py
@@ -480,3 +480,26 @@ def resolve_reference(prop: Property):
     else:
         if isinstance(prop.value, int):
             prop.value = retrieve_entity_with_id(prop.value)
+
+
+def create_flat_list(ent_list: list[Entity], flat: list[Entity]):
+    """
+    Recursively adds all properties contained in entities from ent_list to
+    the output list flat. Each element will only be added once to the list.
+
+    TODO: Currently this function is also contained in newcrawler module crawl.
+          We are planning to permanently move it to here.
+    """
+    for ent in ent_list:
+        for p in ent.properties:
+            # For lists append each element that is of type Entity to flat:
+            if isinstance(p.value, list):
+                for el in p.value:
+                    if isinstance(el, Entity):
+                        if el not in flat:
+                            flat.append(el)
+                        create_flat_list([el], flat) # TODO: move inside if block?
+            elif isinstance(p.value, Entity):
+                if p.value not in flat:
+                    flat.append(p.value)
+                create_flat_list([p.value], flat)  # TODO: move inside if block?
diff --git a/src/caosdb/high_level_api.py b/src/caosdb/high_level_api.py
index f3235894..3daf9f2f 100644
--- a/src/caosdb/high_level_api.py
+++ b/src/caosdb/high_level_api.py
@@ -37,7 +37,7 @@ from caosdb.common.datatype import (BOOLEAN, DATETIME, DOUBLE, FILE, INTEGER,
                                     is_reference)
 import caosdb as db
 
-from .apiutils import get_type_of_entity_with
+from .apiutils import get_type_of_entity_with, create_flat_list
 
 from typing import Any, Optional, List, Union, Dict
 
@@ -806,11 +806,9 @@ def convert_to_python_object(entity: Union[db.Container, db.Entity],
         high_level_type_for_standard_type(entity)(), entity, references)
     
 
-def new_high_level_entity_for_record_type(entity: db.RecordType,
-                                          importance_level: str,
-                                          name: str = None,
-                                          deep: bool = True,
-                                          references: Optional[db.Container] = None):
+def new_high_level_entity(entity: db.RecordType,
+                          importance_level: str,
+                          name: str = None):
     """
     Create an new record in high level format based on a record type in standard format.
 
@@ -840,9 +838,45 @@ def new_high_level_entity_for_record_type(entity: db.RecordType,
 
         r.add_property(prop)
 
-    if deep:
-        raise NotImplementedError("Recursive creation is not possible at the moment.")
-
     return convert_to_python_object(r)
             
     
+def create_record(rtname: str, name: str = None, **kwargs):
+    """
+    Create a new record based on the name of a record type. The new record is returned.
+
+    rtname: str
+            The name of the record type.
+
+    name: str
+          This is optional. A name for the new record.
+
+    kwargs:
+            Additional arguments are used to set attributes of the
+            new record.
+    """
+    obj = new_high_level_entity(
+        db.RecordType(name=rtname).retrieve(), "SUGGESTED", name)
+    for key, value in kwargs.items():
+        obj.__setattr__(key, value)
+    return obj
+
+
+def load_external_record(record_name: str):
+    """
+    Retrieve a record by name and convert it to the high level API format.
+    """
+    return convert_to_python_object(db.Record(name=record_name).retrieve())
+
+
+def create_entity_container(record: CaosDBPythonEntity):
+    """
+    Convert this record into an entity container in standard format that can be used
+    to insert or update entities in a running CaosDB instance.
+    """
+    ent = convert_to_entity(record)
+    lse: List[db.Entity] = [ent]
+    create_flat_list([ent], lse)
+    return db.Container().extend(lse)
+    
+
-- 
GitLab