diff --git a/src/metldata/builtin_transformations/add_content_properties/model_transform.py b/src/metldata/builtin_transformations/add_content_properties/model_transform.py index d0378be..eb5c6c9 100644 --- a/src/metldata/builtin_transformations/add_content_properties/model_transform.py +++ b/src/metldata/builtin_transformations/add_content_properties/model_transform.py @@ -47,7 +47,7 @@ def add_content_properties( for cls_instruction in cls_instructions: try: - target_object = resolve_schema_object_path( + target_schema = resolve_schema_object_path( content_schema, cls_instruction.target_content.object_path ) except KeyError as e: @@ -58,12 +58,12 @@ def add_content_properties( ): raise EvitableTransformationError() - target_object.setdefault("properties", {})[ + target_schema.setdefault("properties", {})[ cls_instruction.target_content.property_name ] = deepcopy(cls_instruction.content_schema) if cls_instruction.required: - target_object.setdefault("required", []).append( + target_schema.setdefault("required", []).append( cls_instruction.target_content.property_name ) diff --git a/src/metldata/builtin_transformations/count_references/assumptions.py b/src/metldata/builtin_transformations/count_references/assumptions.py index b6df458..abb3192 100644 --- a/src/metldata/builtin_transformations/count_references/assumptions.py +++ b/src/metldata/builtin_transformations/count_references/assumptions.py @@ -165,10 +165,8 @@ def assert_object_path_exists( + f" in class {class_name}." ) from exc - # Check if the propert_name already exists in the model - if instruction.target_content.property_name not in target_schema.get( - "properties", {} - ): + # Check if the propert_name already exists in the model and raise an error if so + if instruction.target_content.property_name in target_schema.get("properties", {}): raise ModelAssumptionError( f"Property { instruction.target_content.property_name} does not exist" diff --git a/src/metldata/builtin_transformations/count_references/model_transform.py b/src/metldata/builtin_transformations/count_references/model_transform.py index 4a45a72..8343840 100644 --- a/src/metldata/builtin_transformations/count_references/model_transform.py +++ b/src/metldata/builtin_transformations/count_references/model_transform.py @@ -15,6 +15,7 @@ """Model transformation logic for the 'count references' transformation""" from schemapack.spec.schemapack import ( + ClassDefinition, SchemaPack, ) @@ -26,16 +27,18 @@ ) from metldata.transform.base import EvitableTransformationError +DEFAULT_PROPERTY_SCHEMA = {"type": "integer"} + def add_count_references( *, model: SchemaPack, instructions_by_class: dict[str, list[AddReferenceCountPropertyInstruction]], ) -> SchemaPack: - """The content properties are added to the model with the 'add_content_properties - step of the workflow. Thus, this function applies no transformation. - It only checks for EvitableTransformationError. + """The target content - object_names are added to the model with the 'add_content_properties + step of the workflow. Thus, this function only adds the property_name to a content schema. """ + updated_class_defs: dict[str, ClassDefinition] = {} for class_name, cls_instructions in instructions_by_class.items(): class_def = model.classes.get(class_name) @@ -45,15 +48,24 @@ def add_count_references( content_schema = class_def.content.json_schema_dict for cls_instruction in cls_instructions: + object_path = cls_instruction.target_content.object_path + property_name = cls_instruction.target_content.property_name try: - resolve_schema_object_path( - content_schema, cls_instruction.target_content.object_path - ) - except KeyError as e: - raise EvitableTransformationError() from e - - if cls_instruction.target_content.property_name in content_schema.get( - "properties", {} - ): + target_schema = resolve_schema_object_path(content_schema, object_path) + except KeyError as exc: + raise EvitableTransformationError() from exc + + if property_name in target_schema.get("properties", {}): raise EvitableTransformationError() - return model + + target_schema.setdefault("properties", {})[property_name] = ( + DEFAULT_PROPERTY_SCHEMA + ) + + updated_class_defs[class_name] = class_def.model_validate( + {**class_def.model_dump(), "content": content_schema} + ) + + model_dict = model.model_dump() + model_dict["classes"].update(updated_class_defs) + return SchemaPack.model_validate(model_dict) diff --git a/tests/fixtures/example_transformations/count_references/multiple/input.datapack.yaml b/tests/fixtures/example_transformations/count_references/multiple/input.datapack.yaml index e75b5de..9702cb2 100644 --- a/tests/fixtures/example_transformations/count_references/multiple/input.datapack.yaml +++ b/tests/fixtures/example_transformations/count_references/multiple/input.datapack.yaml @@ -23,8 +23,7 @@ resources: dataset_1: content: dac_contact: dac@example.org - file_summary: # <- - count: 0 + file_summary: {} # <- relations: files: - file_a @@ -34,24 +33,21 @@ resources: sample_x: content: description: Some sample. - file_summary: # <- - count: 0 + file_summary: {} # <- relations: files: - file_a - file_b sample_y: content: - file_summary: # <- - count: 0 + file_summary: {} # <- relations: files: - file_c Experiment: experiment_i: content: - sample_summary: # <- - count: 0 + sample_summary: {} # <- relations: samples: - sample_x diff --git a/tests/fixtures/example_transformations/count_references/multiple/input.schemapack.yaml b/tests/fixtures/example_transformations/count_references/multiple/input.schemapack.yaml index a800d6b..7e5305f 100644 --- a/tests/fixtures/example_transformations/count_references/multiple/input.schemapack.yaml +++ b/tests/fixtures/example_transformations/count_references/multiple/input.schemapack.yaml @@ -16,13 +16,7 @@ classes: "properties": { "dac_contact": { "type": "string" }, - "file_summary": - { - "type": "object", - "additionalProperties": false, - "properties": { "count": { "type": "integer" } }, - "required": ["count"], - }, + "file_summary": { "type": "object", "additionalProperties": true }, }, "type": "object", } @@ -46,13 +40,7 @@ classes: "properties": { "description": { "type": "string" }, - "file_summary": - { - "type": "object", - "additionalProperties": false, - "properties": { "count": { "type": "integer" } }, - "required": ["count"], - }, + "file_summary": { "type": "object", "additionalProperties": true }, }, "type": "object", } @@ -77,12 +65,7 @@ classes: { "description": { "type": "string" }, "sample_summary": - { - "type": "object", - "additionalProperties": false, - "properties": { "count": { "type": "integer" } }, - "required": ["count"], - }, + { "type": "object", "additionalProperties": true }, }, "type": "object", } diff --git a/tests/fixtures/example_transformations/count_references/multiple/transformed.schemapack.yaml b/tests/fixtures/example_transformations/count_references/multiple/transformed.schemapack.yaml index a800d6b..8676fe8 100644 --- a/tests/fixtures/example_transformations/count_references/multiple/transformed.schemapack.yaml +++ b/tests/fixtures/example_transformations/count_references/multiple/transformed.schemapack.yaml @@ -19,9 +19,8 @@ classes: "file_summary": { "type": "object", - "additionalProperties": false, + "additionalProperties": true, "properties": { "count": { "type": "integer" } }, - "required": ["count"], }, }, "type": "object", @@ -49,9 +48,8 @@ classes: "file_summary": { "type": "object", - "additionalProperties": false, + "additionalProperties": true, "properties": { "count": { "type": "integer" } }, - "required": ["count"], }, }, "type": "object", @@ -79,9 +77,8 @@ classes: "sample_summary": { "type": "object", - "additionalProperties": false, + "additionalProperties": true, "properties": { "count": { "type": "integer" } }, - "required": ["count"], }, }, "type": "object",