nci-cidc-api-modules 1.2.31__tar.gz → 1.2.39__tar.gz
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.
- {nci_cidc_api_modules-1.2.31/nci_cidc_api_modules.egg-info → nci_cidc_api_modules-1.2.39}/PKG-INFO +22 -13
- nci_cidc_api_modules-1.2.39/cidc_api/__init__.py +1 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/additional_treatment_orm.py +3 -3
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/demographic_orm.py +6 -4
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/other_malignancy_orm.py +6 -6
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/prior_treatment_orm.py +11 -10
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/response_by_system_orm.py +1 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/response_orm.py +2 -2
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/trial_orm.py +19 -16
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/models.py +140 -9
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/additional_treatment.py +3 -3
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/base.py +5 -1
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/demographic.py +11 -3
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/other_malignancy.py +11 -7
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/prior_treatment.py +11 -11
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/response.py +3 -9
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/response_by_system.py +4 -1
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/trial.py +12 -2
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/types.py +6 -0
- nci_cidc_api_modules-1.2.39/cidc_api/shared/assay_handling.py +68 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/shared/auth.py +5 -5
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/shared/file_handling.py +3 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/shared/gcloud_client.py +27 -5
- nci_cidc_api_modules-1.2.39/cidc_api/shared/utils.py +19 -0
- nci_cidc_api_modules-1.2.39/cidc_api/telemetry.py +101 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39/nci_cidc_api_modules.egg-info}/PKG-INFO +22 -13
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/nci_cidc_api_modules.egg-info/SOURCES.txt +3 -0
- nci_cidc_api_modules-1.2.39/nci_cidc_api_modules.egg-info/requires.txt +35 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/pyproject.toml +3 -0
- nci_cidc_api_modules-1.2.39/requirements.modules.txt +43 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/setup.py +3 -1
- nci_cidc_api_modules-1.2.31/cidc_api/shared/utils.py +0 -11
- nci_cidc_api_modules-1.2.31/nci_cidc_api_modules.egg-info/requires.txt +0 -26
- nci_cidc_api_modules-1.2.31/requirements.modules.txt +0 -28
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/LICENSE +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/MANIFEST.in +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/README.md +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/config/__init__.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/config/db.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/config/logging.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/config/secrets.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/config/settings.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/__init__.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/data.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/base_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/__init__.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/administrative_person_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/administrative_role_assignment_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/adverse_event_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/arm_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/baseline_clinical_assessment_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/cohort_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/comorbidity_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/consent_group_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/contact_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/disease_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/exposure_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/file_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/gvhd_diagnosis_acute_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/gvhd_diagnosis_chronic_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/gvhd_organ_acute_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/gvhd_organ_chronic_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/institution_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/medical_history_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/other_clinical_endpoint_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/participant_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/publication_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/radiotherapy_dose_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/shipment_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/shipment_specimen_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/specimen_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/stem_cell_transplant_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/surgery_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/therapy_agent_dose_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/treatment_orm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/files/__init__.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/files/details.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/files/facets.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/migrations.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/__init__.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/administrative_person.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/administrative_role_assignment.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/adverse_event.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/arm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/baseline_clinical_assessment.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/cohort.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/comorbidity.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/consent_group.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/contact.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/disease.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/exposure.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/file.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/gvhd_diagnosis_acute.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/gvhd_diagnosis_chronic.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/gvhd_organ_acute.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/gvhd_organ_chronic.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/institution.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/medical_history.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/other_clinical_endpoint.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/participant.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/publication.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/radiotherapy_dose.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/shipment.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/shipment_specimen.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/specimen.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/stem_cell_transplant.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/surgery.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/therapy_agent_dose.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/treatment.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/schemas.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/reference/ctcae.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/reference/gvhd.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/reference/icd10cm.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/reference/icdo3.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/reference/uberon.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/shared/__init__.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/shared/email_layout.html +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/shared/emails.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/shared/jose.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/shared/rest_utils.py +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/nci_cidc_api_modules.egg-info/dependency_links.txt +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/nci_cidc_api_modules.egg-info/not-zip-safe +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/nci_cidc_api_modules.egg-info/top_level.txt +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/setup.cfg +0 -0
- {nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/tests/test_api.py +0 -0
{nci_cidc_api_modules-1.2.31/nci_cidc_api_modules.egg-info → nci_cidc_api_modules-1.2.39}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nci_cidc_api_modules
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.39
|
|
4
4
|
Summary: SQLAlchemy data models and configuration tools used in the NCI CIDC API
|
|
5
5
|
Home-page: https://github.com/NCI-CIDC/cidc-api-gae
|
|
6
6
|
License: MIT license
|
|
@@ -8,30 +8,39 @@ Requires-Python: >=3.13
|
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
License-File: LICENSE
|
|
10
10
|
Requires-Dist: certifi>=2025.11.12
|
|
11
|
-
Requires-Dist: cloud-sql-python-connector[pg8000]>=1.
|
|
11
|
+
Requires-Dist: cloud-sql-python-connector[pg8000]>=1.19.0
|
|
12
12
|
Requires-Dist: flask>=3.1.2
|
|
13
13
|
Requires-Dist: flask-migrate>=4.1.0
|
|
14
14
|
Requires-Dist: flask-sqlalchemy>=3.1.1
|
|
15
15
|
Requires-Dist: flask-talisman>=0.7.0
|
|
16
|
-
Requires-Dist: google-auth==2.
|
|
17
|
-
Requires-Dist: google-api-python-client>=2.
|
|
18
|
-
Requires-Dist: google-cloud-bigquery>=3.
|
|
19
|
-
Requires-Dist: google-cloud-pubsub>=2.
|
|
20
|
-
Requires-Dist: google-cloud-secret-manager>=2.
|
|
21
|
-
Requires-Dist: google-cloud-storage>=3.
|
|
16
|
+
Requires-Dist: google-auth==2.45.0
|
|
17
|
+
Requires-Dist: google-api-python-client>=2.187.0
|
|
18
|
+
Requires-Dist: google-cloud-bigquery>=3.39.0
|
|
19
|
+
Requires-Dist: google-cloud-pubsub>=2.34.0
|
|
20
|
+
Requires-Dist: google-cloud-secret-manager>=2.26.0
|
|
21
|
+
Requires-Dist: google-cloud-storage>=3.7.0
|
|
22
22
|
Requires-Dist: jinja2>=3.1.6
|
|
23
|
-
Requires-Dist:
|
|
23
|
+
Requires-Dist: joserfc>=1.6.0
|
|
24
|
+
Requires-Dist: marshmallow>=4.1.2
|
|
24
25
|
Requires-Dist: marshmallow-sqlalchemy>=1.4.2
|
|
25
|
-
Requires-Dist: numpy>=2.
|
|
26
|
+
Requires-Dist: numpy>=2.4.0
|
|
26
27
|
Requires-Dist: packaging>=25.0
|
|
27
28
|
Requires-Dist: pandas>=2.3.3
|
|
28
29
|
Requires-Dist: pyarrow>=22.0.0
|
|
29
|
-
Requires-Dist: pydantic~=2.12.
|
|
30
|
+
Requires-Dist: pydantic~=2.12.5
|
|
30
31
|
Requires-Dist: python-dotenv>=1.2.1
|
|
31
32
|
Requires-Dist: requests>=2.32.5
|
|
32
|
-
Requires-Dist: sqlalchemy>=2.0.
|
|
33
|
+
Requires-Dist: sqlalchemy>=2.0.45
|
|
33
34
|
Requires-Dist: sqlalchemy-mixins~=2.0.5
|
|
34
|
-
Requires-Dist: werkzeug>=3.1.
|
|
35
|
+
Requires-Dist: werkzeug>=3.1.4
|
|
36
|
+
Requires-Dist: opentelemetry-api>=1.39.1
|
|
37
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.39.1
|
|
38
|
+
Requires-Dist: opentelemetry-sdk>=1.39.1
|
|
39
|
+
Requires-Dist: opentelemetry-instrumentation-flask>=0.59b0
|
|
40
|
+
Requires-Dist: opentelemetry-instrumentation-requests>=0.59b0
|
|
41
|
+
Requires-Dist: opentelemetry-instrumentation-sqlalchemy>=0.59b0
|
|
42
|
+
Requires-Dist: opentelemetry-exporter-gcp-trace>=1.11.0
|
|
43
|
+
Requires-Dist: opentelemetry-propagator-gcp>=1.11.0
|
|
35
44
|
Requires-Dist: nci-cidc-schemas==0.28.10
|
|
36
45
|
Dynamic: description
|
|
37
46
|
Dynamic: description-content-type
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.2.39"
|
|
@@ -16,8 +16,8 @@ class AdditionalTreatmentORM(BaseORM):
|
|
|
16
16
|
additional_treatment_id: Mapped[int] = mapped_column(primary_key=True)
|
|
17
17
|
participant_id: Mapped[int] = mapped_column(ForeignKey("stage2.participant.participant_id", ondelete="CASCADE"))
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
additional_treatment_days_to_start: Mapped[Optional[NonNegativeInt]]
|
|
20
|
+
additional_treatment_days_to_end: Mapped[Optional[NonNegativeInt]]
|
|
21
|
+
additional_treatment_description: Mapped[str]
|
|
22
22
|
|
|
23
23
|
participant: Mapped["ParticipantORM"] = relationship(back_populates="additional_treatments", cascade="all, delete")
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
from pydantic import NonNegativeFloat, PositiveFloat, PositiveInt
|
|
2
|
+
from typing import List
|
|
2
3
|
|
|
3
4
|
from sqlalchemy import ForeignKey
|
|
4
5
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
6
|
+
from sqlalchemy.types import JSON
|
|
5
7
|
|
|
6
8
|
from cidc_api.models.db.base_orm import BaseORM
|
|
7
9
|
from cidc_api.models.types import (
|
|
@@ -29,15 +31,15 @@ class DemographicORM(BaseORM):
|
|
|
29
31
|
age_at_enrollment_units: Mapped[AgeAtEnrollmentUnits | None]
|
|
30
32
|
age_90_or_over: Mapped[bool]
|
|
31
33
|
sex: Mapped[Sex]
|
|
32
|
-
race: Mapped[Race]
|
|
34
|
+
race: Mapped[List[Race]] = mapped_column(JSON)
|
|
33
35
|
ethnicity: Mapped[Ethnicity]
|
|
34
36
|
height: Mapped[PositiveFloat]
|
|
35
37
|
height_units: Mapped[HeightUnits]
|
|
36
38
|
weight: Mapped[PositiveFloat]
|
|
37
39
|
weight_units: Mapped[WeightUnits]
|
|
38
|
-
body_mass_index: Mapped[PositiveFloat]
|
|
39
|
-
body_surface_area: Mapped[PositiveFloat]
|
|
40
|
-
body_surface_area_units: Mapped[BodySurfaceAreaUnits]
|
|
40
|
+
body_mass_index: Mapped[PositiveFloat | None]
|
|
41
|
+
body_surface_area: Mapped[PositiveFloat | None]
|
|
42
|
+
body_surface_area_units: Mapped[BodySurfaceAreaUnits | None]
|
|
41
43
|
occupation: Mapped[Occupation | None]
|
|
42
44
|
income: Mapped[NonNegativeFloat | None]
|
|
43
45
|
highest_level_of_education: Mapped[Education | None]
|
|
@@ -19,12 +19,12 @@ class OtherMalignancyORM(BaseORM):
|
|
|
19
19
|
ForeignKey("stage2.medical_history.medical_history_id", ondelete="CASCADE")
|
|
20
20
|
)
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
other_malignancy_primary_disease_site: Mapped[UberonAnatomicalTerm]
|
|
23
|
+
other_malignancy_morphological_code: Mapped[Optional[ICDO3MorphologicalCode]]
|
|
24
|
+
other_malignancy_morphological_term: Mapped[Optional[ICDO3MorphologicalTerm]]
|
|
25
|
+
other_malignancy_description: Mapped[Optional[str]]
|
|
26
|
+
other_malignancy_days_since_diagnosis: Mapped[Optional[NonPositiveInt]]
|
|
27
|
+
other_malignancy_status: Mapped[Optional[MalignancyStatus]]
|
|
28
28
|
|
|
29
29
|
medical_history: Mapped["MedicalHistoryORM"] = relationship(
|
|
30
30
|
back_populates="other_malignancies", cascade="all, delete"
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
from typing import Optional
|
|
1
|
+
from typing import Optional, List
|
|
2
2
|
|
|
3
|
-
from pydantic import NonPositiveInt,
|
|
3
|
+
from pydantic import NonPositiveInt, NegativeInt
|
|
4
4
|
from sqlalchemy import ForeignKey
|
|
5
5
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
6
|
+
from sqlalchemy.types import JSON
|
|
6
7
|
|
|
7
8
|
from cidc_api.models.db.base_orm import BaseORM
|
|
8
9
|
from cidc_api.models.types import PriorTreatmentType, ConditioningRegimenType, StemCellDonorType
|
|
@@ -17,13 +18,13 @@ class PriorTreatmentORM(BaseORM):
|
|
|
17
18
|
prior_treatment_id: Mapped[int] = mapped_column(primary_key=True)
|
|
18
19
|
participant_id: Mapped[int] = mapped_column(ForeignKey("stage2.participant.participant_id", ondelete="CASCADE"))
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
prior_treatment_days_to_start: Mapped[Optional[NonPositiveInt]]
|
|
22
|
+
prior_treatment_days_to_end: Mapped[Optional[NonPositiveInt]]
|
|
23
|
+
prior_treatment_type: Mapped[List[PriorTreatmentType]] = mapped_column(JSON, nullable=False)
|
|
24
|
+
prior_treatment_description: Mapped[Optional[str]]
|
|
25
|
+
prior_treatment_best_response: Mapped[Optional[str]]
|
|
26
|
+
prior_treatment_conditioning_regimen_type: Mapped[Optional[ConditioningRegimenType]]
|
|
27
|
+
prior_treatment_stem_cell_donor_type: Mapped[Optional[StemCellDonorType]]
|
|
28
|
+
prior_treatment_days_to_prior_transplant: Mapped[Optional[NegativeInt]]
|
|
28
29
|
|
|
29
30
|
participant: Mapped["ParticipantORM"] = relationship(back_populates="prior_treatments", cascade="all, delete")
|
|
@@ -18,6 +18,7 @@ class ResponseBySystemORM(BaseORM):
|
|
|
18
18
|
response_system_version: Mapped[ResponseSystemVersion] = mapped_column(String)
|
|
19
19
|
best_overall_response: Mapped[BestOverallResponse] = mapped_column(String)
|
|
20
20
|
response_duration: Mapped[PositiveInt | None]
|
|
21
|
+
duration_of_stable_disease: Mapped[PositiveInt | None]
|
|
21
22
|
durable_clinical_benefit: Mapped[bool | None]
|
|
22
23
|
days_to_first_response: Mapped[PositiveInt | None]
|
|
23
24
|
days_to_best_response: Mapped[PositiveInt | None]
|
|
@@ -16,13 +16,13 @@ class ResponseORM(BaseORM):
|
|
|
16
16
|
response_id: Mapped[int] = mapped_column(primary_key=True)
|
|
17
17
|
participant_id: Mapped[int] = mapped_column(ForeignKey("stage2.participant.participant_id", ondelete="CASCADE"))
|
|
18
18
|
survival_status: Mapped[SurvivalStatus]
|
|
19
|
-
overall_survival: Mapped[NonNegativeInt
|
|
19
|
+
overall_survival: Mapped[NonNegativeInt]
|
|
20
20
|
abscopal_response: Mapped[YNUNA | None]
|
|
21
21
|
pathological_complete_response: Mapped[YNUNA | None]
|
|
22
22
|
days_to_death: Mapped[NonNegativeInt | None]
|
|
23
23
|
cause_of_death: Mapped[CauseOfDeath | None]
|
|
24
24
|
evaluable_for_toxicity: Mapped[bool]
|
|
25
25
|
evaluable_for_efficacy: Mapped[bool]
|
|
26
|
-
|
|
26
|
+
days_to_last_vital_status: Mapped[NonNegativeInt | None]
|
|
27
27
|
|
|
28
28
|
participant: Mapped["ParticipantORM"] = relationship(back_populates="response", cascade="all, delete")
|
{nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/db/stage2/trial_orm.py
RENAMED
|
@@ -6,7 +6,7 @@ from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
|
6
6
|
from sqlalchemy.types import JSON
|
|
7
7
|
|
|
8
8
|
from cidc_api.models.db.base_orm import BaseORM
|
|
9
|
-
from cidc_api.models.types import AssayType, TrialOrganization, TrialFundingAgency
|
|
9
|
+
from cidc_api.models.types import AssayType, TrialOrganization, TrialFundingAgency, AgeGroup
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class TrialORM(BaseORM):
|
|
@@ -18,23 +18,26 @@ class TrialORM(BaseORM):
|
|
|
18
18
|
trial_id: Mapped[str] = mapped_column(primary_key=True)
|
|
19
19
|
version: Mapped[str] = mapped_column(primary_key=True)
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
21
|
+
primary_endpoint: Mapped[str | None]
|
|
22
|
+
age_group: Mapped[List[AgeGroup]] = mapped_column(JSON, nullable=True)
|
|
23
|
+
study_population: Mapped[str | None]
|
|
24
|
+
nct_id: Mapped[str | None]
|
|
25
|
+
nci_id: Mapped[str | None]
|
|
26
|
+
trial_name: Mapped[str | None]
|
|
27
|
+
trial_type: Mapped[str | None]
|
|
28
|
+
trial_description: Mapped[str | None]
|
|
29
|
+
trial_organization: Mapped[TrialOrganization | None]
|
|
30
|
+
grant_or_affiliated_network: Mapped[TrialFundingAgency | None]
|
|
31
|
+
biobank_institution_id: Mapped[int | None]
|
|
32
|
+
justification: Mapped[str | None]
|
|
30
33
|
dates_of_conduct_start: Mapped[datetime]
|
|
31
|
-
dates_of_conduct_end: Mapped[
|
|
32
|
-
schema_file_id: Mapped[
|
|
33
|
-
biomarker_plan: Mapped[
|
|
34
|
-
data_sharing_plan: Mapped[
|
|
35
|
-
expected_assays: Mapped[
|
|
34
|
+
dates_of_conduct_end: Mapped[datetime | None]
|
|
35
|
+
schema_file_id: Mapped[int | None]
|
|
36
|
+
biomarker_plan: Mapped[str | None]
|
|
37
|
+
data_sharing_plan: Mapped[str | None]
|
|
38
|
+
expected_assays: Mapped[List[AssayType]] = mapped_column(JSON, nullable=True)
|
|
36
39
|
is_liquid_tumor_trial: Mapped[bool]
|
|
37
|
-
dbgap_study_accession: Mapped[
|
|
40
|
+
dbgap_study_accession: Mapped[str | None]
|
|
38
41
|
|
|
39
42
|
biobank: Mapped["InstitutionORM"] = relationship(back_populates="trial")
|
|
40
43
|
schema: Mapped[Optional["FileORM"]] = relationship(back_populates="trial", viewonly=True)
|
|
@@ -35,7 +35,8 @@ __all__ = [
|
|
|
35
35
|
"ADMIN_FILE_CATEGORIES",
|
|
36
36
|
"FINAL_JOB_STATUS",
|
|
37
37
|
"INGESTION_JOB_STATUSES",
|
|
38
|
-
"
|
|
38
|
+
"ASSAY_JOB_COLORS",
|
|
39
|
+
"CLINICAL_JOB_COLORS",
|
|
39
40
|
]
|
|
40
41
|
|
|
41
42
|
import hashlib
|
|
@@ -3436,7 +3437,7 @@ INGESTION_JOB_STATUSES = [
|
|
|
3436
3437
|
]
|
|
3437
3438
|
|
|
3438
3439
|
# Business decision to pass hex codes from the backend though that should be done by the front end...
|
|
3439
|
-
|
|
3440
|
+
CLINICAL_JOB_COLORS = {
|
|
3440
3441
|
"DRAFT": "",
|
|
3441
3442
|
"INITIAL SUBMISSION": "#ACCAD7",
|
|
3442
3443
|
"VALIDATION REVIEW": "#DABE90",
|
|
@@ -3444,6 +3445,13 @@ INGESTION_JOB_COLORS = {
|
|
|
3444
3445
|
"INGESTION": "#8FCEC7",
|
|
3445
3446
|
"PUBLISHED": "#90D9E6",
|
|
3446
3447
|
}
|
|
3448
|
+
ASSAY_JOB_COLORS = {
|
|
3449
|
+
"INITIAL SUBMISSION": "#43807E",
|
|
3450
|
+
"VALIDATION REVIEW": "#906F3F",
|
|
3451
|
+
"REVISION SUBMISSION": "#95358A",
|
|
3452
|
+
"INGESTION": "#542C88",
|
|
3453
|
+
"PUBLISHED": "#1C81A0",
|
|
3454
|
+
}
|
|
3447
3455
|
# TODO If have "CANCELLED" concept or other final status, add here
|
|
3448
3456
|
FINAL_JOB_STATUS = ["PUBLISHED"]
|
|
3449
3457
|
TRIAL_APPENDIX_A_CELL_THAT_ENDS_THE_HEADER = "Data Category"
|
|
@@ -3465,11 +3473,44 @@ class IngestionJobs(CommonColumns):
|
|
|
3465
3473
|
pending = Column(Boolean, nullable=False, default=False)
|
|
3466
3474
|
start_date = Column(DateTime, nullable=True)
|
|
3467
3475
|
error_status = Column(String, nullable=True)
|
|
3476
|
+
job_type = Column(String, nullable=False, default="clinical")
|
|
3477
|
+
assay_type = Column(String, nullable=True)
|
|
3478
|
+
batch_id = Column(String, nullable=True)
|
|
3479
|
+
submission_id = Column(String, nullable=True)
|
|
3480
|
+
intake_path = Column(String, nullable=True)
|
|
3481
|
+
uploader_email = Column(String, nullable=True)
|
|
3468
3482
|
|
|
3469
3483
|
@staticmethod
|
|
3470
3484
|
@with_default_session
|
|
3471
|
-
def create(
|
|
3472
|
-
|
|
3485
|
+
def create(
|
|
3486
|
+
trial_id: str,
|
|
3487
|
+
status: str,
|
|
3488
|
+
version: int,
|
|
3489
|
+
error_status: str = None,
|
|
3490
|
+
pending: Boolean = False,
|
|
3491
|
+
job_type: str = "clinical",
|
|
3492
|
+
assay_type: str = None,
|
|
3493
|
+
batch_id: str = None,
|
|
3494
|
+
submission_id: str = None,
|
|
3495
|
+
intake_path: str = None,
|
|
3496
|
+
start_date: datetime = None,
|
|
3497
|
+
uploader_email: str = None,
|
|
3498
|
+
session: Session = None,
|
|
3499
|
+
):
|
|
3500
|
+
new_job = IngestionJobs(
|
|
3501
|
+
trial_id=trial_id,
|
|
3502
|
+
status=status,
|
|
3503
|
+
error_status=error_status,
|
|
3504
|
+
version=version,
|
|
3505
|
+
pending=pending,
|
|
3506
|
+
job_type=job_type,
|
|
3507
|
+
assay_type=assay_type,
|
|
3508
|
+
batch_id=batch_id,
|
|
3509
|
+
submission_id=submission_id,
|
|
3510
|
+
intake_path=intake_path,
|
|
3511
|
+
start_date=start_date,
|
|
3512
|
+
uploader_email=uploader_email,
|
|
3513
|
+
)
|
|
3473
3514
|
new_job.insert(session=session)
|
|
3474
3515
|
return new_job
|
|
3475
3516
|
|
|
@@ -3494,29 +3535,43 @@ class IngestionJobs(CommonColumns):
|
|
|
3494
3535
|
|
|
3495
3536
|
@classmethod
|
|
3496
3537
|
@with_default_session
|
|
3497
|
-
def get_jobs_by_trial(
|
|
3498
|
-
|
|
3538
|
+
def get_jobs_by_trial(
|
|
3539
|
+
cls, trial_id: str, job_type: str = "clinical", session: Session = None
|
|
3540
|
+
) -> list["IngestionJobs"]:
|
|
3541
|
+
return (
|
|
3542
|
+
session.query(cls)
|
|
3543
|
+
.filter(cls.trial_id == trial_id, cls.job_type == job_type)
|
|
3544
|
+
.order_by(cls.version.desc())
|
|
3545
|
+
.all()
|
|
3546
|
+
)
|
|
3499
3547
|
|
|
3500
3548
|
@classmethod
|
|
3501
3549
|
@with_default_session
|
|
3502
|
-
def get_open_job_by_trial(
|
|
3550
|
+
def get_open_job_by_trial(
|
|
3551
|
+
cls, trial_id: str, job_type: str = "clinical", session: Session = None
|
|
3552
|
+
) -> Optional["IngestionJobs"]:
|
|
3503
3553
|
"""Return the open job for a given trial if it exists."""
|
|
3504
3554
|
return (
|
|
3505
3555
|
session.query(cls)
|
|
3506
3556
|
.filter(
|
|
3507
3557
|
cls.trial_id == trial_id,
|
|
3558
|
+
cls.job_type == job_type,
|
|
3508
3559
|
cls.status.notin_(FINAL_JOB_STATUS),
|
|
3509
3560
|
)
|
|
3510
3561
|
.order_by(cls._created.desc())
|
|
3511
3562
|
.first()
|
|
3512
3563
|
)
|
|
3513
3564
|
|
|
3565
|
+
@classmethod
|
|
3566
|
+
def get_jobs_for_user(cls, user: Users, job_type: str = None) -> list["IngestionJobs"]:
|
|
3567
|
+
return cls.get_assay_jobs_for_user(user) if job_type == "assay" else cls.get_clinical_jobs_for_user(user)
|
|
3568
|
+
|
|
3514
3569
|
@classmethod
|
|
3515
3570
|
@with_default_session
|
|
3516
|
-
def
|
|
3571
|
+
def get_clinical_jobs_for_user(cls, user: Users, session: Session = None) -> list["IngestionJobs"]:
|
|
3517
3572
|
if user.role not in [CIDCRole.ADMIN.value, CIDCRole.CLINICAL_TRIAL_USER.value]:
|
|
3518
3573
|
return []
|
|
3519
|
-
job_query = session.query(cls).filter(cls.status.notin_(["DRAFT"]))
|
|
3574
|
+
job_query = session.query(cls).filter(cls.status.notin_(["DRAFT"]), cls.job_type == "clinical")
|
|
3520
3575
|
if (
|
|
3521
3576
|
user.role != CIDCRole.ADMIN.value
|
|
3522
3577
|
and not session.query(Permissions)
|
|
@@ -3539,6 +3594,81 @@ class IngestionJobs(CommonColumns):
|
|
|
3539
3594
|
job_query = job_query.filter(cls.trial_id.in_(map(lambda x: x.trial_id, authorized_trials)))
|
|
3540
3595
|
return job_query.order_by(cls._created.desc()).all()
|
|
3541
3596
|
|
|
3597
|
+
@classmethod
|
|
3598
|
+
@with_default_session
|
|
3599
|
+
def get_assay_jobs_for_user(cls, user: Users, session: Session = None) -> list["IngestionJobs"]:
|
|
3600
|
+
# TODO allow more than just Admin role and get authorized trials based on permissions
|
|
3601
|
+
if user.role not in [CIDCRole.ADMIN.value]:
|
|
3602
|
+
return []
|
|
3603
|
+
return session.query(cls).filter(cls.job_type == "assay").order_by(cls._created.desc()).all()
|
|
3604
|
+
|
|
3605
|
+
@classmethod
|
|
3606
|
+
@with_default_session
|
|
3607
|
+
def get_unique_assay_job(
|
|
3608
|
+
cls,
|
|
3609
|
+
trial_id: str,
|
|
3610
|
+
assay_type: str,
|
|
3611
|
+
batch_id: str,
|
|
3612
|
+
session: Session = None,
|
|
3613
|
+
) -> Optional["IngestionJobs"]:
|
|
3614
|
+
"""Look for unique assay job with matching trial_id/assay_type/batch_id combination."""
|
|
3615
|
+
return (
|
|
3616
|
+
session.query(cls)
|
|
3617
|
+
.filter(
|
|
3618
|
+
cls.job_type == "assay",
|
|
3619
|
+
cls.trial_id == trial_id,
|
|
3620
|
+
cls.assay_type == assay_type,
|
|
3621
|
+
cls.batch_id == batch_id,
|
|
3622
|
+
)
|
|
3623
|
+
.first()
|
|
3624
|
+
)
|
|
3625
|
+
|
|
3626
|
+
@classmethod
|
|
3627
|
+
@with_default_session
|
|
3628
|
+
def next_assay_submission_id(cls, trial_id: str, assay_type: str, session: Session = None) -> str:
|
|
3629
|
+
"""
|
|
3630
|
+
Generate the next CIDC Submission ID for an assay job.
|
|
3631
|
+
|
|
3632
|
+
Format:
|
|
3633
|
+
<trial_id>-<assay_type>-<yyyymmdd> (first submission of the day)
|
|
3634
|
+
<trial_id>-<assay_type>-<yyyymmdd>-<#> (subsequent submissions on same day)
|
|
3635
|
+
|
|
3636
|
+
Uses only the most recent matching submission_id to determine the next suffix.
|
|
3637
|
+
"""
|
|
3638
|
+
today_str = datetime.now().strftime("%Y%m%d")
|
|
3639
|
+
base_submission_id = f"{trial_id}-{assay_type}-{today_str}"
|
|
3640
|
+
|
|
3641
|
+
# Get the most recent submission_id matching this prefix
|
|
3642
|
+
latest = (
|
|
3643
|
+
session.query(cls.submission_id)
|
|
3644
|
+
.filter(
|
|
3645
|
+
cls.trial_id == trial_id,
|
|
3646
|
+
cls.assay_type == assay_type,
|
|
3647
|
+
cls.submission_id.like(f"{base_submission_id}%"),
|
|
3648
|
+
)
|
|
3649
|
+
.order_by(cls._created.desc())
|
|
3650
|
+
.first()
|
|
3651
|
+
)
|
|
3652
|
+
|
|
3653
|
+
# No existing submission for this prefix -> start at 1
|
|
3654
|
+
if not latest or not latest[0]:
|
|
3655
|
+
return base_submission_id
|
|
3656
|
+
|
|
3657
|
+
last_id = latest[0]
|
|
3658
|
+
# Case 1: the latest is exactly the prefix (i.e., first submission today)
|
|
3659
|
+
if last_id == base_submission_id:
|
|
3660
|
+
return f"{base_submission_id}-2"
|
|
3661
|
+
|
|
3662
|
+
# Case 2: latest already has a suffix
|
|
3663
|
+
try:
|
|
3664
|
+
_, last_suffix = last_id.rsplit("-", 1)
|
|
3665
|
+
n = int(last_suffix)
|
|
3666
|
+
return f"{base_submission_id}-{n + 1}"
|
|
3667
|
+
except Exception as e:
|
|
3668
|
+
# If malformed, restart numbering for safety
|
|
3669
|
+
logger.error("Unexpected error parsing Submission ID in next_assay_submission_id: %s", e)
|
|
3670
|
+
return f"{base_submission_id}-2"
|
|
3671
|
+
|
|
3542
3672
|
|
|
3543
3673
|
class JobFileCategories(CommonColumns):
|
|
3544
3674
|
__tablename__ = "job_file_categories"
|
|
@@ -3613,6 +3743,7 @@ class CategoryDataElements(CommonColumns):
|
|
|
3613
3743
|
name = Column(String, nullable=False)
|
|
3614
3744
|
is_custom = Column(Boolean, nullable=False, default=False, server_default="false")
|
|
3615
3745
|
element_type = Column(String, nullable=False)
|
|
3746
|
+
data_type = Column(String, nullable=True)
|
|
3616
3747
|
cardinality = Column(String, nullable=True)
|
|
3617
3748
|
|
|
3618
3749
|
@classmethod
|
|
@@ -15,11 +15,11 @@ class AdditionalTreatment(Base):
|
|
|
15
15
|
)
|
|
16
16
|
|
|
17
17
|
# Number of days from the enrollment date to the first recorded administration or occurrence of the treatment modality.
|
|
18
|
-
|
|
18
|
+
additional_treatment_days_to_start: NonNegativeInt | None = None
|
|
19
19
|
|
|
20
20
|
# Number of days from the enrollment date to the last recorded administration or occurrence of the treatment modality.
|
|
21
|
-
|
|
21
|
+
additional_treatment_days_to_end: NonNegativeInt | None = None
|
|
22
22
|
|
|
23
23
|
# Description of the prior treatment such as its full generic name if it is a type of therapy agent, radiotherapy procedure
|
|
24
24
|
# name and location, or surgical procedure name and location.
|
|
25
|
-
|
|
25
|
+
additional_treatment_description: str
|
{nci_cidc_api_modules-1.2.31 → nci_cidc_api_modules-1.2.39}/cidc_api/models/pydantic/stage2/base.py
RENAMED
|
@@ -6,7 +6,11 @@ import copy
|
|
|
6
6
|
|
|
7
7
|
class Base(BaseModel):
|
|
8
8
|
|
|
9
|
-
model_config = ConfigDict(
|
|
9
|
+
model_config = ConfigDict(
|
|
10
|
+
validate_assignment=True,
|
|
11
|
+
from_attributes=True,
|
|
12
|
+
# extra="forbid" # TODO: enable me one stage1 models are implemented
|
|
13
|
+
)
|
|
10
14
|
|
|
11
15
|
# Validates the new state and updates the object if valid
|
|
12
16
|
def update(self, **kwargs):
|
|
@@ -68,15 +68,15 @@ class Demographic(Base):
|
|
|
68
68
|
|
|
69
69
|
# The body mass index of the participant at the enrollment date.
|
|
70
70
|
# CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=2006410%20and%20ver_nr=3
|
|
71
|
-
body_mass_index: PositiveFloat
|
|
71
|
+
body_mass_index: PositiveFloat | None = None
|
|
72
72
|
|
|
73
73
|
# A decimal number that represents the measure of the 2-dimensional extent of the body surface (i.e., the skin) of the participant at the enrollment date.
|
|
74
74
|
# CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=6606197%20and%20ver_nr=1
|
|
75
|
-
body_surface_area: PositiveFloat
|
|
75
|
+
body_surface_area: PositiveFloat | None = None
|
|
76
76
|
|
|
77
77
|
# Unit of measurement for body surface area of the participant at the enrollment date. e.g. "m2"
|
|
78
78
|
# https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=15114329%20and%20ver_nr=1
|
|
79
|
-
body_surface_area_units: BodySurfaceAreaUnits
|
|
79
|
+
body_surface_area_units: BodySurfaceAreaUnits | None = None
|
|
80
80
|
|
|
81
81
|
# The occupation/job category of the participant. e.g. "Manager"
|
|
82
82
|
# CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=6617540%20and%20ver_nr=1
|
|
@@ -113,3 +113,11 @@ class Demographic(Base):
|
|
|
113
113
|
if age_in_years >= 90:
|
|
114
114
|
raise ValueError('"age_at_enrollment" cannot represent a value greater than 90 years of age.')
|
|
115
115
|
return self
|
|
116
|
+
|
|
117
|
+
@model_validator(mode="after")
|
|
118
|
+
def validate_body_surface_area_units_cr(self) -> Self:
|
|
119
|
+
if self.body_surface_area and not self.body_surface_area_units:
|
|
120
|
+
raise ValueError(
|
|
121
|
+
'If "body_surface_area" is provided then "body_surface_area_units_other" must also be provided.'
|
|
122
|
+
)
|
|
123
|
+
return self
|
|
@@ -17,28 +17,32 @@ class OtherMalignancy(Base):
|
|
|
17
17
|
medical_history_id: int | None = None
|
|
18
18
|
|
|
19
19
|
# The location within the body from where the prior malignancy originated as captured in the Uberon anatomical term.
|
|
20
|
-
|
|
20
|
+
other_malignancy_primary_disease_site: UberonAnatomicalTerm
|
|
21
21
|
|
|
22
22
|
# The ICD-O-3 code which identifies the specific appearance of cells and tissues (normal and abnormal) used
|
|
23
23
|
# to define the presence and nature of disease.
|
|
24
|
-
|
|
24
|
+
other_malignancy_morphological_code: ICDO3MorphologicalCode | None = None
|
|
25
25
|
|
|
26
26
|
# The ICD-O-3 textual label which identifies the specific appearance of cells and tissues (normal and abnormal) used
|
|
27
27
|
# to define the presence and nature of disease.
|
|
28
|
-
|
|
28
|
+
other_malignancy_morphological_term: ICDO3MorphologicalTerm | None = None
|
|
29
29
|
|
|
30
30
|
# Description of the cancer type as recorded in the trial.
|
|
31
|
-
|
|
31
|
+
other_malignancy_description: str | None = None
|
|
32
32
|
|
|
33
33
|
# Number of days since original diagnosis from the enrollment date. This may be a negative number.
|
|
34
|
-
|
|
34
|
+
other_malignancy_days_since_diagnosis: NonPositiveInt | None = None
|
|
35
35
|
|
|
36
36
|
# Indicates the participant’s current clinical state regarding the cancer diagnosis.
|
|
37
|
-
|
|
37
|
+
other_malignancy_status: MalignancyStatus | None = None
|
|
38
38
|
|
|
39
39
|
@model_validator(mode="after")
|
|
40
40
|
def validate_code_or_term_or_description_cr(self) -> Self:
|
|
41
|
-
if
|
|
41
|
+
if (
|
|
42
|
+
not self.other_malignancy_morphological_code
|
|
43
|
+
and not self.other_malignancy_morphological_term
|
|
44
|
+
and not self.other_malignancy_description
|
|
45
|
+
):
|
|
42
46
|
raise ValueError(
|
|
43
47
|
'Please provide at least one of "morphological_code", "morphological_term" or "malignancy_description".'
|
|
44
48
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
from typing import Self
|
|
1
|
+
from typing import Self, Annotated, List
|
|
2
2
|
|
|
3
|
-
from pydantic import NonPositiveInt,
|
|
3
|
+
from pydantic import NonPositiveInt, NegativeInt, model_validator, BeforeValidator
|
|
4
4
|
|
|
5
5
|
from .base import Base
|
|
6
6
|
from cidc_api.models.types import PriorTreatmentType, ConditioningRegimenType, StemCellDonorType
|
|
@@ -18,35 +18,35 @@ class PriorTreatment(Base):
|
|
|
18
18
|
|
|
19
19
|
# Number of days from the enrollment date to the first recorded administration or occurrence of
|
|
20
20
|
# the treatment modality.
|
|
21
|
-
|
|
21
|
+
prior_treatment_days_to_start: NonPositiveInt | None = None
|
|
22
22
|
|
|
23
23
|
# Number of days from the enrollment date to the last recorded administration or occurrence of
|
|
24
24
|
# the treatment modality.
|
|
25
|
-
|
|
25
|
+
prior_treatment_days_to_end: NonPositiveInt | None = None
|
|
26
26
|
|
|
27
27
|
# Specifies the category or kind of prior treatment modality a participant received.
|
|
28
|
-
|
|
28
|
+
prior_treatment_type: Annotated[List[PriorTreatmentType], BeforeValidator(Base.split_list)]
|
|
29
29
|
|
|
30
30
|
# Description of the prior treatment such as its full generic name if it is a type of therapy agent,
|
|
31
31
|
# radiotherapy procedure name and location, or surgical procedure name and location.
|
|
32
|
-
|
|
32
|
+
prior_treatment_description: str | None = None
|
|
33
33
|
|
|
34
34
|
# Best response from any response assessment system to the prior treatment if available or applicable.
|
|
35
|
-
|
|
35
|
+
prior_treatment_best_response: str | None = None
|
|
36
36
|
|
|
37
37
|
# If the prior treatment is "Conditioning therapy" received before a stem cell transplant, specifies what
|
|
38
38
|
# type of conditioning regimen used.
|
|
39
|
-
|
|
39
|
+
prior_treatment_conditioning_regimen_type: ConditioningRegimenType | None = None
|
|
40
40
|
|
|
41
41
|
# If prior treatment is "Stem cell transplant", indicates what stem cell donor type used.
|
|
42
|
-
|
|
42
|
+
prior_treatment_stem_cell_donor_type: StemCellDonorType | None = None
|
|
43
43
|
|
|
44
44
|
# If prior treatment is "Stem cell transplant", indicates the number of days from the transplant
|
|
45
45
|
# date to the start of the current treatment.
|
|
46
|
-
|
|
46
|
+
prior_treatment_days_to_prior_transplant: NegativeInt | None = None
|
|
47
47
|
|
|
48
48
|
@model_validator(mode="after")
|
|
49
49
|
def validate_description_cr(self) -> Self:
|
|
50
|
-
if
|
|
50
|
+
if "Other therapy" in self.prior_treatment_type and not self.prior_treatment_description:
|
|
51
51
|
raise ValueError('If type is "Other therapy", please provide description.')
|
|
52
52
|
return self
|
|
@@ -22,7 +22,7 @@ class Response(Base):
|
|
|
22
22
|
survival_status: SurvivalStatus
|
|
23
23
|
|
|
24
24
|
# Number of days from enrollment date to death date.
|
|
25
|
-
overall_survival: NonNegativeInt
|
|
25
|
+
overall_survival: NonNegativeInt
|
|
26
26
|
|
|
27
27
|
# Indicator for whether there was an abscopal effect on disease after local therapy.
|
|
28
28
|
abscopal_response: YNUNA | None = None
|
|
@@ -43,14 +43,8 @@ class Response(Base):
|
|
|
43
43
|
# Indicates whether participant was evaluable for efficacy (for example, response, PFS, OS, etc.) overall.
|
|
44
44
|
evaluable_for_efficacy: bool
|
|
45
45
|
|
|
46
|
-
# Days from enrollment date to the last time patient
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
@model_validator(mode="after")
|
|
50
|
-
def validate_overall_survival_cr(self) -> Self:
|
|
51
|
-
if self.survival_status != "Unknown" and not self.overall_survival:
|
|
52
|
-
raise ValueError('If survival_status is not "Unknown" then overall_survival is required.')
|
|
53
|
-
return self
|
|
46
|
+
# Days from enrollment date to the last time the patient's vital status was verified.
|
|
47
|
+
days_to_last_vital_status: NonNegativeInt | None = None
|
|
54
48
|
|
|
55
49
|
@model_validator(mode="after")
|
|
56
50
|
def validate_cause_of_death_cr(self) -> Self:
|