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