AllenNeuralDynamics / AllenNeuralDynamics/biodata-schema

HumanSubject species validator not working correctly with JSON/dictionary input

Đang mở
#59 0 bình luận 0 reaction 1 người được giao Được @dbirman nhận Xem trên GitHub
Ngôn ngữ chính
Python
Star
0
Fork
0
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Mô tả

**Describe the bug**
The `HumanSubject` validator that checks that the species field is human does not work properly when validating a model from dictionaries read in from a JSON file.

**To Reproduce**
```python
import json
from aind_data_schema.components.subjects import HumanSubject, Sex
from aind_data_schema_models.species import Species, SpeciesModel
from aind_data_schema_models.organizations import Organization

# Make a dictionary directly from the schema
my_human_dict = json.loads(Species.HUMAN.model_dump_json())

# Make a HumanSubject using Species.HUMAN -- works
HumanSubject.model_validate({
"species": Species.HUMAN,
"sex": "Male",
"year_of_birth": 1948,
"source": Organization.AI
})
# HumanSubject(object_type='Human subject', species=_Homo_Sapiens(name='Homo sapiens', common_name='Human', registry=, registry_identifier='NCBI:txid9606'), sex='Male', year_of_birth=1948, source=_Allen_Institute(name='Allen Institute', abbreviation='AI', registry=, registry_identifier='03cpe7c52'))

# Make a HumanSubject using the dictionary -- fails
HumanSubject.model_validate({
"species": my_human_dict,
"sex": "Male",
"year_of_birth": 1948,
"source": Organization.AI
})
# pydantic_core._pydantic_core.ValidationError: 1 validation error for HumanSubject
# species
# Value error, HumanSubject species must be HUMAN [type=value_error, input_value={'name': 'Homo sapiens', ...ifier': 'NCBI:txid9606'}, input_type=dict]
# For further information visit https://errors.pydantic.dev/2.11/v/value_error
```

**Expected behavior**
Should return a valid `HumanSubject`.

I was able to get a version of `HumanSubject` to work like this if I changed the `species` field to be `Species.ONE_OF` (like the other species-specific subject models) and change the `field_validator` parameter to `mode="after"`. But this does lose the default of `Species.HUMAN` --- not sure how to keep that. I did need to make both changes for it to work.

```python
from pydantic import Field, field_validator, model_validator
from aind_data_schema.base import DataModel

class MyHumanSubject(DataModel):
"""Description of a human subject that validates with a dictionary for Species"""

species: Species.ONE_OF = Field(..., title="species") # Changed from original SpeciesModel = Field(default=Species.HUMAN, title="Species")
sex: Sex = Field(..., title="Sex")
year_of_birth: int = Field(..., title="Year of birth")
source: Organization.ONE_OF = Field(
...,
description="Where the subject was acquired from.",
title="Source",
)

@field_validator("species", mode="after") # Mode changed from "before" in original
def validate_species_is_human(cls, v):
"""Ensure species is always human for HumanSubject"""
if v != Species.HUMAN:
raise ValueError("HumanSubject species must be HUMAN")
return v

# Make a HumanSubject using Species.HUMAN -- still works
MyHumanSubject.model_validate({
"species": Species.HUMAN,
"sex": "Male",
"year_of_birth": 1948,
"source": Organization.AI
})
# MyHumanSubject(object_type='My human subject', species=_Homo_Sapiens(name='Homo sapiens', common_name='Human', registry=, registry_identifier='NCBI:txid9606'), sex='Male', year_of_birth=1948, source=_Allen_Institute(name='Allen Institute', abbreviation='AI', registry=, registry_identifier='03cpe7c52'))

# Make a HumanSubject using the dictionary -- now works
MyHumanSubject.model_validate({
"species": my_human_dict,
"sex": "Male",
"year_of_birth": 1948,
"source": Organization.AI
})
# MyHumanSubject(object_type='My human subject', species=_Homo_Sapiens(name='Homo sapiens', common_name='Human', registry=, registry_identifier='NCBI:txid9606'), sex='Male', year_of_birth=1948, source=_Allen_Institute(name='Allen Institute', abbreviation='AI', registry=, registry_identifier='03cpe7c52'))

# Make a HumanSubject using the wrong species -- fails as expected
MyHumanSubject.model_validate({
"species": Species.RHESUS_MACAQUE,
"sex": "Male",
"year_of_birth": 1948,
"source": Organization.AI
})
# pydantic_core._pydantic_core.ValidationError: 1 validation error for MyHumanSubject
# species
# Value error, HumanSubject species must be HUMAN [type=value_error, input_value=_Macaca_Mulatta(name='Mac...ntifier='NCBI:txid9544'), input_type=_Macaca_Mulatta]
# For further information visit https://errors.pydantic.dev/2.11/v/value_error
```

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.