From fd9aef95315aa98b8c3ca2b1140a72d8c0081c87 Mon Sep 17 00:00:00 2001 From: sneakers-the-rat Date: Wed, 30 Aug 2023 20:56:30 -0700 Subject: [PATCH] Cleaner code generation, npytyping type hints for arrays - split off generated subclasses into "include" files, not sure if that's good, but in any case we have them separable now. - more work on cleanly un-nesting scalar and 1D-vector data into attributes and lists, respectively - brought the pydantic generator in-repo to do a bunch of overrides --- nwb_linkml/adapters/namespaces.py | 1 - nwb_schema_language/.gitignore | 2 +- nwb_schema_language/Makefile | 5 - .../project/excel/nwb_schema_language.xlsx | Bin 10580 -> 10405 bytes .../graphql/nwb_schema_language.graphql | 16 +- .../jsonld/nwb_schema_language.context.jsonld | 9 +- .../project/jsonld/nwb_schema_language.jsonld | 190 ++++++++---------- .../nwb_schema_language.schema.json | 118 ++++++----- .../protobuf/nwb_schema_language.proto | 6 +- .../project/shex/nwb_schema_language.shex | 22 +- .../project/sqlschema/nwb_schema_language.sql | 6 +- nwb_schema_language/pyproject.toml | 2 +- .../datamodel/nwb_schema_language.py | 60 +++--- .../datamodel/nwb_schema_pydantic.py | 43 ++-- .../schema/nwb_schema_language.yaml | 15 -- 15 files changed, 229 insertions(+), 266 deletions(-) diff --git a/nwb_linkml/adapters/namespaces.py b/nwb_linkml/adapters/namespaces.py index 7f3c67b..b0f687d 100644 --- a/nwb_linkml/adapters/namespaces.py +++ b/nwb_linkml/adapters/namespaces.py @@ -92,7 +92,6 @@ class NamespacesAdapter(Adapter): all_matches = [*internal_matches, *import_matches] if len(all_matches)>1: - pdb.set_trace() raise KeyError(f"Found multiple schemas in namespace that define {name}:\ninternal: {pformat(internal_matches)}\nimported:{pformat(import_matches)}") elif len(all_matches) == 1: return all_matches[0] diff --git a/nwb_schema_language/.gitignore b/nwb_schema_language/.gitignore index e110be5..82cc468 100644 --- a/nwb_schema_language/.gitignore +++ b/nwb_schema_language/.gitignore @@ -1,4 +1,4 @@ -/docs/ + /project/docs/ /tmp/ diff --git a/nwb_schema_language/Makefile b/nwb_schema_language/Makefile index 9fa7103..0692fd9 100644 --- a/nwb_schema_language/Makefile +++ b/nwb_schema_language/Makefile @@ -110,11 +110,6 @@ gen-pydantic: $(PYMODEL) $(RUN) gen-pydantic $(SOURCE_SCHEMA_PATH) --pydantic_version 1 > $(PYMODEL)/nwb_schema_pydantic.py $(RUN) run_patches --phase post_generation_pydantic -gen-pydantic-test: $(PYMODEL) - $(RUN) gen-pydantic src/nwb_schema_language/schema/test_multival.yml --pydantic_version 1 > $(PYMODEL)/test_multival_pydantic.py -# $(RUN) run_patches --phase post_generation - - test: test-schema test-python test-examples test-schema: diff --git a/nwb_schema_language/project/excel/nwb_schema_language.xlsx b/nwb_schema_language/project/excel/nwb_schema_language.xlsx index fcd7b4086e96bc907035507ee786c1811dacb6c2..13103d694f6b2a6e34e0de059c6e27cbefae3c74 100644 GIT binary patch delta 1440 zcmcZ-v^0=6z?+#xgn@y9gW=FJxrw}M>w#3b;FATrUjYSAGcqs;0_l|eMp(d;Fg{z&+In`WKa!SltJZR{S)H65!j z->bf&We1!4n%*?t$p-x0hSr+AdZ#`J-i}NVSfT1JtFF;4q^A>H^74F}W#kFPo2{>Y z?|bojrnI@%!>=D7R>s+Fk4?I(n7YbP!*EiX{MC{`3%*?D`(0-fM zyIV|5Qs$MdYBar2eVm!+sps-bVlfw92=SMy$)$fznj;}0FZHV+P~GqhTcPy9?5UlZ zUs%|@x`eu>=W868vEqo|KE6edYBJ{RS=0aNymQ^Q?SYJ3Ci8bKG85)kTDc(1+FAQe z{DTQEzvX=NoOmj@zxGk`4IABL!Tyv*WgjP9i+{3n{ZExsb2m-!N@5p0{pmn_%;WHg zf6n^rE@j^TdvW@kw-Oa5((;def4c3SAh9Ac!)oVqk2)W7rbBrZdw7Kw%AT5L&-%mT z!C$F~ehT;Ay`2AaKWdC#lyZecfTT1DJU@ocr!AIFvD|wxb$T9SLHxsi!hudAOJQfLJeY2 zj+!*nUO}+XdqGwmbaU#X_gAh3nlpg~-Fg1PU`4V>kOu4X(~xGmB|AA=LoyZ=WoxvKUDye9?mwWv_)+v6mSbS3$k8v) zFUn5J&(FpdxPJ;H>%IUrd2%o?NTFz6sWADW2E?H}n$k>H6(=uH5}ju zaqRu$q^;+s^jxovI>obl`CjF>5G=}Z4}oK-R4xH3WYxM0_s2Ia|~N9QCqR<=ub*i7S|oUc`W7#$dwRxf%&r;W4e{5-Rh zrj;w-ZT}s+=+vGymulvUy{_FSbT#PC+Iw!-<@^85zOZeX-If0aajag4*4GEmM+u_M z*BI^Cn1O+`S)5}HBbafFvk=0t;+_d%T;sV6VXWcHgD_+TRzVo21p6V37~uyHhP`M$ zgt1ZV4I>{Y_#gjRUGNha^w*gu>q<%08-hZ-H27@ZZ3CVxxo$g5&WYe> z?Gk%^uFLnhQ_983D|XiY4lH}L>~@vF(fYb2E7rJ|f8b?MUB7mtoj7k`x%N_h>5QrS z5Af+kXO*l~61yAs>s;fiwguNt9L?D_W$mRfk(&#uOI+I;d$xUeAtZk*Z0B}Ui8sZD z_2TMBC*LzS(MXwCn#F(K!QP55A<(Z<>u%FmsoX~k&KZJ(^OK4~=3#j?q#w#IgY&a?Y_>xC^GkR>E`@h`J``38S+)o=EKL>|jd6J|$ zi7QK#$2Rf5Y@coHe&;({L9Wj>_{ZdIJ8|m7kxBJ$R^-ZDGPb;yz0RdIR5xXkgyWRd z$}jQt&*Bq*%6~t*{N0ypf2YP9Z3{lEe531Sx6!Qpd9(bzc&531koR5Am?!o}YxC-> zU(Zfzzm>4R^hWN+?H?K0j_!TSWZUrl&$-E;Ru{iGH}%wqzBRp@+7tDauEj{a?bJU0 zm)q?ucc6606u$Z|MH9m$%GlfrE2m0r`5kimgi&vM?TmBNHK&&}r%i3k;9hLlbIm}~ z;!2y?9KGPC@NbK)=7p-nhpqgy^qQvrOwXwBfmGekIcCkj}r94bqY{#Wr}5%cYAmsu@44qlGe7t&iScxfZB*0t>p{ z0AaAg24U98R%$$8`#sg9nT$oj!qsXJC-nn`mWly|#0(9v`4o{=85kr{d^$w}q-!## zI>aDZb!ny}Qa~YT9rVz;#QM=K2pCfCTnr4n$YwC|$V_fjmj=6SK2U$B+~hs#lChvL zS)+CA!cL&S{sH~PkD{kYo`InvN54G3C_5=XKO38){}f2peF19n @ ? ; @linkml:String ; @linkml:Boolean ? ; - @linkml:String ? + @linkml:String * ) ; rdf:type [ ] ? ) @@ -68,7 +68,7 @@ linkml:Sparqlpath xsd:string CLOSED { ( $ ( @linkml:String ; @linkml:String ; - @ + @linkml:String + ) ; rdf:type [ ] ? ) @@ -77,8 +77,6 @@ linkml:Sparqlpath xsd:string CLOSED { ( $ ( & ; rdf:type [ ] ? ; - & ; - rdf:type [ ] ? ; @linkml:String ? ; @linkml:String ? ; @linkml:String ? ; @@ -91,7 +89,7 @@ linkml:Sparqlpath xsd:string @linkml:String ? ; @linkml:Boolean ? ; @ * ; - @linkml:String ? + @linkml:String * ) ; rdf:type [ ] ? ) @@ -104,15 +102,13 @@ linkml:Sparqlpath xsd:string } { - ( $ @linkml:String ? ; + ( $ @linkml:String * ; rdf:type [ ] ? ) } CLOSED { - ( $ ( & ; - rdf:type [ ] ? ; - @linkml:String ? ; + ( $ ( @linkml:String ? ; @linkml:String ? ; @linkml:String ? ; @linkml:String ? ; @@ -152,7 +148,7 @@ linkml:Sparqlpath xsd:string schema1:dateModified @linkml:Date ? ; schema1:author @linkml:String + ; schema1:email @linkml:String + ; - @ * + @ * ) ; rdf:type [ ] ? ) @@ -164,12 +160,6 @@ linkml:Sparqlpath xsd:string ) } - { - ( $ rdf:type . * ; - rdf:type [ ] ? - ) -} - CLOSED { ( $ ( @linkml:String ; @ ? diff --git a/nwb_schema_language/project/sqlschema/nwb_schema_language.sql b/nwb_schema_language/project/sqlschema/nwb_schema_language.sql index f890c08..bbb9284 100644 --- a/nwb_schema_language/project/sqlschema/nwb_schema_language.sql +++ b/nwb_schema_language/project/sqlschema/nwb_schema_language.sql @@ -15,7 +15,7 @@ CREATE TABLE "Attribute" ( CREATE TABLE "CompoundDtype" ( name TEXT NOT NULL, doc TEXT NOT NULL, - dtype VARCHAR(11) NOT NULL, + dtype TEXT NOT NULL, PRIMARY KEY (name, doc, dtype) ); @@ -77,8 +77,8 @@ CREATE TABLE "Namespace" ( date DATE, author TEXT NOT NULL, contact TEXT NOT NULL, - schema TEXT, - PRIMARY KEY (doc, name, full_name, version, date, author, contact, schema) + schema_ TEXT, + PRIMARY KEY (doc, name, full_name, version, date, author, contact, schema_) ); CREATE TABLE "Namespaces" ( diff --git a/nwb_schema_language/pyproject.toml b/nwb_schema_language/pyproject.toml index a720763..8b95b15 100644 --- a/nwb_schema_language/pyproject.toml +++ b/nwb_schema_language/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "nwb_schema_language" -version = "0.1.0" +version = "0.1.1" description = "Translation of the nwb-schema-language to LinkML" authors = ["Jonny Saunders "] license = "GNU GPL v3.0" diff --git a/nwb_schema_language/src/nwb_schema_language/datamodel/nwb_schema_language.py b/nwb_schema_language/src/nwb_schema_language/datamodel/nwb_schema_language.py index a9bb3ef..2084de0 100644 --- a/nwb_schema_language/src/nwb_schema_language/datamodel/nwb_schema_language.py +++ b/nwb_schema_language/src/nwb_schema_language/datamodel/nwb_schema_language.py @@ -1,9 +1,9 @@ # Auto generated from nwb_schema_language.yaml by pythongen.py version: 0.0.1 -# Generation date: 2023-08-18T00:36:55 -# Schema: nwb_schema_language +# Generation date: 2023-08-30T20:54:02 +# Schema: nwb-schema-language # # id: https://w3id.org/p2p_ld/nwb-schema-language -# description: Translation of the nwb_schema_language to LinkML +# description: Translation of the nwb-schema-language to LinkML # license: GNU GPL v3.0 import dataclasses @@ -59,7 +59,7 @@ class Namespace(YAMLRoot): contact: Union[str, List[str]] = None full_name: Optional[str] = None date: Optional[Union[str, XSDDate]] = None - schema: Optional[Union[Union[dict, "Schema"], List[Union[dict, "Schema"]]]] = empty_list() + schema_: Optional[Union[Union[dict, "Schema"], List[Union[dict, "Schema"]]]] = empty_list() def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self._is_empty(self.doc): @@ -95,9 +95,9 @@ class Namespace(YAMLRoot): if self.date is not None and not isinstance(self.date, XSDDate): self.date = XSDDate(self.date) - if not isinstance(self.schema, list): - self.schema = [self.schema] if self.schema is not None else [] - self.schema = [v if isinstance(v, Schema) else Schema(**as_dict(v)) for v in self.schema] + if not isinstance(self.schema_, list): + self.schema_ = [self.schema_] if self.schema_ is not None else [] + self.schema_ = [v if isinstance(v, Schema) else Schema(**as_dict(v)) for v in self.schema_] super().__post_init__(**kwargs) @@ -251,7 +251,7 @@ class Attribute(YAMLRoot): value: Optional[Union[dict, "AnyType"]] = None default_value: Optional[Union[dict, "AnyType"]] = None required: Optional[Union[bool, Bool]] = True - dtype: Optional[str] = None + dtype: Optional[Union[str, List[str]]] = empty_list() def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self._is_empty(self.name): @@ -275,8 +275,9 @@ class Attribute(YAMLRoot): if self.required is not None and not isinstance(self.required, Bool): self.required = Bool(self.required) - if self.dtype is not None and not isinstance(self.dtype, str): - self.dtype = str(self.dtype) + if not isinstance(self.dtype, list): + self.dtype = [self.dtype] if self.dtype is not None else [] + self.dtype = [v if isinstance(v, str) else str(v) for v in self.dtype] super().__post_init__(**kwargs) @@ -336,7 +337,7 @@ class Dataset(YAMLRoot): quantity: Optional[str] = 1 linkable: Optional[Union[bool, Bool]] = None attributes: Optional[Union[Union[dict, Attribute], List[Union[dict, Attribute]]]] = empty_list() - dtype: Optional[str] = None + dtype: Optional[Union[str, List[str]]] = empty_list() def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self._is_empty(self.doc): @@ -372,8 +373,9 @@ class Dataset(YAMLRoot): self._normalize_inlined_as_dict(slot_name="attributes", slot_type=Attribute, key_name="name", keyed=False) - if self.dtype is not None and not isinstance(self.dtype, str): - self.dtype = str(self.dtype) + if not isinstance(self.dtype, list): + self.dtype = [self.dtype] if self.dtype is not None else [] + self.dtype = [v if isinstance(v, str) else str(v) for v in self.dtype] super().__post_init__(**kwargs) @@ -432,7 +434,7 @@ class CompoundDtype(YAMLRoot): name: str = None doc: str = None - dtype: Union[str, "FlatDtype"] = None + dtype: Union[str, List[str]] = None def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): if self._is_empty(self.name): @@ -447,8 +449,9 @@ class CompoundDtype(YAMLRoot): if self._is_empty(self.dtype): self.MissingRequiredField("dtype") - if not isinstance(self.dtype, FlatDtype): - self.dtype = FlatDtype(self.dtype) + if not isinstance(self.dtype, list): + self.dtype = [self.dtype] if self.dtype is not None else [] + self.dtype = [v if isinstance(v, str) else str(v) for v in self.dtype] super().__post_init__(**kwargs) @@ -462,27 +465,16 @@ class DtypeMixin(YAMLRoot): class_name: ClassVar[str] = "DtypeMixin" class_model_uri: ClassVar[URIRef] = NWB_SCHEMA_LANGUAGE.DtypeMixin - dtype: Optional[str] = None + dtype: Optional[Union[str, List[str]]] = empty_list() def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]): - if self.dtype is not None and not isinstance(self.dtype, str): - self.dtype = str(self.dtype) + if not isinstance(self.dtype, list): + self.dtype = [self.dtype] if self.dtype is not None else [] + self.dtype = [v if isinstance(v, str) else str(v) for v in self.dtype] super().__post_init__(**kwargs) -class NamingMixin(YAMLRoot): - """ - require either neurodata_type_def or name to be present - """ - _inherited_slots: ClassVar[List[str]] = [] - - class_class_uri: ClassVar[URIRef] = NWB_SCHEMA_LANGUAGE.NamingMixin - class_class_curie: ClassVar[str] = "nwb_schema_language:NamingMixin" - class_name: ClassVar[str] = "NamingMixin" - class_model_uri: ClassVar[URIRef] = NWB_SCHEMA_LANGUAGE.NamingMixin - - AnyType = Any # Enumerations @@ -645,7 +637,7 @@ slots.author = Slot(uri=SCHEMA.author, name="author", curie=SCHEMA.curie('author slots.contact = Slot(uri=SCHEMA.email, name="contact", curie=SCHEMA.curie('email'), model_uri=NWB_SCHEMA_LANGUAGE.contact, domain=None, range=Union[str, List[str]]) -slots.schema = Slot(uri=NWB_SCHEMA_LANGUAGE.schema, name="schema", curie=NWB_SCHEMA_LANGUAGE.curie('schema'), +slots.schema = Slot(uri=NWB_SCHEMA_LANGUAGE.schema_, name="schema", curie=NWB_SCHEMA_LANGUAGE.curie('schema_'), model_uri=NWB_SCHEMA_LANGUAGE.schema, domain=None, range=Optional[Union[Union[dict, Schema], List[Union[dict, Schema]]]]) slots.source = Slot(uri=NWB_SCHEMA_LANGUAGE.source, name="source", curie=NWB_SCHEMA_LANGUAGE.curie('source'), @@ -692,7 +684,7 @@ slots.links = Slot(uri=NWB_SCHEMA_LANGUAGE.links, name="links", curie=NWB_SCHEMA model_uri=NWB_SCHEMA_LANGUAGE.links, domain=None, range=Optional[Union[Union[dict, Link], List[Union[dict, Link]]]]) slots.dtype = Slot(uri=NWB_SCHEMA_LANGUAGE.dtype, name="dtype", curie=NWB_SCHEMA_LANGUAGE.curie('dtype'), - model_uri=NWB_SCHEMA_LANGUAGE.dtype, domain=None, range=Optional[str]) + model_uri=NWB_SCHEMA_LANGUAGE.dtype, domain=None, range=Optional[Union[str, List[str]]]) slots.dims = Slot(uri=NWB_SCHEMA_LANGUAGE.dims, name="dims", curie=NWB_SCHEMA_LANGUAGE.curie('dims'), model_uri=NWB_SCHEMA_LANGUAGE.dims, domain=None, range=Optional[Union[str, List[str]]]) @@ -728,4 +720,4 @@ slots.CompoundDtype_name = Slot(uri=NWB_SCHEMA_LANGUAGE.name, name="CompoundDtyp model_uri=NWB_SCHEMA_LANGUAGE.CompoundDtype_name, domain=CompoundDtype, range=str) slots.CompoundDtype_dtype = Slot(uri=NWB_SCHEMA_LANGUAGE.dtype, name="CompoundDtype_dtype", curie=NWB_SCHEMA_LANGUAGE.curie('dtype'), - model_uri=NWB_SCHEMA_LANGUAGE.CompoundDtype_dtype, domain=CompoundDtype, range=Union[str, "FlatDtype"]) \ No newline at end of file + model_uri=NWB_SCHEMA_LANGUAGE.CompoundDtype_dtype, domain=CompoundDtype, range=Union[str, List[str]]) \ No newline at end of file diff --git a/nwb_schema_language/src/nwb_schema_language/datamodel/nwb_schema_pydantic.py b/nwb_schema_language/src/nwb_schema_language/datamodel/nwb_schema_pydantic.py index 48e808f..59e2ad4 100644 --- a/nwb_schema_language/src/nwb_schema_language/datamodel/nwb_schema_pydantic.py +++ b/nwb_schema_language/src/nwb_schema_language/datamodel/nwb_schema_pydantic.py @@ -135,6 +135,21 @@ class Schema(ConfiguredBaseModel): doc: Optional[str] = Field(None) +class Group(ConfiguredBaseModel): + + neurodata_type_def: Optional[str] = Field(None, description="""Used alongside neurodata_type_inc to indicate inheritance, naming, and mixins""") + neurodata_type_inc: Optional[str] = Field(None, description="""Used alongside neurodata_type_def to indicate inheritance, naming, and mixins""") + name: Optional[str] = Field(None) + default_name: Optional[str] = Field(None) + doc: str = Field(..., description="""Description of corresponding object.""") + quantity: Optional[Union[QuantityEnum, int]] = Field(1) + linkable: Optional[bool] = Field(None) + attributes: Optional[List[Attribute]] = Field(default_factory=list) + datasets: Optional[List[Dataset]] = Field(default_factory=list) + groups: Optional[List[Group]] = Field(default_factory=list) + links: Optional[List[Link]] = Field(default_factory=list) + + class Groups(ConfiguredBaseModel): groups: Optional[List[Group]] = Field(default_factory=list) @@ -183,29 +198,7 @@ class Attribute(DtypeMixin): dtype: Optional[Union[List[CompoundDtype], FlatDtype, ReferenceDtype]] = Field(default_factory=list) -class NamingMixin(ConfiguredBaseModel): - """ - require either neurodata_type_def or name to be present - """ - None - - -class Group(NamingMixin): - - neurodata_type_def: Optional[str] = Field(None, description="""Used alongside neurodata_type_inc to indicate inheritance, naming, and mixins""") - neurodata_type_inc: Optional[str] = Field(None, description="""Used alongside neurodata_type_def to indicate inheritance, naming, and mixins""") - name: Optional[str] = Field(None) - default_name: Optional[str] = Field(None) - doc: str = Field(..., description="""Description of corresponding object.""") - quantity: Optional[Union[QuantityEnum, int]] = Field(1) - linkable: Optional[bool] = Field(None) - attributes: Optional[List[Attribute]] = Field(default_factory=list) - datasets: Optional[List[Dataset]] = Field(default_factory=list) - groups: Optional[List[Group]] = Field(default_factory=list) - links: Optional[List[Link]] = Field(default_factory=list) - - -class Dataset(NamingMixin, DtypeMixin): +class Dataset(DtypeMixin): neurodata_type_def: Optional[str] = Field(None, description="""Used alongside neurodata_type_inc to indicate inheritance, naming, and mixins""") neurodata_type_inc: Optional[str] = Field(None, description="""Used alongside neurodata_type_def to indicate inheritance, naming, and mixins""") @@ -219,7 +212,6 @@ class Dataset(NamingMixin, DtypeMixin): quantity: Optional[Union[QuantityEnum, int]] = Field(1) linkable: Optional[bool] = Field(None) attributes: Optional[List[Attribute]] = Field(default_factory=list) - datasets: Optional[List[Dataset]] = Field(default_factory=list) dtype: Optional[Union[List[CompoundDtype], FlatDtype, ReferenceDtype]] = Field(default_factory=list) @@ -229,6 +221,7 @@ class Dataset(NamingMixin, DtypeMixin): Namespace.update_forward_refs() Namespaces.update_forward_refs() Schema.update_forward_refs() +Group.update_forward_refs() Groups.update_forward_refs() Link.update_forward_refs() Datasets.update_forward_refs() @@ -236,7 +229,5 @@ ReferenceDtype.update_forward_refs() CompoundDtype.update_forward_refs() DtypeMixin.update_forward_refs() Attribute.update_forward_refs() -NamingMixin.update_forward_refs() -Group.update_forward_refs() Dataset.update_forward_refs() diff --git a/nwb_schema_language/src/nwb_schema_language/schema/nwb_schema_language.yaml b/nwb_schema_language/src/nwb_schema_language/schema/nwb_schema_language.yaml index a8446aa..923f433 100644 --- a/nwb_schema_language/src/nwb_schema_language/schema/nwb_schema_language.yaml +++ b/nwb_schema_language/src/nwb_schema_language/schema/nwb_schema_language.yaml @@ -66,8 +66,6 @@ classes: description: If source is present, namespace cannot be. Group: - mixins: - - NamingMixin slots: - neurodata_type_def - neurodata_type_inc @@ -110,7 +108,6 @@ classes: Dataset: mixins: - DtypeMixin - - NamingMixin slots: - neurodata_type_def - neurodata_type_inc @@ -124,7 +121,6 @@ classes: - quantity - linkable - attributes - - groups Datasets: slots: @@ -164,17 +160,6 @@ classes: dtype: multivalued: false - NamingMixin: - mixin: true - description: require either neurodata_type_def or name to be present - rules: - - preconditions: { slot_conditions: { neurodata_type_def: { value_presence: ABSENT } } } - postconditions: { slot_conditions: { name: { required: true } } } - description: If not defining a new type, a name is required - - preconditions: { slot_conditions: { name: { value_presence: ABSENT } } } - postconditions: { slot_conditions: { neurodata_type_def: { required: true } } } - description: If a name is not given, must be defining a new type - AnyType: class_uri: linkml:Any