diff --git a/oteapi_dlite/strategies/generate.py b/oteapi_dlite/strategies/generate.py index c277703b..e80065e3 100644 --- a/oteapi_dlite/strategies/generate.py +++ b/oteapi_dlite/strategies/generate.py @@ -27,16 +27,6 @@ class DLiteStorageConfig(AttrDict): Either `label` or `datamodel` should be provided. """ - label: Optional[str] = Field( - None, - description="Label of DLite instance in the collection to serialise.", - ) - datamodel: Optional[str] = Field( - None, - description="URI to the datamodel of the new instance. Needed when " - "generating the instance from mappings. Cannot be combined with " - "`label`", - ) driver: Optional[str] = Field( None, description='Name of DLite driver (ex: "json").', @@ -60,6 +50,21 @@ class DLiteStorageConfig(AttrDict): "storage plugin." ), ) + label: Optional[str] = Field( + None, + description="Label of DLite instance in the collection to serialise.", + ) + datamodel: Optional[str] = Field( + None, + description="URI to the datamodel of the new instance. Needed when " + "generating the instance from mappings. Cannot be combined with " + "`label`", + ) + store_collection: bool = Field( + False, + description="Whether to store the entire collection instead of a " + "single instance. Cannot be combined with `label` or `datamodel`.", + ) allow_incomplete: Optional[bool] = Field( False, description="Whether to allow incomplete property mappings.", @@ -137,8 +142,9 @@ def get( allow_incomplete=config.allow_incomplete, ) inst = next(instances) - # fail if there are more instances - else: + elif config.store_collection: + inst = coll + else: # fail if there are more instances raise ValueError( "One of `label` or `datamodel` configurations should be given." ) diff --git a/requirements.txt b/requirements.txt index aa688a82..1b1e057b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -DLite-Python>=0.3.3,<0.4 +DLite-Python>=0.3.3,<0.5 numpy>=1.21,<2 oteapi-core>=0.1.2 Pillow>=9.0.1,<11 diff --git a/tests/strategies/test_generate_collection.py b/tests/strategies/test_generate_collection.py new file mode 100644 index 00000000..f79941ac --- /dev/null +++ b/tests/strategies/test_generate_collection.py @@ -0,0 +1,60 @@ +"""Test to store the entire collection with the generate strategy.""" +from pathlib import Path + +import dlite +from oteapi.datacache import DataCache + +from oteapi_dlite.strategies.generate import ( + DLiteGenerateConfig, + DLiteGenerateStrategy, +) +from oteapi_dlite.utils import get_meta + +thisdir = Path(__file__).resolve().parent +entitydir = thisdir / ".." / "entities" +outdir = thisdir / ".." / "output" + + +config = DLiteGenerateConfig( + functionType="application/vnd.dlite-generate", + configuration={ + "driver": "json", + "location": str(outdir / "coll.json"), + "options": "mode=w", + "store_collection": True, + }, +) + +coll = dlite.Collection("coll_id") + +Image = get_meta("http://onto-ns.com/meta/1.0/Image") +image = Image([2, 2, 1]) +image.data = [[[1], [2]], [[3], [4]]] +coll.add("image", image) +coll.add_relation("image", "rdf:type", "onto:Image") +coll.add_relation("image", "dcterms:title", "Madonna") + + +session = {"collection_id": coll.uuid} +DataCache().add(coll.asjson(), key=coll.uuid) + +generator = DLiteGenerateStrategy(config) +session.update(generator.initialize(session)) + +generator = DLiteGenerateStrategy(config) +session.update(generator.get(session)) + + +# Check that the data in the newly created generated json file matches our +# collection. +# Before loading the generated file, we delete the original collection +# to ensure that we are not just fetching it from the dlite cache... +del coll +with dlite.Storage("json", outdir / "coll.json", "mode=r") as s: + # Assume we don't know the collection uuid, but we know that there is only + # one collection in the json file + (coll_uuid,) = s.get_uuids("http://onto-ns.com/meta/0.1/Collection") + coll = s.load(id=coll_uuid) +assert coll.uri == "coll_id" +assert coll.nrelations == 5 +assert coll["image"] == image