From 4e6df1a98e456760f953e1606efe7bf9a9f63d75 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20tom=20W=C3=B6rden?= <henrik@trineo.org>
Date: Fri, 22 Apr 2022 11:20:45 +0200
Subject: [PATCH] MAINT: docs and user warning

---
 src/caosdb/high_level_api.py |   5 ++
 src/doc/future_caosdb.md     | 112 +++++++++++++++++++++++++++++++++++
 2 files changed, 117 insertions(+)
 create mode 100644 src/doc/future_caosdb.md

diff --git a/src/caosdb/high_level_api.py b/src/caosdb/high_level_api.py
index 03dd208e..0c936112 100644
--- a/src/caosdb/high_level_api.py
+++ b/src/caosdb/high_level_api.py
@@ -38,6 +38,7 @@ from caosdb.common.datatype import (BOOLEAN, DATETIME, DOUBLE, FILE, INTEGER,
 import caosdb as db
 
 from .apiutils import get_type_of_entity_with, create_flat_list
+import warnings
 
 from typing import Any, Optional, List, Union, Dict
 
@@ -47,6 +48,10 @@ from dataclasses import dataclass, fields
 from datetime import datetime
 from dateutil import parser
 
+warnings.warn("""EXPERIMENTAL! The high_level_api module is experimental and may be changed or
+removed in future. Its purpose is to give an impression on how the Python client user interface
+might be changed.""")
+
 
 def standard_type_for_high_level_type(high_level_record: "CaosDBPythonEntity",
                                       return_string: bool = False):
diff --git a/src/doc/future_caosdb.md b/src/doc/future_caosdb.md
new file mode 100644
index 00000000..a34d97ef
--- /dev/null
+++ b/src/doc/future_caosdb.md
@@ -0,0 +1,112 @@
+# The future of the CaosDB Python Client
+
+The current Python client has done us great services but its structure and the 
+way it is used sometimes feels outdated and clumsy. In this document we sketch
+how it might look different in future and invite everyone to comment or
+contribute to this development.
+
+At several locations in this document there will be links to discussion issues.
+If you want to discuss something new, you can create a new issue
+[here](https://gitlab.com/caosdb/caosdb-pylib/-/issues/new).
+
+## Overview
+Let's get a general impression before discussing single aspects.
+
+``` python
+import caosdb as db
+experiments = db.query("FIND Experiment")
+# print name and date for each `Experiment`
+for exp in experiments:
+   print(exp.name, exp.date)
+
+# suppose `Experiments` reference `Projects` which have a `Funding` Property
+one_exp = experiments[0]
+print(one_exp.Project.Funding)
+
+new_one = db.create_record("Experiment")
+new_one.date = "2022-01-01"
+new_one.name = "Needle Measurement"
+new_one.insert()
+```
+Related discussions:
+- [recursive retrieve in query](https://gitlab.com/caosdb/caosdb-pylib/-/issues/57)
+- [create_record function](https://gitlab.com/caosdb/caosdb-pylib/-/issues/58)
+- [data model utility](https://gitlab.com/caosdb/caosdb-pylib/-/issues/59)
+
+## Quickstart
+Note that you can try out one possible implementation using the 
+`caosdb.high_level_api` module. It is experimental and might be removed in 
+future!
+
+A `resolve_references` function allows to retrieve the referenced entities of 
+an entity, container or a query result set (which is a container).
+It has the following parameters which can also be supplied to the `query` 
+function:
+
+-   `deep`: Whether to use recursive retrieval
+-   `depth`: Maximum recursion depth
+-   `references`: Whether to use the supplied db.Container to resolve
+    references. This allows offline usage. Set it to None if you want to
+    automatically retrieve entities from the current CaosDB connection.
+
+In order to allow a quick look at the object structures an easily readable 
+serialization is provided by the `to_dict` function. It has the following 
+argument:
+-   `without_metadata`: Set this to True if you don\'t want to see
+    property metadata like \"unit\" or \"importance\".
+
+This function creates a simple dictionary containing a representation of
+the entity, which can be stored to disk and completely deserialized
+using the function `from_dict`.
+
+Furthermore, the `__str__` function uses this to display objects in yaml 
+format by default statement
+
+## Design Decisions
+
+### Dot Notation
+Analogue, to what Pandas does. Provide bracket notation 
+`rec.properties["test"]` for Properties with names that are in conflict with 
+default attributes or contain spaces (or other forbidden characters).
+
+- Raise Exception if attribute does not exist but is accessed?
+- How to deal with lists? b has a list as value: `a.b[0].c = 5`
+
+[Discussion](https://gitlab.com/caosdb/caosdb-pylib/-/issues/60)
+
+### Serialization
+What information needs to be contained in (meta)data? How compatible is it with 
+GRPC json serialization?
+
+
+### Recursive Retrieval
+I can resolve later and end up with the same result:
+`recs =db.query("FIND Experiment", depth=2)`  equals `recs = db.query("FIND Experiment"); recs = resolve_references(recs, depth=2)`
+
+[Discussion](https://gitlab.com/caosdb/caosdb-pylib/-/issues/57)
+
+### In-Place operations
+Default behavior is to return new objects instead of modifying them in-place.
+This can be changed with the argument `inplace=True`.
+Especially the following functions operate by default NOT in-place:
+- update
+- insert
+- retrieve
+- resolve_references
+[Discussion](https://gitlab.com/caosdb/caosdb-pylib/-/issues/61)
+
+## Extend Example
+``` python
+import caosdb as db
+
+dm = db.get_data_model()
+
+new_one = db.create_record(dm.Experiment)
+new_one.date = "2022-01-01"
+new_one.name = "Needle Measurement"
+new_one.dataset = db.create_record(dm.Dataset)
+new_one.dataset.voltage = (5, "V")
+new_one.dataset.pulses = [5, 5.3]
+inserted = new_one.insert()
+print("The new record has the ID:", inserted.id)
+```
-- 
GitLab