Skip to content

Commit

Permalink
Merge pull request #245 from dandi/pydantic-discriminated-unions
Browse files Browse the repository at this point in the history
Use discriminated unions to provide more helpful error messages
  • Loading branch information
satra authored Jul 10, 2024
2 parents e135307 + abccf00 commit 06c0ee3
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 8 deletions.
3 changes: 2 additions & 1 deletion dandischema/consts.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
DANDI_SCHEMA_VERSION = "0.6.7"
DANDI_SCHEMA_VERSION = "0.6.8"
ALLOWED_INPUT_SCHEMAS = [
"0.4.4",
"0.5.1",
Expand All @@ -10,6 +10,7 @@
"0.6.4",
"0.6.5",
"0.6.6",
"0.6.7",
]

# ATM we allow only for a single target version which is current
Expand Down
30 changes: 24 additions & 6 deletions dandischema/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
)
from pydantic.json_schema import JsonSchemaValue
from pydantic_core import CoreSchema
from typing_extensions import (
Annotated, # TODO: import from `typing` when Python 3.8 support is dropped
)
from zarr_checksum.checksum import InvalidZarrChecksum, ZarrDirectoryDigest

from .consts import DANDI_SCHEMA_VERSION
Expand Down Expand Up @@ -1188,9 +1191,14 @@ class Activity(DandiBaseModel):

# isPartOf: Optional["Activity"] = Field(None, json_schema_extra={"nskey": "schema"})
# hasPart: Optional["Activity"] = Field(None, json_schema_extra={"nskey": "schema"})
wasAssociatedWith: Optional[List[Union[Person, Organization, Software, Agent]]] = (
Field(None, json_schema_extra={"nskey": "prov"})
)
wasAssociatedWith: Optional[
List[
Annotated[
Union[Person, Organization, Software, Agent],
Field(discriminator="schemaKey"),
]
]
] = Field(None, json_schema_extra={"nskey": "prov"})
used: Optional[List[Equipment]] = Field(
None,
description="A listing of equipment used for the activity.",
Expand Down Expand Up @@ -1467,13 +1475,21 @@ class CommonModel(DandiBaseModel):
description="A description of the item.",
json_schema_extra={"nskey": "schema"},
)
contributor: Optional[List[Union[Person, Organization]]] = Field(
contributor: Optional[
List[Annotated[Union[Person, Organization], Field(discriminator="schemaKey")]]
] = Field(
None,
title="Contributors",
description="Contributors to this item: persons or organizations.",
json_schema_extra={"nskey": "schema"},
)
about: Optional[List[Union[Disorder, Anatomy, GenericType]]] = Field(
about: Optional[
List[
Annotated[
Union[Disorder, Anatomy, GenericType], Field(discriminator="schemaKey")
]
]
] = Field(
None,
title="Subject matter of the dataset",
description="The subject matter of the content, such as disorders, brain anatomy.",
Expand Down Expand Up @@ -1586,7 +1602,9 @@ def contributor_musthave_contact(
max_length=3000,
json_schema_extra={"nskey": "schema"},
)
contributor: List[Union[Person, Organization]] = Field(
contributor: List[
Annotated[Union[Person, Organization], Field(discriminator="schemaKey")]
] = Field(
title="Dandiset contributors",
description="People or Organizations that have contributed to this Dandiset.",
json_schema_extra={"nskey": "schema"},
Expand Down
2 changes: 2 additions & 0 deletions dandischema/tests/data/metadata/meta_000008.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
{
"schemaKey": "Person",
"name": "Scala, Federico",
"email": "fscala@example.com",
"roleName": [
"dcite:DataCollector",
"dcite:Author",
Expand Down Expand Up @@ -150,6 +151,7 @@
"schemaKey": "Person",
"identifier": "0000-0002-4305-6376",
"name": "Tolias, Andreas Savas",
"email": "atolias@example.com",
"roleName": [
"dcite:Author",
"dcite:ContactPerson"
Expand Down
21 changes: 20 additions & 1 deletion dandischema/tests/test_datacite.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def metadata_basic() -> Dict[str, Any]:
"name": "A_last, A_first",
"email": "nemo@example.com",
"roleName": [RoleType("dcite:ContactPerson")],
"schemaKey": "Person",
}
],
"license": [LicenseType("spdx:CC-BY-4.0")],
Expand Down Expand Up @@ -195,12 +196,18 @@ def test_datacite(dandi_id: str, schema: Any) -> None:
{
"name": "A_last, A_first",
"roleName": [RoleType("dcite:ContactPerson")],
"email": "nemo@example.com",
"schemaKey": "Person",
},
{
"name": "B_last, B_first",
"roleName": [RoleType("dcite:Author")],
"schemaKey": "Person",
},
{
"name": "C_last, C_first",
"schemaKey": "Person",
},
{"name": "C_last, C_first"},
],
},
{
Expand All @@ -218,10 +225,13 @@ def test_datacite(dandi_id: str, schema: Any) -> None:
{
"name": "A_last, A_first",
"roleName": [RoleType("dcite:ContactPerson")],
"email": "nemo@example.com",
"schemaKey": "Person",
},
{
"name": "B_last, B_first",
"roleName": [RoleType("dcite:Sponsor")],
"schemaKey": "Person",
},
],
},
Expand All @@ -237,11 +247,14 @@ def test_datacite(dandi_id: str, schema: Any) -> None:
{
"name": "A_last, A_first",
"roleName": [RoleType("dcite:ContactPerson")],
"email": "nemo@example.com",
"schemaKey": "Person",
},
{
"name": "B_last, B_first",
"identifier": "0000-0001-0000-0000",
"roleName": [RoleType("dcite:Sponsor")],
"schemaKey": "Person",
},
],
},
Expand All @@ -264,11 +277,14 @@ def test_datacite(dandi_id: str, schema: Any) -> None:
{
"name": "A_last, A_first",
"roleName": [RoleType("dcite:ContactPerson")],
"email": "nemo@example.com",
"schemaKey": "Person",
},
{
"name": "B_last, B_first",
"identifier": "0000-0001-0000-0000",
"roleName": [RoleType("dcite:Funder")],
"schemaKey": "Person",
},
],
},
Expand Down Expand Up @@ -297,10 +313,13 @@ def test_datacite(dandi_id: str, schema: Any) -> None:
RoleType("dcite:Software"),
],
"identifier": "0000-0001-0000-0000",
"schemaKey": "Person",
},
{
"name": "B_last, B_first",
"roleName": [RoleType("dcite:ContactPerson")],
"email": "nemo@example.com",
"schemaKey": "Person",
},
],
},
Expand Down
1 change: 1 addition & 0 deletions dandischema/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ def test_dantimeta_1() -> None:
"name": "last name, first name",
"email": "someone@dandiarchive.org",
"roleName": [RoleType("dcite:ContactPerson")],
"schemaKey": "Person",
}
],
"license": [LicenseType("spdx:CC-BY-4.0")],
Expand Down

0 comments on commit 06c0ee3

Please sign in to comment.