diff --git a/Makefile b/Makefile index 8c85b4081c..b1522d0075 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ gen-project: $(PYMODEL) -d $(DEST) $(SOURCE_SCHEMA_PATH) && mv $(DEST)/*.py $(PYMODEL) mv $(DEST)/prefixmap/biolink_model.yaml $(DEST)/prefixmap/biolink-model-prefix-map.json mv $(PYMODEL)/biolink*.py $(PYMODEL)/model.py - $(RUN) gen-pydantic --meta None src/biolink_model/schema/biolink_model.yaml > $(PYMODEL)/pydanticmodel_v2.py + $(RUN) python scripts/biolink_pydantic_generator.py src/biolink_model/schema/biolink_model.yaml > $(PYMODEL)/pydanticmodel_v2.py $(RUN) gen-owl --mergeimports --no-metaclasses --no-type-objects --add-root-classes --mixins-as-expressions src/biolink_model/schema/biolink_model.yaml > $(DEST)/owl/biolink_model.owl.ttl cp biolink-model.yaml src/biolink_model/schema/biolink_model.yaml cp attributes.yaml src/biolink_model/schema/attributes.yaml diff --git a/scripts/biolink_pydantic_generator.py b/scripts/biolink_pydantic_generator.py new file mode 100644 index 0000000000..9b53eb1908 --- /dev/null +++ b/scripts/biolink_pydantic_generator.py @@ -0,0 +1,205 @@ +""" +Custom PydanticGenerator for biolink-model that adds deterministic +hash-based Association IDs to generated Pydantic classes. + +Supports runtime-configurable identity strategies: + - SPO_Q_KLAT_PKS (default): SPO + qualifiers + KL + AT + primary_knowledge_source + publications + - QUALIFIER_BASED: SPO + qualifiers + KL + AT + primary_knowledge_source (no pubs) + - ALL_FIELDS: every field on the class except id + - CUSTOM: user-specified field list +""" +import sys +from dataclasses import dataclass + +from linkml.generators.pydanticgen.pydanticgen import PydanticGenerator +from linkml.generators.pydanticgen.template import Import, Imports, ObjectImport +from linkml_runtime.utils.formatutils import camelcase, underscore + + +# Fields shared by QUALIFIER_BASED and SPO_Q_KLAT_PKS strategies +CORE_IDENTITY_FIELDS = [ + "subject", + "predicate", + "object", + "negated", + "knowledge_level", + "agent_type", + "primary_knowledge_source", +] + +# Additional fields for the SPO_Q_KLAT_PKS "standard" strategy +STANDARD_EXTRA_FIELDS = [ + "publications", +] + + +def _compute_qualifier_slots(generator: PydanticGenerator) -> dict[str, list[str]]: + """ + For every class descending from 'association', discover qualifier slots + via the slot is_a hierarchy and combine with CORE_IDENTITY_FIELDS. + """ + sv = generator.schemaview + identity_map: dict[str, list[str]] = {} + + for class_name in sv.class_descendants("association", reflexive=True): + qualifier_slots = [] + for slot_name in sv.class_slots(class_name): + ancestors = sv.slot_ancestors(slot_name, reflexive=True) + if "qualifier" in ancestors: + qualifier_slots.append(underscore(slot_name)) + + all_identity = sorted(set(CORE_IDENTITY_FIELDS + qualifier_slots)) + identity_map[camelcase(class_name)] = all_identity + + return identity_map + + +def _compute_standard_slots(qualifier_map: dict[str, list[str]]) -> dict[str, list[str]]: + """ + Extend the qualifier-based map with STANDARD_EXTRA_FIELDS (publications) + to produce the SPO+Q+KL+AT+pubs strategy. + """ + return { + class_name: sorted(set(fields + STANDARD_EXTRA_FIELDS)) + for class_name, fields in qualifier_map.items() + } + + +def _build_slots_dict_code(var_name: str, slots_map: dict[str, list[str]]) -> str: + """Generate a Python dict literal for a named slot mapping.""" + lines = [f"{var_name}: dict[str, list[str]] = {{"] + for class_name in sorted(slots_map.keys()): + lines.append(f' "{class_name}": {slots_map[class_name]!r},') + lines.append("}") + return "\n".join(lines) + + +# --- Injected runtime code (becomes part of pydanticmodel_v2.py) --- + +ID_STRATEGY_CODE = ''' +class IdStrategy(enum.Enum): + """Strategy for selecting which fields define Association identity.""" + SPO_Q_KLAT_PKS = "spo_q_klat_pks" # SPO + qualifiers + KL + AT + PKS + pubs (default) + QUALIFIER_BASED = "qualifier_based" # SPO + qualifiers + KL + AT + PKS (no pubs) + ALL_FIELDS = "all_fields" # Every field except id + CUSTOM = "custom" # User-specified field list + + +class AssociationIdConfig: + """ + Process-level configuration for deterministic Association ID generation. + + Set once at startup before constructing any Association instances: + + AssociationIdConfig.strategy = IdStrategy.ALL_FIELDS + + For CUSTOM strategy, also set custom_fields: + + AssociationIdConfig.strategy = IdStrategy.CUSTOM + AssociationIdConfig.custom_fields = ["subject", "predicate", "object"] + """ + strategy: IdStrategy = IdStrategy.SPO_Q_KLAT_PKS + custom_fields: list[str] = [] +''' + +DETERMINISTIC_ID_MIXIN_CODE = ''' +class DeterministicIdMixin(ConfiguredBaseModel): + """ + Mixin that auto-generates a deterministic hash-based ID for Association + instances when no explicit ID is provided. + + The fields included in the hash depend on AssociationIdConfig.strategy. + """ + + @model_validator(mode="before") + @classmethod + def _generate_deterministic_id(cls, data: Any) -> Any: + if isinstance(data, dict): + existing_id = data.get("id") + if existing_id is None or existing_id is ...: + class_name = cls.__name__ + strategy = AssociationIdConfig.strategy + + if strategy == IdStrategy.ALL_FIELDS: + identity_fields = sorted( + f for f in cls.model_fields if f != "id" + ) + elif strategy == IdStrategy.CUSTOM: + identity_fields = sorted(AssociationIdConfig.custom_fields) + elif strategy == IdStrategy.QUALIFIER_BASED: + identity_fields = _QUALIFIER_IDENTITY_SLOTS.get(class_name, []) + else: # SPO_Q_KLAT_PKS (default) + identity_fields = _STANDARD_IDENTITY_SLOTS.get(class_name, []) + + parts = [class_name] + for field_name in identity_fields: + value = data.get(field_name) + parts.append(field_name) + parts.append( + json.dumps(value, sort_keys=True, default=str) + if value is not None else "null" + ) + hash_input = "|".join(parts) + hash_value = hashlib.sha256( + hash_input.encode("utf-8") + ).hexdigest() + data["id"] = f"uuid:{hash_value}" + return data +''' + + +@dataclass +class BiolinkPydanticGenerator(PydanticGenerator): + """PydanticGenerator with deterministic Association ID injection.""" + + def __post_init__(self): + super().__post_init__() + + # Compute both slot maps from schema's slot is_a hierarchy + qualifier_map = _compute_qualifier_slots(self) + standard_map = _compute_standard_slots(qualifier_map) + + qualifier_slots_code = _build_slots_dict_code( + "_QUALIFIER_IDENTITY_SLOTS", qualifier_map + ) + standard_slots_code = _build_slots_dict_code( + "_STANDARD_IDENTITY_SLOTS", standard_map + ) + + # Inject enum, config, lookup dicts, and mixin class + if self.injected_classes is None: + self.injected_classes = [] + self.injected_classes.append(ID_STRATEGY_CODE) + self.injected_classes.append(qualifier_slots_code) + self.injected_classes.append(standard_slots_code) + self.injected_classes.append(DETERMINISTIC_ID_MIXIN_CODE) + + # Add required imports + extra_imports = ( + Imports() + + Import(module="enum") + + Import(module="hashlib") + + Import(module="json") + + Import(module="pydantic", + objects=[ObjectImport(name="model_validator")]) + ) + if self.imports is None: + self.imports = extra_imports + else: + self.imports = self.imports + extra_imports + + def after_render_template(self, template: str, sv) -> str: + """Splice DeterministicIdMixin into Association's bases.""" + template = template.replace( + "class Association(Entity):", + "class Association(DeterministicIdMixin, Entity):", + ) + return template + + +if __name__ == "__main__": + gen = BiolinkPydanticGenerator( + sys.argv[1], + metadata_mode=None, + ) + print(gen.serialize(), end="") diff --git a/src/biolink_model/datamodel/pydanticmodel_v2.py b/src/biolink_model/datamodel/pydanticmodel_v2.py index b89ba654ea..18358a85f7 100644 --- a/src/biolink_model/datamodel/pydanticmodel_v2.py +++ b/src/biolink_model/datamodel/pydanticmodel_v2.py @@ -1,5 +1,8 @@ -from __future__ import annotations +from __future__ import annotations +import enum +import hashlib +import json import re import sys from datetime import ( @@ -7,8 +10,8 @@ datetime, time ) -from decimal import Decimal -from enum import Enum +from decimal import Decimal +from enum import Enum from typing import ( Any, ClassVar, @@ -22,7 +25,11 @@ ConfigDict, Field, RootModel, - field_validator + SerializationInfo, + SerializerFunctionWrapHandler, + field_validator, + model_serializer, + model_validator ) @@ -32,6 +39,8 @@ class ConfiguredBaseModel(BaseModel): model_config = ConfigDict( + serialize_by_alias = True, + validate_by_name = True, validate_assignment = True, validate_default = True, extra = "forbid", @@ -39,7 +48,7 @@ class ConfiguredBaseModel(BaseModel): use_enum_values = True, strict = False, ) - pass + @@ -61,6 +70,291 @@ def __contains__(self, key:str) -> bool: return key in self.root + + +class IdStrategy(enum.Enum): + """Strategy for selecting which fields define Association identity.""" + SPO_Q_KLAT_PKS = "spo_q_klat_pks" # SPO + qualifiers + KL + AT + PKS + pubs (default) + QUALIFIER_BASED = "qualifier_based" # SPO + qualifiers + KL + AT + PKS (no pubs) + ALL_FIELDS = "all_fields" # Every field except id + CUSTOM = "custom" # User-specified field list + + +class AssociationIdConfig: + """ + Process-level configuration for deterministic Association ID generation. + + Set once at startup before constructing any Association instances: + + AssociationIdConfig.strategy = IdStrategy.ALL_FIELDS + + For CUSTOM strategy, also set custom_fields: + + AssociationIdConfig.strategy = IdStrategy.CUSTOM + AssociationIdConfig.custom_fields = ["subject", "predicate", "object"] + """ + strategy: IdStrategy = IdStrategy.SPO_Q_KLAT_PKS + custom_fields: list[str] = [] + + +_QUALIFIER_IDENTITY_SLOTS: dict[str, list[str]] = { + "AnatomicalEntityHasPartAnatomicalEntityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "AnatomicalEntityPartOfAnatomicalEntityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "AnatomicalEntityToAnatomicalEntityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "AnatomicalEntityToAnatomicalEntityOntogenicAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "Association": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "BehaviorToBehavioralFeatureAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'sex_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "BiologicalProcessOrActivityToAnatomicalEntityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "BiologicalProcessOrActivityToBiologicalProcessOrActivityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "BiologicalProcessOrActivityToGeneOrGeneProductOrGeneFamilyAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "CaseToDiseaseAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'onset_qualifier', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "CaseToGeneAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "CaseToPhenotypicFeatureAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'onset_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'sex_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "CaseToVariantAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "CausalGeneToDiseaseAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_form_or_variant_qualifier'], + "CellLineAsAModelOfDiseaseAssociation": ['agent_type', 'anatomical_context_qualifier', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'object_specialization_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier', 'subject_specialization_qualifier'], + "CellLineToDiseaseOrPhenotypicFeatureAssociation": ['agent_type', 'anatomical_context_qualifier', 'disease_context_qualifier', 'knowledge_level', 'negated', 'object', 'object_specialization_qualifier', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject', 'subject_specialization_qualifier'], + "ChemicalAffectsBiologicalEntityAssociation": ['agent_type', 'anatomical_context_qualifier', 'causal_mechanism_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_context_qualifier', 'object_direction_qualifier', 'object_form_or_variant_qualifier', 'object_part_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'species_context_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_context_qualifier', 'subject_derivative_qualifier', 'subject_direction_qualifier', 'subject_form_or_variant_qualifier', 'subject_part_qualifier'], + "ChemicalAffectsGeneAssociation": ['agent_type', 'anatomical_context_qualifier', 'causal_mechanism_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_context_qualifier', 'object_direction_qualifier', 'object_form_or_variant_qualifier', 'object_part_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'species_context_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_context_qualifier', 'subject_derivative_qualifier', 'subject_direction_qualifier', 'subject_form_or_variant_qualifier', 'subject_part_qualifier'], + "ChemicalEntityAssessesNamedThingAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "ChemicalEntityOrGeneOrGeneProductRegulatesGeneAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "ChemicalEntityToBiologicalProcessAssociation": ['agent_type', 'anatomical_context_qualifier', 'knowledge_level', 'negated', 'object', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'species_context_qualifier', 'subject'], + "ChemicalEntityToChemicalDerivationAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'species_context_qualifier', 'subject'], + "ChemicalEntityToChemicalEntityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'species_context_qualifier', 'subject'], + "ChemicalEntityToDiseaseOrPhenotypicFeatureAssociation": ['agent_type', 'anatomical_context_qualifier', 'disease_context_qualifier', 'knowledge_level', 'negated', 'object', 'object_specialization_qualifier', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject', 'subject_specialization_qualifier'], + "ChemicalEntityToPathwayAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "ChemicalGeneInteractionAssociation": ['agent_type', 'anatomical_context_qualifier', 'causal_mechanism_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_context_qualifier', 'object_direction_qualifier', 'object_form_or_variant_qualifier', 'object_part_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'subject', 'subject_context_qualifier', 'subject_derivative_qualifier', 'subject_form_or_variant_qualifier', 'subject_part_qualifier'], + "ChemicalOrDrugOrTreatmentAdverseEventAssociation": ['agent_type', 'anatomical_context_qualifier', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'object_specialization_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier', 'subject_specialization_qualifier'], + "ChemicalOrDrugOrTreatmentSideEffectAssociation": ['agent_type', 'anatomical_context_qualifier', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'object_specialization_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier', 'subject_specialization_qualifier'], + "ChemicalOrDrugOrTreatmentToDiseaseOrPhenotypicFeatureAssociation": ['agent_type', 'anatomical_context_qualifier', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'object_specialization_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier', 'subject_specialization_qualifier'], + "ContributorAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "CorrelatedGeneToDiseaseAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier', 'subject_form_or_variant_qualifier'], + "DiseaseAssociatedWithResponseToChemicalEntityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'response_context_qualifier', 'response_target_context_qualifier', 'subject'], + "DiseaseOrPhenotypicFeatureToGeneticInheritanceAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "DiseaseOrPhenotypicFeatureToLocationAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "DiseaseToExposureEventAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "DiseaseToPhenotypicFeatureAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'onset_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'sex_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "DrugToGeneAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "DruggableGeneToDiseaseAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier', 'subject_form_or_variant_qualifier'], + "EntityToDiseaseAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "EntityToPhenotypicFeatureAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "ExonToTranscriptRelationship": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "ExposureEventToOutcomeAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'population_context_qualifier', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject', 'temporal_context_qualifier'], + "ExposureEventToPhenotypicFeatureAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'sex_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "FunctionalAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "GeneAffectsChemicalAssociation": ['agent_type', 'anatomical_context_qualifier', 'causal_mechanism_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_context_qualifier', 'object_derivative_qualifier', 'object_direction_qualifier', 'object_form_or_variant_qualifier', 'object_part_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'species_context_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_context_qualifier', 'subject_derivative_qualifier', 'subject_direction_qualifier', 'subject_form_or_variant_qualifier', 'subject_part_qualifier'], + "GeneAsAModelOfDiseaseAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier', 'subject_form_or_variant_qualifier'], + "GeneFamilyToGeneOrGeneProductOrGeneFamilyAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "GeneHasVariantThatContributesToDiseaseAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_form_or_variant_qualifier'], + "GeneOrGeneProductOrGeneFamilyToAnatomicalEntityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "GeneOrGeneProductOrGeneFamilyToBiologicalProcessOrActivityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "GeneRegulatesGeneAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'species_context_qualifier', 'subject'], + "GeneToDiseaseAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_form_or_variant_qualifier'], + "GeneToExpressionSiteAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'object_specialization_qualifier', 'predicate', 'primary_knowledge_source', 'qualifier', 'stage_qualifier', 'subject'], + "GeneToGeneAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "GeneToGeneCoexpressionAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'stage_qualifier', 'subject'], + "GeneToGeneFamilyAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "GeneToGeneHomologyAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "GeneToGeneProductRelationship": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "GeneToGoTermAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "GeneToPathwayAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "GeneToPhenotypicFeatureAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'sex_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier', 'subject_form_or_variant_qualifier'], + "GenomicSequenceLocalization": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "GenotypeAsAModelOfDiseaseAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "GenotypeToDiseaseAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "GenotypeToGeneAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "GenotypeToGenotypePartAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "GenotypeToPhenotypicFeatureAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'sex_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "GenotypeToVariantAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "InformationContentEntityToNamedThingAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "MacromolecularMachineHasSubstrateAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "MacromolecularMachineToBiologicalProcessAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'species_context_qualifier', 'subject'], + "MacromolecularMachineToCellularComponentAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'species_context_qualifier', 'subject'], + "MacromolecularMachineToMolecularActivityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'species_context_qualifier', 'subject'], + "MaterialSampleDerivationAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "MaterialSampleToDiseaseOrPhenotypicFeatureAssociation": ['agent_type', 'anatomical_context_qualifier', 'disease_context_qualifier', 'knowledge_level', 'negated', 'object', 'object_specialization_qualifier', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject', 'subject_specialization_qualifier'], + "MolecularActivityToChemicalEntityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "MolecularActivityToMolecularActivityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "MolecularActivityToPathwayAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "NamedThingAssociatedWithLikelihoodOfNamedThingAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_context_qualifier', 'population_context_qualifier', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_context_qualifier'], + "OrganismTaxonToEnvironmentAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "OrganismTaxonToOrganismTaxonAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "OrganismTaxonToOrganismTaxonInteraction": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "OrganismTaxonToOrganismTaxonSpecialization": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "OrganismToOrganismAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "OrganismalEntityAsAModelOfDiseaseAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "PairwiseGeneToGeneInteraction": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "PairwiseMolecularInteraction": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "PhenotypicFeatureToDiseaseAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'sex_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "PhenotypicFeatureToPhenotypicFeatureAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'sex_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "PopulationToPopulationAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "ProcessRegulatesProcessAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "ReactionToCatalystAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'species_context_qualifier', 'subject'], + "ReactionToParticipantAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'species_context_qualifier', 'subject'], + "SequenceAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "SequenceFeatureRelationship": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "SequenceVariantModulatesTreatmentAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "TaxonToTaxonAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "TranscriptToGeneRelationship": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "VariantAsAModelOfDiseaseAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "VariantToDiseaseAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "VariantToGeneAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], + "VariantToGeneExpressionAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'stage_qualifier', 'subject'], + "VariantToPhenotypicFeatureAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'qualified_predicate', 'qualifier', 'sex_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "VariantToPopulationAssociation": ['agent_type', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'qualifier', 'subject'], +} + +_STANDARD_IDENTITY_SLOTS: dict[str, list[str]] = { + "AnatomicalEntityHasPartAnatomicalEntityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "AnatomicalEntityPartOfAnatomicalEntityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "AnatomicalEntityToAnatomicalEntityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "AnatomicalEntityToAnatomicalEntityOntogenicAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "Association": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "BehaviorToBehavioralFeatureAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'sex_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "BiologicalProcessOrActivityToAnatomicalEntityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "BiologicalProcessOrActivityToBiologicalProcessOrActivityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "BiologicalProcessOrActivityToGeneOrGeneProductOrGeneFamilyAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "CaseToDiseaseAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'onset_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "CaseToGeneAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "CaseToPhenotypicFeatureAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'onset_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'sex_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "CaseToVariantAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "CausalGeneToDiseaseAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_form_or_variant_qualifier'], + "CellLineAsAModelOfDiseaseAssociation": ['agent_type', 'anatomical_context_qualifier', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'object_specialization_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier', 'subject_specialization_qualifier'], + "CellLineToDiseaseOrPhenotypicFeatureAssociation": ['agent_type', 'anatomical_context_qualifier', 'disease_context_qualifier', 'knowledge_level', 'negated', 'object', 'object_specialization_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject', 'subject_specialization_qualifier'], + "ChemicalAffectsBiologicalEntityAssociation": ['agent_type', 'anatomical_context_qualifier', 'causal_mechanism_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_context_qualifier', 'object_direction_qualifier', 'object_form_or_variant_qualifier', 'object_part_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'species_context_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_context_qualifier', 'subject_derivative_qualifier', 'subject_direction_qualifier', 'subject_form_or_variant_qualifier', 'subject_part_qualifier'], + "ChemicalAffectsGeneAssociation": ['agent_type', 'anatomical_context_qualifier', 'causal_mechanism_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_context_qualifier', 'object_direction_qualifier', 'object_form_or_variant_qualifier', 'object_part_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'species_context_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_context_qualifier', 'subject_derivative_qualifier', 'subject_direction_qualifier', 'subject_form_or_variant_qualifier', 'subject_part_qualifier'], + "ChemicalEntityAssessesNamedThingAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "ChemicalEntityOrGeneOrGeneProductRegulatesGeneAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "ChemicalEntityToBiologicalProcessAssociation": ['agent_type', 'anatomical_context_qualifier', 'knowledge_level', 'negated', 'object', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'species_context_qualifier', 'subject'], + "ChemicalEntityToChemicalDerivationAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'species_context_qualifier', 'subject'], + "ChemicalEntityToChemicalEntityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'species_context_qualifier', 'subject'], + "ChemicalEntityToDiseaseOrPhenotypicFeatureAssociation": ['agent_type', 'anatomical_context_qualifier', 'disease_context_qualifier', 'knowledge_level', 'negated', 'object', 'object_specialization_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject', 'subject_specialization_qualifier'], + "ChemicalEntityToPathwayAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "ChemicalGeneInteractionAssociation": ['agent_type', 'anatomical_context_qualifier', 'causal_mechanism_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_context_qualifier', 'object_direction_qualifier', 'object_form_or_variant_qualifier', 'object_part_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'subject', 'subject_context_qualifier', 'subject_derivative_qualifier', 'subject_form_or_variant_qualifier', 'subject_part_qualifier'], + "ChemicalOrDrugOrTreatmentAdverseEventAssociation": ['agent_type', 'anatomical_context_qualifier', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'object_specialization_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier', 'subject_specialization_qualifier'], + "ChemicalOrDrugOrTreatmentSideEffectAssociation": ['agent_type', 'anatomical_context_qualifier', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'object_specialization_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier', 'subject_specialization_qualifier'], + "ChemicalOrDrugOrTreatmentToDiseaseOrPhenotypicFeatureAssociation": ['agent_type', 'anatomical_context_qualifier', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'object_specialization_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier', 'subject_specialization_qualifier'], + "ContributorAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "CorrelatedGeneToDiseaseAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier', 'subject_form_or_variant_qualifier'], + "DiseaseAssociatedWithResponseToChemicalEntityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'response_context_qualifier', 'response_target_context_qualifier', 'subject'], + "DiseaseOrPhenotypicFeatureToGeneticInheritanceAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "DiseaseOrPhenotypicFeatureToLocationAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "DiseaseToExposureEventAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "DiseaseToPhenotypicFeatureAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'onset_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'sex_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "DrugToGeneAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "DruggableGeneToDiseaseAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier', 'subject_form_or_variant_qualifier'], + "EntityToDiseaseAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "EntityToPhenotypicFeatureAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "ExonToTranscriptRelationship": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "ExposureEventToOutcomeAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'population_context_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject', 'temporal_context_qualifier'], + "ExposureEventToPhenotypicFeatureAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'sex_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "FunctionalAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "GeneAffectsChemicalAssociation": ['agent_type', 'anatomical_context_qualifier', 'causal_mechanism_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_context_qualifier', 'object_derivative_qualifier', 'object_direction_qualifier', 'object_form_or_variant_qualifier', 'object_part_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'species_context_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_context_qualifier', 'subject_derivative_qualifier', 'subject_direction_qualifier', 'subject_form_or_variant_qualifier', 'subject_part_qualifier'], + "GeneAsAModelOfDiseaseAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier', 'subject_form_or_variant_qualifier'], + "GeneFamilyToGeneOrGeneProductOrGeneFamilyAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "GeneHasVariantThatContributesToDiseaseAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_form_or_variant_qualifier'], + "GeneOrGeneProductOrGeneFamilyToAnatomicalEntityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "GeneOrGeneProductOrGeneFamilyToBiologicalProcessOrActivityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "GeneRegulatesGeneAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'species_context_qualifier', 'subject'], + "GeneToDiseaseAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_form_or_variant_qualifier'], + "GeneToExpressionSiteAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'object_specialization_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'stage_qualifier', 'subject'], + "GeneToGeneAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "GeneToGeneCoexpressionAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'stage_qualifier', 'subject'], + "GeneToGeneFamilyAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "GeneToGeneHomologyAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "GeneToGeneProductRelationship": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "GeneToGoTermAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "GeneToPathwayAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "GeneToPhenotypicFeatureAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'sex_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier', 'subject_form_or_variant_qualifier'], + "GenomicSequenceLocalization": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "GenotypeAsAModelOfDiseaseAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "GenotypeToDiseaseAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "GenotypeToGeneAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "GenotypeToGenotypePartAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "GenotypeToPhenotypicFeatureAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'sex_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "GenotypeToVariantAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "InformationContentEntityToNamedThingAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "MacromolecularMachineHasSubstrateAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "MacromolecularMachineToBiologicalProcessAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'species_context_qualifier', 'subject'], + "MacromolecularMachineToCellularComponentAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'species_context_qualifier', 'subject'], + "MacromolecularMachineToMolecularActivityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'species_context_qualifier', 'subject'], + "MaterialSampleDerivationAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "MaterialSampleToDiseaseOrPhenotypicFeatureAssociation": ['agent_type', 'anatomical_context_qualifier', 'disease_context_qualifier', 'knowledge_level', 'negated', 'object', 'object_specialization_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject', 'subject_specialization_qualifier'], + "MolecularActivityToChemicalEntityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "MolecularActivityToMolecularActivityAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "MolecularActivityToPathwayAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "NamedThingAssociatedWithLikelihoodOfNamedThingAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_context_qualifier', 'population_context_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_context_qualifier'], + "OrganismTaxonToEnvironmentAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "OrganismTaxonToOrganismTaxonAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "OrganismTaxonToOrganismTaxonInteraction": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "OrganismTaxonToOrganismTaxonSpecialization": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "OrganismToOrganismAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "OrganismalEntityAsAModelOfDiseaseAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "PairwiseGeneToGeneInteraction": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "PairwiseMolecularInteraction": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "PhenotypicFeatureToDiseaseAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'sex_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "PhenotypicFeatureToPhenotypicFeatureAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'sex_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "PopulationToPopulationAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "ProcessRegulatesProcessAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "ReactionToCatalystAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'species_context_qualifier', 'subject'], + "ReactionToParticipantAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'species_context_qualifier', 'subject'], + "SequenceAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "SequenceFeatureRelationship": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "SequenceVariantModulatesTreatmentAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "TaxonToTaxonAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "TranscriptToGeneRelationship": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "VariantAsAModelOfDiseaseAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "VariantToDiseaseAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "VariantToGeneAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], + "VariantToGeneExpressionAssociation": ['agent_type', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'stage_qualifier', 'subject'], + "VariantToPhenotypicFeatureAssociation": ['agent_type', 'disease_context_qualifier', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'object_aspect_qualifier', 'object_direction_qualifier', 'predicate', 'primary_knowledge_source', 'publications', 'qualified_predicate', 'qualifier', 'sex_qualifier', 'subject', 'subject_aspect_qualifier', 'subject_direction_qualifier'], + "VariantToPopulationAssociation": ['agent_type', 'frequency_qualifier', 'knowledge_level', 'negated', 'object', 'predicate', 'primary_knowledge_source', 'publications', 'qualifier', 'subject'], +} + + +class DeterministicIdMixin(ConfiguredBaseModel): + """ + Mixin that auto-generates a deterministic hash-based ID for Association + instances when no explicit ID is provided. + + The fields included in the hash depend on AssociationIdConfig.strategy. + """ + + @model_validator(mode="before") + @classmethod + def _generate_deterministic_id(cls, data: Any) -> Any: + if isinstance(data, dict): + existing_id = data.get("id") + if existing_id is None or existing_id is ...: + class_name = cls.__name__ + strategy = AssociationIdConfig.strategy + + if strategy == IdStrategy.ALL_FIELDS: + identity_fields = sorted( + f for f in cls.model_fields if f != "id" + ) + elif strategy == IdStrategy.CUSTOM: + identity_fields = sorted(AssociationIdConfig.custom_fields) + elif strategy == IdStrategy.QUALIFIER_BASED: + identity_fields = _QUALIFIER_IDENTITY_SLOTS.get(class_name, []) + else: # SPO_Q_KLAT_PKS (default) + identity_fields = _STANDARD_IDENTITY_SLOTS.get(class_name, []) + + parts = [class_name] + for field_name in identity_fields: + value = data.get(field_name) + parts.append(field_name) + parts.append( + json.dumps(value, sort_keys=True, default=str) + if value is not None else "null" + ) + hash_input = "|".join(parts) + hash_value = hashlib.sha256( + hash_input.encode("utf-8") + ).hexdigest() + data["id"] = f"uuid:{hash_value}" + return data + linkml_meta = None class BinaryRelationEnum(str, Enum): @@ -5293,7 +5587,7 @@ class SocioeconomicOutcome(Outcome): pass -class Association(Entity): +class Association(DeterministicIdMixin, Entity): """ A typed association between two entities, supported by evidence """ @@ -5355,7 +5649,7 @@ class DiseaseAssociatedWithResponseToChemicalEntityAssociation(Association): response_context_qualifier: Optional[ResponseEnum] = Field(default=None, description="""a biological response (general, study, cohort, etc.) with a specific set of characteristics to constrain an association.""") response_target_context_qualifier: Optional[ResponseTargetEnum] = Field(default=None, description="""a biological response target (a patient, a cohort, a model system, a cell line, a sample of biological material, etc.)""") subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:associated_with_resistance_to", "biolink:associated_with_response_to", "biolink:associated_with_sensitivity_to"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -5407,7 +5701,7 @@ class DiseaseAssociatedWithResponseToChemicalEntityAssociation(Association): class ChemicalEntityAssessesNamedThingAssociation(Association): subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:was_tested_for_effect_on"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -5462,7 +5756,7 @@ class ContributorAssociation(Association): Any association between an entity (such as a publication) and various agents that contribute to its realisation """ subject: str = Field(default=..., description="""information content entity which an agent has helped realise""") - predicate: str = Field(default=..., description="""generally one of the predicate values 'provider', 'publisher', 'editor' or 'author'""") + predicate: Literal["biolink:author", "biolink:contributor", "biolink:editor", "biolink:provider", "biolink:publisher"] = Field(default=..., description="""generally one of the predicate values 'provider', 'publisher', 'editor' or 'author'""") object: str = Field(default=..., description="""agent helping to realise the given entity (e.g. such as a publication)""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -5517,7 +5811,7 @@ class GenotypeToGenotypePartAssociation(Association): Any association between one genotype and a genotypic entity that is a sub-component of it """ subject: str = Field(default=..., description="""parent genotype""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:has_variant_part"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""child genotype""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -5737,7 +6031,7 @@ class GeneToGeneHomologyAssociation(GeneToGeneAssociation): A homology association between two genes. May be orthology (in which case the species of subject and object should differ) or paralogy (in which case the species may be the same) """ subject: str = Field(default=..., description="""the subject gene in the association. If the relation is symmetric, subject vs object is arbitrary. We allow a gene product to stand as a proxy for the gene or vice versa.""") - predicate: str = Field(default=..., description="""homology relationship type""") + predicate: Literal["biolink:homologous_to", "biolink:orthologous_to", "biolink:paralogous_to", "biolink:xenologous_to"] = Field(default=..., description="""homology relationship type""") object: str = Field(default=..., description="""the object gene in the association. If the relation is symmetric, subject vs object is arbitrary. We allow a gene product to stand as a proxy for the gene or vice versa.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -5792,7 +6086,7 @@ class GeneToGeneFamilyAssociation(Association): Set membership of a gene in a family of genes related by common evolutionary ancestry usually inferred by sequence comparisons. The genes in a given family generally share common sequence motifs which generally map onto shared gene product structure-function relationships. """ subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""membership of the gene in the given gene family.""") + predicate: Literal["biolink:member_of"] = Field(default=..., description="""membership of the gene in the given gene family.""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -5847,7 +6141,7 @@ class GeneFamilyToGeneOrGeneProductOrGeneFamilyAssociation(Association): Relationship between a gene family and a contained gene or gene product or gene family. """ subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""membership of a gene or gene product, or strict subset relationship gene family, in the given gene family.""") + predicate: Literal["biolink:has_active_ingredient", "biolink:has_excipient", "biolink:has_food_component", "biolink:has_nutrient", "biolink:has_part", "biolink:has_plasma_membrane_part", "biolink:has_variant_part"] = Field(default=..., description="""membership of a gene or gene product, or strict subset relationship gene family, in the given gene family.""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -5902,7 +6196,7 @@ class GeneOrGeneProductOrGeneFamilyToBiologicalProcessOrActivityAssociation(Asso Relationship between a gene or gene product or gene family to a specified biological process or activity (e.g. molecular activity, biological process or pathway). """ subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""participation of a gene or gene product or gene family in a given biological process or activity (e.g., gene product participates in biological process; gene catalyzes molecular activity; gene family is actively involved in a pathway).""") + predicate: Literal["biolink:actively_involved_in", "biolink:capable_of", "biolink:catalyzes", "biolink:consumed_by", "biolink:enables", "biolink:is_input_of", "biolink:is_output_of", "biolink:is_substrate_of", "biolink:participates_in"] = Field(default=..., description="""participation of a gene or gene product or gene family in a given biological process or activity (e.g., gene product participates in biological process; gene catalyzes molecular activity; gene family is actively involved in a pathway).""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -5957,7 +6251,7 @@ class BiologicalProcessOrActivityToGeneOrGeneProductOrGeneFamilyAssociation(Asso Relationship between a biological processor activity (e.g. molecular activity, biological process or pathway) to gene or gene product or gene family. """ subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""Relationship in which a biological process has the participation of a gene or gene product or gene family in a (e.g., pathway has participant gene product).""") + predicate: Literal["biolink:actively_involves", "biolink:can_be_carried_out_by", "biolink:consumes", "biolink:enabled_by", "biolink:has_catalyst", "biolink:has_input", "biolink:has_output", "biolink:has_participant", "biolink:has_substrate"] = Field(default=..., description="""Relationship in which a biological process has the participation of a gene or gene product or gene family in a (e.g., pathway has participant gene product).""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -6012,7 +6306,7 @@ class BiologicalProcessOrActivityToBiologicalProcessOrActivityAssociation(Associ Classification relationship between biological processes or activities (e.g. coupling of two molecular activities; assignment of molecular activity to a pathway; implicating a pathway in a biological process; etc.) """ subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""One biological processes or activities is a subclass of another.""") + predicate: Literal["biolink:subclass_of"] = Field(default=..., description="""One biological processes or activities is a subclass of another.""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -6081,7 +6375,7 @@ class GeneToGeneCoexpressionAssociation(GeneExpressionMixin, GeneToGeneAssociati stage_qualifier: Optional[str] = Field(default=None, description="""stage during which gene or protein expression of takes place.""") phenotypic_state: Optional[str] = Field(default=None, description="""in experiments (e.g. gene expression) assaying diseased or unhealthy tissue, the phenotypic state can be put here, e.g. MONDO ID. For healthy tissues, use XXX.""") subject: str = Field(default=..., description="""the subject gene in the association. If the relation is symmetric, subject vs object is arbitrary. We allow a gene product to stand as a proxy for the gene or vice versa.""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:coexpressed_with"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""the object gene in the association. If the relation is symmetric, subject vs object is arbitrary. We allow a gene product to stand as a proxy for the gene or vice versa.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -6136,7 +6430,7 @@ class PairwiseGeneToGeneInteraction(GeneToGeneAssociation): An interaction between two genes or two gene products. May be physical (e.g. protein binding) or genetic (between genes). May be symmetric (e.g. protein interaction) or directed (e.g. phosphorylation) """ subject: str = Field(default=..., description="""the subject gene in the association. If the relation is symmetric, subject vs object is arbitrary. We allow a gene product to stand as a proxy for the gene or vice versa.""") - predicate: str = Field(default=..., description="""interaction relationship type""") + predicate: Literal["biolink:binds", "biolink:directly_physically_interacts_with", "biolink:gene_fusion_with", "biolink:genetic_neighborhood_of", "biolink:genetically_interacts_with", "biolink:indirectly_physically_interacts_with", "biolink:interacts_with", "biolink:physically_interacts_with", "biolink:regulates"] = Field(default=..., description="""interaction relationship type""") object: str = Field(default=..., description="""the object gene in the association. If the relation is symmetric, subject vs object is arbitrary. We allow a gene product to stand as a proxy for the gene or vice versa.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -6192,7 +6486,7 @@ class PairwiseMolecularInteraction(PairwiseGeneToGeneInteraction): """ interacting_molecules_category: Optional[str] = Field(default=None) subject: str = Field(default=..., description="""the subject gene in the association. If the relation is symmetric, subject vs object is arbitrary. We allow a gene product to stand as a proxy for the gene or vice versa.""") - predicate: str = Field(default=..., description="""interaction relationship type""") + predicate: Literal["biolink:binds", "biolink:directly_physically_interacts_with", "biolink:gene_fusion_with", "biolink:genetic_neighborhood_of", "biolink:genetically_interacts_with", "biolink:indirectly_physically_interacts_with", "biolink:interacts_with", "biolink:physically_interacts_with", "biolink:regulates"] = Field(default=..., description="""interaction relationship type""") object: str = Field(default=..., description="""the object gene in the association. If the relation is symmetric, subject vs object is arbitrary. We allow a gene product to stand as a proxy for the gene or vice versa.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -6461,7 +6755,7 @@ class ChemicalEntityToChemicalDerivationAssociation(ChemicalEntityToChemicalEnti """ catalyst_qualifier: Optional[list[str]] = Field(default=None, description="""this connects the derivation edge to the chemical entity that catalyzes the reaction that causes the subject chemical to transform into the object chemical.""") subject: str = Field(default=..., description="""the upstream chemical entity""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:derives_into", "biolink:has_metabolite"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""the downstream chemical entity""") species_context_qualifier: Optional[str] = Field(default=None, description="""A statement qualifier representing a taxonomic category of species in which a relationship expressed in an association took place.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") @@ -6517,7 +6811,7 @@ class MolecularActivityToPathwayAssociation(Association): Association that holds the relationship between a reaction and the pathway it participates in. """ subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:food_component_of", "biolink:is_active_ingredient_of", "biolink:is_excipient_of", "biolink:nutrient_of", "biolink:part_of", "biolink:plasma_membrane_part_of", "biolink:variant_part_of"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -6631,7 +6925,7 @@ class ChemicalEntityToBiologicalProcessAssociation(Association): qualified_predicate: Optional[str] = Field(default=None, description="""Predicate to be used in an association when subject and object qualifiers are present and the full reading of the statement requires a qualification to the predicate in use in order to refine or increase the specificity of the full statement reading. Has a value from the Biolink 'related_to' hierarchy, for example, biolink:related_to, biolink:causes, biolink:treats This qualifier holds a relationship to be used instead of that expressed by the primary predicate, in a ‘full statement’ reading of the association, where qualifier-based semantics are included. This is necessary only in cases where the primary predicate does not work in a full statement reading.""") object_direction_qualifier: Optional[DirectionQualifierEnum] = Field(default=None, description="""Composes with the core concept (+ aspect if provided) to describe a change in its direction or degree. This qualifier qualifies the object of an association (aka: statement).""") subject: str = Field(default=..., description="""the chemical entity that affects the biological process""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:active_in", "biolink:actively_involved_in", "biolink:actively_involves", "biolink:acts_upstream_of", "biolink:acts_upstream_of_negative_effect", "biolink:acts_upstream_of_or_within", "biolink:acts_upstream_of_or_within_negative_effect", "biolink:acts_upstream_of_or_within_positive_effect", "biolink:acts_upstream_of_positive_effect", "biolink:adverse_event_of", "biolink:affected_by", "biolink:affects", "biolink:affects_likelihood_of", "biolink:affects_sensitivity_to", "biolink:ameliorates_condition", "biolink:amount_or_activity_decreased_by", "biolink:amount_or_activity_increased_by", "biolink:applied_to_treat", "biolink:associated_with", "biolink:associated_with_decreased_likelihood_of", "biolink:associated_with_increased_likelihood_of", "biolink:associated_with_likelihood_of", "biolink:associated_with_resistance_to", "biolink:associated_with_response_to", "biolink:associated_with_sensitivity_to", "biolink:author", "biolink:beneficial_in_models_for", "biolink:binds", "biolink:biomarker_for", "biolink:can_be_carried_out_by", "biolink:capable_of", "biolink:catalyzes", "biolink:caused_by", "biolink:causes", "biolink:chemically_similar_to", "biolink:coexists_with", "biolink:coexpressed_with", "biolink:colocalizes_with", "biolink:completed_by", "biolink:condition_ameliorated_by", "biolink:condition_associated_with_gene", "biolink:condition_exacerbated_by", "biolink:condition_predisposed_by", "biolink:condition_prevented_by", "biolink:condition_promoted_by", "biolink:consumed_by", "biolink:consumes", "biolink:contains_process", "biolink:contraindicated_in", "biolink:contributes_to", "biolink:contribution_from", "biolink:contributor", "biolink:correlated_with", "biolink:decreased_amount_in", "biolink:decreased_likelihood_associated_with", "biolink:decreases_amount_or_activity_of", "biolink:decreases_sensitivity_to", "biolink:derives_from", "biolink:derives_into", "biolink:develops_from", "biolink:develops_into", "biolink:diagnoses", "biolink:directly_physically_interacts_with", "biolink:disease_has_basis_in", "biolink:disrupted_by", "biolink:disrupts", "biolink:editor", "biolink:enabled_by", "biolink:enables", "biolink:exacerbates_condition", "biolink:expressed_in", "biolink:expresses", "biolink:food_component_of", "biolink:gene_associated_with_condition", "biolink:gene_fusion_with", "biolink:gene_product_of", "biolink:genetic_association", "biolink:genetic_neighborhood_of", "biolink:genetically_associated_with", "biolink:genetically_interacts_with", "biolink:has_active_component", "biolink:has_active_ingredient", "biolink:has_adverse_event", "biolink:has_author", "biolink:has_biomarker", "biolink:has_catalyst", "biolink:has_completed", "biolink:has_contraindication", "biolink:has_contributor", "biolink:has_decreased_amount", "biolink:has_editor", "biolink:has_excipient", "biolink:has_food_component", "biolink:has_frameshift_variant", "biolink:has_gene_product", "biolink:has_increased_amount", "biolink:has_input", "biolink:has_manifestation", "biolink:has_metabolite", "biolink:has_missense_variant", "biolink:has_mode_of_inheritance", "biolink:has_molecular_consequence", "biolink:has_nearby_variant", "biolink:has_negative_upstream_actor", "biolink:has_negative_upstream_or_within_actor", "biolink:has_non_coding_variant", "biolink:has_nonsense_variant", "biolink:has_not_completed", "biolink:has_nutrient", "biolink:has_output", "biolink:has_part", "biolink:has_participant", "biolink:has_phenotype", "biolink:has_plasma_membrane_part", "biolink:has_positive_upstream_actor", "biolink:has_positive_upstream_or_within_actor", "biolink:has_provider", "biolink:has_publisher", "biolink:has_sequence_location", "biolink:has_sequence_variant", "biolink:has_side_effect", "biolink:has_splice_site_variant", "biolink:has_substrate", "biolink:has_synonymous_variant", "biolink:has_target", "biolink:has_upstream_actor", "biolink:has_upstream_or_within_actor", "biolink:has_variant_part", "biolink:homologous_to", "biolink:in_cell_population_with", "biolink:in_clinical_trials_for", "biolink:in_complex_with", "biolink:in_linkage_disequilibrium_with", "biolink:in_pathway_with", "biolink:in_preclinical_trials_for", "biolink:in_taxon", "biolink:increased_amount_of", "biolink:increased_likelihood_associated_with", "biolink:increases_amount_or_activity_of", "biolink:increases_sensitivity_to", "biolink:indirectly_physically_interacts_with", "biolink:interacts_with", "biolink:is_active_ingredient_of", "biolink:is_diagnosed_by", "biolink:is_excipient_of", "biolink:is_frameshift_variant_of", "biolink:is_input_of", "biolink:is_metabolite_of", "biolink:is_missense_variant_of", "biolink:is_molecular_consequence_of", "biolink:is_nearby_variant_of", "biolink:is_non_coding_variant_of", "biolink:is_nonsense_variant_of", "biolink:is_output_of", "biolink:is_sequence_variant_of", "biolink:is_side_effect_of", "biolink:is_splice_site_variant_of", "biolink:is_substrate_of", "biolink:is_synonymous_variant_of", "biolink:lacks_part", "biolink:likelihood_affected_by", "biolink:likelihood_associated_with", "biolink:located_in", "biolink:location_of", "biolink:manifestation_of", "biolink:mentioned_by", "biolink:mentions", "biolink:missing_from", "biolink:mode_of_inheritance_of", "biolink:model_of", "biolink:models", "biolink:models_demonstrating_benefits_for", "biolink:negatively_correlated_with", "biolink:not_completed_by", "biolink:nutrient_of", "biolink:occurs_in", "biolink:occurs_in_disease", "biolink:occurs_together_in_literature_with", "biolink:opposite_of", "biolink:orthologous_to", "biolink:overlaps", "biolink:paralogous_to", "biolink:part_of", "biolink:participates_in", "biolink:phenotype_of", "biolink:physically_interacts_with", "biolink:plasma_membrane_part_of", "biolink:positively_correlated_with", "biolink:preceded_by", "biolink:precedes", "biolink:predisposes_to_condition", "biolink:preventative_for_condition", "biolink:produced_by", "biolink:produces", "biolink:promotes_condition", "biolink:provider", "biolink:publisher", "biolink:regulated_by", "biolink:regulates", "biolink:related_condition", "biolink:related_to_at_instance_level", "biolink:resistance_associated_with", "biolink:response_associated_with", "biolink:sensitivity_affected_by", "biolink:sensitivity_associated_with", "biolink:sensitivity_decreased_by", "biolink:sensitivity_increased_by", "biolink:sequence_location_of", "biolink:similar_to", "biolink:studied_to_treat", "biolink:subject_of_treatment_application_or_study_for_treatment_by", "biolink:target_for", "biolink:taxon_of", "biolink:temporally_related_to", "biolink:tested_by_clinical_trials_of", "biolink:tested_by_preclinical_trials_of", "biolink:transcribed_from", "biolink:transcribed_to", "biolink:translates_to", "biolink:translation_of", "biolink:treated_by", "biolink:treated_in_studies_by", "biolink:treatment_applications_from", "biolink:treats", "biolink:treats_or_applied_or_studied_to_treat", "biolink:variant_part_of", "biolink:was_tested_for_effect_of", "biolink:was_tested_for_effect_on", "biolink:xenologous_to"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""the biological process that is affected by the chemical entity""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -6685,7 +6979,7 @@ class NamedThingAssociatedWithLikelihoodOfNamedThingAssociation(Association): subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") subject_aspect_qualifier: Optional[str] = Field(default=None, description="""Composes with the core concept to describe new concepts of a different ontological type. e.g. a process in which the core concept participates, a function/activity/role held by the core concept, or a characteristic/quality that inheres in the core concept. The purpose of the aspect slot is to indicate what aspect is being affected in an 'affects' association. This qualifier specifies a change in the subject of an association (aka: statement).""") subject_context_qualifier: Optional[str] = Field(default=None) - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:associated_with", "biolink:associated_with_decreased_likelihood_of", "biolink:associated_with_increased_likelihood_of", "biolink:associated_with_likelihood_of", "biolink:associated_with_resistance_to", "biolink:associated_with_response_to", "biolink:associated_with_sensitivity_to", "biolink:biomarker_for", "biolink:coexpressed_with", "biolink:condition_associated_with_gene", "biolink:correlated_with", "biolink:decreased_likelihood_associated_with", "biolink:gene_associated_with_condition", "biolink:genetic_association", "biolink:genetically_associated_with", "biolink:has_biomarker", "biolink:increased_likelihood_associated_with", "biolink:likelihood_associated_with", "biolink:negatively_correlated_with", "biolink:occurs_together_in_literature_with", "biolink:positively_correlated_with", "biolink:resistance_associated_with", "biolink:response_associated_with", "biolink:sensitivity_associated_with"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") object_aspect_qualifier: Optional[str] = Field(default=None, description="""Composes with the core concept to describe new concepts of a different ontological type. e.g. a process in which the core concept participates, a function/activity/role held by the core concept, or a characteristic/quality that inheres in the core concept. The purpose of the aspect slot is to indicate what aspect is being affected in an 'affects' association. This qualifier specifies a change in the object of an association (aka: statement).""") object_context_qualifier: Optional[str] = Field(default=None) @@ -6758,7 +7052,7 @@ class ChemicalGeneInteractionAssociation(Association): dgidb_interaction_score: Optional[float] = Field(default=None, description="""A score defined by DGIdb that is used to rank interaction record results in DGIdb, which combines their evidence score (based on total supporting sources and pubs), with their relative gene specificity score and relative drug specificity score. See https://dgidb.org/about/overview/interaction-score.""") dgidb_evidence_score: Optional[int] = Field(default=None, description="""A score defined by DGIdb that is used to report the amount of evidence supporting a given interaction statement, which is simply the sum of all supporting sources and publications. See https://dgidb.org/about/overview/interaction-score.""") subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:binds", "biolink:directly_physically_interacts_with", "biolink:gene_fusion_with", "biolink:genetic_neighborhood_of", "biolink:genetically_interacts_with", "biolink:indirectly_physically_interacts_with", "biolink:interacts_with", "biolink:physically_interacts_with", "biolink:regulates"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -6813,7 +7107,7 @@ class MacromolecularMachineHasSubstrateAssociation(Association): Describes the relationship between an enzyme (usually a macromolecular complex or gene product) and the molecules it acts on (substrate). The substrate can be a chemical, a polypeptide, or a protein. """ subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:has_substrate"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -6869,7 +7163,7 @@ class GeneRegulatesGeneAssociation(Association): """ object_aspect_qualifier: GeneOrGeneProductOrChemicalEntityAspectEnum = Field(default=..., description="""the aspect of the object gene or gene product that is being regulated, must be a descendant of \"activity_or_abundance\"\"""") object_direction_qualifier: DirectionQualifierEnum = Field(default=..., description="""Composes with the core concept (+ aspect if provided) to describe a change in its direction or degree. This qualifier qualifies the object of an association (aka: statement).""") - qualified_predicate: str = Field(default=..., description="""Predicate to be used in an association when subject and object qualifiers are present and the full reading of the statement requires a qualification to the predicate in use in order to refine or increase the specificity of the full statement reading. Has a value from the Biolink 'related_to' hierarchy, for example, biolink:related_to, biolink:causes, biolink:treats This qualifier holds a relationship to be used instead of that expressed by the primary predicate, in a ‘full statement’ reading of the association, where qualifier-based semantics are included. This is necessary only in cases where the primary predicate does not work in a full statement reading.""") + qualified_predicate: Literal["biolink:causes"] = Field(default=..., description="""Predicate to be used in an association when subject and object qualifiers are present and the full reading of the statement requires a qualification to the predicate in use in order to refine or increase the specificity of the full statement reading. Has a value from the Biolink 'related_to' hierarchy, for example, biolink:related_to, biolink:causes, biolink:treats This qualifier holds a relationship to be used instead of that expressed by the primary predicate, in a ‘full statement’ reading of the association, where qualifier-based semantics are included. This is necessary only in cases where the primary predicate does not work in a full statement reading.""") species_context_qualifier: Optional[str] = Field(default=None, description="""A statement qualifier representing a taxonomic category of species in which a relationship expressed in an association took place.""") subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") @@ -6927,7 +7221,7 @@ class ProcessRegulatesProcessAssociation(Association): Describes a regulatory relationship between two genes or gene products. """ subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:regulates"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -6994,10 +7288,10 @@ class ChemicalAffectsBiologicalEntityAssociation(Association): object_direction_qualifier: Optional[DirectionQualifierEnum] = Field(default=None, description="""Composes with the core concept (+ aspect if provided) to describe a change in its direction or degree. This qualifier qualifies the object of an association (aka: statement).""") causal_mechanism_qualifier: Optional[CausalMechanismQualifierEnum] = Field(default=None, description="""A statement qualifier representing a type of molecular control mechanism through which an effect of a chemical on a gene or gene product is mediated (e.g. 'agonism', 'inhibition', 'allosteric modulation', 'channel blocker')""") anatomical_context_qualifier: Optional[list[str]] = Field(default=None, description="""A statement qualifier representing an anatomical location where an relationship expressed in an association took place (can be a tissue, cell type, or sub-cellular location).""") - qualified_predicate: Optional[str] = Field(default=None, description="""Predicate to be used in an association when subject and object qualifiers are present and the full reading of the statement requires a qualification to the predicate in use in order to refine or increase the specificity of the full statement reading. Has a value from the Biolink 'related_to' hierarchy, for example, biolink:related_to, biolink:causes, biolink:treats This qualifier holds a relationship to be used instead of that expressed by the primary predicate, in a ‘full statement’ reading of the association, where qualifier-based semantics are included. This is necessary only in cases where the primary predicate does not work in a full statement reading.""") + qualified_predicate: Optional[Literal["biolink:causes"]] = Field(default=None, description="""Predicate to be used in an association when subject and object qualifiers are present and the full reading of the statement requires a qualification to the predicate in use in order to refine or increase the specificity of the full statement reading. Has a value from the Biolink 'related_to' hierarchy, for example, biolink:related_to, biolink:causes, biolink:treats This qualifier holds a relationship to be used instead of that expressed by the primary predicate, in a ‘full statement’ reading of the association, where qualifier-based semantics are included. This is necessary only in cases where the primary predicate does not work in a full statement reading.""") species_context_qualifier: Optional[str] = Field(default=None, description="""A statement qualifier representing a taxonomic category of species in which a relationship expressed in an association took place.""") subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:affects", "biolink:ameliorates_condition", "biolink:disrupts", "biolink:exacerbates_condition", "biolink:has_adverse_event", "biolink:has_side_effect", "biolink:regulates"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -7068,10 +7362,10 @@ class ChemicalAffectsGeneAssociation(ChemicalAffectsBiologicalEntityAssociation) object_direction_qualifier: Optional[DirectionQualifierEnum] = Field(default=None, description="""Composes with the core concept (+ aspect if provided) to describe a change in its direction or degree. This qualifier qualifies the object of an association (aka: statement).""") causal_mechanism_qualifier: Optional[CausalMechanismQualifierEnum] = Field(default=None, description="""A statement qualifier representing a type of molecular control mechanism through which an effect of a chemical on a gene or gene product is mediated (e.g. 'agonism', 'inhibition', 'allosteric modulation', 'channel blocker')""") anatomical_context_qualifier: Optional[list[str]] = Field(default=None, description="""A statement qualifier representing an anatomical location where an relationship expressed in an association took place (can be a tissue, cell type, or sub-cellular location).""") - qualified_predicate: Optional[str] = Field(default=None, description="""Predicate to be used in an association when subject and object qualifiers are present and the full reading of the statement requires a qualification to the predicate in use in order to refine or increase the specificity of the full statement reading. Has a value from the Biolink 'related_to' hierarchy, for example, biolink:related_to, biolink:causes, biolink:treats This qualifier holds a relationship to be used instead of that expressed by the primary predicate, in a ‘full statement’ reading of the association, where qualifier-based semantics are included. This is necessary only in cases where the primary predicate does not work in a full statement reading.""") + qualified_predicate: Optional[Literal["biolink:causes"]] = Field(default=None, description="""Predicate to be used in an association when subject and object qualifiers are present and the full reading of the statement requires a qualification to the predicate in use in order to refine or increase the specificity of the full statement reading. Has a value from the Biolink 'related_to' hierarchy, for example, biolink:related_to, biolink:causes, biolink:treats This qualifier holds a relationship to be used instead of that expressed by the primary predicate, in a ‘full statement’ reading of the association, where qualifier-based semantics are included. This is necessary only in cases where the primary predicate does not work in a full statement reading.""") species_context_qualifier: Optional[str] = Field(default=None, description="""A statement qualifier representing a taxonomic category of species in which a relationship expressed in an association took place.""") subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:affects", "biolink:ameliorates_condition", "biolink:disrupts", "biolink:exacerbates_condition", "biolink:has_adverse_event", "biolink:has_side_effect", "biolink:regulates"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -7138,10 +7432,10 @@ class GeneAffectsChemicalAssociation(Association): object_derivative_qualifier: Optional[ChemicalEntityDerivativeEnum] = Field(default=None, description="""A qualifier that composes with a core subject/object concept to describe something that is derived from the core concept. For example, the qualifier ‘metabolite’ combines with a ‘Chemical X’ core concept to express the composed concept ‘a metabolite of Chemical X’. This qualifier is for the object of an association (or statement).""") causal_mechanism_qualifier: Optional[CausalMechanismQualifierEnum] = Field(default=None, description="""A statement qualifier representing a type of molecular control mechanism through which an effect of a chemical on a gene or gene product is mediated (e.g. 'agonism', 'inhibition', 'allosteric modulation', 'channel blocker')""") anatomical_context_qualifier: Optional[list[str]] = Field(default=None, description="""A statement qualifier representing an anatomical location where an relationship expressed in an association took place (can be a tissue, cell type, or sub-cellular location).""") - qualified_predicate: Optional[str] = Field(default=None, description="""Predicate to be used in an association when subject and object qualifiers are present and the full reading of the statement requires a qualification to the predicate in use in order to refine or increase the specificity of the full statement reading. Has a value from the Biolink 'related_to' hierarchy, for example, biolink:related_to, biolink:causes, biolink:treats This qualifier holds a relationship to be used instead of that expressed by the primary predicate, in a ‘full statement’ reading of the association, where qualifier-based semantics are included. This is necessary only in cases where the primary predicate does not work in a full statement reading.""") + qualified_predicate: Optional[Literal["biolink:causes"]] = Field(default=None, description="""Predicate to be used in an association when subject and object qualifiers are present and the full reading of the statement requires a qualification to the predicate in use in order to refine or increase the specificity of the full statement reading. Has a value from the Biolink 'related_to' hierarchy, for example, biolink:related_to, biolink:causes, biolink:treats This qualifier holds a relationship to be used instead of that expressed by the primary predicate, in a ‘full statement’ reading of the association, where qualifier-based semantics are included. This is necessary only in cases where the primary predicate does not work in a full statement reading.""") species_context_qualifier: Optional[str] = Field(default=None, description="""A statement qualifier representing a taxonomic category of species in which a relationship expressed in an association took place.""") subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:affects", "biolink:ameliorates_condition", "biolink:disrupts", "biolink:exacerbates_condition", "biolink:has_adverse_event", "biolink:has_side_effect", "biolink:regulates"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -7260,7 +7554,7 @@ class MaterialSampleDerivationAssociation(Association): An association between a material sample and the material entity from which it is derived. """ subject: str = Field(default=..., description="""the material sample being described""") - predicate: str = Field(default=..., description="""derivation relationship""") + predicate: Literal["biolink:derives_from", "biolink:is_metabolite_of"] = Field(default=..., description="""derivation relationship""") object: str = Field(default=..., description="""the material entity the sample was derived from. This may be another material sample, or any other material entity, including for example an organism, a geographic feature, or some environmental material.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -7624,7 +7918,7 @@ class InformationContentEntityToNamedThingAssociation(Association): association between a named thing and a information content entity where the specific context of the relationship between that named thing and the publication is unknown. For example, model organisms databases often capture the knowledge that a gene is found in a journal article, but not specifically the context in which that gene was documented in the article. In these cases, this association with the accompanying predicate 'mentions' could be used. Conversely, for more specific associations (like 'gene to disease association', the publication should be captured as an edge property). """ subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:mentions"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -7756,7 +8050,7 @@ class DiseaseOrPhenotypicFeatureToGeneticInheritanceAssociation(DiseaseOrPhenoty An association between either a disease or a phenotypic feature and its mode of (genetic) inheritance. """ subject: str = Field(default=..., description="""disease or phenotype""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:has_mode_of_inheritance"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""genetic inheritance associated with the specified disease or phenotypic feature.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -7941,7 +8235,7 @@ class ChemicalOrDrugOrTreatmentToDiseaseOrPhenotypicFeatureAssociation(EntityToD This association defines a relationship between a chemical or treatment (or procedure) and a disease or phenotypic feature where the chemical or treatment is used to treat, or is being studied to treat, the disease or phenotypic feature. """ subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:ameliorates_condition", "biolink:applied_to_treat", "biolink:beneficial_in_models_for", "biolink:in_clinical_trials_for", "biolink:in_preclinical_trials_for", "biolink:preventative_for_condition", "biolink:studied_to_treat", "biolink:treats", "biolink:treats_or_applied_or_studied_to_treat"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""disease or phenotype""") disease_context_qualifier: Optional[str] = Field(default=None, description="""A context qualifier representing a disease or condition in which a relationship expressed in an association took place.""") subject_specialization_qualifier: Optional[str] = Field(default=None, description="""A qualifier that composes with a core subject/object concept to define a more specific version of the subject concept, specifically using an ontology term that is not a subclass or descendant of the core concept and in the vast majority of cases, is of a different ontological namespace than the category or namespace of the subject identifier.""") @@ -8007,7 +8301,7 @@ class ChemicalOrDrugOrTreatmentAdverseEventAssociation(EntityToDiseaseOrPhenotyp """ FDA_adverse_event_level: Optional[FDAIDAAdverseEventEnum] = Field(default=None) subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:has_adverse_event"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""disease or phenotype""") disease_context_qualifier: Optional[str] = Field(default=None, description="""A context qualifier representing a disease or condition in which a relationship expressed in an association took place.""") subject_specialization_qualifier: Optional[str] = Field(default=None, description="""A qualifier that composes with a core subject/object concept to define a more specific version of the subject concept, specifically using an ontology term that is not a subclass or descendant of the core concept and in the vast majority of cases, is of a different ontological namespace than the category or namespace of the subject identifier.""") @@ -8072,7 +8366,7 @@ class ChemicalOrDrugOrTreatmentSideEffectAssociation(EntityToDiseaseOrPhenotypic This association defines a relationship between a chemical or treatment (or procedure) and a disease or phenotypic feature where the disease or phenotypic feature is an unintended, but predictable, secondary effect of the treatment. """ subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:has_side_effect"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""disease or phenotype""") disease_context_qualifier: Optional[str] = Field(default=None, description="""A context qualifier representing a disease or condition in which a relationship expressed in an association took place.""") subject_specialization_qualifier: Optional[str] = Field(default=None, description="""A qualifier that composes with a core subject/object concept to define a more specific version of the subject concept, specifically using an ontology term that is not a subclass or descendant of the core concept and in the vast majority of cases, is of a different ontological namespace than the category or namespace of the subject identifier.""") @@ -8202,7 +8496,7 @@ class GenotypeToPhenotypicFeatureAssociation(GenotypeToEntityAssociationMixin, E Any association between one genotype and a phenotypic feature, where having the genotype confers the phenotype, either in isolation or through environment """ subject: str = Field(default=..., description="""genotype that is associated with the phenotypic feature""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:has_phenotype"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") sex_qualifier: Optional[str] = Field(default=None, description="""a qualifier used in a phenotypic association to state whether the association is specific to a particular sex.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") @@ -8998,7 +9292,7 @@ class CorrelatedGeneToDiseaseAssociation(GeneToEntityAssociationMixin, EntityToD allelic_requirement: Optional[str] = Field(default=None, description="""The allele configuration of a particular gene or variant required for the expression of a disease or phenotype in a specific patient or instance.""") qualified_predicate: Optional[str] = Field(default=None, description="""Predicate to be used in an association when subject and object qualifiers are present and the full reading of the statement requires a qualification to the predicate in use in order to refine or increase the specificity of the full statement reading. Has a value from the Biolink 'related_to' hierarchy, for example, biolink:related_to, biolink:causes, biolink:treats This qualifier holds a relationship to be used instead of that expressed by the primary predicate, in a ‘full statement’ reading of the association, where qualifier-based semantics are included. This is necessary only in cases where the primary predicate does not work in a full statement reading.""") subject: str = Field(default=..., description="""gene in which variation is shown to correlate with the disease.""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:biomarker_for", "biolink:coexpressed_with", "biolink:correlated_with", "biolink:has_biomarker", "biolink:negatively_correlated_with", "biolink:occurs_together_in_literature_with", "biolink:positively_correlated_with"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""disease""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -9068,7 +9362,7 @@ def pattern_allelic_requirement(cls, v): class DruggableGeneToDiseaseAssociation(GeneToDiseaseAssociation, GeneToEntityAssociationMixin, EntityToDiseaseAssociationMixin): druggable_gene_category: Optional[DruggableGeneCategoryEnum] = Field(default=None, description="""Classification of druggable genes based on knowledge about drug or small molecule activities.""") subject: str = Field(default=..., description="""gene in which variation is correlated with the disease in a protective manner, or if the product produced by the gene can be targeted by a small molecule and this leads to a protective or improving disease state.""") - predicate: GeneToDiseasePredicateEnum = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["target_for"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""disease""") subject_form_or_variant_qualifier: Optional[ChemicalOrGeneOrGeneProductFormOrVariantEnum] = Field(default=None, description="""A qualifier that composes with a core subject/object concept to define a specific type, variant, alternative version of this concept. The composed concept remains a subtype or instance of the core concept. For example, the qualifier ‘mutation’ combines with the core concept ‘Gene X’ to express the compose concept ‘a mutation of Gene X’. This qualifier specifies a change in the subject of an association (aka: statement).""") subject_aspect_qualifier: Optional[GeneOrGeneProductOrChemicalEntityAspectEnum] = Field(default=None, description="""Composes with the core concept to describe new concepts of a different ontological type. e.g. a process in which the core concept participates, a function/activity/role held by the core concept, or a characteristic/quality that inheres in the core concept. The purpose of the aspect slot is to indicate what aspect is being affected in an 'affects' association. This qualifier specifies a change in the subject of an association (aka: statement).""") @@ -9145,7 +9439,7 @@ def pattern_allelic_requirement(cls, v): class PhenotypicFeatureToDiseaseAssociation(EntityToDiseaseAssociationMixin, PhenotypicFeatureToEntityAssociationMixin, Association): sex_qualifier: Optional[str] = Field(default=None, description="""a qualifier used in a phenotypic association to state whether the association is specific to a particular sex.""") subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:associated_with", "biolink:associated_with_decreased_likelihood_of", "biolink:associated_with_increased_likelihood_of", "biolink:associated_with_likelihood_of", "biolink:associated_with_resistance_to", "biolink:associated_with_response_to", "biolink:associated_with_sensitivity_to", "biolink:biomarker_for", "biolink:coexpressed_with", "biolink:condition_associated_with_gene", "biolink:correlated_with", "biolink:decreased_likelihood_associated_with", "biolink:gene_associated_with_condition", "biolink:genetic_association", "biolink:genetically_associated_with", "biolink:has_biomarker", "biolink:increased_likelihood_associated_with", "biolink:likelihood_associated_with", "biolink:negatively_correlated_with", "biolink:occurs_together_in_literature_with", "biolink:positively_correlated_with", "biolink:resistance_associated_with", "biolink:response_associated_with", "biolink:sensitivity_associated_with"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""disease""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -9211,7 +9505,7 @@ class VariantToGeneAssociation(VariantToEntityAssociationMixin, Association): An association between a variant and a gene, where the variant has a genetic association with the gene (i.e. is in linkage disequilibrium) """ subject: str = Field(default=..., description="""a sequence variant in which the allele state is associated with some other entity""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:condition_associated_with_gene", "biolink:gene_associated_with_condition", "biolink:genetically_associated_with"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -9270,7 +9564,7 @@ class VariantToGeneExpressionAssociation(VariantToGeneAssociation, GeneExpressio stage_qualifier: Optional[str] = Field(default=None, description="""stage during which gene or protein expression of takes place.""") phenotypic_state: Optional[str] = Field(default=None, description="""in experiments (e.g. gene expression) assaying diseased or unhealthy tissue, the phenotypic state can be put here, e.g. MONDO ID. For healthy tissues, use XXX.""") subject: str = Field(default=..., description="""a sequence variant in which the allele state is associated with some other entity""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:affects", "biolink:ameliorates_condition", "biolink:disrupts", "biolink:exacerbates_condition", "biolink:has_adverse_event", "biolink:has_side_effect", "biolink:regulates"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -9501,7 +9795,7 @@ class VariantToPhenotypicFeatureAssociation(VariantToEntityAssociationMixin, Ent class VariantToDiseaseAssociation(VariantToEntityAssociationMixin, EntityToDiseaseAssociationMixin, Association): subject: str = Field(default=..., description="""a sequence variant in which the allele state is associated in some way with the disease state""") - predicate: str = Field(default=..., description="""E.g. is pathogenic for""") + predicate: Literal["biolink:related_condition"] = Field(default=..., description="""E.g. is pathogenic for""") object: str = Field(default=..., description="""a disease that is associated with that variant""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -9560,7 +9854,7 @@ class VariantToDiseaseAssociation(VariantToEntityAssociationMixin, EntityToDisea class GenotypeToDiseaseAssociation(GenotypeToEntityAssociationMixin, EntityToDiseaseAssociationMixin, Association): subject: str = Field(default=..., description="""a genotype that is associated in some way with a disease state""") - predicate: str = Field(default=..., description="""E.g. is pathogenic for""") + predicate: Literal["biolink:related_condition"] = Field(default=..., description="""E.g. is pathogenic for""") object: str = Field(default=..., description="""a disease that is associated with that genotype""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -9622,13 +9916,13 @@ class ModelToDiseaseAssociationMixin(ConfiguredBaseModel): This mixin is used for any association class for which the subject (source node) plays the role of a 'model', in that it recapitulates some features of the disease in a way that is useful for studying the disease outside a patient carrying the disease """ subject: str = Field(default=..., description="""The entity that serves as the model of the disease. This may be an organism, a strain of organism, a genotype or variant that exhibits similar features, or a gene that when mutated exhibits features of the disease""") - predicate: str = Field(default=..., description="""The relationship to the disease""") + predicate: Literal["biolink:model_of"] = Field(default=..., description="""The relationship to the disease""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") class GeneAsAModelOfDiseaseAssociation(ModelToDiseaseAssociationMixin, GeneToDiseaseAssociation, EntityToDiseaseAssociationMixin): subject: str = Field(default=..., description="""A gene that has a role in modeling the disease. This may be a model organism ortholog of a known disease gene, or it may be a gene whose mutants recapitulate core features of the disease.""") - predicate: GeneToDiseasePredicateEnum = Field(default=..., description="""The relationship to the disease""") + predicate: Literal["model_of"] = Field(default=..., description="""The relationship to the disease""") object: str = Field(default=..., description="""disease""") subject_form_or_variant_qualifier: Optional[ChemicalOrGeneOrGeneProductFormOrVariantEnum] = Field(default=None, description="""A qualifier that composes with a core subject/object concept to define a specific type, variant, alternative version of this concept. The composed concept remains a subtype or instance of the core concept. For example, the qualifier ‘mutation’ combines with the core concept ‘Gene X’ to express the compose concept ‘a mutation of Gene X’. This qualifier specifies a change in the subject of an association (aka: statement).""") subject_aspect_qualifier: Optional[GeneOrGeneProductOrChemicalEntityAspectEnum] = Field(default=None, description="""Composes with the core concept to describe new concepts of a different ontological type. e.g. a process in which the core concept participates, a function/activity/role held by the core concept, or a characteristic/quality that inheres in the core concept. The purpose of the aspect slot is to indicate what aspect is being affected in an 'affects' association. This qualifier specifies a change in the subject of an association (aka: statement).""") @@ -9704,7 +9998,7 @@ def pattern_allelic_requirement(cls, v): class VariantAsAModelOfDiseaseAssociation(ModelToDiseaseAssociationMixin, VariantToDiseaseAssociation, EntityToDiseaseAssociationMixin): subject: str = Field(default=..., description="""A variant that has a role in modeling the disease.""") - predicate: str = Field(default=..., description="""The relationship to the disease""") + predicate: Literal["biolink:model_of"] = Field(default=..., description="""The relationship to the disease""") object: str = Field(default=..., description="""disease""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -9763,7 +10057,7 @@ class VariantAsAModelOfDiseaseAssociation(ModelToDiseaseAssociationMixin, Varian class GenotypeAsAModelOfDiseaseAssociation(ModelToDiseaseAssociationMixin, GenotypeToDiseaseAssociation, EntityToDiseaseAssociationMixin): subject: str = Field(default=..., description="""A genotype that has a role in modeling the disease.""") - predicate: str = Field(default=..., description="""The relationship to the disease""") + predicate: Literal["biolink:model_of"] = Field(default=..., description="""The relationship to the disease""") object: str = Field(default=..., description="""disease""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -9822,7 +10116,7 @@ class GenotypeAsAModelOfDiseaseAssociation(ModelToDiseaseAssociationMixin, Genot class CellLineAsAModelOfDiseaseAssociation(ModelToDiseaseAssociationMixin, CellLineToDiseaseOrPhenotypicFeatureAssociation, EntityToDiseaseAssociationMixin): subject: str = Field(default=..., description="""A cell line derived from an organismal entity with a disease state that is used as a model of that disease.""") - predicate: str = Field(default=..., description="""The relationship to the disease""") + predicate: Literal["biolink:model_of"] = Field(default=..., description="""The relationship to the disease""") object: str = Field(default=..., description="""disease""") disease_context_qualifier: Optional[str] = Field(default=None, description="""A context qualifier representing a disease or condition in which a relationship expressed in an association took place.""") subject_specialization_qualifier: Optional[str] = Field(default=None, description="""A qualifier that composes with a core subject/object concept to define a more specific version of the subject concept, specifically using an ontology term that is not a subclass or descendant of the core concept and in the vast majority of cases, is of a different ontological namespace than the category or namespace of the subject identifier.""") @@ -9884,7 +10178,7 @@ class CellLineAsAModelOfDiseaseAssociation(ModelToDiseaseAssociationMixin, CellL class OrganismalEntityAsAModelOfDiseaseAssociation(ModelToDiseaseAssociationMixin, EntityToDiseaseAssociationMixin, Association): subject: str = Field(default=..., description="""A organismal entity (strain, breed) with a predisposition to a disease, or bred/created specifically to model a disease.""") - predicate: str = Field(default=..., description="""The relationship to the disease""") + predicate: Literal["biolink:model_of"] = Field(default=..., description="""The relationship to the disease""") object: str = Field(default=..., description="""disease""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -10054,7 +10348,7 @@ class GeneHasVariantThatContributesToDiseaseAssociation(GeneToDiseaseAssociation diseases_confidence_score: Optional[float] = Field(default=None, description="""A score defined by Jensen Lab Diseases that reports confidence level in an association on a scale of 1-5 stars. It is based on different inputs for curated knowledge associations vs text-mined associations vs experimental/GWAS based associations, but adjusts/caps scores for these types of knowledge such that they are comparable on a single scale.""") gene2phenotype_confidence_category: Optional[str] = Field(default=None, description="""A term used by EBI Gene2Phenotype to describe the confidence that the association is real. GenCC confidence terms are used for different levels of confidence (enum). See https://www.ebi.ac.uk/gene2phenotype/about/terminology#g2p-confidence-section.""") subject: str = Field(default=..., description="""A gene that has a role in modeling the disease. This may be a model organism ortholog of a known disease gene, or it may be a gene whose mutants recapitulate core features of the disease.""") - predicate: GeneToDiseasePredicateEnum = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["causes", "contributes_to"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -10125,7 +10419,7 @@ class GeneToExpressionSiteAssociation(Association): quantifier_qualifier: Optional[str] = Field(default=None, description="""can be used to indicate magnitude, or also ranking""") object_specialization_qualifier: Optional[str] = Field(default=None, description="""A qualifier that composes with a core subject/object concept to define a more specific version of the subject concept, specifically using an ontology term that is not a subclass or descendant of the core concept and in the vast majority of cases, is of a different ontological namespace than the category or namespace of the subject identifier.""") subject: str = Field(default=..., description="""Gene or gene product positively within the specified anatomical entity (or subclass, i.e. cellular component) location.""") - predicate: str = Field(default=..., description="""expression relationship""") + predicate: Literal["biolink:expressed_in"] = Field(default=..., description="""expression relationship""") object: str = Field(default=..., description="""location in which the gene is expressed""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -10802,7 +11096,7 @@ class GenomicSequenceLocalization(SequenceAssociation): strand: Optional[StrandEnum] = Field(default=None, description="""The strand on which a feature is located. Has a value of '+' (sense strand or forward strand) or '-' (anti-sense strand or reverse strand).""") phase: Optional[PhaseEnum] = Field(default=None, description="""The phase for a coding sequence entity. For example, phase of a CDS as represented in a GFF3 with a value of 0, 1 or 2.""") subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:has_sequence_location"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -10967,7 +11261,7 @@ class GeneToGeneProductRelationship(SequenceFeatureRelationship): A gene is transcribed and potentially translated to a gene product """ subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:has_gene_product"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -11078,7 +11372,7 @@ class ChemicalEntityOrGeneOrGeneProductRegulatesGeneAssociation(Association): """ object_direction_qualifier: Optional[DirectionQualifierEnum] = Field(default=None, description="""Composes with the core concept (+ aspect if provided) to describe a change in its direction or degree. This qualifier qualifies the object of an association (aka: statement).""") subject: str = Field(default=..., description="""connects an association to the subject of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") - predicate: str = Field(default=..., description="""the direction is always from regulator to regulated""") + predicate: Literal["biolink:regulates"] = Field(default=..., description="""the direction is always from regulator to regulated""") object: str = Field(default=..., description="""connects an association to the object of the association. For example, in a gene-to-phenotype association, the gene is subject and phenotype is object.""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -11185,7 +11479,7 @@ class AnatomicalEntityHasPartAnatomicalEntityAssociation(AnatomicalEntityToAnato A relationship between two anatomical entities where the relationship is mereological, i.e the two entities are related by parthood, that is, the subject is has the object entity as a part (the expected predicate is \"biolink:has_part\" or suitable predicate slots inheriting from it, i.e., \"biolink:has_plasma_membrane_part\", \"biolink:has_variant_part\", etc.). This includes relationships between cells and cellular components, between issues and cells, whole organisms and tissues. """ subject: str = Field(default=..., description="""the whole""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:has_active_ingredient", "biolink:has_excipient", "biolink:has_food_component", "biolink:has_nutrient", "biolink:has_part", "biolink:has_plasma_membrane_part", "biolink:has_variant_part"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""the part""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -11240,7 +11534,7 @@ class AnatomicalEntityPartOfAnatomicalEntityAssociation(AnatomicalEntityToAnatom A relationship between two anatomical entities where the relationship is mereological, i.e the two entities are related by parthood, that is, the subject is a part of the object entity (the expected predicate is \"biolink:part_of\" or suitable predicate slots inheriting from it, i.e., \"biolink:plasma_membrane_part_of\", \"biolink:variant_part_of\", etc.). This includes relationships between cellular components and cells, between cells and tissues, tissues and whole organisms. """ subject: str = Field(default=..., description="""the part""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:food_component_of", "biolink:is_active_ingredient_of", "biolink:is_excipient_of", "biolink:nutrient_of", "biolink:part_of", "biolink:plasma_membrane_part_of", "biolink:variant_part_of"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""the whole""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -11295,7 +11589,7 @@ class AnatomicalEntityToAnatomicalEntityOntogenicAssociation(AnatomicalEntityToA A relationship between two anatomical entities where the relationship is ontogenic, i.e. the two entities are related by development. A number of different relationship types can be used to specify the precise nature of the relationship. """ subject: str = Field(default=..., description="""the structure at a later time""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:develops_from"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""the structure at an earlier time""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -11524,7 +11818,7 @@ class OrganismTaxonToOrganismTaxonSpecialization(OrganismTaxonToOrganismTaxonAss A child-parent relationship between two taxa. For example: Homo sapiens subclass_of Homo """ subject: str = Field(default=..., description="""the more specific taxon""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:subclass_of"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""the more general taxon""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -11580,7 +11874,7 @@ class OrganismTaxonToOrganismTaxonInteraction(OrganismTaxonToOrganismTaxonAssoci """ associated_environmental_context: Optional[str] = Field(default=None, description="""the environment in which the two taxa interact""") subject: str = Field(default=..., description="""the taxon that is the subject of the association""") - predicate: str = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") + predicate: Literal["biolink:binds", "biolink:directly_physically_interacts_with", "biolink:gene_fusion_with", "biolink:genetic_neighborhood_of", "biolink:genetically_interacts_with", "biolink:indirectly_physically_interacts_with", "biolink:interacts_with", "biolink:physically_interacts_with", "biolink:regulates"] = Field(default=..., description="""Has a value from the Biolink 'related_to' hierarchy. In RDF, this corresponds to rdf:predicate and in Neo4j this corresponds to the relationship type. The convention is for an edge label in snake_case form. For example, biolink:related_to, biolink:causes, biolink:treats""") object: str = Field(default=..., description="""the taxon that is the subject of the association""") negated: Optional[bool] = Field(default=None, description="""if set to true, then the association is negated i.e. is not true""") qualifier: Optional[str] = Field(default=None, description="""grouping slot for all qualifiers on an edge. useful for testing compliance with association classes""") @@ -12015,4 +12309,3 @@ class OrganismTaxonToEnvironmentAssociation(OrganismTaxonToEntityAssociation, As OrganismTaxonToOrganismTaxonSpecialization.model_rebuild() OrganismTaxonToOrganismTaxonInteraction.model_rebuild() OrganismTaxonToEnvironmentAssociation.model_rebuild() - diff --git a/tests/test_deterministic_ids.py b/tests/test_deterministic_ids.py new file mode 100644 index 0000000000..55ee75e2ae --- /dev/null +++ b/tests/test_deterministic_ids.py @@ -0,0 +1,163 @@ +import pytest +from biolink_model.datamodel.pydanticmodel_v2 import ( + Association, GeneToDiseaseAssociation, + AssociationIdConfig, IdStrategy, +) + + +@pytest.fixture(autouse=True) +def reset_strategy(): + """Reset to default strategy after each test.""" + yield + AssociationIdConfig.strategy = IdStrategy.SPO_Q_KLAT_PKS + AssociationIdConfig.custom_fields = [] + + +# -- Core behavior (works with any strategy) ---------------------------------- + +def test_auto_generated_id(): + assoc = Association( + subject="HGNC:1234", + predicate="biolink:related_to", + object="HP:0001234", + knowledge_level="not_provided", + agent_type="not_provided", + ) + assert assoc.id.startswith("uuid:") + + +def test_deterministic_same_inputs(): + kwargs = dict( + subject="HGNC:1234", + predicate="biolink:related_to", + object="HP:0001234", + knowledge_level="not_provided", + agent_type="not_provided", + ) + assert Association(**kwargs).id == Association(**kwargs).id + + +def test_different_inputs_different_id(): + assoc1 = Association( + subject="HGNC:1234", predicate="biolink:related_to", object="HP:0001234", + knowledge_level="not_provided", agent_type="not_provided", + ) + assoc2 = Association( + subject="HGNC:9999", predicate="biolink:related_to", object="HP:0001234", + knowledge_level="not_provided", agent_type="not_provided", + ) + assert assoc1.id != assoc2.id + + +def test_explicit_id_preserved(): + assoc = Association( + id="my:custom-id", + subject="HGNC:1234", predicate="biolink:related_to", object="HP:0001234", + knowledge_level="not_provided", agent_type="not_provided", + ) + assert assoc.id == "my:custom-id" + + +def test_subclass_inherits_id_generation(): + g2d = GeneToDiseaseAssociation( + subject="HGNC:1234", predicate="biolink:contributes_to", object="MONDO:0005148", + knowledge_level="knowledge_assertion", agent_type="manual_agent", + ) + assert g2d.id.startswith("uuid:") + + +def test_different_subclass_different_id(): + """Same core data in Association vs a subclass produces different IDs + because the class name is included in the hash.""" + base_kwargs = dict( + subject="HGNC:1234", predicate="biolink:contributes_to", object="MONDO:0005148", + knowledge_level="not_provided", agent_type="not_provided", + ) + assoc_id = Association(**base_kwargs).id + g2d_id = GeneToDiseaseAssociation(**base_kwargs).id + assert assoc_id != g2d_id + + +# -- Strategy-specific behavior ------------------------------------------------ + +def test_standard_strategy_includes_publications(): + """With SPO_Q_KLAT_PKS, different publications -> different ID.""" + AssociationIdConfig.strategy = IdStrategy.SPO_Q_KLAT_PKS + base = dict( + subject="HGNC:1234", predicate="biolink:related_to", object="HP:0001234", + knowledge_level="not_provided", agent_type="not_provided", + ) + a1 = Association(**base, publications=["PMID:12345"]) + a2 = Association(**base, publications=["PMID:99999"]) + assert a1.id != a2.id + + +def test_standard_strategy_ignores_evidence(): + """With SPO_Q_KLAT_PKS, different evidence -> same ID.""" + AssociationIdConfig.strategy = IdStrategy.SPO_Q_KLAT_PKS + base = dict( + subject="HGNC:1234", predicate="biolink:related_to", object="HP:0001234", + knowledge_level="not_provided", agent_type="not_provided", + publications=["PMID:12345"], + ) + a1 = Association(**base, has_evidence=["ECO:0000304"]) + a2 = Association(**base, has_evidence=["ECO:0000501"]) + assert a1.id == a2.id + + +def test_all_fields_strategy(): + """With ALL_FIELDS, any field change -> different ID.""" + AssociationIdConfig.strategy = IdStrategy.ALL_FIELDS + base = dict( + subject="HGNC:1234", predicate="biolink:related_to", object="HP:0001234", + knowledge_level="not_provided", agent_type="not_provided", + ) + a1 = Association(**base, has_evidence=["ECO:0000304"]) + a2 = Association(**base, has_evidence=["ECO:0000501"]) + assert a1.id != a2.id + + +def test_qualifier_based_strategy_excludes_publications(): + """With QUALIFIER_BASED, different publications -> same ID.""" + AssociationIdConfig.strategy = IdStrategy.QUALIFIER_BASED + base = dict( + subject="HGNC:1234", predicate="biolink:related_to", object="HP:0001234", + knowledge_level="not_provided", agent_type="not_provided", + ) + a1 = Association(**base, publications=["PMID:12345"]) + a2 = Association(**base, publications=["PMID:99999"]) + assert a1.id == a2.id + + +def test_custom_strategy(): + """With CUSTOM, only specified fields matter.""" + AssociationIdConfig.strategy = IdStrategy.CUSTOM + AssociationIdConfig.custom_fields = ["subject", "predicate", "object"] + a1 = Association( + subject="HGNC:1234", predicate="biolink:related_to", object="HP:0001234", + knowledge_level="not_provided", agent_type="not_provided", + primary_knowledge_source="infores:monarchinitiative", + ) + a2 = Association( + subject="HGNC:1234", predicate="biolink:related_to", object="HP:0001234", + knowledge_level="knowledge_assertion", agent_type="manual_agent", # different + primary_knowledge_source="infores:other", # different + ) + assert a1.id == a2.id # only SPO matters + + +def test_switching_strategy_changes_id(): + """Same data produces different IDs under different strategies.""" + kwargs = dict( + subject="HGNC:1234", predicate="biolink:related_to", object="HP:0001234", + knowledge_level="not_provided", agent_type="not_provided", + ) + AssociationIdConfig.strategy = IdStrategy.SPO_Q_KLAT_PKS + id_standard = Association(**kwargs).id + + AssociationIdConfig.strategy = IdStrategy.ALL_FIELDS + id_all = Association(**kwargs).id + + # Different strategies -> (very likely) different IDs + # because ALL_FIELDS includes more fields in the hash + assert id_standard != id_all