Skip to content

Commit 795b63d

Browse files
authored
Merge pull request #643 from hubmapconsortium/karlburke/AddAttribsToTrackMultiAssayComponents
Karlburke/add attribs to track multi assay components
2 parents cc29504 + c5aebe4 commit 795b63d

File tree

2 files changed

+91
-2
lines changed

2 files changed

+91
-2
lines changed

src/schema/provenance_schema.yaml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# - type: data type of the property, one of the following: string|integer|boolean|list|json_string
44
# - generated: whether the property is auto generated (either with a `before_create_trigger` or not) or user provided, default to false
55
# - required_on_create: whether the property is required from user reqeust JSON for entity creation via POST
6-
# - immutable: whether the property can NOT be updated once being created, default to false
6+
# - immutable: true indicates the property can NOT be updated after the entity is created, default to false
77
# - transient: whether the property to persist in database or not, default to false
88
# - exposed: whether the property gets returned to the user or not, default to true
99
# - trigger types: before_create_trigger|after_create_trigger|before_update_trigger|after_update_trigger|on_read_trigger, one property can have none (default) or more than one triggers
@@ -457,6 +457,28 @@ ENTITIES:
457457
immutable: true
458458
description: "The list of the uuids of next revision datasets"
459459
on_read_trigger: get_next_revision_uuids
460+
superseded_associated_processed_component_uuids:
461+
type: list
462+
# This property gets set via a PUT by entity-api /entities/{{dataset_uuid}} to point to the Multi-Assay Dataset
463+
# superseding the entity with this attribute, so we can't define it as `immutable: true`.
464+
# Modifications to an existing attribute are rejected using a validation trigger.
465+
immutable: false
466+
description: "List of uuids of existing Datasets used to construct this Multi-Assay Dataset, when present"
467+
before_property_create_validators:
468+
- verify_multi_assay_dataset_components
469+
before_property_update_validators:
470+
- verify_multi_assay_dataset_components
471+
new_associated_multi_assay_uuid:
472+
type: string
473+
# This property gets set via a PUT by entity-api /entities/{{dataset_uuid}} to point to the Multi-Assay Dataset
474+
# superseding the entity with this attribute, so we can't define it as `immutable: true`.
475+
# Modifications to an existing attribute are rejected using a validation trigger.
476+
immutable: false
477+
description: "The uuid of the Multi-Assay Dataset constructed using this Dataset, when present"
478+
before_property_create_validators:
479+
- verify_multi_assay_dataset_components
480+
before_property_update_validators:
481+
- verify_multi_assay_dataset_components
460482
# No like image and metadata files handling for Donor/Sample
461483
# Dataset has only one thumbnail file
462484
thumbnail_file:
@@ -609,6 +631,8 @@ ENTITIES:
609631
after_update_trigger: link_publication_to_associated_collection
610632
assigned_to_group_name: null # This assigned_to_group_name is Dataset specific, Publication doesn't have it
611633
ingest_task: null # This ingest_task is Dataset specific, Publication doesn't have it
634+
new_associated_multi_assay_uuid: null # Dataset-only attribute of Multi-Assay Dataset relationships
635+
superseded_associated_processed_component_uuids: null # Dataset-only attribute of Multi-Assay Dataset relationships
612636

613637
############################################# Donor #############################################
614638
Donor:

src/schema/schema_validators.py

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ def validate_application_header_before_entity_create(normalized_entity_type, req
4646

4747

4848
"""
49-
@TODO-KBKBKB redo doc...
5049
Validate the specified value for a Dataset's dataset_type is in the valueset UBKG recognizes.
5150
5251
Parameters
@@ -630,6 +629,72 @@ def validate_group_name(property_key, normalized_entity_type, request, existing_
630629
raise ValueError("Invalid group in 'assigned_to_group_name'. Must be a data provider")
631630

632631

632+
"""
633+
Trigger event method to verify tracking fields new_associated_multi_assay_uuid and
634+
superseded_associated_processed_component_uuids are set coherently on Multi-Assay Datasets and
635+
their component Datasets.
636+
637+
Parameters
638+
----------
639+
property_key : str
640+
The target property key
641+
normalized_type : str
642+
One of the types defined in the schema yaml: Dataset
643+
user_token: str
644+
The user's globus nexus token
645+
existing_data_dict : dict
646+
A dictionary that contains all existing entity properties as Neo4j data types.
647+
N.B. elements are not Python data types and must be converted with utilities like schema_manager.convert_str_literal()
648+
new_data_dict : dict
649+
The request input data as Python data structures converted from JSON, which has passed schema validation, entity
650+
validation, and possibly other property validations.
651+
"""
652+
653+
def verify_multi_assay_dataset_components(property_key, normalized_type, user_token, existing_data_dict, new_data_dict):
654+
655+
if 'superseded_associated_processed_component_uuids' in existing_data_dict \
656+
and 'superseded_associated_processed_component_uuids' in new_data_dict:
657+
raise ValueError( f"'superseded_associated_processed_component_uuids' is already set on"
658+
f" {existing_data_dict['uuid']}.")
659+
if 'new_associated_multi_assay_uuid' in existing_data_dict \
660+
and 'new_associated_multi_assay_uuid' in new_data_dict:
661+
raise ValueError( f"'new_associated_multi_assay_uuid' is already set on"
662+
f" {existing_data_dict['uuid']}.")
663+
if 'superseded_associated_processed_component_uuids' in new_data_dict \
664+
and 'new_associated_multi_assay_uuid' in new_data_dict:
665+
raise ValueError( f"'superseded_associated_processed_component_uuids' and 'new_associated_multi_assay_uuid'"
666+
f" cannot both be specified on a single Dataset.")
667+
if 'superseded_associated_processed_component_uuids' in new_data_dict \
668+
and 'new_associated_multi_assay_uuid' in existing_data_dict:
669+
raise ValueError( f"'superseded_associated_processed_component_uuids' cannot be set on"
670+
f" existing Dataset {existing_data_dict['uuid']} because it is a component Dataset of"
671+
f" {existing_data_dict['new_associated_multi_assay_uuid']}.")
672+
if 'new_associated_multi_assay_uuid' in new_data_dict \
673+
and 'superseded_associated_processed_component_uuids' in existing_data_dict:
674+
# Convert the string from Neo4j the Python list
675+
supersededComponentDatasets = schema_manager.convert_str_literal(existing_data_dict['superseded_associated_processed_component_uuids'])
676+
raise ValueError( f"'new_associated_multi_assay_uuid' cannot be set on"
677+
f" existing Dataset {existing_data_dict['uuid']} because it is a Multi-Assay Dataset"
678+
f" with {len(supersededComponentDatasets)}"
679+
f" component Datasets it supersedes.")
680+
# If no contradictions above have caused a ValueError, check if new data contains UUIDs for valid entities.
681+
if 'new_associated_multi_assay_uuid' in new_data_dict:
682+
proposedMultiAssayDataset = schema_neo4j_queries.get_entity(schema_manager.get_neo4j_driver_instance()
683+
, new_data_dict['new_associated_multi_assay_uuid'])
684+
if len(proposedMultiAssayDataset) < 1:
685+
raise ValueError( f"'new_associated_multi_assay_uuid' value"
686+
f" {new_data_dict['new_associated_multi_assay_uuid']}"
687+
f" does not exist.")
688+
if 'superseded_associated_processed_component_uuids' in new_data_dict:
689+
for uuid in new_data_dict['superseded_associated_processed_component_uuids']:
690+
proposedComponentDataset = schema_neo4j_queries.get_entity( schema_manager.get_neo4j_driver_instance()
691+
, uuid)
692+
if len(proposedComponentDataset) < 1:
693+
raise ValueError(f"'superseded_associated_processed_component_uuids' entry with value"
694+
f" {uuid} does not exist.")
695+
696+
# fall out successfully if no raise() occurred.
697+
return
633698

634699
####################################################################################################
635700
## Internal Functions

0 commit comments

Comments
 (0)