nci-cidc-api-modules 1.2.54__py3-none-any.whl → 1.2.55__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- boot.py +8 -0
- cidc_api/__init__.py +1 -1
- cidc_api/config/db.py +0 -2
- cidc_api/models/dataset.py +80 -0
- cidc_api/models/db/stage1/additional_treatment_orm.py +8 -1
- cidc_api/models/db/stage1/adverse_event_orm.py +8 -1
- cidc_api/models/db/stage1/baseline_clinical_assessment_orm.py +8 -1
- cidc_api/models/db/stage1/comorbidity_orm.py +8 -1
- cidc_api/models/db/stage1/consent_group_orm.py +6 -6
- cidc_api/models/db/stage1/demographic_orm.py +8 -1
- cidc_api/models/db/stage1/disease_orm.py +8 -1
- cidc_api/models/db/stage1/exposure_orm.py +8 -1
- cidc_api/models/db/stage1/gvhd_diagnosis_acute_orm.py +8 -3
- cidc_api/models/db/stage1/gvhd_diagnosis_chronic_orm.py +8 -3
- cidc_api/models/db/stage1/gvhd_organ_acute_orm.py +8 -1
- cidc_api/models/db/stage1/gvhd_organ_chronic_orm.py +8 -1
- cidc_api/models/db/stage1/medical_history_orm.py +8 -1
- cidc_api/models/db/stage1/other_malignancy_orm.py +8 -1
- cidc_api/models/db/stage1/participant_orm.py +4 -5
- cidc_api/models/db/stage1/prior_treatment_orm.py +8 -2
- cidc_api/models/db/stage1/radiotherapy_dose_orm.py +8 -1
- cidc_api/models/db/stage1/response_by_system_orm.py +8 -1
- cidc_api/models/db/stage1/response_orm.py +9 -2
- cidc_api/models/db/stage1/specimen_orm.py +9 -25
- cidc_api/models/db/stage1/stem_cell_transplant_orm.py +8 -1
- cidc_api/models/db/stage1/surgery_orm.py +8 -1
- cidc_api/models/db/stage1/therapy_agent_dose_orm.py +8 -1
- cidc_api/models/db/stage1/treatment_orm.py +8 -1
- cidc_api/models/db/stage1/trial_orm.py +1 -2
- cidc_api/models/db/stage2/additional_treatment_orm.py +8 -1
- cidc_api/models/db/stage2/administrative_person_orm.py +8 -1
- cidc_api/models/db/stage2/administrative_role_assignment_orm.py +1 -0
- cidc_api/models/db/stage2/adverse_event_orm.py +8 -1
- cidc_api/models/db/stage2/arm_orm.py +5 -4
- cidc_api/models/db/stage2/baseline_clinical_assessment_orm.py +8 -1
- cidc_api/models/db/stage2/cohort_orm.py +5 -4
- cidc_api/models/db/stage2/comorbidity_orm.py +8 -1
- cidc_api/models/db/stage2/consent_group_orm.py +5 -5
- cidc_api/models/db/stage2/contact_orm.py +10 -1
- cidc_api/models/db/stage2/demographic_orm.py +8 -1
- cidc_api/models/db/stage2/disease_orm.py +8 -1
- cidc_api/models/db/stage2/exposure_orm.py +8 -1
- cidc_api/models/db/stage2/file_orm.py +4 -4
- cidc_api/models/db/stage2/gvhd_diagnosis_acute_orm.py +8 -3
- cidc_api/models/db/stage2/gvhd_diagnosis_chronic_orm.py +8 -3
- cidc_api/models/db/stage2/gvhd_organ_acute_orm.py +8 -1
- cidc_api/models/db/stage2/gvhd_organ_chronic_orm.py +8 -1
- cidc_api/models/db/stage2/institution_orm.py +4 -4
- cidc_api/models/db/stage2/medical_history_orm.py +8 -1
- cidc_api/models/db/stage2/other_clinical_endpoint_orm.py +9 -1
- cidc_api/models/db/stage2/other_malignancy_orm.py +8 -1
- cidc_api/models/db/stage2/participant_orm.py +6 -6
- cidc_api/models/db/stage2/prior_treatment_orm.py +9 -3
- cidc_api/models/db/stage2/publication_orm.py +5 -4
- cidc_api/models/db/stage2/radiotherapy_dose_orm.py +9 -2
- cidc_api/models/db/stage2/response_by_system_orm.py +8 -1
- cidc_api/models/db/stage2/response_orm.py +9 -2
- cidc_api/models/db/stage2/shipment_orm.py +5 -5
- cidc_api/models/db/stage2/shipment_specimen_orm.py +8 -2
- cidc_api/models/db/stage2/specimen_orm.py +9 -75
- cidc_api/models/db/stage2/stem_cell_transplant_orm.py +8 -1
- cidc_api/models/db/stage2/surgery_orm.py +8 -1
- cidc_api/models/db/stage2/therapy_agent_dose_orm.py +8 -1
- cidc_api/models/db/stage2/treatment_orm.py +8 -1
- cidc_api/models/db/stage2/trial_orm.py +1 -2
- cidc_api/models/pydantic/stage1/trial.py +1 -1
- cidc_api/models/pydantic/stage2/adverse_event.py +52 -25
- cidc_api/models/pydantic/stage2/comorbidity.py +15 -8
- cidc_api/models/pydantic/stage2/demographic.py +45 -28
- cidc_api/models/pydantic/stage2/disease.py +100 -58
- cidc_api/models/pydantic/stage2/exposure.py +14 -8
- cidc_api/models/pydantic/stage2/medical_history.py +15 -8
- cidc_api/models/pydantic/stage2/other_malignancy.py +17 -11
- cidc_api/models/pydantic/stage2/participant.py +27 -15
- cidc_api/models/pydantic/stage2/prior_treatment.py +2 -0
- cidc_api/models/pydantic/stage2/radiotherapy_dose.py +27 -14
- cidc_api/models/pydantic/stage2/response.py +42 -23
- cidc_api/models/pydantic/stage2/response_by_system.py +138 -30
- cidc_api/models/pydantic/stage2/specimen.py +2 -185
- cidc_api/models/pydantic/stage2/surgery.py +15 -7
- cidc_api/models/pydantic/stage2/therapy_agent_dose.py +27 -14
- cidc_api/models/pydantic/stage2/treatment.py +30 -16
- cidc_api/telemetry.py +13 -13
- {nci_cidc_api_modules-1.2.54.dist-info → nci_cidc_api_modules-1.2.55.dist-info}/METADATA +1 -1
- nci_cidc_api_modules-1.2.55.dist-info/RECORD +163 -0
- cidc_api/models/data.py +0 -28
- nci_cidc_api_modules-1.2.54.dist-info/RECORD +0 -163
- {nci_cidc_api_modules-1.2.54.dist-info → nci_cidc_api_modules-1.2.55.dist-info}/WHEEL +0 -0
- {nci_cidc_api_modules-1.2.54.dist-info → nci_cidc_api_modules-1.2.55.dist-info}/licenses/LICENSE +0 -0
- {nci_cidc_api_modules-1.2.54.dist-info → nci_cidc_api_modules-1.2.55.dist-info}/top_level.txt +0 -0
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Any
|
|
2
2
|
|
|
3
|
-
from pydantic import
|
|
3
|
+
from cidc_api.models.pydantic.base import forced_validator, forced_validators
|
|
4
4
|
|
|
5
|
+
from cidc_api.models.errors import ValueLocError
|
|
5
6
|
from cidc_api.models.pydantic.base import Base
|
|
6
7
|
from cidc_api.models.types import ICD10CMCode, ICD10CMTerm
|
|
7
8
|
|
|
8
9
|
|
|
10
|
+
@forced_validators
|
|
9
11
|
class Comorbidity(Base):
|
|
10
12
|
__data_category__ = "comorbidity"
|
|
11
13
|
__cardinality__ = "many"
|
|
@@ -27,10 +29,15 @@ class Comorbidity(Base):
|
|
|
27
29
|
# A descriptive string that names or briefly describes the comorbidity.
|
|
28
30
|
comorbidity_other: str | None = None
|
|
29
31
|
|
|
30
|
-
@
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
@forced_validator
|
|
33
|
+
@classmethod
|
|
34
|
+
def validate_code_or_term_or_other_cr(cls, data, info) -> None:
|
|
35
|
+
comorbidity_term = data.get("comorbidity_term", None)
|
|
36
|
+
comorbidity_other = data.get("comorbidity_other", None)
|
|
37
|
+
comorbidity_code = data.get("comorbidity_code", None)
|
|
38
|
+
|
|
39
|
+
if not comorbidity_code and not comorbidity_term and not comorbidity_other:
|
|
40
|
+
raise ValueLocError(
|
|
41
|
+
'Please provide at least one of "comorbidity_code", "comorbidity_term" or "comorbidity_other".',
|
|
42
|
+
loc="comorbidity_code,comorbidity_term,comorbidity_other",
|
|
35
43
|
)
|
|
36
|
-
return self
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Annotated, List
|
|
2
2
|
|
|
3
|
-
from pydantic import PositiveInt, NonNegativeFloat, PositiveFloat,
|
|
3
|
+
from pydantic import PositiveInt, NonNegativeFloat, PositiveFloat, BeforeValidator
|
|
4
|
+
from cidc_api.models.pydantic.base import forced_validator, forced_validators
|
|
4
5
|
|
|
6
|
+
from cidc_api.models.errors import ValueLocError
|
|
5
7
|
from cidc_api.models.pydantic.base import Base
|
|
6
8
|
from cidc_api.models.types import (
|
|
7
9
|
Sex,
|
|
@@ -17,6 +19,7 @@ from cidc_api.models.types import (
|
|
|
17
19
|
)
|
|
18
20
|
|
|
19
21
|
|
|
22
|
+
@forced_validators
|
|
20
23
|
class Demographic(Base):
|
|
21
24
|
__data_category__ = "demographic"
|
|
22
25
|
__cardinality__ = "one"
|
|
@@ -91,34 +94,48 @@ class Demographic(Base):
|
|
|
91
94
|
# CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=2681552%20and%20ver_nr=1
|
|
92
95
|
highest_level_of_education: Education | None = None
|
|
93
96
|
|
|
94
|
-
@
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
@forced_validator
|
|
98
|
+
@classmethod
|
|
99
|
+
def validate_age_at_enrollment_cr(cls, data, info) -> None:
|
|
100
|
+
age_at_enrollment_units = data.get("age_at_enrollment_units", None)
|
|
101
|
+
age_90_or_over = data.get("age_90_or_over", None)
|
|
102
|
+
age_at_enrollment = int(data.get("age_at_enrollment", None) or 0)
|
|
103
|
+
|
|
104
|
+
if age_90_or_over == "Yes":
|
|
105
|
+
if age_at_enrollment or age_at_enrollment_units:
|
|
106
|
+
raise ValueLocError(
|
|
107
|
+
'If "age_90_or_over" is "Yes" then "age_at_enrollment" and "age_at_enrollment_units" must be blank.',
|
|
108
|
+
loc="age_at_enrollment",
|
|
100
109
|
)
|
|
101
|
-
elif
|
|
102
|
-
if not
|
|
103
|
-
raise
|
|
104
|
-
'If "age_90_or_over" is "No" then "age_at_enrollment" and "age_at_enrollment_units" are required.'
|
|
110
|
+
elif age_90_or_over == "No":
|
|
111
|
+
if not age_at_enrollment or not age_at_enrollment_units:
|
|
112
|
+
raise ValueLocError(
|
|
113
|
+
'If "age_90_or_over" is "No" then "age_at_enrollment" and "age_at_enrollment_units" are required.',
|
|
114
|
+
loc="age_at_enrollment",
|
|
105
115
|
)
|
|
106
|
-
return self
|
|
107
116
|
|
|
108
|
-
@
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
117
|
+
@forced_validator
|
|
118
|
+
@classmethod
|
|
119
|
+
def validate_age_at_enrollment_value(cls, data, info) -> None:
|
|
120
|
+
age_at_enrollment_units = data.get("age_at_enrollment_units", None)
|
|
121
|
+
age_90_or_over = data.get("age_90_or_over", None)
|
|
122
|
+
age_at_enrollment = int(data.get("age_at_enrollment", None) or 0)
|
|
123
|
+
|
|
124
|
+
if age_90_or_over == "No":
|
|
125
|
+
age_in_years = age_at_enrollment if age_at_enrollment_units == "Years" else age_at_enrollment / 365.25
|
|
114
126
|
if age_in_years >= 90:
|
|
115
|
-
raise
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
127
|
+
raise ValueLocError(
|
|
128
|
+
'"age_at_enrollment" cannot represent a value greater than 90 years of age.',
|
|
129
|
+
loc="age_at_enrollment",
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
@forced_validator
|
|
133
|
+
@classmethod
|
|
134
|
+
def validate_body_surface_area_units_cr(cls, data, info) -> None:
|
|
135
|
+
body_surface_area = data.get("body_surface_area", None)
|
|
136
|
+
body_surface_area_units = data.get("body_surface_area_units", None)
|
|
137
|
+
|
|
138
|
+
if body_surface_area and not body_surface_area_units:
|
|
139
|
+
raise ValueLocError(
|
|
140
|
+
'If "body_surface_area" is provided then "body_surface_area_units" must also be provided.'
|
|
123
141
|
)
|
|
124
|
-
return self
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
from pydantic import NonPositiveInt,
|
|
2
|
-
from
|
|
1
|
+
from pydantic import NonPositiveInt, BeforeValidator
|
|
2
|
+
from cidc_api.models.pydantic.base import forced_validator, forced_validators
|
|
3
3
|
|
|
4
|
+
from typing import List, Self, Annotated, get_args, Any
|
|
5
|
+
|
|
6
|
+
from cidc_api.models.errors import ValueLocError
|
|
4
7
|
from cidc_api.models.pydantic.base import Base
|
|
5
8
|
from cidc_api.models.types import (
|
|
6
9
|
TumorGrade,
|
|
@@ -20,6 +23,7 @@ from cidc_api.models.types import (
|
|
|
20
23
|
)
|
|
21
24
|
|
|
22
25
|
|
|
26
|
+
@forced_validators
|
|
23
27
|
class Disease(Base):
|
|
24
28
|
__data_category__ = "disease"
|
|
25
29
|
__cardinality__ = "many"
|
|
@@ -92,67 +96,105 @@ class Disease(Base):
|
|
|
92
96
|
|
|
93
97
|
extramedullary_organ: Annotated[List[UberonAnatomicalTerm] | None, BeforeValidator(Base.split_list)] = []
|
|
94
98
|
|
|
95
|
-
@
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
@forced_validator
|
|
100
|
+
@classmethod
|
|
101
|
+
def validate_code_or_term_or_description_cr(cls, data, info) -> None:
|
|
102
|
+
morphological_term = data.get("morphological_term", None)
|
|
103
|
+
cancer_type_description = data.get("cancer_type_description", None)
|
|
104
|
+
morphological_code = data.get("morphological_code", None)
|
|
105
|
+
|
|
106
|
+
if not morphological_code and not morphological_term and not cancer_type_description:
|
|
107
|
+
raise ValueLocError(
|
|
108
|
+
'Please provide at least one of "morphological_code", "morphological_term" or "cancer_type_description".',
|
|
109
|
+
loc="morphological_code",
|
|
100
110
|
)
|
|
101
|
-
return self
|
|
102
111
|
|
|
103
|
-
@
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
112
|
+
@forced_validator
|
|
113
|
+
@classmethod
|
|
114
|
+
def validate_cancer_stage_system_version(cls, data, info) -> None:
|
|
115
|
+
cancer_stage_system_version = data.get("cancer_stage_system_version", None)
|
|
116
|
+
cancer_stage_system = data.get("cancer_stage_system", None)
|
|
117
|
+
|
|
118
|
+
msg = f"{cancer_stage_system_version} is not applicable to {cancer_stage_system}"
|
|
119
|
+
if cancer_stage_system == "AJCC" and cancer_stage_system_version not in get_args(CancerStageSystemVersionAJCC):
|
|
120
|
+
raise ValueLocError(msg, loc="cancer_stage_system")
|
|
121
|
+
elif cancer_stage_system == "RISS" and cancer_stage_system_version not in get_args(
|
|
111
122
|
CancerStageSystemVersionRISS
|
|
112
123
|
):
|
|
113
|
-
raise
|
|
114
|
-
elif
|
|
124
|
+
raise ValueLocError(msg, loc="cancer_stage_system")
|
|
125
|
+
elif cancer_stage_system == "FIGO" and cancer_stage_system_version not in get_args(
|
|
115
126
|
CancerStageSystemVersionFIGO
|
|
116
127
|
):
|
|
117
|
-
raise
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
@
|
|
121
|
-
def validate_cancer_stage_system_version_cr(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
128
|
+
raise ValueLocError(msg, loc="cancer_stage_system")
|
|
129
|
+
|
|
130
|
+
@forced_validator
|
|
131
|
+
@classmethod
|
|
132
|
+
def validate_cancer_stage_system_version_cr(cls, data, info) -> None:
|
|
133
|
+
cancer_stage_system = data.get("cancer_stage_system", None)
|
|
134
|
+
cancer_stage_system_version = data.get("cancer_stage_system_version", None)
|
|
135
|
+
|
|
136
|
+
if cancer_stage_system != "Not Applicable" and not cancer_stage_system_version:
|
|
137
|
+
raise ValueLocError(
|
|
138
|
+
f'Please provide cancer_stage_system_version when cancer_stage_system is "{cancer_stage_system}"',
|
|
139
|
+
loc="cancer_stage_system_version",
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
@forced_validator
|
|
143
|
+
@classmethod
|
|
144
|
+
def validate_cancer_stage_cr(cls, data, info) -> None:
|
|
145
|
+
cancer_stage_system = data.get("cancer_stage_system", None)
|
|
146
|
+
cancer_stage = data.get("cancer_stage", None)
|
|
147
|
+
|
|
148
|
+
if cancer_stage_system != "Not Applicable" and not cancer_stage:
|
|
149
|
+
raise ValueLocError(
|
|
150
|
+
f'Please provide cancer_stage when cancer_stage_system is "{cancer_stage_system}"',
|
|
151
|
+
loc="cancer_stage",
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
@forced_validator
|
|
155
|
+
@classmethod
|
|
156
|
+
def validate_t_category_cr(cls, data, info) -> None:
|
|
157
|
+
cancer_stage_system = data.get("cancer_stage_system", None)
|
|
158
|
+
t_category = data.get("t_category", None)
|
|
159
|
+
|
|
160
|
+
if cancer_stage_system == "AJCC" and not t_category:
|
|
161
|
+
raise ValueLocError(
|
|
162
|
+
f'Please provide t_category when cancer_stage_system is "{cancer_stage_system}"',
|
|
163
|
+
loc="t_category",
|
|
125
164
|
)
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
@
|
|
129
|
-
def
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
@
|
|
141
|
-
def
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
@
|
|
153
|
-
def validate_extramedullary_organ_cr(
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
165
|
+
|
|
166
|
+
@forced_validator
|
|
167
|
+
@classmethod
|
|
168
|
+
def validate_n_category_cr(cls, data, info) -> None:
|
|
169
|
+
cancer_stage_system = data.get("cancer_stage_system", None)
|
|
170
|
+
n_category = data.get("n_category", None)
|
|
171
|
+
|
|
172
|
+
if cancer_stage_system == "AJCC" and not n_category:
|
|
173
|
+
raise ValueLocError(
|
|
174
|
+
f'Please provide n_category when cancer_stage_system is "{cancer_stage_system}"',
|
|
175
|
+
loc="n_category",
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
@forced_validator
|
|
179
|
+
@classmethod
|
|
180
|
+
def validate_m_category_cr(cls, data, info) -> None:
|
|
181
|
+
cancer_stage_system = data.get("cancer_stage_system", None)
|
|
182
|
+
m_category = data.get("m_category", None)
|
|
183
|
+
|
|
184
|
+
if cancer_stage_system == "AJCC" and not m_category:
|
|
185
|
+
raise ValueLocError(
|
|
186
|
+
f'Please provide m_category when cancer_stage_system is "{cancer_stage_system}"',
|
|
187
|
+
loc="m_category",
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
@forced_validator
|
|
191
|
+
@classmethod
|
|
192
|
+
def validate_extramedullary_organ_cr(cls, data, info) -> None:
|
|
193
|
+
solely_extramedullary_disease = data.get("solely_extramedullary_disease", None)
|
|
194
|
+
extramedullary_organ = data.get("extramedullary_organ", None)
|
|
195
|
+
|
|
196
|
+
if solely_extramedullary_disease in ["No", "Unknown"] and extramedullary_organ:
|
|
197
|
+
raise ValueLocError(
|
|
198
|
+
"If solely_extramedullary_disease indicates no disease, please leave extramedullary_organ blank.",
|
|
199
|
+
loc="extramedullary_organ",
|
|
157
200
|
)
|
|
158
|
-
return self
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
from pydantic import model_validator
|
|
1
|
+
from cidc_api.models.pydantic.base import forced_validator, forced_validators
|
|
4
2
|
|
|
3
|
+
from cidc_api.models.errors import ValueLocError
|
|
5
4
|
from cidc_api.models.pydantic.base import Base
|
|
6
5
|
from cidc_api.models.types import YNU, ExposureType
|
|
7
6
|
|
|
8
7
|
|
|
8
|
+
@forced_validators
|
|
9
9
|
class Exposure(Base):
|
|
10
10
|
__data_category__ = "exposure"
|
|
11
11
|
__cardinality__ = "many"
|
|
@@ -25,8 +25,14 @@ class Exposure(Base):
|
|
|
25
25
|
# CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=15753203%20and%20ver_nr=1
|
|
26
26
|
exposure_type: ExposureType | None = None
|
|
27
27
|
|
|
28
|
-
@
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
@forced_validator
|
|
29
|
+
@classmethod
|
|
30
|
+
def validate_exposure_type_cr(cls, data, info) -> None:
|
|
31
|
+
carcinogen_exposure = data.get("carcinogen_exposure", None)
|
|
32
|
+
exposure_type = data.get("exposure_type", None)
|
|
33
|
+
|
|
34
|
+
if carcinogen_exposure in ["No", "Unknown"] and exposure_type:
|
|
35
|
+
raise ValueLocError(
|
|
36
|
+
"If carcinogen_exposure indicates non exposure, please leave exposure_type blank.",
|
|
37
|
+
loc="exposure_type",
|
|
38
|
+
)
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
from pydantic import NonNegativeInt, PositiveFloat, model_validator
|
|
1
|
+
from pydantic import NonNegativeInt, PositiveFloat
|
|
2
|
+
from cidc_api.models.pydantic.base import forced_validator, forced_validators
|
|
4
3
|
|
|
4
|
+
from cidc_api.models.errors import ValueLocError
|
|
5
5
|
from cidc_api.models.pydantic.base import Base
|
|
6
6
|
from cidc_api.models.types import TobaccoSmokingStatus
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
@forced_validators
|
|
9
10
|
class MedicalHistory(Base):
|
|
10
11
|
__data_category__ = "medical_history"
|
|
11
12
|
__cardinality__ = "one"
|
|
@@ -29,8 +30,14 @@ class MedicalHistory(Base):
|
|
|
29
30
|
# CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=16089302%20and%20ver_nr=1
|
|
30
31
|
num_prior_systemic_therapies: NonNegativeInt | None = None
|
|
31
32
|
|
|
32
|
-
@
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
@forced_validator
|
|
34
|
+
@classmethod
|
|
35
|
+
def validate_pack_years_smoked_cr(cls, data, info) -> None:
|
|
36
|
+
tobacco_smoking_status = data.get("tobacco_smoking_status", None)
|
|
37
|
+
pack_years_smoked = data.get("pack_years_smoked", None)
|
|
38
|
+
|
|
39
|
+
if tobacco_smoking_status in ["Never Smoker", "Unknown", "Not reported"] and pack_years_smoked:
|
|
40
|
+
raise ValueLocError(
|
|
41
|
+
"If tobacco_smoking_status indicates non-smoker, please leave pack_years_smoked blank.",
|
|
42
|
+
loc="pack_years_smoked",
|
|
43
|
+
)
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
from pydantic import NonPositiveInt, model_validator
|
|
1
|
+
from pydantic import NonPositiveInt
|
|
2
|
+
from cidc_api.models.pydantic.base import forced_validator, forced_validators
|
|
4
3
|
|
|
4
|
+
from cidc_api.models.errors import ValueLocError
|
|
5
5
|
from cidc_api.models.pydantic.base import Base
|
|
6
6
|
from cidc_api.models.types import UberonAnatomicalTerm, ICDO3MorphologicalCode, ICDO3MorphologicalTerm, MalignancyStatus
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
@forced_validators
|
|
9
10
|
class OtherMalignancy(Base):
|
|
10
11
|
__data_category__ = "other_malignancy"
|
|
11
12
|
__cardinality__ = "many"
|
|
@@ -36,14 +37,19 @@ class OtherMalignancy(Base):
|
|
|
36
37
|
# Indicates the participant’s current clinical state regarding the cancer diagnosis.
|
|
37
38
|
other_malignancy_status: MalignancyStatus | None = None
|
|
38
39
|
|
|
39
|
-
@
|
|
40
|
-
|
|
40
|
+
@forced_validator
|
|
41
|
+
@classmethod
|
|
42
|
+
def validate_code_or_term_or_description_cr(cls, data, info) -> None:
|
|
43
|
+
other_malignancy_morphological_term = data.get("other_malignancy_morphological_term", None)
|
|
44
|
+
other_malignancy_description = data.get("other_malignancy_description", None)
|
|
45
|
+
other_malignancy_morphological_code = data.get("other_malignancy_morphological_code", None)
|
|
46
|
+
|
|
41
47
|
if (
|
|
42
|
-
not
|
|
43
|
-
and not
|
|
44
|
-
and not
|
|
48
|
+
not other_malignancy_morphological_code
|
|
49
|
+
and not other_malignancy_morphological_term
|
|
50
|
+
and not other_malignancy_description
|
|
45
51
|
):
|
|
46
|
-
raise
|
|
47
|
-
'Please provide at least one of "morphological_code", "morphological_term" or "malignancy_description".'
|
|
52
|
+
raise ValueLocError(
|
|
53
|
+
'Please provide at least one of "morphological_code", "morphological_term" or "malignancy_description".',
|
|
54
|
+
loc="other_malignancy_morphological_code",
|
|
48
55
|
)
|
|
49
|
-
return self
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
from pydantic import model_validator
|
|
1
|
+
from cidc_api.models.pydantic.base import forced_validator, forced_validators
|
|
4
2
|
|
|
3
|
+
from cidc_api.models.errors import ValueLocError
|
|
5
4
|
from cidc_api.models.pydantic.base import Base
|
|
6
5
|
from cidc_api.models.types import YNU
|
|
7
6
|
from cidc_api.models.types import OffStudyReason
|
|
8
7
|
|
|
9
8
|
|
|
9
|
+
@forced_validators
|
|
10
10
|
class Participant(Base):
|
|
11
11
|
__data_category__ = "participant"
|
|
12
12
|
__cardinality__ = "one"
|
|
@@ -16,7 +16,7 @@ class Participant(Base):
|
|
|
16
16
|
participant_id: str | None = None
|
|
17
17
|
|
|
18
18
|
# The participant identifier assigned by the clinical trial team overseeing the study
|
|
19
|
-
native_participant_id: str
|
|
19
|
+
native_participant_id: str | None = None
|
|
20
20
|
|
|
21
21
|
# The globally unique participant identifier assigned by the CIMAC network. e.g. C8P29A7
|
|
22
22
|
cimac_participant_id: str | None = None
|
|
@@ -38,14 +38,26 @@ class Participant(Base):
|
|
|
38
38
|
# Additional information if "Other" is selected for off_study_reason. e.g. "Transfer to another study"
|
|
39
39
|
off_study_reason_other: str | None = None
|
|
40
40
|
|
|
41
|
-
@
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
41
|
+
@forced_validator
|
|
42
|
+
@classmethod
|
|
43
|
+
def off_study_reason_cr(cls, data, info) -> None:
|
|
44
|
+
off_study = data.get("off_study", None)
|
|
45
|
+
off_study_reason = data.get("off_study_reason", None)
|
|
46
|
+
|
|
47
|
+
if off_study == "Yes" and not off_study_reason:
|
|
48
|
+
raise ValueLocError(
|
|
49
|
+
'If "off_study" is "Yes" then "off_study_reason" is required.',
|
|
50
|
+
loc="off_study_reason",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
@forced_validator
|
|
54
|
+
@classmethod
|
|
55
|
+
def off_study_reason_other_cr(cls, data, info) -> None:
|
|
56
|
+
off_study_reason_other = data.get("off_study_reason_other", None)
|
|
57
|
+
off_study_reason = data.get("off_study_reason", None)
|
|
58
|
+
|
|
59
|
+
if off_study_reason == "Other" and not off_study_reason_other:
|
|
60
|
+
raise ValueLocError(
|
|
61
|
+
'If "off_study_reason" is "Other" then "off_study_reason_other" is required.',
|
|
62
|
+
loc="off_study_reason_other",
|
|
63
|
+
)
|
|
@@ -24,6 +24,8 @@ class PriorTreatment(Base):
|
|
|
24
24
|
# the treatment modality.
|
|
25
25
|
prior_treatment_days_to_end: NonPositiveInt | None = None
|
|
26
26
|
|
|
27
|
+
# Specifies the category or kind of prior treatment modality a participant received.
|
|
28
|
+
|
|
27
29
|
# Description of the prior treatment such as its full generic name if it is a type of therapy agent,
|
|
28
30
|
# radiotherapy procedure name and location, or surgical procedure name and location.
|
|
29
31
|
prior_treatment_description: str
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
from pydantic import NonNegativeInt, NonNegativeFloat, model_validator
|
|
1
|
+
from pydantic import NonNegativeInt, NonNegativeFloat
|
|
2
|
+
from cidc_api.models.pydantic.base import forced_validator, forced_validators
|
|
4
3
|
|
|
4
|
+
from cidc_api.models.errors import ValueLocError
|
|
5
5
|
from cidc_api.models.pydantic.base import Base
|
|
6
6
|
from cidc_api.models.types import (
|
|
7
7
|
YN,
|
|
@@ -13,6 +13,7 @@ from cidc_api.models.types import (
|
|
|
13
13
|
)
|
|
14
14
|
|
|
15
15
|
|
|
16
|
+
@forced_validators
|
|
16
17
|
class RadiotherapyDose(Base):
|
|
17
18
|
__data_category__ = "radiotherapy_dose"
|
|
18
19
|
__cardinality__ = "many"
|
|
@@ -67,14 +68,26 @@ class RadiotherapyDose(Base):
|
|
|
67
68
|
# CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=7063755%20and%20ver_nr=1
|
|
68
69
|
radiation_extent: RadiationExtent
|
|
69
70
|
|
|
70
|
-
@
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
71
|
+
@forced_validator
|
|
72
|
+
@classmethod
|
|
73
|
+
def validate_changes_delays_description_cr(cls, data, info) -> None:
|
|
74
|
+
dose_changes_delays = data.get("dose_changes_delays", None)
|
|
75
|
+
changes_delays_description = data.get("changes_delays_description", None)
|
|
76
|
+
|
|
77
|
+
if dose_changes_delays == "Yes" and not changes_delays_description:
|
|
78
|
+
raise ValueLocError(
|
|
79
|
+
'If dose_changes_delays is "Yes", please provide changes_delays_description.',
|
|
80
|
+
loc="changes_delays_description",
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
@forced_validator
|
|
84
|
+
@classmethod
|
|
85
|
+
def validate_planned_dose_units_cr(cls, data, info) -> None:
|
|
86
|
+
planned_dose = data.get("planned_dose", None)
|
|
87
|
+
planned_dose_units = data.get("planned_dose_units", None)
|
|
88
|
+
|
|
89
|
+
if planned_dose and not planned_dose_units:
|
|
90
|
+
raise ValueLocError(
|
|
91
|
+
"If planned_dose is provided, please provide planned_dose_units.",
|
|
92
|
+
loc="planned_dose_units",
|
|
93
|
+
)
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
from pydantic import NonNegativeInt, model_validator
|
|
1
|
+
from pydantic import NonNegativeInt
|
|
2
|
+
from cidc_api.models.pydantic.base import forced_validator, forced_validators
|
|
4
3
|
|
|
4
|
+
from cidc_api.models.errors import ValueLocError
|
|
5
5
|
from cidc_api.models.pydantic.base import Base
|
|
6
|
-
from cidc_api.models.types import SurvivalStatus,
|
|
6
|
+
from cidc_api.models.types import SurvivalStatus, YNUNA, YN, CauseOfDeath
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
@forced_validators
|
|
9
10
|
class Response(Base):
|
|
10
11
|
__data_category__ = "response"
|
|
11
12
|
__cardinality__ = "one"
|
|
@@ -44,22 +45,40 @@ class Response(Base):
|
|
|
44
45
|
evaluable_for_efficacy: YN
|
|
45
46
|
|
|
46
47
|
# Days from enrollment date to the last time the patient's vital status was verified.
|
|
47
|
-
days_to_last_vital_status: NonNegativeInt | None = None
|
|
48
|
-
|
|
49
|
-
@
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
@
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
48
|
+
days_to_last_vital_status: NonNegativeInt | None = None
|
|
49
|
+
|
|
50
|
+
@forced_validator
|
|
51
|
+
@classmethod
|
|
52
|
+
def validate_cause_of_death_cr(cls, data, info) -> None:
|
|
53
|
+
survival_status = data.get("survival_status", None)
|
|
54
|
+
cause_of_death = data.get("cause_of_death", None)
|
|
55
|
+
|
|
56
|
+
if survival_status == "Dead" and not cause_of_death:
|
|
57
|
+
raise ValueLocError(
|
|
58
|
+
'If survival_status is "Dead" then cause_of_death is required.',
|
|
59
|
+
loc="cause_of_death",
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
@forced_validator
|
|
63
|
+
@classmethod
|
|
64
|
+
def validate_cause_of_death_cr2(cls, data, info) -> None:
|
|
65
|
+
survival_status = data.get("survival_status", None)
|
|
66
|
+
cause_of_death = data.get("cause_of_death", None)
|
|
67
|
+
|
|
68
|
+
if survival_status == "Alive" and cause_of_death:
|
|
69
|
+
raise ValueLocError(
|
|
70
|
+
'If survival_status is "Alive", please leave cause_of_death blank.',
|
|
71
|
+
loc="cause_of_death",
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
@forced_validator
|
|
75
|
+
@classmethod
|
|
76
|
+
def validate_days_to_death_cr(cls, data, info) -> None:
|
|
77
|
+
survival_status = data.get("survival_status", None)
|
|
78
|
+
days_to_death = data.get("days_to_death", None)
|
|
79
|
+
|
|
80
|
+
if survival_status in ["Alive", "Unknown"] and days_to_death:
|
|
81
|
+
raise ValueLocError(
|
|
82
|
+
"If survival_status does not indicate death, please leave days_to_death blank.",
|
|
83
|
+
loc="days_to_death",
|
|
84
|
+
)
|