nci-cidc-api-modules 1.2.18__py3-none-any.whl → 1.2.25__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.
- cidc_api/models/__init__.py +2 -0
- cidc_api/models/data.py +15 -0
- cidc_api/models/db/base_orm.py +25 -0
- cidc_api/models/db/stage2/__init__.py +78 -0
- cidc_api/models/db/stage2/additional_treatment_orm.py +22 -0
- cidc_api/models/db/stage2/administrative_person_orm.py +25 -0
- cidc_api/models/db/stage2/administrative_role_assignment_orm.py +28 -0
- cidc_api/models/db/stage2/adverse_event_orm.py +47 -0
- cidc_api/models/db/stage2/arm_orm.py +23 -0
- cidc_api/models/db/stage2/baseline_clinical_assessment_orm.py +23 -0
- cidc_api/models/db/stage2/cohort_orm.py +23 -0
- cidc_api/models/db/stage2/comorbidity_orm.py +24 -0
- cidc_api/models/db/stage2/consent_group_orm.py +31 -0
- cidc_api/models/db/stage2/contact_orm.py +32 -0
- cidc_api/models/db/stage2/demographic_orm.py +44 -0
- cidc_api/models/db/stage2/disease_orm.py +53 -0
- cidc_api/models/db/stage2/exposure_orm.py +21 -0
- cidc_api/models/db/stage2/file_orm.py +38 -0
- cidc_api/models/db/stage2/gvhd_diagnosis_acute_orm.py +33 -0
- cidc_api/models/db/stage2/gvhd_diagnosis_chronic_orm.py +37 -0
- cidc_api/models/db/stage2/gvhd_organ_acute_orm.py +20 -0
- cidc_api/models/db/stage2/gvhd_organ_chronic_orm.py +20 -0
- cidc_api/models/db/stage2/institution_orm.py +33 -0
- cidc_api/models/db/stage2/medical_history_orm.py +29 -0
- cidc_api/models/db/stage2/other_clinical_endpoint_orm.py +28 -0
- cidc_api/models/db/stage2/other_malignancy_orm.py +30 -0
- cidc_api/models/db/stage2/participant_orm.py +79 -0
- cidc_api/models/db/stage2/prior_treatment_orm.py +28 -0
- cidc_api/models/db/stage2/publication_orm.py +31 -0
- cidc_api/models/db/stage2/radiotherapy_dose_orm.py +39 -0
- cidc_api/models/db/stage2/response_by_system_orm.py +28 -0
- cidc_api/models/db/stage2/response_orm.py +27 -0
- cidc_api/models/db/stage2/shipment_orm.py +47 -0
- cidc_api/models/db/stage2/shipment_specimen_orm.py +24 -0
- cidc_api/models/db/stage2/specimen_orm.py +100 -0
- cidc_api/models/db/stage2/stem_cell_transplant_orm.py +25 -0
- cidc_api/models/db/stage2/surgery_orm.py +27 -0
- cidc_api/models/db/stage2/therapy_agent_dose_orm.py +31 -0
- cidc_api/models/db/stage2/treatment_orm.py +39 -0
- cidc_api/models/db/stage2/trial_orm.py +60 -0
- cidc_api/models/files/facets.py +5 -0
- cidc_api/models/migrations.py +12 -39
- cidc_api/models/models.py +12 -0
- cidc_api/models/pydantic/stage2/__init__.py +78 -0
- cidc_api/models/pydantic/stage2/additional_treatment.py +23 -0
- cidc_api/models/pydantic/stage2/administrative_person.py +30 -0
- cidc_api/models/pydantic/stage2/administrative_role_assignment.py +16 -0
- cidc_api/models/pydantic/stage2/adverse_event.py +100 -0
- cidc_api/models/pydantic/stage2/arm.py +16 -0
- cidc_api/models/pydantic/stage2/base.py +30 -0
- cidc_api/models/pydantic/stage2/baseline_clinical_assessment.py +23 -0
- cidc_api/models/pydantic/stage2/cohort.py +16 -0
- cidc_api/models/pydantic/stage2/comorbidity.py +36 -0
- cidc_api/models/pydantic/stage2/consent_group.py +30 -0
- cidc_api/models/pydantic/stage2/contact.py +35 -0
- cidc_api/models/pydantic/stage2/demographic.py +114 -0
- cidc_api/models/pydantic/stage2/disease.py +144 -0
- cidc_api/models/pydantic/stage2/exposure.py +32 -0
- cidc_api/models/pydantic/stage2/file.py +44 -0
- cidc_api/models/pydantic/stage2/gvhd_diagnosis_acute.py +33 -0
- cidc_api/models/pydantic/stage2/gvhd_diagnosis_chronic.py +32 -0
- cidc_api/models/pydantic/stage2/gvhd_organ_acute.py +22 -0
- cidc_api/models/pydantic/stage2/gvhd_organ_chronic.py +23 -0
- cidc_api/models/pydantic/stage2/institution.py +10 -0
- cidc_api/models/pydantic/stage2/medical_history.py +36 -0
- cidc_api/models/pydantic/stage2/other_clinical_endpoint.py +32 -0
- cidc_api/models/pydantic/stage2/other_malignancy.py +45 -0
- cidc_api/models/pydantic/stage2/participant.py +47 -0
- cidc_api/models/pydantic/stage2/prior_treatment.py +52 -0
- cidc_api/models/pydantic/stage2/publication.py +37 -0
- cidc_api/models/pydantic/stage2/radiotherapy_dose.py +79 -0
- cidc_api/models/pydantic/stage2/response.py +71 -0
- cidc_api/models/pydantic/stage2/response_by_system.py +109 -0
- cidc_api/models/pydantic/stage2/shipment.py +48 -0
- cidc_api/models/pydantic/stage2/shipment_specimen.py +15 -0
- cidc_api/models/pydantic/stage2/specimen.py +211 -0
- cidc_api/models/pydantic/stage2/stem_cell_transplant.py +35 -0
- cidc_api/models/pydantic/stage2/surgery.py +49 -0
- cidc_api/models/pydantic/stage2/therapy_agent_dose.py +67 -0
- cidc_api/models/pydantic/stage2/treatment.py +50 -0
- cidc_api/models/pydantic/stage2/trial.py +85 -0
- cidc_api/models/types.py +1439 -0
- cidc_api/shared/utils.py +4 -1
- {nci_cidc_api_modules-1.2.18.dist-info → nci_cidc_api_modules-1.2.25.dist-info}/METADATA +6 -4
- nci_cidc_api_modules-1.2.25.dist-info/RECORD +104 -0
- nci_cidc_api_modules-1.2.18.dist-info/RECORD +0 -26
- {nci_cidc_api_modules-1.2.18.dist-info → nci_cidc_api_modules-1.2.25.dist-info}/WHEEL +0 -0
- {nci_cidc_api_modules-1.2.18.dist-info → nci_cidc_api_modules-1.2.25.dist-info}/licenses/LICENSE +0 -0
- {nci_cidc_api_modules-1.2.18.dist-info → nci_cidc_api_modules-1.2.25.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
|
|
3
|
+
from sqlalchemy import ForeignKey
|
|
4
|
+
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
5
|
+
|
|
6
|
+
from cidc_api.models.db.base_orm import BaseORM
|
|
7
|
+
from cidc_api.models.types import YNU, OffTreatmentReason
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TreatmentORM(BaseORM):
|
|
11
|
+
__tablename__ = "treatment"
|
|
12
|
+
__repr_attrs__ = ["treatment_id", "participant_id", "treatment_description"]
|
|
13
|
+
__table_args__ = {"schema": "stage2"}
|
|
14
|
+
|
|
15
|
+
treatment_id: Mapped[int] = mapped_column(primary_key=True)
|
|
16
|
+
participant_id: Mapped[int] = mapped_column(ForeignKey("stage2.participant.participant_id", ondelete="CASCADE"))
|
|
17
|
+
arm_id: Mapped[Optional[int]] = mapped_column(ForeignKey("stage2.arm.arm_id", ondelete="CASCADE"))
|
|
18
|
+
cohort_id: Mapped[Optional[int]] = mapped_column(ForeignKey("stage2.cohort.cohort_id", ondelete="CASCADE"))
|
|
19
|
+
|
|
20
|
+
treatment_description: Mapped[str]
|
|
21
|
+
off_treatment: Mapped[YNU]
|
|
22
|
+
off_treatment_reason: Mapped[Optional[OffTreatmentReason]]
|
|
23
|
+
off_treatment_reason_other: Mapped[Optional[str]]
|
|
24
|
+
|
|
25
|
+
participant: Mapped["ParticipantORM"] = relationship(back_populates="treatments", cascade="all, delete")
|
|
26
|
+
arm: Mapped[Optional["ArmORM"]] = relationship(cascade="all, delete")
|
|
27
|
+
cohort: Mapped[Optional["CohortORM"]] = relationship(cascade="all, delete")
|
|
28
|
+
adverse_events: Mapped[List["AdverseEventORM"]] = relationship(back_populates="treatment", cascade="all, delete")
|
|
29
|
+
|
|
30
|
+
therapy_agent_doses: Mapped[List["TherapyAgentDoseORM"]] = relationship(
|
|
31
|
+
back_populates="treatment", cascade="all, delete"
|
|
32
|
+
)
|
|
33
|
+
radiotherapy_doses: Mapped[List["RadiotherapyDoseORM"]] = relationship(
|
|
34
|
+
back_populates="treatment", cascade="all, delete"
|
|
35
|
+
)
|
|
36
|
+
surgeries: Mapped[List["SurgeryORM"]] = relationship(back_populates="treatment", cascade="all, delete")
|
|
37
|
+
stem_cell_transplants: Mapped[List["StemCellTransplantORM"]] = relationship(
|
|
38
|
+
back_populates="treatment", cascade="all, delete"
|
|
39
|
+
)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import List, Optional
|
|
3
|
+
|
|
4
|
+
from sqlalchemy import ForeignKey
|
|
5
|
+
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
6
|
+
from sqlalchemy.types import JSON
|
|
7
|
+
|
|
8
|
+
from cidc_api.models.db.base_orm import BaseORM
|
|
9
|
+
from cidc_api.models.types import TrialStatus, AssayType, TrialOrganization, TrialFundingAgency
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TrialORM(BaseORM):
|
|
13
|
+
__tablename__ = "trial"
|
|
14
|
+
__repr_attrs__ = ["trial_id", "version"]
|
|
15
|
+
__table_args__ = {"schema": "stage2"}
|
|
16
|
+
|
|
17
|
+
trial_id: Mapped[str] = mapped_column(primary_key=True)
|
|
18
|
+
version: Mapped[str] = mapped_column(primary_key=True)
|
|
19
|
+
|
|
20
|
+
nct_id: Mapped[Optional[str]]
|
|
21
|
+
nci_id: Mapped[Optional[str]]
|
|
22
|
+
trial_name: Mapped[Optional[str]]
|
|
23
|
+
trial_type: Mapped[Optional[str]]
|
|
24
|
+
trial_description: Mapped[Optional[str]]
|
|
25
|
+
trial_organization: Mapped[Optional[TrialOrganization]]
|
|
26
|
+
grant_or_affiliated_network: Mapped[Optional[TrialFundingAgency]]
|
|
27
|
+
trial_status: Mapped[TrialStatus]
|
|
28
|
+
biobank_institution_id: Mapped[Optional[int]]
|
|
29
|
+
justification: Mapped[Optional[str]]
|
|
30
|
+
dates_of_conduct_start: Mapped[datetime]
|
|
31
|
+
dates_of_conduct_end: Mapped[Optional[datetime]]
|
|
32
|
+
schema_file_id: Mapped[Optional[int]]
|
|
33
|
+
biomarker_plan: Mapped[Optional[str]]
|
|
34
|
+
data_sharing_plan: Mapped[Optional[str]]
|
|
35
|
+
expected_assays: Mapped[Optional[List[AssayType]]] = mapped_column(JSON, nullable=True)
|
|
36
|
+
is_liquid_tumor_trial: Mapped[bool]
|
|
37
|
+
dbgap_study_accession: Mapped[Optional[str]]
|
|
38
|
+
|
|
39
|
+
biobank: Mapped["InstitutionORM"] = relationship(back_populates="trial")
|
|
40
|
+
schema: Mapped[Optional["FileORM"]] = relationship(back_populates="trial", viewonly=True)
|
|
41
|
+
administrative_role_assignments: Mapped[List["AdministrativeRoleAssignmentORM"]] = relationship(
|
|
42
|
+
back_populates="trial", cascade="all, delete", passive_deletes=True
|
|
43
|
+
)
|
|
44
|
+
arms: Mapped[List["ArmORM"]] = relationship(back_populates="trial", cascade="all, delete", passive_deletes=True)
|
|
45
|
+
cohorts: Mapped[List["CohortORM"]] = relationship(
|
|
46
|
+
back_populates="trial", cascade="all, delete", passive_deletes=True
|
|
47
|
+
)
|
|
48
|
+
participants: Mapped[List["ParticipantORM"]] = relationship(
|
|
49
|
+
back_populates="trial", cascade="all, delete", passive_deletes=True
|
|
50
|
+
)
|
|
51
|
+
shipments: Mapped[List["ShipmentORM"]] = relationship(
|
|
52
|
+
back_populates="trial", cascade="all, delete", passive_deletes=True
|
|
53
|
+
)
|
|
54
|
+
files: Mapped[List["FileORM"]] = relationship(back_populates="trial", cascade="all, delete", passive_deletes=True)
|
|
55
|
+
publications: Mapped[List["PublicationORM"]] = relationship(
|
|
56
|
+
back_populates="trial", cascade="all, delete", passive_deletes=True
|
|
57
|
+
)
|
|
58
|
+
consent_groups: Mapped[List["ConsentGroupORM"]] = relationship(
|
|
59
|
+
back_populates="trial", cascade="all, delete", passive_deletes=True
|
|
60
|
+
)
|
cidc_api/models/files/facets.py
CHANGED
|
@@ -439,6 +439,11 @@ assay_facets: Facets = {
|
|
|
439
439
|
"Analysis files for all samples run on the Olink platform in the trial.",
|
|
440
440
|
),
|
|
441
441
|
},
|
|
442
|
+
"Olink HT": {
|
|
443
|
+
"Batch-Level Combined File": FacetConfig(["/olink_ht/batch_level_combined_file.parquet"]),
|
|
444
|
+
"Study-Level Combined File": FacetConfig(["/olink_ht/study_level_combined_file.parquet"]),
|
|
445
|
+
"Npx Run File": FacetConfig(["/olink_ht/npx_run_file.parquet"]),
|
|
446
|
+
},
|
|
442
447
|
"IHC": {
|
|
443
448
|
"Images": FacetConfig(["/ihc/ihc_image."]),
|
|
444
449
|
"Combined Markers": FacetConfig(["csv|ihc marker combined"]),
|
cidc_api/models/migrations.py
CHANGED
|
@@ -91,15 +91,11 @@ def migration_session():
|
|
|
91
91
|
session.close()
|
|
92
92
|
|
|
93
93
|
|
|
94
|
-
def run_metadata_migration(
|
|
95
|
-
metadata_migration: Callable[[dict], MigrationResult], use_upload_jobs_table: bool
|
|
96
|
-
):
|
|
94
|
+
def run_metadata_migration(metadata_migration: Callable[[dict], MigrationResult], use_upload_jobs_table: bool):
|
|
97
95
|
"""Migrate trial metadata, upload job patches, and downloadable files according to `metadata_migration`"""
|
|
98
96
|
with migration_session() as (session, task_queue):
|
|
99
97
|
try:
|
|
100
|
-
_run_metadata_migration(
|
|
101
|
-
metadata_migration, use_upload_jobs_table, task_queue, session
|
|
102
|
-
)
|
|
98
|
+
_run_metadata_migration(metadata_migration, use_upload_jobs_table, task_queue, session)
|
|
103
99
|
except:
|
|
104
100
|
traceback.print_exc()
|
|
105
101
|
raise
|
|
@@ -122,9 +118,7 @@ class ManifestUploads(CommonColumns):
|
|
|
122
118
|
__tablename__ = "manifest_uploads"
|
|
123
119
|
|
|
124
120
|
|
|
125
|
-
def _select_successful_assay_uploads(
|
|
126
|
-
use_upload_jobs_table: bool, session: Session
|
|
127
|
-
) -> List[UploadJobs]:
|
|
121
|
+
def _select_successful_assay_uploads(use_upload_jobs_table: bool, session: Session) -> List[UploadJobs]:
|
|
128
122
|
if use_upload_jobs_table:
|
|
129
123
|
return (
|
|
130
124
|
session.query(UploadJobs)
|
|
@@ -133,21 +127,12 @@ def _select_successful_assay_uploads(
|
|
|
133
127
|
.all()
|
|
134
128
|
)
|
|
135
129
|
|
|
136
|
-
return (
|
|
137
|
-
session.query(AssayUploads)
|
|
138
|
-
.filter_by(status=UploadJobStatus.MERGE_COMPLETED.value)
|
|
139
|
-
.with_for_update()
|
|
140
|
-
.all()
|
|
141
|
-
)
|
|
130
|
+
return session.query(AssayUploads).filter_by(status=UploadJobStatus.MERGE_COMPLETED.value).with_for_update().all()
|
|
142
131
|
|
|
143
132
|
|
|
144
|
-
def _select_manifest_uploads(
|
|
145
|
-
use_upload_jobs_table: bool, session: Session
|
|
146
|
-
) -> List[UploadJobs]:
|
|
133
|
+
def _select_manifest_uploads(use_upload_jobs_table: bool, session: Session) -> List[UploadJobs]:
|
|
147
134
|
if use_upload_jobs_table:
|
|
148
|
-
return (
|
|
149
|
-
session.query(UploadJobs).filter_by(multifile=False).with_for_update().all()
|
|
150
|
-
)
|
|
135
|
+
return session.query(UploadJobs).filter_by(multifile=False).with_for_update().all()
|
|
151
136
|
|
|
152
137
|
return session.query(ManifestUploads).with_for_update().all()
|
|
153
138
|
|
|
@@ -188,21 +173,15 @@ def _run_metadata_migration(
|
|
|
188
173
|
|
|
189
174
|
# Regenerate additional metadata from the migrated clinical trial
|
|
190
175
|
# metadata object.
|
|
191
|
-
print(
|
|
192
|
-
f"Regenerating additional metadata for artifact with uuid {artifact['upload_placeholder']}"
|
|
193
|
-
)
|
|
176
|
+
print(f"Regenerating additional metadata for artifact with uuid {artifact['upload_placeholder']}")
|
|
194
177
|
artifact_path = uuid_path_map[artifact["upload_placeholder"]]
|
|
195
|
-
df.additional_metadata = get_source(
|
|
196
|
-
migration.result, artifact_path, skip_last=True
|
|
197
|
-
)[1]
|
|
178
|
+
df.additional_metadata = get_source(migration.result, artifact_path, skip_last=True)[1]
|
|
198
179
|
|
|
199
180
|
# If the GCS URI has changed, rename the blob
|
|
200
181
|
# makes call to bucket.rename_blob
|
|
201
182
|
new_gcs_uri = artifact["object_url"]
|
|
202
183
|
if old_gcs_uri != new_gcs_uri:
|
|
203
|
-
print(
|
|
204
|
-
f"Encountered GCS data bucket artifact URI to update: {old_gcs_uri}"
|
|
205
|
-
)
|
|
184
|
+
print(f"Encountered GCS data bucket artifact URI to update: {old_gcs_uri}")
|
|
206
185
|
renamer = PieceOfWork(
|
|
207
186
|
partial(
|
|
208
187
|
rename_gcs_blob,
|
|
@@ -220,9 +199,7 @@ def _run_metadata_migration(
|
|
|
220
199
|
gcs_tasks.schedule(renamer)
|
|
221
200
|
|
|
222
201
|
# Migrate all assay upload successes
|
|
223
|
-
successful_assay_uploads = _select_successful_assay_uploads(
|
|
224
|
-
use_upload_jobs_table, session
|
|
225
|
-
)
|
|
202
|
+
successful_assay_uploads = _select_successful_assay_uploads(use_upload_jobs_table, session)
|
|
226
203
|
for upload in successful_assay_uploads:
|
|
227
204
|
print(f"Running metadata migration for assay upload: {upload.id}")
|
|
228
205
|
if use_upload_jobs_table:
|
|
@@ -248,9 +225,7 @@ def _run_metadata_migration(
|
|
|
248
225
|
if old_target_uri in migration.file_updates:
|
|
249
226
|
new_target_uri = migration.file_updates[old_target_uri]["object_url"]
|
|
250
227
|
if old_target_uri != new_target_uri:
|
|
251
|
-
print(
|
|
252
|
-
f"Encountered GCS upload bucket artifact URI to update: {old_upload_uri}"
|
|
253
|
-
)
|
|
228
|
+
print(f"Encountered GCS upload bucket artifact URI to update: {old_upload_uri}")
|
|
254
229
|
new_upload_uri = "/".join([new_target_uri, upload_timestamp])
|
|
255
230
|
renamer = PieceOfWork(
|
|
256
231
|
partial(
|
|
@@ -325,7 +300,5 @@ def republish_artifact_uploads():
|
|
|
325
300
|
with migration_session() as (session, _):
|
|
326
301
|
files = session.query(DownloadableFiles).all()
|
|
327
302
|
for f in files:
|
|
328
|
-
print(
|
|
329
|
-
f"Publishing to 'artifact_upload' topic for downloadable file with in bucket url {f.object_url}"
|
|
330
|
-
)
|
|
303
|
+
print(f"Publishing to 'artifact_upload' topic for downloadable file with in bucket url {f.object_url}")
|
|
331
304
|
publish_artifact_upload(f.object_url)
|
cidc_api/models/models.py
CHANGED
|
@@ -3415,6 +3415,15 @@ class PreprocessedFiles(CommonColumns):
|
|
|
3415
3415
|
|
|
3416
3416
|
return query.filter(cls.job_id.is_(None))
|
|
3417
3417
|
|
|
3418
|
+
@with_default_session
|
|
3419
|
+
def category_description(self, session: Session):
|
|
3420
|
+
category = (
|
|
3421
|
+
session.query(JobFileCategories)
|
|
3422
|
+
.filter(JobFileCategories.job_id == self.job_id, JobFileCategories.category == self.file_category)
|
|
3423
|
+
.first()
|
|
3424
|
+
)
|
|
3425
|
+
return category.description if category else None
|
|
3426
|
+
|
|
3418
3427
|
|
|
3419
3428
|
INGESTION_JOB_STATUSES = [
|
|
3420
3429
|
"DRAFT",
|
|
@@ -3546,6 +3555,7 @@ class JobFileCategories(CommonColumns):
|
|
|
3546
3555
|
)
|
|
3547
3556
|
|
|
3548
3557
|
category = Column(String)
|
|
3558
|
+
description = Column(String)
|
|
3549
3559
|
job_id = Column(Integer, nullable=False)
|
|
3550
3560
|
type = Column(Enum("required", "optional", name="type"), nullable=False)
|
|
3551
3561
|
is_custom = Column(Boolean, nullable=False, default=False, server_default="false")
|
|
@@ -3556,6 +3566,7 @@ class JobFileCategories(CommonColumns):
|
|
|
3556
3566
|
category: str,
|
|
3557
3567
|
job_id: int,
|
|
3558
3568
|
type: str,
|
|
3569
|
+
description: str = None,
|
|
3559
3570
|
is_custom: bool = False,
|
|
3560
3571
|
session: Session = None,
|
|
3561
3572
|
):
|
|
@@ -3563,6 +3574,7 @@ class JobFileCategories(CommonColumns):
|
|
|
3563
3574
|
category=category,
|
|
3564
3575
|
job_id=job_id,
|
|
3565
3576
|
type=type,
|
|
3577
|
+
description=description,
|
|
3566
3578
|
is_custom=is_custom,
|
|
3567
3579
|
)
|
|
3568
3580
|
new_category.insert(session=session)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from .additional_treatment import AdditionalTreatment
|
|
2
|
+
from .administrative_person import AdministrativePerson
|
|
3
|
+
from .administrative_role_assignment import AdministrativeRoleAssignment
|
|
4
|
+
from .adverse_event import AdverseEvent
|
|
5
|
+
from .arm import Arm
|
|
6
|
+
from .baseline_clinical_assessment import BaselineClinicalAssessment
|
|
7
|
+
from .cohort import Cohort
|
|
8
|
+
from .comorbidity import Comorbidity
|
|
9
|
+
from .consent_group import ConsentGroup
|
|
10
|
+
from .contact import Contact
|
|
11
|
+
from .demographic import Demographic
|
|
12
|
+
from .disease import Disease
|
|
13
|
+
from .exposure import Exposure
|
|
14
|
+
from .file import File
|
|
15
|
+
from .gvhd_diagnosis_acute import GVHDDiagnosisAcute
|
|
16
|
+
from .gvhd_diagnosis_chronic import GVHDDiagnosisChronic
|
|
17
|
+
from .gvhd_organ_acute import GVHDOrganAcute
|
|
18
|
+
from .gvhd_organ_chronic import GVHDOrganChronic
|
|
19
|
+
from .institution import Institution
|
|
20
|
+
from .medical_history import MedicalHistory
|
|
21
|
+
from .other_clinical_endpoint import OtherClinicalEndpoint
|
|
22
|
+
from .other_malignancy import OtherMalignancy
|
|
23
|
+
from .participant import Participant
|
|
24
|
+
from .prior_treatment import PriorTreatment
|
|
25
|
+
from .publication import Publication
|
|
26
|
+
from .radiotherapy_dose import RadiotherapyDose
|
|
27
|
+
from .response import Response
|
|
28
|
+
from .response_by_system import ResponseBySystem
|
|
29
|
+
from .shipment import Shipment
|
|
30
|
+
from .shipment_specimen import ShipmentSpecimen
|
|
31
|
+
from .specimen import Specimen
|
|
32
|
+
from .stem_cell_transplant import StemCellTransplant
|
|
33
|
+
from .surgery import Surgery
|
|
34
|
+
from .therapy_agent_dose import TherapyAgentDose
|
|
35
|
+
from .treatment import Treatment
|
|
36
|
+
from .trial import Trial
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
__all__ = [
|
|
40
|
+
"AdditionalTreatment",
|
|
41
|
+
"AdministrativePerson",
|
|
42
|
+
"AdministrativeRoleAssignment",
|
|
43
|
+
"AdverseEvent",
|
|
44
|
+
"Arm",
|
|
45
|
+
"BaselineClinicalAssessment",
|
|
46
|
+
"Cohort",
|
|
47
|
+
"Comorbidity",
|
|
48
|
+
"ConsentGroup",
|
|
49
|
+
"Contact",
|
|
50
|
+
"Demographic",
|
|
51
|
+
"Disease",
|
|
52
|
+
"Exposure",
|
|
53
|
+
"File",
|
|
54
|
+
"GVHDDiagnosisAcute",
|
|
55
|
+
"GVHDOrganAcute",
|
|
56
|
+
"GVHDDiagnosisChronic",
|
|
57
|
+
"GVHDOrganChronic",
|
|
58
|
+
"Institution",
|
|
59
|
+
"MedicalHistory",
|
|
60
|
+
"OtherClinicalEndpoint",
|
|
61
|
+
"OtherMalignancy",
|
|
62
|
+
"Participant",
|
|
63
|
+
"PriorTreatment",
|
|
64
|
+
"Publication",
|
|
65
|
+
"RadiotherapyDose",
|
|
66
|
+
"Response",
|
|
67
|
+
"ResponseBySystem",
|
|
68
|
+
"Shipment",
|
|
69
|
+
"ShipmentSpecimen",
|
|
70
|
+
"Specimen",
|
|
71
|
+
"StemCellTransplant",
|
|
72
|
+
"Surgery",
|
|
73
|
+
"TherapyAgentDose",
|
|
74
|
+
"Treatment",
|
|
75
|
+
"Trial",
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
all_models = [globals()[cls_name] for cls_name in __all__]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from pydantic import NonNegativeInt
|
|
2
|
+
from .base import Base
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class AdditionalTreatment(Base):
|
|
6
|
+
__data_category__ = "additional_treatment"
|
|
7
|
+
__cardinality__ = "many"
|
|
8
|
+
|
|
9
|
+
# The unique internal identifier for the AdditionalTreatment record
|
|
10
|
+
additional_treatment_id: int | None = None
|
|
11
|
+
|
|
12
|
+
# The unique internal identifier for the associated Participant record
|
|
13
|
+
participant_id: int | None = None
|
|
14
|
+
|
|
15
|
+
# Number of days from the enrollment date to the first recorded administration or occurrence of the treatment modality.
|
|
16
|
+
days_to_start: NonNegativeInt | None = None
|
|
17
|
+
|
|
18
|
+
# Number of days from the enrollment date to the last recorded administration or occurrence of the treatment modality.
|
|
19
|
+
days_to_end: NonNegativeInt | None = None
|
|
20
|
+
|
|
21
|
+
# Description of the prior treatment such as its full generic name if it is a type of therapy agent, radiotherapy procedure
|
|
22
|
+
# name and location, or surgical procedure name and location.
|
|
23
|
+
description: str
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from .base import Base
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class AdministrativePerson(Base):
|
|
5
|
+
|
|
6
|
+
# The unique internal identifier for the administrative person
|
|
7
|
+
administrative_person_id: int | None = None
|
|
8
|
+
|
|
9
|
+
# The internal identifier for the Institution the administrative person belongs to
|
|
10
|
+
institution_id: int | None = None
|
|
11
|
+
|
|
12
|
+
# The word or group of words indicating a person's first (personal or given) name, e.g. "John"
|
|
13
|
+
# CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=2179589%20and%20ver_nr=2
|
|
14
|
+
first_name: str
|
|
15
|
+
|
|
16
|
+
# The word or group of worlds indicating a person's middle name, e.g. "Alan"
|
|
17
|
+
# CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=2179590%20and%20ver_nr=2
|
|
18
|
+
middle_name: str | None = None
|
|
19
|
+
|
|
20
|
+
# The means of identifying an individual by using a word or group of words indicating a person's last (family) name, e.g. "Smith"
|
|
21
|
+
# CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=2179591%20and%20ver_nr=2
|
|
22
|
+
last_name: str
|
|
23
|
+
|
|
24
|
+
# The string of characters that represents the electronic mail address of a person.
|
|
25
|
+
# CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=2517550%20and%20ver_nr=1
|
|
26
|
+
email: str | None = None
|
|
27
|
+
|
|
28
|
+
# The string of digits that represent a telephone number that can be used to contact the person.
|
|
29
|
+
# CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=2179593%20and%20ver_nr=3
|
|
30
|
+
phone_number: str | None = None
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from .base import Base
|
|
2
|
+
from cidc_api.models.types import AdministrativeRole
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class AdministrativeRoleAssignment(Base):
|
|
6
|
+
# The unique identifier for the associated trial
|
|
7
|
+
trial_id: int | None = None
|
|
8
|
+
|
|
9
|
+
# The version number of the trial dataset
|
|
10
|
+
version: str | None = None
|
|
11
|
+
|
|
12
|
+
# The unique identifier for the associated administrative person
|
|
13
|
+
administrative_person_id: int
|
|
14
|
+
|
|
15
|
+
# The role the administrative_person is performing for the associated trial
|
|
16
|
+
administrative_role: AdministrativeRole
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
from typing import Self
|
|
2
|
+
|
|
3
|
+
from pydantic import NonNegativeInt, model_validator
|
|
4
|
+
|
|
5
|
+
from .base import Base
|
|
6
|
+
from cidc_api.reference.ctcae import is_ctcae_other_term
|
|
7
|
+
from cidc_api.models.types import (
|
|
8
|
+
CTCAEEventTerm,
|
|
9
|
+
CTCAEEventCode,
|
|
10
|
+
SeverityGradeSystem,
|
|
11
|
+
SeverityGradeSystemVersion,
|
|
12
|
+
SeverityGrade,
|
|
13
|
+
SystemOrganClass,
|
|
14
|
+
AttributionCause,
|
|
15
|
+
AttributionLikelihood,
|
|
16
|
+
YNU,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class AdverseEvent(Base):
|
|
21
|
+
__data_category__ = "adverse_event"
|
|
22
|
+
__cardinality__ = "many"
|
|
23
|
+
|
|
24
|
+
# The unique internal identifier of the adverse event
|
|
25
|
+
adverse_event_id: int | None = None
|
|
26
|
+
|
|
27
|
+
# The unique internal identifier of the associated participant
|
|
28
|
+
participant_id: int | None = None
|
|
29
|
+
|
|
30
|
+
# The unique internal identifier of the attributed treatment, if any
|
|
31
|
+
treatment_id: int | None = None
|
|
32
|
+
|
|
33
|
+
# Text that represents the Common Terminology Criteria for Adverse Events low level term name for an adverse event.
|
|
34
|
+
event_term: CTCAEEventTerm | None = None
|
|
35
|
+
|
|
36
|
+
# A MedDRA code mapped to a CTCAE low level name for an adverse event.
|
|
37
|
+
event_code: CTCAEEventCode | None = None
|
|
38
|
+
|
|
39
|
+
# System used to define and report adverse event severity grade.
|
|
40
|
+
severity_grade_system: SeverityGradeSystem
|
|
41
|
+
|
|
42
|
+
# The version of the adverse event grading system.
|
|
43
|
+
severity_grade_system_version: SeverityGradeSystemVersion
|
|
44
|
+
|
|
45
|
+
# Numerical grade indicating the severity of an adverse event.
|
|
46
|
+
severity_grade: SeverityGrade
|
|
47
|
+
|
|
48
|
+
# A brief description that sufficiently details the event.
|
|
49
|
+
event_other_specify: str | None = None
|
|
50
|
+
|
|
51
|
+
# The highest level of the MedDRA hierarchy, distinguished by anatomical or physiological system, etiology (disease origin) or purpose.
|
|
52
|
+
system_organ_class: SystemOrganClass | None = None
|
|
53
|
+
|
|
54
|
+
# Indicator to identify whether a participant exited the study prematurely due to the adverse event being described.
|
|
55
|
+
discontinuation_due_to_event: bool
|
|
56
|
+
|
|
57
|
+
# Days from enrollment date to date of onset of the adverse event.
|
|
58
|
+
days_to_onset_of_event: NonNegativeInt
|
|
59
|
+
|
|
60
|
+
# Days from enrollment date to date of resolution of the adverse event.
|
|
61
|
+
days_to_resolution_of_event: NonNegativeInt | None = None
|
|
62
|
+
|
|
63
|
+
# Indicates whether the adverse event was a serious adverse event (SAE).
|
|
64
|
+
serious_adverse_event: YNU
|
|
65
|
+
|
|
66
|
+
# Indicates whether the adverse event was a dose-limiting toxicity (DLT).
|
|
67
|
+
dose_limiting_toxicity: YNU
|
|
68
|
+
|
|
69
|
+
# Indicates if the adverse was attributable to the protocol as a whole or to an individual treatment.
|
|
70
|
+
attribution_cause: AttributionCause
|
|
71
|
+
|
|
72
|
+
# The code that indicates whether the adverse event is related to the treatment/intervention.
|
|
73
|
+
attribution_likelihood: AttributionLikelihood
|
|
74
|
+
|
|
75
|
+
# The individual therapy (therapy agent, radiotherapy, surgery, stem cell transplant) in the treatment that is attributed to the adverse event.
|
|
76
|
+
individual_therapy: str | None = None
|
|
77
|
+
|
|
78
|
+
@model_validator(mode="after")
|
|
79
|
+
def validate_term_and_code_cr(self) -> Self:
|
|
80
|
+
if not self.event_term and not self.event_code:
|
|
81
|
+
raise ValueError("Please provide event_term or event_code or both")
|
|
82
|
+
return self
|
|
83
|
+
|
|
84
|
+
@model_validator(mode="after")
|
|
85
|
+
def validate_event_other_specify_cr(self) -> Self:
|
|
86
|
+
if (
|
|
87
|
+
self.severity_grade_system == "CTCAE"
|
|
88
|
+
and is_ctcae_other_term(self.event_term)
|
|
89
|
+
and not self.event_other_specify
|
|
90
|
+
):
|
|
91
|
+
raise ValueError(
|
|
92
|
+
'If severity_grade_system is "CTCAE" and the event_code or event_term are of type "Other, specify", please provide event_other_specify'
|
|
93
|
+
)
|
|
94
|
+
return self
|
|
95
|
+
|
|
96
|
+
@model_validator(mode="after")
|
|
97
|
+
def validate_system_organ_class_cr(self) -> Self:
|
|
98
|
+
if self.event_other_specify and not self.system_organ_class:
|
|
99
|
+
raise ValueError("If event_other_specify is provided, please provide system_organ_class.")
|
|
100
|
+
return self
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from .base import Base
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Arm(Base):
|
|
5
|
+
# The unique internal identifier for the arm
|
|
6
|
+
arm_id: int | None = None
|
|
7
|
+
|
|
8
|
+
# The unique identifier for the associated trial
|
|
9
|
+
trial_id: int | None = None
|
|
10
|
+
|
|
11
|
+
# The version number of the trial dataset
|
|
12
|
+
version: str | None = None
|
|
13
|
+
|
|
14
|
+
# The name of the arm, e.g. "Arm A1"
|
|
15
|
+
# CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=2001626%20and%20ver_nr=3
|
|
16
|
+
name: str
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from pydantic import BaseModel, ConfigDict
|
|
2
|
+
from contextlib import contextmanager
|
|
3
|
+
|
|
4
|
+
import copy
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Base(BaseModel):
|
|
8
|
+
|
|
9
|
+
model_config = ConfigDict(validate_assignment=True, from_attributes=True)
|
|
10
|
+
|
|
11
|
+
# Validates the new state and updates the object if valid
|
|
12
|
+
def update(self, **kwargs):
|
|
13
|
+
self.model_validate(self.__dict__ | kwargs)
|
|
14
|
+
self.__dict__.update(kwargs)
|
|
15
|
+
|
|
16
|
+
# CM that delays validation until all fields are applied.
|
|
17
|
+
# If validation fails the original fields are restored and the ValidationError is raised.
|
|
18
|
+
@contextmanager
|
|
19
|
+
def delay_validation(self):
|
|
20
|
+
original_dict = copy.deepcopy(self.__dict__)
|
|
21
|
+
self.model_config["validate_assignment"] = False
|
|
22
|
+
try:
|
|
23
|
+
yield
|
|
24
|
+
finally:
|
|
25
|
+
self.model_config["validate_assignment"] = True
|
|
26
|
+
try:
|
|
27
|
+
self.model_validate(self.__dict__)
|
|
28
|
+
except:
|
|
29
|
+
self.__dict__.update(original_dict)
|
|
30
|
+
raise
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from .base import Base
|
|
2
|
+
from cidc_api.models.types import ECOGScore, KarnofskyScore
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class BaselineClinicalAssessment(Base):
|
|
6
|
+
__data_category__ = "baseline_clinical_assessment"
|
|
7
|
+
__cardinality__ = "one"
|
|
8
|
+
|
|
9
|
+
# A unique internal identifier for the baseline clinical assessment
|
|
10
|
+
baseline_clinical_assessment_id: int | None = None
|
|
11
|
+
|
|
12
|
+
# The unique identifier for the associated participant
|
|
13
|
+
participant_id: int | None = None
|
|
14
|
+
|
|
15
|
+
# The numerical score that represents the functional capabilities of a participant at the
|
|
16
|
+
# enrollment date using the Eastern Cooperative Oncology Group Performance Status assessment.
|
|
17
|
+
# CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=88%20and%20ver_nr=5.1
|
|
18
|
+
ecog_score: ECOGScore | None = None
|
|
19
|
+
|
|
20
|
+
# Score from the Karnofsky Performance status scale, representing the functional capabilities of a participant
|
|
21
|
+
# at the enrollment date.
|
|
22
|
+
# CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=2003853%20and%20ver_nr=4.2
|
|
23
|
+
karnofsky_score: KarnofskyScore | None = None
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from .base import Base
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Cohort(Base):
|
|
5
|
+
# A unique internal identifier for the cohort
|
|
6
|
+
cohort_id: int | None = None
|
|
7
|
+
|
|
8
|
+
# The unique identifier for the associated trial
|
|
9
|
+
trial_id: str | None = None
|
|
10
|
+
|
|
11
|
+
# The version number of the trial dataset
|
|
12
|
+
version: str | None = None
|
|
13
|
+
|
|
14
|
+
# The name of the cohort, e.g. "Cohort A"
|
|
15
|
+
# CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=7979585%20and%20ver_nr=1
|
|
16
|
+
name: str
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from typing import Self
|
|
2
|
+
|
|
3
|
+
from pydantic import model_validator
|
|
4
|
+
|
|
5
|
+
from .base import Base
|
|
6
|
+
from cidc_api.models.types import ICD10CMCode, ICD10CMTerm
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Comorbidity(Base):
|
|
10
|
+
__data_category__ = "comorbidity"
|
|
11
|
+
__cardinality__ = "many"
|
|
12
|
+
|
|
13
|
+
# The unique internal identifier for the comorbidity record
|
|
14
|
+
comorbidity_id: int | None = None
|
|
15
|
+
|
|
16
|
+
# The unique internal identifier for the associated MedicalHistory record
|
|
17
|
+
medical_history_id: int | None = None
|
|
18
|
+
|
|
19
|
+
# The diagnosis, in humans, as captured in the tenth version of the
|
|
20
|
+
# International Classification of Disease (ICD-10-CM, the disease code subset of ICD-10).
|
|
21
|
+
comorbidity_code: ICD10CMCode | None = None
|
|
22
|
+
|
|
23
|
+
# The words from the tenth version of the International Classification of Disease (ICD-10-CM,
|
|
24
|
+
# the disease subset of ICD-10) used to identify the diagnosis in humans.
|
|
25
|
+
comorbidity_term: ICD10CMTerm | None = None
|
|
26
|
+
|
|
27
|
+
# A descriptive string that names or briefly describes the comorbidity.
|
|
28
|
+
comorbidity_other: str | None = None
|
|
29
|
+
|
|
30
|
+
@model_validator(mode="after")
|
|
31
|
+
def validate_code_or_term_or_other_cr(self) -> Self:
|
|
32
|
+
if not self.comorbidity_code and not self.comorbidity_term and not self.comorbidity_other:
|
|
33
|
+
raise ValueError(
|
|
34
|
+
'Please provide at least one of "comorbidity_code", "comorbidity_term" or "comorbidity_other".'
|
|
35
|
+
)
|
|
36
|
+
return self
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from pydantic import NonNegativeInt
|
|
2
|
+
|
|
3
|
+
from .base import Base
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ConsentGroup(Base):
|
|
7
|
+
__data_category__ = "consent_group"
|
|
8
|
+
__cardinality__ = "one"
|
|
9
|
+
|
|
10
|
+
# The unique internal identifier for the consent group record
|
|
11
|
+
consent_group_id: int | None = None
|
|
12
|
+
|
|
13
|
+
# The unique internal identifier for the associated Trial record
|
|
14
|
+
trial_id: int | None = None
|
|
15
|
+
|
|
16
|
+
# The version number of the trial dataset
|
|
17
|
+
version: str | None = None
|
|
18
|
+
|
|
19
|
+
# An abbreviated name for the consent group
|
|
20
|
+
consent_group_short_name: str
|
|
21
|
+
|
|
22
|
+
# The words or acronym which describe a set of study participants
|
|
23
|
+
# who have signed the same consent agreement and that will be included in the dbGaP repository.
|
|
24
|
+
# CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=14534329%20and%20ver_nr=1.00
|
|
25
|
+
consent_group_name: str
|
|
26
|
+
|
|
27
|
+
# A numeral or string of numerals used to identify the set of study participants who have signed the same consent
|
|
28
|
+
# agreement and that will be included in the dbGaP repository.
|
|
29
|
+
# CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=14534330%20and%20ver_nr=1.00
|
|
30
|
+
consent_group_number: NonNegativeInt
|