Skip to content

Commit 37ac602

Browse files
author
notactuallyfinn
committed
added draft for the adr of the internal data model
1 parent 4bdad2b commit 37ac602

1 file changed

Lines changed: 107 additions & 0 deletions

File tree

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<!--
2+
SPDX-FileCopyrightText: 2026 German Aerospace Center (DLR), Forschungszentrum Jülich, Helmholtz-Zentrum Dresden-Rossendorf
3+
4+
SPDX-License-Identifier: CC-BY-SA-4.0
5+
-->
6+
7+
# Capabilities of the internal data model
8+
9+
* Status: proposed
10+
* Date: 2026-03-17
11+
12+
## Context and Problem Statement
13+
14+
As decided in [ADR 2](./0002-use-a-common-data-model) the metadata that is created and manipulated by HERMES is stored as JSON-LD.
15+
But the critical questions how it is stored and how it can be accessed are not yet discussed.
16+
There are a few requirements though:
17+
* The data should probably be stored in some form of expanded JSON-LD.
18+
* Read and write access should be possible with non expanded JSON-LD (the values then have to be expanded).
19+
* The objects should be as user friendly as possible (supply many different ways to interact with the data).
20+
21+
## Considered Options
22+
23+
* Providing our own JSON-LD wrapper classes
24+
25+
## Decision Outcome
26+
27+
Chosen option: "", because comes out best.
28+
29+
## Pros and Cons of the Options
30+
31+
### Providing our own JSON-LD wrapper classes
32+
33+
This includes a base class (supplying basic functions like expansion and compaction named `ld_container`), a class representing dictionaries (named `ld_dict`) and one for list-like objects (like @list and @set named `ld_list`). Additionally a wrapper class (named SoftwareMetdata) for complete sets of metadata of SoftwareSourceCode and SoftwareApplication (schema.org types) is supplied which is an `ld_dict` that has a standard context and supplies a function to load from the HERMES cache.
34+
Furthermore for processing of JSON-LD the `JsonLdProcessor` from `jsonld` from the [pyld](https://pypi.org/project/PyLD/) package is used.
35+
36+
The following features will be supported:
37+
```python
38+
from hermes.model import SoftwareMetadata
39+
40+
# initializing SoftwareMetadata objects
41+
SoftwareMetadata() # contains no data and only standard context
42+
SoftwareMetadata(extra_vocabs=ctx) # contains no data but extra context (ctx is a dict mapping shortend prefixes to full iri's)
43+
SoftwareMetadata(data) # data can be any valid JSON-LD dictionary (where dicts and lists can be replaced by ld_dicts and ld_lists)
44+
SoftwareMetadata(data, ctx) # contains the given data and context additionally to the standard context
45+
46+
metadata = SoftwareMetadata(data)
47+
# getting values from ld_dicts (here metadata)
48+
# key may be compacted or expanded, returned is always an ld_list
49+
metadata[key] # KeyError if no value in metadata for that key
50+
metadata.get(key, default_value) # if default_value is given, it is returned when no entry for key is in metadata
51+
metadata.set_default(key, default_value) # inserts the default_value before returning metadata[key] if no entry for key is in metadata
52+
# default value may only be a value that can be inserted as a value of key
53+
# iterating over ld_dicts
54+
for key, value in metadata.items(): # iterating over all key, value pairs, value is metadata[key]
55+
# do stuff
56+
for key in metadata.keys(): # iterating over all expanded keys
57+
# do stuff
58+
for compact_key in metadata.compact_keys(): # iterating over all compacted keys
59+
# do stuff
60+
# setting values in ld_dicts
61+
# key may be compacted or expanded, value may be any valid JSON-LD value (where dicts and lists can be replaced by ld_dicts and ld_lists)
62+
metadata[key] = value
63+
metadata.set_default(key, value) # sets metadata[key] to value if metadata had no entry for key before
64+
metadata.update(values) # values is a dict mapping keys to values (each with the same constrictions as key and value)
65+
metadata.emplace(key) # equivalent to metadata[key] = [] if key not in metadata
66+
# misc functions for ld_dicts
67+
bool(metadata) # False if and only if metadata == {}
68+
metadata == value # ld_dicts are comparable to dicts and ld_dicts
69+
metadata != value
70+
key in metadata # checks if there is an entry for that key
71+
metadata.to_python() # return a pythonized version of the contents (compacted version where all ld_dicts are dicts and ld_lists lists)
72+
del metadata[key] # removes the entry of key
73+
metadata.ref # returns {"@id": metadata["@id"]}
74+
75+
metadata_list = SoftwareMetadata(data)[key]
76+
# getting values from ld_lists (here metadata_list)
77+
# returned single values can be ld_lists, ld_dicts, ints, floats, bools, strings, dates, datetimes, times
78+
metadata_list[index] # index may be int or slice (when slice a list of single values is returned)
79+
# iterating over ld_lists
80+
for item in metadata_list: # iterating over all items
81+
# do stuff
82+
for index in range(len(metadata_list)): # iterate over all indices
83+
# do stuff
84+
# setting values in ld_lists
85+
# value may be any valid JSON-LD value (where dicts and lists can be replaced by ld_dicts and ld_lists)
86+
metadata_list[index] = value # index is int
87+
metadata_list[index] = values # index is slice and values is some iterable of values that share the constrictions of value
88+
metadata_list.append(value)
89+
metadata_list.extend(values) # values is some iterable of values that share the constrictions of value
90+
# misc functions for ld_lists
91+
len(metadata_list) # gives the number of elements
92+
metadata_list == value # ld_lists are comparable to ld_lists and lists
93+
metadata_list != value
94+
metadata_list.to_python() # return a pythonized version of the contents (compacted version where all ld_dicts are dicts and ld_lists lists)
95+
del metadata_list[index] # removes the entry/ entries at index, where index is int or slice
96+
value in metadata_list # checks if a value is in the list
97+
98+
metadata = SoftwareMetadata(data)
99+
# additional valuable information
100+
metadata_list_copy = metadata_list = metadata[key] # assume metadata has an entry for key
101+
metadata_list.append(value) # any operation here will have an effect on metadata and metadata_list_copy (this works for every nesting depth)
102+
```
103+
104+
* Good, because it keeps the expanded JSON-LD data safe from getting invalidated by accidental wrong manipulation
105+
* Good, because it offers much flexibility and easy access for the user/ plugin developers
106+
* Good, because it could be extended to record provenance information on every manipulation
107+
* Bad, because hard to maintain

0 commit comments

Comments
 (0)