From 29b7ec7de8b72f4c37e3bd928ee266dbea890cff Mon Sep 17 00:00:00 2001 From: Rico Koschmitzky Date: Tue, 20 Jun 2023 13:06:38 +0200 Subject: [PATCH] quickstart documentation update (#16) --- doc/sphinx_source/collections.md | 9 ++-- .../collections/emptycollection.md | 54 ++++++++++++++++++- .../collections/entitycollection.md | 1 - doc/sphinx_source/quickstart.md | 28 +++++++++- 4 files changed, 85 insertions(+), 7 deletions(-) diff --git a/doc/sphinx_source/collections.md b/doc/sphinx_source/collections.md index 92aba26..96a13f3 100644 --- a/doc/sphinx_source/collections.md +++ b/doc/sphinx_source/collections.md @@ -3,7 +3,10 @@ ```{include} collections/overview.md ``` -```{toctree} -collections/entitycollection.md -collections/emptycollection.md +## EntityCollection +```{include} collections/entitycollection.md +``` + +## EmptyCollection +```{include} collections/emptycollection.md ``` \ No newline at end of file diff --git a/doc/sphinx_source/collections/emptycollection.md b/doc/sphinx_source/collections/emptycollection.md index fbce5aa..7a7407f 100644 --- a/doc/sphinx_source/collections/emptycollection.md +++ b/doc/sphinx_source/collections/emptycollection.md @@ -1 +1,53 @@ -# EmptyCollection \ No newline at end of file +The concept of the `EmptyCollection` shares similarities with the [optional type](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html) found in various programming languages. It serves as a mechanism to handle the absence of values or empty results. + +Similar to optional types in other languages, the `EmptyCollection` provides a consistent interface and allows for operations and attribute access without the need for explicit checks for empty or null values. It acts as a container that represents the absence of a value or result. + +By utilizing the `EmptyCollection`, developers can write cleaner and more concise code by treating empty results as a valid state without the need for verbose conditional statements. This promotes a more functional programming style, allowing for seamless chaining and composition of operations even in scenarios where the result might be empty. + +Just as optional types in different programming languages offer methods or functions to check for presence (_isPresent()_) and provide fallback values (_orElse()_), the `EmptyCollection` provides a simple fallback functionality to handle cases where the collection is empty as it always evaluates to `False`. + +This demonstrates how you can implement a straightforward fallback mechanism using the or operator when retrieving the final data. +```python +from trackteroid import ( + Asset, + Query +) + +asset_collection = Query(Asset).by_name("DOESNT_EXIST").get_all() +print(asset_collection) +# output: EmptyCollection[Asset] + +print(not asset_collection) +# output: True + +print(asset_collection or "Oh vey... no results found.") +# output: Oh vey... no results found. +``` + +This code example showcases how to gracefully handle scenarios where the intermediate steps of querying, filtering, and retrieving data may result in an empty collection. By utilizing the or operator and providing an empty list as a fallback, we ensure that the final result is either the desired data or an empty list, mitigating the risk of errors or unexpected behavior. + +```python +from trackteroid import ( + Asset, + Query +) + +print( + # The Query result could already be empty. + # This is more likely when using criteria to filter results when querying. + Query(Asset).get_first( + projections=[ + "versions.is_published", + "versions.user.username" + ] + ). + # An asset could have no versions or at least no versions that have been marked as `is_published`. + versions.filter( + lambda avc: avc.is_published[0] + ). + user.username + # Finally, we retrieve the username of the user associated with the filtered versions. + # If at any point we encounter no results, we can gracefully handle it by providing an empty list as a fallback. + or [] +) +``` diff --git a/doc/sphinx_source/collections/entitycollection.md b/doc/sphinx_source/collections/entitycollection.md index 5b55e2a..e69de29 100644 --- a/doc/sphinx_source/collections/entitycollection.md +++ b/doc/sphinx_source/collections/entitycollection.md @@ -1 +0,0 @@ -# EntityCollection \ No newline at end of file diff --git a/doc/sphinx_source/quickstart.md b/doc/sphinx_source/quickstart.md index db072f9..0a2c7b5 100644 --- a/doc/sphinx_source/quickstart.md +++ b/doc/sphinx_source/quickstart.md @@ -52,9 +52,8 @@ However, you also have the flexibility to initialize your own `Session` object a from trackteroid import ( AssetVersion, Query, - SESSION, + SCHEMA ) -from trackteroid.query import SCHEMA from trackteroid.session import Session my_session = Session(server_url="") @@ -219,6 +218,7 @@ The EntityCollection class provides higher-order methods that accept functions a The presented example highlights a subset of the transformation methods available. ```python from pprint import pprint + from tracteroid import ( Query, Asset, @@ -309,11 +309,35 @@ print(f"(a + b) - ((a - b) + (b - a)) = {collection_a.intersection(collection_b) #### Fetching Attributes +As Trackteroid's default Sessions disable the _autopolulate_ feature, it is possible to work with unprojected data. In such cases, you may need to fetch missing attributes when required. This can be accomplished using the `fetch_attributes` method on your collection. +```python +from trackteroid import ( + Asset, + Query, + Task +) +# assuming you receive a collection from somewhere +some_asset_collection = Query(Asset).by_name(Task, "%").get_all(limit=10) +print(some_asset_collection) +# output: EntityCollection[Asset]{10} +print( + some_asset_collection. + fetch_attributes(Task.State.name, "versions"). + filter( + lambda a: a.versions and a.Task.State.name[0] == "Blocked" + ) + .Task.State.name +) +# output: ['Blocked'] +``` #### Fallback Concept +```{include} collections/emptycollection.md +``` + ## Authoring ### CRUD (Create, Read, Update, Delete)