nci-cidc-api-modules 1.2.51__tar.gz → 1.2.52__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.
Files changed (179) hide show
  1. {nci_cidc_api_modules-1.2.51/nci_cidc_api_modules.egg-info → nci_cidc_api_modules-1.2.52}/PKG-INFO +1 -1
  2. nci_cidc_api_modules-1.2.52/cidc_api/__init__.py +1 -0
  3. nci_cidc_api_modules-1.2.52/cidc_api/models/pydantic/base.py +109 -0
  4. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/adverse_event.py +36 -28
  5. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/comorbidity.py +12 -7
  6. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/demographic.py +32 -22
  7. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/disease.py +70 -44
  8. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/exposure.py +9 -7
  9. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/medical_history.py +10 -7
  10. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/other_malignancy.py +14 -10
  11. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/participant.py +16 -11
  12. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/radiotherapy_dose.py +17 -11
  13. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/response.py +24 -15
  14. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/response_by_system.py +78 -45
  15. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/surgery.py +10 -6
  16. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/therapy_agent_dose.py +17 -11
  17. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/treatment.py +18 -11
  18. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52/nci_cidc_api_modules.egg-info}/PKG-INFO +1 -1
  19. nci_cidc_api_modules-1.2.51/cidc_api/__init__.py +0 -1
  20. nci_cidc_api_modules-1.2.51/cidc_api/models/pydantic/base.py +0 -48
  21. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/LICENSE +0 -0
  22. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/MANIFEST.in +0 -0
  23. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/README.md +0 -0
  24. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/boot.py +0 -0
  25. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/config/__init__.py +0 -0
  26. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/config/db.py +0 -0
  27. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/config/logging.py +0 -0
  28. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/config/secrets.py +0 -0
  29. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/config/settings.py +0 -0
  30. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/__init__.py +0 -0
  31. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/data.py +0 -0
  32. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/__init__.py +0 -0
  33. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/additional_treatment_orm.py +0 -0
  34. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/adverse_event_orm.py +0 -0
  35. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/base_orm.py +0 -0
  36. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/baseline_clinical_assessment_orm.py +0 -0
  37. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/comorbidity_orm.py +0 -0
  38. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/consent_group_orm.py +0 -0
  39. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/demographic_orm.py +0 -0
  40. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/disease_orm.py +0 -0
  41. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/exposure_orm.py +0 -0
  42. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/gvhd_diagnosis_acute_orm.py +0 -0
  43. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/gvhd_diagnosis_chronic_orm.py +0 -0
  44. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/gvhd_organ_acute_orm.py +0 -0
  45. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/gvhd_organ_chronic_orm.py +0 -0
  46. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/medical_history_orm.py +0 -0
  47. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/other_malignancy_orm.py +0 -0
  48. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/participant_orm.py +0 -0
  49. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/prior_treatment_orm.py +0 -0
  50. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/radiotherapy_dose_orm.py +0 -0
  51. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/response_by_system_orm.py +0 -0
  52. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/response_orm.py +0 -0
  53. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/specimen_orm.py +0 -0
  54. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/stem_cell_transplant_orm.py +0 -0
  55. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/surgery_orm.py +0 -0
  56. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/therapy_agent_dose_orm.py +0 -0
  57. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/treatment_orm.py +0 -0
  58. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage1/trial_orm.py +0 -0
  59. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/__init__.py +0 -0
  60. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/additional_treatment_orm.py +0 -0
  61. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/administrative_person_orm.py +0 -0
  62. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/administrative_role_assignment_orm.py +0 -0
  63. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/adverse_event_orm.py +0 -0
  64. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/arm_orm.py +0 -0
  65. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/base_orm.py +0 -0
  66. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/baseline_clinical_assessment_orm.py +0 -0
  67. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/cohort_orm.py +0 -0
  68. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/comorbidity_orm.py +0 -0
  69. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/consent_group_orm.py +0 -0
  70. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/contact_orm.py +0 -0
  71. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/demographic_orm.py +0 -0
  72. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/disease_orm.py +0 -0
  73. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/exposure_orm.py +0 -0
  74. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/file_orm.py +0 -0
  75. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/gvhd_diagnosis_acute_orm.py +0 -0
  76. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/gvhd_diagnosis_chronic_orm.py +0 -0
  77. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/gvhd_organ_acute_orm.py +0 -0
  78. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/gvhd_organ_chronic_orm.py +0 -0
  79. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/institution_orm.py +0 -0
  80. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/medical_history_orm.py +0 -0
  81. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/other_clinical_endpoint_orm.py +0 -0
  82. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/other_malignancy_orm.py +0 -0
  83. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/participant_orm.py +0 -0
  84. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/prior_treatment_orm.py +0 -0
  85. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/publication_orm.py +0 -0
  86. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/radiotherapy_dose_orm.py +0 -0
  87. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/response_by_system_orm.py +0 -0
  88. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/response_orm.py +0 -0
  89. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/shipment_orm.py +0 -0
  90. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/shipment_specimen_orm.py +0 -0
  91. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/specimen_orm.py +0 -0
  92. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/stem_cell_transplant_orm.py +0 -0
  93. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/surgery_orm.py +0 -0
  94. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/therapy_agent_dose_orm.py +0 -0
  95. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/treatment_orm.py +0 -0
  96. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/db/stage2/trial_orm.py +0 -0
  97. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/errors.py +0 -0
  98. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/files/__init__.py +0 -0
  99. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/files/details.py +0 -0
  100. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/files/facets.py +0 -0
  101. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/migrations.py +0 -0
  102. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/models.py +0 -0
  103. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/__init__.py +0 -0
  104. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/additional_treatment.py +0 -0
  105. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/baseline_clinical_assessment.py +0 -0
  106. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/consent_group.py +0 -0
  107. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/gvhd_diagnosis_acute.py +0 -0
  108. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/gvhd_diagnosis_chronic.py +0 -0
  109. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/gvhd_organ_acute.py +0 -0
  110. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/gvhd_organ_chronic.py +0 -0
  111. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/prior_treatment.py +0 -0
  112. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/specimen.py +0 -0
  113. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/stem_cell_transplant.py +0 -0
  114. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage1/trial.py +0 -0
  115. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/__init__.py +0 -0
  116. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/additional_treatment.py +0 -0
  117. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/administrative_person.py +0 -0
  118. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/administrative_role_assignment.py +0 -0
  119. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/adverse_event.py +0 -0
  120. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/arm.py +0 -0
  121. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/baseline_clinical_assessment.py +0 -0
  122. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/cohort.py +0 -0
  123. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/comorbidity.py +0 -0
  124. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/consent_group.py +0 -0
  125. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/contact.py +0 -0
  126. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/demographic.py +0 -0
  127. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/disease.py +0 -0
  128. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/exposure.py +0 -0
  129. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/file.py +0 -0
  130. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/gvhd_diagnosis_acute.py +0 -0
  131. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/gvhd_diagnosis_chronic.py +0 -0
  132. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/gvhd_organ_acute.py +0 -0
  133. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/gvhd_organ_chronic.py +0 -0
  134. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/institution.py +0 -0
  135. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/medical_history.py +0 -0
  136. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/other_clinical_endpoint.py +0 -0
  137. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/other_malignancy.py +0 -0
  138. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/participant.py +0 -0
  139. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/prior_treatment.py +0 -0
  140. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/publication.py +0 -0
  141. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/radiotherapy_dose.py +0 -0
  142. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/response.py +0 -0
  143. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/response_by_system.py +0 -0
  144. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/shipment.py +0 -0
  145. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/shipment_specimen.py +0 -0
  146. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/specimen.py +0 -0
  147. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/stem_cell_transplant.py +0 -0
  148. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/surgery.py +0 -0
  149. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/therapy_agent_dose.py +0 -0
  150. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/treatment.py +0 -0
  151. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/pydantic/stage2/trial.py +0 -0
  152. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/schemas.py +0 -0
  153. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/models/types.py +0 -0
  154. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/reference/ctcae.py +0 -0
  155. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/reference/gvhd.py +0 -0
  156. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/reference/icd10cm.py +0 -0
  157. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/reference/icdo3.py +0 -0
  158. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/reference/uberon.py +0 -0
  159. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/shared/__init__.py +0 -0
  160. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/shared/assay_handling.py +0 -0
  161. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/shared/auth.py +0 -0
  162. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/shared/email_layout.html +0 -0
  163. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/shared/emails.py +0 -0
  164. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/shared/file_handling.py +0 -0
  165. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/shared/gcloud_client.py +0 -0
  166. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/shared/jose.py +0 -0
  167. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/shared/rest_utils.py +0 -0
  168. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/shared/utils.py +0 -0
  169. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/cidc_api/telemetry.py +0 -0
  170. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/nci_cidc_api_modules.egg-info/SOURCES.txt +0 -0
  171. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/nci_cidc_api_modules.egg-info/dependency_links.txt +0 -0
  172. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/nci_cidc_api_modules.egg-info/not-zip-safe +0 -0
  173. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/nci_cidc_api_modules.egg-info/requires.txt +0 -0
  174. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/nci_cidc_api_modules.egg-info/top_level.txt +0 -0
  175. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/pyproject.toml +0 -0
  176. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/requirements.modules.txt +0 -0
  177. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/setup.cfg +0 -0
  178. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/setup.py +0 -0
  179. {nci_cidc_api_modules-1.2.51 → nci_cidc_api_modules-1.2.52}/tests/test_api.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nci_cidc_api_modules
3
- Version: 1.2.51
3
+ Version: 1.2.52
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
@@ -0,0 +1 @@
1
+ __version__ = "1.2.52"
@@ -0,0 +1,109 @@
1
+ import copy
2
+ from contextlib import contextmanager
3
+ from typing import Self, ClassVar
4
+ from pydantic import BaseModel, ConfigDict, model_validator, ValidationError
5
+ from pydantic_core import InitErrorDetails
6
+
7
+ from cidc_api.models.errors import ValueLocError
8
+ from functools import wraps
9
+
10
+
11
+ class Base(BaseModel):
12
+
13
+ model_config = ConfigDict(
14
+ validate_assignment=True,
15
+ from_attributes=True,
16
+ extra="allow",
17
+ )
18
+ forced_validators: ClassVar = []
19
+
20
+ # Validates the new state and updates the object if valid
21
+ def update(self, **kwargs):
22
+ self.model_validate(self.__dict__ | kwargs)
23
+ self.__dict__.update(kwargs)
24
+
25
+ # CM that delays validation until all fields are applied.
26
+ # If validation fails the original fields are restored and the ValidationError is raised.
27
+ @contextmanager
28
+ def delay_validation(self):
29
+ original_dict = copy.deepcopy(self.__dict__)
30
+ self.model_config["validate_assignment"] = False
31
+ try:
32
+ yield
33
+ finally:
34
+ self.model_config["validate_assignment"] = True
35
+ try:
36
+ self.model_validate(self.__dict__)
37
+ except:
38
+ self.__dict__.update(original_dict)
39
+ raise
40
+
41
+ # CM that delays validation until all fields are applied.
42
+
43
+ @classmethod
44
+ def split_list(cls, val):
45
+ """Listify fields that are multi-valued in input data, e.g. 'lung|kidney'"""
46
+ if type(val) == list:
47
+ return val
48
+ elif type(val) == str:
49
+ if not val:
50
+ return []
51
+ return val.split("|")
52
+ elif val == None:
53
+ return []
54
+ else:
55
+ raise ValueError("Field value must be string or list")
56
+
57
+ @model_validator(mode="wrap")
58
+ @classmethod
59
+ def check_all_forced_validators(cls, data, handler, info) -> Self:
60
+ """This base validator ensures all registered forced_validator(s) get called along with
61
+ normal model field validators no matter what the outcome of either is. Normal field_validator
62
+ and model_validator decorators don't guarantee this. We want to collect as many errors as we can.
63
+
64
+ Collects errors from both attempts and raises them in a combined ValidationError."""
65
+
66
+ validation_errors = []
67
+ # When assigning attributes to an already-hydrated model, data is an instance of the model
68
+ # instead of a dict and handler is an AssignmentValidatorCallable instead of a ValidatorCallable(!!)
69
+ extracted_data = data.model_dump() if not isinstance(data, dict) else data
70
+
71
+ for validator in cls.forced_validators:
72
+ try:
73
+ func_name = validator.__name__
74
+ func = getattr(cls, func_name)
75
+ func(extracted_data, info)
76
+ except (ValueError, ValueLocError) as e:
77
+ validation_errors.append(
78
+ InitErrorDetails(
79
+ type="value_error",
80
+ loc=e.loc,
81
+ input=extracted_data,
82
+ ctx={"error": e},
83
+ )
84
+ )
85
+ try:
86
+ # Instantiate the model to ensure all other normal field validations are called
87
+ retval = handler(data)
88
+ except ValidationError as e:
89
+ validation_errors.extend(e.errors())
90
+ if validation_errors:
91
+ raise ValidationError.from_exception_data(title=cls.__name__, line_errors=validation_errors)
92
+ return retval
93
+
94
+
95
+ def forced_validator(func):
96
+ """A method marked with this decorator is added to the class list of forced_validators"""
97
+ func._is_forced_validator = True # Tag the function object with a custom attribute
98
+ return func
99
+
100
+
101
+ def forced_validators(cls):
102
+ """A class marked with this decorator accumulates its methods marked with force_validator into a list
103
+ for later invocation."""
104
+
105
+ cls.forced_validators = []
106
+ for obj in cls.__dict__.values():
107
+ if getattr(obj, "_is_forced_validator", False):
108
+ cls.forced_validators.append(obj)
109
+ return cls
@@ -1,9 +1,8 @@
1
- from typing import Self
2
-
3
- from pydantic import Field, NonNegativeInt, model_validator
1
+ from pydantic import NonNegativeInt
4
2
 
5
3
  from cidc_api.models.pydantic.base import Base
6
4
  from cidc_api.reference.ctcae import is_ctcae_other_term
5
+ from cidc_api.models.pydantic.base import forced_validator, forced_validators
7
6
  from cidc_api.models.errors import ValueLocError
8
7
  from cidc_api.models.types import (
9
8
  CTCAEEventTerm,
@@ -18,6 +17,7 @@ from cidc_api.models.types import (
18
17
  )
19
18
 
20
19
 
20
+ @forced_validators
21
21
  class AdverseEvent(Base):
22
22
  __data_category__ = "adverse_event"
23
23
  __cardinality__ = "many"
@@ -76,44 +76,52 @@ class AdverseEvent(Base):
76
76
  # The individual therapy (therapy agent, radiotherapy, surgery, stem cell transplant) in the treatment that is attributed to the adverse event.
77
77
  individual_therapy: str | None = None
78
78
 
79
- @model_validator(mode="after")
80
- def validate_term_and_code_cr(self) -> Self:
81
- if not self.event_term and not self.event_code:
79
+ @forced_validator
80
+ @classmethod
81
+ def validate_term_and_code_cr(cls, data, info) -> None:
82
+ event_code = data.get("event_code", None)
83
+ event_term = data.get("event_term", None)
84
+
85
+ if not event_term and not event_code:
82
86
  raise ValueLocError(
83
87
  "Please provide event_term or event_code or both",
84
- loc="event_term",
88
+ loc="event_term,event_code",
85
89
  )
86
- return self
87
-
88
- @model_validator(mode="after")
89
- def validate_event_other_specify_cr(self) -> Self:
90
- if (
91
- self.severity_grade_system == "CTCAE"
92
- and is_ctcae_other_term(self.event_term)
93
- and not self.event_other_specify
94
- ):
90
+
91
+ @forced_validator
92
+ @classmethod
93
+ def validate_event_other_specify_cr(cls, data, info) -> None:
94
+ event_other_specify = data.get("event_other_specify", None)
95
+ severity_grade_system = data.get("severity_grade_system", None)
96
+ event_term = data.get("event_term", None)
97
+
98
+ if severity_grade_system == "CTCAE" and is_ctcae_other_term(event_term) and not event_other_specify:
95
99
  raise ValueLocError(
96
100
  'If severity_grade_system is "CTCAE" and the event_code or event_term are of type '
97
101
  '"Other, specify", please provide event_other_specify',
98
102
  loc="event_other_specify",
99
103
  )
100
- return self
101
104
 
102
- @model_validator(mode="after")
103
- def validate_system_organ_class_cr(self) -> Self:
104
- if self.event_other_specify and not self.system_organ_class:
105
+ @forced_validator
106
+ @classmethod
107
+ def validate_system_organ_class_cr(cls, data, info) -> None:
108
+ event_other_specify = data.get("event_other_specify", None)
109
+ system_organ_class = data.get("system_organ_class", None)
110
+
111
+ if event_other_specify and not system_organ_class:
105
112
  raise ValueLocError(
106
- "If event_other_specify is provided, please provide system_organ_class.",
107
- loc="system_organ_class",
113
+ "If event_other_specify is provided, please provide system_organ_class.", loc="system_organ_class"
108
114
  )
109
- return self
110
115
 
111
- @model_validator(mode="after")
112
- def validate_days_to_resolution_of_event_chronology(self) -> Self:
113
- if self.days_to_resolution_of_event is not None and self.days_to_onset_of_event is not None:
114
- if self.days_to_resolution_of_event < self.days_to_onset_of_event:
116
+ @forced_validator
117
+ @classmethod
118
+ def validate_days_to_resolution_of_event_chronology(cls, data, info) -> None:
119
+ days_to_onset_of_event = data.get("days_to_onset_of_event", None)
120
+ days_to_resolution_of_event = data.get("days_to_resolution_of_event", None)
121
+
122
+ if days_to_resolution_of_event is not None and days_to_onset_of_event is not None:
123
+ if int(days_to_resolution_of_event) < int(days_to_onset_of_event):
115
124
  raise ValueLocError(
116
125
  'Violate "days_to_onset_of_event" <= "days_to_resolution_of_event"',
117
126
  loc="days_to_resolution_of_event",
118
127
  )
119
- return self
@@ -1,12 +1,13 @@
1
- from typing import Self, Any
1
+ from typing import Any
2
2
 
3
- from pydantic import model_validator, field_validator
3
+ from cidc_api.models.pydantic.base import forced_validator, forced_validators
4
4
 
5
5
  from cidc_api.models.errors import ValueLocError
6
6
  from cidc_api.models.pydantic.base import Base
7
7
  from cidc_api.models.types import ICD10CMCode, ICD10CMTerm
8
8
 
9
9
 
10
+ @forced_validators
10
11
  class Comorbidity(Base):
11
12
  __data_category__ = "comorbidity"
12
13
  __cardinality__ = "many"
@@ -28,11 +29,15 @@ class Comorbidity(Base):
28
29
  # A descriptive string that names or briefly describes the comorbidity.
29
30
  comorbidity_other: str | None = None
30
31
 
31
- @model_validator(mode="after")
32
- def validate_code_or_term_or_other_cr(self) -> Self:
33
- if not self.comorbidity_code and not self.comorbidity_term and not self.comorbidity_other:
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:
34
40
  raise ValueLocError(
35
41
  'Please provide at least one of "comorbidity_code", "comorbidity_term" or "comorbidity_other".',
36
- loc="comorbidity_code",
42
+ loc="comorbidity_code,comorbidity_term,comorbidity_other",
37
43
  )
38
- return self
@@ -1,6 +1,7 @@
1
- from typing import Self, Annotated, List
1
+ from typing import Annotated, List
2
2
 
3
- from pydantic import PositiveInt, NonNegativeFloat, PositiveFloat, model_validator, field_validator, BeforeValidator
3
+ from pydantic import PositiveInt, NonNegativeFloat, PositiveFloat, BeforeValidator
4
+ from cidc_api.models.pydantic.base import forced_validator, forced_validators
4
5
 
5
6
  from cidc_api.models.errors import ValueLocError
6
7
  from cidc_api.models.pydantic.base import Base
@@ -17,6 +18,7 @@ from cidc_api.models.types import (
17
18
  )
18
19
 
19
20
 
21
+ @forced_validators
20
22
  class Demographic(Base):
21
23
  __data_category__ = "demographic"
22
24
  __cardinality__ = "one"
@@ -91,40 +93,48 @@ class Demographic(Base):
91
93
  # CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=2681552%20and%20ver_nr=1
92
94
  highest_level_of_education: Education | None = None
93
95
 
94
- @model_validator(mode="after")
95
- def validate_age_at_enrollment_cr(self) -> Self:
96
- if self.age_90_or_over:
97
- if self.age_at_enrollment or self.age_at_enrollment_units:
96
+ @forced_validator
97
+ @classmethod
98
+ def validate_age_at_enrollment_cr(cls, data, info) -> None:
99
+ age_at_enrollment_units = data.get("age_at_enrollment_units", None)
100
+ age_90_or_over = data.get("age_90_or_over", None)
101
+ age_at_enrollment = int(data.get("age_at_enrollment", None) or 0)
102
+
103
+ if age_90_or_over:
104
+ if age_at_enrollment or age_at_enrollment_units:
98
105
  raise ValueLocError(
99
106
  'If "age_90_or_over" is "Yes" then "age_at_enrollment" and "age_at_enrollment_units" must be blank.',
100
107
  loc="age_at_enrollment",
101
108
  )
102
109
  else:
103
- if not self.age_at_enrollment or not self.age_at_enrollment_units:
110
+ if not age_at_enrollment or not age_at_enrollment_units:
104
111
  raise ValueLocError(
105
112
  'If "age_90_or_over" is "No" then "age_at_enrollment" and "age_at_enrollment_units" are required.',
106
- loc="age_at_enrollment_units",
113
+ loc="age_at_enrollment",
107
114
  )
108
- return self
109
115
 
110
- @model_validator(mode="after")
111
- def validate_age_at_enrollment_value(self) -> Self:
112
- if not self.age_90_or_over:
113
- age_in_years = (
114
- self.age_at_enrollment if self.age_at_enrollment_units == "Years" else self.age_at_enrollment / 365.25
115
- )
116
+ @forced_validator
117
+ @classmethod
118
+ def validate_age_at_enrollment_value(cls, data, info) -> None:
119
+ age_at_enrollment_units = data.get("age_at_enrollment_units", None)
120
+ age_90_or_over = data.get("age_90_or_over", None)
121
+ age_at_enrollment = int(data.get("age_at_enrollment", None) or 0)
122
+
123
+ if not age_90_or_over:
124
+ age_in_years = age_at_enrollment if age_at_enrollment_units == "Years" else age_at_enrollment / 365.25
116
125
  if age_in_years >= 90:
117
126
  raise ValueLocError(
118
127
  '"age_at_enrollment" cannot represent a value greater than 90 years of age.',
119
128
  loc="age_at_enrollment",
120
129
  )
121
- return self
122
130
 
123
- @model_validator(mode="after")
124
- def validate_body_surface_area_units_cr(self) -> Self:
125
- if self.body_surface_area and not self.body_surface_area_units:
131
+ @forced_validator
132
+ @classmethod
133
+ def validate_body_surface_area_units_cr(cls, data, info) -> None:
134
+ body_surface_area = data.get("body_surface_area", None)
135
+ body_surface_area_units = data.get("body_surface_area_units", None)
136
+
137
+ if body_surface_area and not body_surface_area_units:
126
138
  raise ValueLocError(
127
- 'If "body_surface_area" is provided then "body_surface_area_units_other" must also be provided.',
128
- loc="body_surface_area_units_other",
139
+ 'If "body_surface_area" is provided then "body_surface_area_units" must also be provided.'
129
140
  )
130
- return self
@@ -1,5 +1,7 @@
1
- from pydantic import NonPositiveInt, model_validator, BeforeValidator
2
- from typing import List, Self, Annotated, get_args
1
+ from pydantic import NonPositiveInt, BeforeValidator
2
+ from cidc_api.models.pydantic.base import forced_validator, forced_validators
3
+
4
+ from typing import List, Self, Annotated, get_args, Any
3
5
 
4
6
  from cidc_api.models.errors import ValueLocError
5
7
  from cidc_api.models.pydantic.base import Base
@@ -21,6 +23,7 @@ from cidc_api.models.types import (
21
23
  )
22
24
 
23
25
 
26
+ @forced_validators
24
27
  class Disease(Base):
25
28
  __data_category__ = "disease"
26
29
  __cardinality__ = "many"
@@ -93,82 +96,105 @@ class Disease(Base):
93
96
 
94
97
  extramedullary_organ: Annotated[List[UberonAnatomicalTerm] | None, BeforeValidator(Base.split_list)] = []
95
98
 
96
- @model_validator(mode="after")
97
- def validate_code_or_term_or_description_cr(self) -> Self:
98
- if not self.morphological_code and not self.morphological_term and not self.cancer_type_description:
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:
99
107
  raise ValueLocError(
100
108
  'Please provide at least one of "morphological_code", "morphological_term" or "cancer_type_description".',
101
109
  loc="morphological_code",
102
110
  )
103
- return self
104
111
 
105
- @model_validator(mode="after")
106
- def validate_cancer_stage_system_version(self) -> Self:
107
- msg = f"{self.cancer_stage_system_version} is not applicable to {self.cancer_stage_system}"
108
- if self.cancer_stage_system == "AJCC" and self.cancer_stage_system_version not in get_args(
109
- CancerStageSystemVersionAJCC
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):
111
120
  raise ValueLocError(msg, loc="cancer_stage_system")
112
- elif self.cancer_stage_system == "RISS" and self.cancer_stage_system_version not in get_args(
121
+ elif cancer_stage_system == "RISS" and cancer_stage_system_version not in get_args(
113
122
  CancerStageSystemVersionRISS
114
123
  ):
115
124
  raise ValueLocError(msg, loc="cancer_stage_system")
116
- elif self.cancer_stage_system == "FIGO" and self.cancer_stage_system_version not in get_args(
125
+ elif cancer_stage_system == "FIGO" and cancer_stage_system_version not in get_args(
117
126
  CancerStageSystemVersionFIGO
118
127
  ):
119
128
  raise ValueLocError(msg, loc="cancer_stage_system")
120
- return self
121
129
 
122
- @model_validator(mode="after")
123
- def validate_cancer_stage_system_version_cr(self) -> Self:
124
- if self.cancer_stage_system != "Not Applicable" and not self.cancer_stage_system_version:
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:
125
137
  raise ValueLocError(
126
- f'Please provide cancer_stage_system_version when cancer_stage_system is "{self.cancer_stage_system}"',
138
+ f'Please provide cancer_stage_system_version when cancer_stage_system is "{cancer_stage_system}"',
127
139
  loc="cancer_stage_system_version",
128
140
  )
129
- return self
130
141
 
131
- @model_validator(mode="after")
132
- def validate_cancer_stage_cr(self) -> Self:
133
- if self.cancer_stage_system != "Not Applicable" and not self.cancer_stage:
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:
134
149
  raise ValueLocError(
135
- f'Please provide cancer_stage when cancer_stage_system is "{self.cancer_stage_system}"',
150
+ f'Please provide cancer_stage when cancer_stage_system is "{cancer_stage_system}"',
136
151
  loc="cancer_stage",
137
152
  )
138
- return self
139
153
 
140
- @model_validator(mode="after")
141
- def validate_t_category_cr(self) -> Self:
142
- if self.cancer_stage_system == "AJCC" and not self.t_category:
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:
143
161
  raise ValueLocError(
144
- f'Please provide t_category when cancer_stage_system is "{self.cancer_stage_system}"',
162
+ f'Please provide t_category when cancer_stage_system is "{cancer_stage_system}"',
145
163
  loc="t_category",
146
164
  )
147
- return self
148
165
 
149
- @model_validator(mode="after")
150
- def validate_n_category_cr(self) -> Self:
151
- if self.cancer_stage_system == "AJCC" and not self.n_category:
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:
152
173
  raise ValueLocError(
153
- f'Please provide n_category when cancer_stage_system is "{self.cancer_stage_system}"',
174
+ f'Please provide n_category when cancer_stage_system is "{cancer_stage_system}"',
154
175
  loc="n_category",
155
176
  )
156
- return self
157
177
 
158
- @model_validator(mode="after")
159
- def validate_m_category_cr(self) -> Self:
160
- if self.cancer_stage_system == "AJCC" and not self.m_category:
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:
161
185
  raise ValueLocError(
162
- f'Please provide m_category when cancer_stage_system is "{self.cancer_stage_system}"',
186
+ f'Please provide m_category when cancer_stage_system is "{cancer_stage_system}"',
163
187
  loc="m_category",
164
188
  )
165
- return self
166
189
 
167
- @model_validator(mode="after")
168
- def validate_extramedullary_organ_cr(self) -> Self:
169
- if self.solely_extramedullary_disease in ["No", "Unknown"] and self.extramedullary_organ:
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:
170
197
  raise ValueLocError(
171
198
  "If solely_extramedullary_disease indicates no disease, please leave extramedullary_organ blank.",
172
199
  loc="extramedullary_organ",
173
200
  )
174
- return self
@@ -1,12 +1,11 @@
1
- from typing import Self
2
-
3
- from pydantic import model_validator
1
+ from cidc_api.models.pydantic.base import forced_validator, forced_validators
4
2
 
5
3
  from cidc_api.models.errors import ValueLocError
6
4
  from cidc_api.models.pydantic.base import Base
7
5
  from cidc_api.models.types import YNU, ExposureType
8
6
 
9
7
 
8
+ @forced_validators
10
9
  class Exposure(Base):
11
10
  __data_category__ = "exposure"
12
11
  __cardinality__ = "many"
@@ -26,11 +25,14 @@ class Exposure(Base):
26
25
  # CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=15753203%20and%20ver_nr=1
27
26
  exposure_type: ExposureType | None = None
28
27
 
29
- @model_validator(mode="after")
30
- def validate_exposure_type_cr(self) -> Self:
31
- if self.carcinogen_exposure in ["No", "Unknown"] and self.exposure_type:
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:
32
35
  raise ValueLocError(
33
36
  "If carcinogen_exposure indicates non exposure, please leave exposure_type blank.",
34
37
  loc="exposure_type",
35
38
  )
36
- return self
@@ -1,12 +1,12 @@
1
- from typing import Self
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
 
5
4
  from cidc_api.models.errors import ValueLocError
6
5
  from cidc_api.models.pydantic.base import Base
7
6
  from cidc_api.models.types import TobaccoSmokingStatus
8
7
 
9
8
 
9
+ @forced_validators
10
10
  class MedicalHistory(Base):
11
11
  __data_category__ = "medical_history"
12
12
  __cardinality__ = "one"
@@ -30,11 +30,14 @@ class MedicalHistory(Base):
30
30
  # CDE: https://cadsr.cancer.gov/onedata/dmdirect/NIH/NCI/CO/CDEDD?filter=CDEDD.ITEM_ID=16089302%20and%20ver_nr=1
31
31
  num_prior_systemic_therapies: NonNegativeInt | None = None
32
32
 
33
- @model_validator(mode="after")
34
- def validate_pack_years_smoked_cr(self) -> Self:
35
- if self.tobacco_smoking_status in ["Never Smoker", "Unknown", "Not reported"] and self.pack_years_smoked:
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:
36
40
  raise ValueLocError(
37
41
  "If tobacco_smoking_status indicates non-smoker, please leave pack_years_smoked blank.",
38
42
  loc="pack_years_smoked",
39
43
  )
40
- return self
@@ -1,12 +1,12 @@
1
- from typing import Self
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
 
5
4
  from cidc_api.models.errors import ValueLocError
6
5
  from cidc_api.models.pydantic.base import Base
7
6
  from cidc_api.models.types import UberonAnatomicalTerm, ICDO3MorphologicalCode, ICDO3MorphologicalTerm, MalignancyStatus
8
7
 
9
8
 
9
+ @forced_validators
10
10
  class OtherMalignancy(Base):
11
11
  __data_category__ = "other_malignancy"
12
12
  __cardinality__ = "many"
@@ -37,15 +37,19 @@ class OtherMalignancy(Base):
37
37
  # Indicates the participant’s current clinical state regarding the cancer diagnosis.
38
38
  other_malignancy_status: MalignancyStatus | None = None
39
39
 
40
- @model_validator(mode="after")
41
- def validate_code_or_term_or_description_cr(self) -> Self:
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
+
42
47
  if (
43
- not self.other_malignancy_morphological_code
44
- and not self.other_malignancy_morphological_term
45
- and not self.other_malignancy_description
48
+ not other_malignancy_morphological_code
49
+ and not other_malignancy_morphological_term
50
+ and not other_malignancy_description
46
51
  ):
47
52
  raise ValueLocError(
48
53
  'Please provide at least one of "morphological_code", "morphological_term" or "malignancy_description".',
49
- loc="morphological_code",
54
+ loc="other_malignancy_morphological_code",
50
55
  )
51
- return self