endoreg-db 0.8.6.1__py3-none-any.whl → 0.8.8.0__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.

Potentially problematic release.


This version of endoreg-db might be problematic. Click here for more details.

Files changed (360) hide show
  1. endoreg_db/authz/auth.py +74 -0
  2. endoreg_db/authz/backends.py +168 -0
  3. endoreg_db/authz/management/commands/list_routes.py +18 -0
  4. endoreg_db/authz/middleware.py +83 -0
  5. endoreg_db/authz/permissions.py +127 -0
  6. endoreg_db/authz/policy.py +218 -0
  7. endoreg_db/authz/views_auth.py +66 -0
  8. endoreg_db/config/env.py +13 -8
  9. endoreg_db/data/__init__.py +8 -31
  10. endoreg_db/data/_examples/disease.yaml +55 -0
  11. endoreg_db/data/_examples/disease_classification.yaml +13 -0
  12. endoreg_db/data/_examples/disease_classification_choice.yaml +62 -0
  13. endoreg_db/data/_examples/event.yaml +64 -0
  14. endoreg_db/data/_examples/examination.yaml +72 -0
  15. endoreg_db/data/_examples/finding/anatomy_colon.yaml +128 -0
  16. endoreg_db/data/_examples/finding/colonoscopy.yaml +40 -0
  17. endoreg_db/data/_examples/finding/colonoscopy_bowel_prep.yaml +56 -0
  18. endoreg_db/data/_examples/finding/complication.yaml +16 -0
  19. endoreg_db/data/_examples/finding/data.yaml +105 -0
  20. endoreg_db/data/_examples/finding/examination_setting.yaml +16 -0
  21. endoreg_db/data/_examples/finding/medication_related.yaml +18 -0
  22. endoreg_db/data/_examples/finding/outcome.yaml +12 -0
  23. endoreg_db/data/_examples/finding_classification/colonoscopy_bowel_preparation.yaml +68 -0
  24. endoreg_db/data/_examples/finding_classification/colonoscopy_jnet.yaml +22 -0
  25. endoreg_db/data/_examples/finding_classification/colonoscopy_kudo.yaml +25 -0
  26. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_circularity.yaml +20 -0
  27. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_planarity.yaml +24 -0
  28. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_size.yaml +68 -0
  29. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_surface.yaml +20 -0
  30. endoreg_db/data/_examples/finding_classification/colonoscopy_location.yaml +80 -0
  31. endoreg_db/data/_examples/finding_classification/colonoscopy_lst.yaml +21 -0
  32. endoreg_db/data/_examples/finding_classification/colonoscopy_nice.yaml +20 -0
  33. endoreg_db/data/_examples/finding_classification/colonoscopy_paris.yaml +26 -0
  34. endoreg_db/data/_examples/finding_classification/colonoscopy_sano.yaml +22 -0
  35. endoreg_db/data/_examples/finding_classification/colonoscopy_summary.yaml +53 -0
  36. endoreg_db/data/_examples/finding_classification/complication_generic.yaml +25 -0
  37. endoreg_db/data/_examples/finding_classification/examination_setting_generic.yaml +40 -0
  38. endoreg_db/data/_examples/finding_classification/histology_colo.yaml +51 -0
  39. endoreg_db/data/_examples/finding_classification/intervention_required.yaml +26 -0
  40. endoreg_db/data/_examples/finding_classification/medication_related.yaml +23 -0
  41. endoreg_db/data/_examples/finding_classification/visualized.yaml +33 -0
  42. endoreg_db/data/_examples/finding_classification_choice/bowel_preparation.yaml +78 -0
  43. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_circularity_default.yaml +32 -0
  44. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_jnet.yaml +15 -0
  45. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_kudo.yaml +23 -0
  46. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_lst.yaml +15 -0
  47. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_nice.yaml +17 -0
  48. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_paris.yaml +57 -0
  49. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_planarity_default.yaml +49 -0
  50. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_sano.yaml +14 -0
  51. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_surface_intact_default.yaml +36 -0
  52. endoreg_db/data/_examples/finding_classification_choice/colonoscopy_location.yaml +229 -0
  53. endoreg_db/data/_examples/finding_classification_choice/colonoscopy_not_complete_reason.yaml +19 -0
  54. endoreg_db/data/_examples/finding_classification_choice/colonoscopy_size.yaml +82 -0
  55. endoreg_db/data/_examples/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +15 -0
  56. endoreg_db/data/_examples/finding_classification_choice/complication_generic_types.yaml +15 -0
  57. endoreg_db/data/_examples/finding_classification_choice/examination_setting_generic_types.yaml +15 -0
  58. endoreg_db/data/_examples/finding_classification_choice/histology.yaml +24 -0
  59. endoreg_db/data/_examples/finding_classification_choice/histology_polyp.yaml +20 -0
  60. endoreg_db/data/_examples/finding_classification_choice/outcome.yaml +19 -0
  61. endoreg_db/data/_examples/finding_classification_choice/yes_no_na.yaml +11 -0
  62. endoreg_db/data/_examples/finding_classification_type/colonoscopy_basic.yaml +48 -0
  63. endoreg_db/data/_examples/finding_intervention/endoscopy.yaml +43 -0
  64. endoreg_db/data/_examples/finding_intervention/endoscopy_colonoscopy.yaml +168 -0
  65. endoreg_db/data/_examples/finding_intervention/endoscopy_egd.yaml +128 -0
  66. endoreg_db/data/_examples/finding_intervention/endoscopy_ercp.yaml +32 -0
  67. endoreg_db/data/_examples/finding_intervention/endoscopy_eus_lower.yaml +9 -0
  68. endoreg_db/data/_examples/finding_intervention/endoscopy_eus_upper.yaml +36 -0
  69. endoreg_db/data/_examples/finding_intervention_type/endoscopy.yaml +15 -0
  70. endoreg_db/data/_examples/finding_type/data.yaml +43 -0
  71. endoreg_db/data/_examples/requirement/age.yaml +26 -0
  72. endoreg_db/data/_examples/requirement/colonoscopy_baseline_austria.yaml +45 -0
  73. endoreg_db/data/_examples/requirement/disease_cardiovascular.yaml +79 -0
  74. endoreg_db/data/_examples/requirement/disease_classification_choice_cardiovascular.yaml +41 -0
  75. endoreg_db/data/_examples/requirement/disease_hepatology.yaml +12 -0
  76. endoreg_db/data/_examples/requirement/disease_misc.yaml +12 -0
  77. endoreg_db/data/_examples/requirement/disease_renal.yaml +96 -0
  78. endoreg_db/data/_examples/requirement/endoscopy_bleeding_risk.yaml +59 -0
  79. endoreg_db/data/_examples/requirement/event_cardiology.yaml +251 -0
  80. endoreg_db/data/_examples/requirement/event_requirements.yaml +145 -0
  81. endoreg_db/data/_examples/requirement/finding_colon_polyp.yaml +50 -0
  82. endoreg_db/data/_examples/requirement/gender.yaml +25 -0
  83. endoreg_db/data/_examples/requirement/lab_value.yaml +441 -0
  84. endoreg_db/data/_examples/requirement/medication.yaml +93 -0
  85. endoreg_db/data/_examples/requirement_operator/age.yaml +13 -0
  86. endoreg_db/data/_examples/requirement_operator/lab_operators.yaml +129 -0
  87. endoreg_db/data/_examples/requirement_operator/model_operators.yaml +96 -0
  88. endoreg_db/data/_examples/requirement_set/01_endoscopy_generic.yaml +48 -0
  89. endoreg_db/data/_examples/requirement_set/colonoscopy_austria_screening.yaml +57 -0
  90. endoreg_db/data/_examples/yaml_examples.xlsx +0 -0
  91. endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +4 -3
  92. endoreg_db/data/event_classification/data.yaml +4 -0
  93. endoreg_db/data/event_classification_choice/data.yaml +9 -0
  94. endoreg_db/data/finding_classification/colonoscopy_bowel_preparation.yaml +43 -70
  95. endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +22 -52
  96. endoreg_db/data/finding_classification/colonoscopy_location.yaml +31 -62
  97. endoreg_db/data/finding_classification/histology_colo.yaml +28 -36
  98. endoreg_db/data/requirement/colon_polyp_intervention.yaml +49 -0
  99. endoreg_db/data/requirement/coloreg_colon_polyp.yaml +49 -0
  100. endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +31 -12
  101. endoreg_db/data/requirement_set/01_laboratory.yaml +13 -0
  102. endoreg_db/data/requirement_set/02_endoscopy_bleeding_risk.yaml +46 -0
  103. endoreg_db/data/requirement_set/90_coloreg.yaml +178 -0
  104. endoreg_db/data/requirement_set/_old_ +109 -0
  105. endoreg_db/data/requirement_set_type/data.yaml +21 -0
  106. endoreg_db/data/setup_config.yaml +4 -4
  107. endoreg_db/data/tag/requirement_set_tags.yaml +21 -0
  108. endoreg_db/exceptions.py +5 -2
  109. endoreg_db/helpers/data_loader.py +1 -1
  110. endoreg_db/management/commands/create_model_meta_from_huggingface.py +21 -10
  111. endoreg_db/management/commands/create_multilabel_model_meta.py +299 -129
  112. endoreg_db/management/commands/import_video.py +9 -10
  113. endoreg_db/management/commands/import_video_with_classification.py +1 -1
  114. endoreg_db/management/commands/init_default_ai_model.py +1 -1
  115. endoreg_db/management/commands/list_routes.py +18 -0
  116. endoreg_db/management/commands/load_center_data.py +12 -12
  117. endoreg_db/management/commands/load_requirement_data.py +60 -31
  118. endoreg_db/management/commands/load_requirement_set_tags.py +95 -0
  119. endoreg_db/management/commands/setup_endoreg_db.py +3 -3
  120. endoreg_db/management/commands/storage_management.py +271 -203
  121. endoreg_db/migrations/0001_initial.py +1799 -1300
  122. endoreg_db/migrations/0002_requirementset_depends_on.py +18 -0
  123. endoreg_db/migrations/_old/0001_initial.py +1857 -0
  124. endoreg_db/migrations/_old/0004_employee_city_employee_post_code_employee_street_and_more.py +68 -0
  125. endoreg_db/migrations/_old/0004_remove_casetemplate_rules_and_more.py +77 -0
  126. endoreg_db/migrations/_old/0005_merge_20251111_1003.py +14 -0
  127. endoreg_db/migrations/_old/0006_sensitivemeta_anonymized_text_and_more.py +68 -0
  128. endoreg_db/migrations/_old/0007_remove_rule_attribute_dtype_remove_rule_rule_type_and_more.py +89 -0
  129. endoreg_db/migrations/_old/0008_remove_event_event_classification_and_more.py +27 -0
  130. endoreg_db/migrations/_old/0009_alter_modelmeta_options_and_more.py +21 -0
  131. endoreg_db/models/__init__.py +78 -123
  132. endoreg_db/models/administration/__init__.py +21 -42
  133. endoreg_db/models/administration/ai/active_model.py +2 -2
  134. endoreg_db/models/administration/ai/ai_model.py +7 -6
  135. endoreg_db/models/administration/case/__init__.py +1 -15
  136. endoreg_db/models/administration/case/case.py +3 -3
  137. endoreg_db/models/administration/case/case_template/__init__.py +2 -14
  138. endoreg_db/models/administration/case/case_template/case_template.py +2 -124
  139. endoreg_db/models/administration/case/case_template/case_template_rule.py +2 -268
  140. endoreg_db/models/administration/case/case_template/case_template_rule_value.py +2 -85
  141. endoreg_db/models/administration/case/case_template/case_template_type.py +2 -25
  142. endoreg_db/models/administration/center/center.py +33 -19
  143. endoreg_db/models/administration/center/center_product.py +12 -9
  144. endoreg_db/models/administration/center/center_resource.py +25 -19
  145. endoreg_db/models/administration/center/center_shift.py +21 -17
  146. endoreg_db/models/administration/center/center_waste.py +16 -8
  147. endoreg_db/models/administration/person/__init__.py +2 -0
  148. endoreg_db/models/administration/person/employee/employee.py +10 -5
  149. endoreg_db/models/administration/person/employee/employee_qualification.py +9 -4
  150. endoreg_db/models/administration/person/employee/employee_type.py +12 -6
  151. endoreg_db/models/administration/person/examiner/examiner.py +13 -11
  152. endoreg_db/models/administration/person/patient/__init__.py +2 -0
  153. endoreg_db/models/administration/person/patient/patient.py +103 -100
  154. endoreg_db/models/administration/person/patient/patient_external_id.py +37 -0
  155. endoreg_db/models/administration/person/person.py +4 -0
  156. endoreg_db/models/administration/person/profession/__init__.py +8 -4
  157. endoreg_db/models/administration/person/user/portal_user_information.py +11 -7
  158. endoreg_db/models/administration/product/product.py +20 -15
  159. endoreg_db/models/administration/product/product_material.py +17 -18
  160. endoreg_db/models/administration/product/product_weight.py +12 -8
  161. endoreg_db/models/administration/product/reference_product.py +23 -55
  162. endoreg_db/models/administration/qualification/qualification.py +7 -3
  163. endoreg_db/models/administration/qualification/qualification_type.py +7 -3
  164. endoreg_db/models/administration/shift/scheduled_days.py +8 -5
  165. endoreg_db/models/administration/shift/shift.py +16 -12
  166. endoreg_db/models/administration/shift/shift_type.py +23 -31
  167. endoreg_db/models/label/__init__.py +7 -8
  168. endoreg_db/models/label/annotation/image_classification.py +10 -9
  169. endoreg_db/models/label/annotation/video_segmentation_annotation.py +8 -5
  170. endoreg_db/models/label/label.py +15 -15
  171. endoreg_db/models/label/label_set.py +19 -6
  172. endoreg_db/models/label/label_type.py +1 -1
  173. endoreg_db/models/label/label_video_segment/_create_from_video.py +5 -8
  174. endoreg_db/models/label/label_video_segment/label_video_segment.py +76 -102
  175. endoreg_db/models/label/video_segmentation_label.py +4 -0
  176. endoreg_db/models/label/video_segmentation_labelset.py +4 -3
  177. endoreg_db/models/media/frame/frame.py +22 -22
  178. endoreg_db/models/media/pdf/raw_pdf.py +110 -182
  179. endoreg_db/models/media/pdf/report_file.py +25 -29
  180. endoreg_db/models/media/pdf/report_reader/report_reader_config.py +30 -46
  181. endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +23 -7
  182. endoreg_db/models/media/video/__init__.py +1 -0
  183. endoreg_db/models/media/video/create_from_file.py +48 -56
  184. endoreg_db/models/media/video/pipe_2.py +8 -9
  185. endoreg_db/models/media/video/video_file.py +150 -108
  186. endoreg_db/models/media/video/video_file_ai.py +288 -74
  187. endoreg_db/models/media/video/video_file_anonymize.py +38 -38
  188. endoreg_db/models/media/video/video_file_frames/__init__.py +3 -1
  189. endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +6 -8
  190. endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +7 -9
  191. endoreg_db/models/media/video/video_file_frames/_delete_frames.py +9 -8
  192. endoreg_db/models/media/video/video_file_frames/_extract_frames.py +38 -45
  193. endoreg_db/models/media/video/video_file_frames/_get_frame.py +6 -8
  194. endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +4 -18
  195. endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +4 -3
  196. endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +7 -6
  197. endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +6 -8
  198. endoreg_db/models/media/video/video_file_frames/_get_frames.py +6 -8
  199. endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +15 -25
  200. endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +26 -23
  201. endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +23 -14
  202. endoreg_db/models/media/video/video_file_io.py +109 -62
  203. endoreg_db/models/media/video/video_file_meta/get_crop_template.py +3 -3
  204. endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +5 -3
  205. endoreg_db/models/media/video/video_file_meta/get_fps.py +37 -34
  206. endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +19 -25
  207. endoreg_db/models/media/video/video_file_meta/text_meta.py +41 -38
  208. endoreg_db/models/media/video/video_file_meta/video_meta.py +14 -7
  209. endoreg_db/models/media/video/video_file_segments.py +24 -17
  210. endoreg_db/models/media/video/video_metadata.py +19 -35
  211. endoreg_db/models/media/video/video_processing.py +96 -95
  212. endoreg_db/models/medical/contraindication/__init__.py +13 -3
  213. endoreg_db/models/medical/disease.py +22 -16
  214. endoreg_db/models/medical/event.py +31 -18
  215. endoreg_db/models/medical/examination/__init__.py +13 -6
  216. endoreg_db/models/medical/examination/examination.py +17 -18
  217. endoreg_db/models/medical/examination/examination_indication.py +26 -25
  218. endoreg_db/models/medical/examination/examination_time.py +16 -6
  219. endoreg_db/models/medical/examination/examination_time_type.py +9 -6
  220. endoreg_db/models/medical/examination/examination_type.py +3 -4
  221. endoreg_db/models/medical/finding/finding.py +38 -39
  222. endoreg_db/models/medical/finding/finding_classification.py +37 -48
  223. endoreg_db/models/medical/finding/finding_intervention.py +27 -22
  224. endoreg_db/models/medical/finding/finding_type.py +13 -12
  225. endoreg_db/models/medical/hardware/endoscope.py +20 -26
  226. endoreg_db/models/medical/hardware/endoscopy_processor.py +2 -2
  227. endoreg_db/models/medical/laboratory/lab_value.py +62 -91
  228. endoreg_db/models/medical/medication/medication.py +22 -10
  229. endoreg_db/models/medical/medication/medication_indication.py +29 -3
  230. endoreg_db/models/medical/medication/medication_indication_type.py +25 -14
  231. endoreg_db/models/medical/medication/medication_intake_time.py +31 -19
  232. endoreg_db/models/medical/medication/medication_schedule.py +27 -16
  233. endoreg_db/models/medical/organ/__init__.py +15 -12
  234. endoreg_db/models/medical/patient/medication_examples.py +1 -5
  235. endoreg_db/models/medical/patient/patient_disease.py +20 -23
  236. endoreg_db/models/medical/patient/patient_event.py +19 -22
  237. endoreg_db/models/medical/patient/patient_examination.py +48 -54
  238. endoreg_db/models/medical/patient/patient_examination_indication.py +16 -14
  239. endoreg_db/models/medical/patient/patient_finding.py +122 -139
  240. endoreg_db/models/medical/patient/patient_finding_classification.py +44 -49
  241. endoreg_db/models/medical/patient/patient_finding_intervention.py +8 -19
  242. endoreg_db/models/medical/patient/patient_lab_sample.py +28 -23
  243. endoreg_db/models/medical/patient/patient_lab_value.py +82 -89
  244. endoreg_db/models/medical/patient/patient_medication.py +27 -38
  245. endoreg_db/models/medical/patient/patient_medication_schedule.py +28 -36
  246. endoreg_db/models/medical/risk/risk.py +7 -6
  247. endoreg_db/models/medical/risk/risk_type.py +8 -5
  248. endoreg_db/models/metadata/model_meta.py +60 -29
  249. endoreg_db/models/metadata/model_meta_logic.py +125 -18
  250. endoreg_db/models/metadata/pdf_meta.py +19 -24
  251. endoreg_db/models/metadata/sensitive_meta.py +102 -85
  252. endoreg_db/models/metadata/sensitive_meta_logic.py +192 -173
  253. endoreg_db/models/metadata/video_meta.py +51 -31
  254. endoreg_db/models/metadata/video_prediction_logic.py +16 -23
  255. endoreg_db/models/metadata/video_prediction_meta.py +29 -33
  256. endoreg_db/models/other/distribution/date_value_distribution.py +89 -29
  257. endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +21 -5
  258. endoreg_db/models/other/distribution/numeric_value_distribution.py +114 -53
  259. endoreg_db/models/other/distribution/single_categorical_value_distribution.py +4 -3
  260. endoreg_db/models/other/emission/emission_factor.py +18 -8
  261. endoreg_db/models/other/gender.py +10 -5
  262. endoreg_db/models/other/information_source.py +25 -25
  263. endoreg_db/models/other/material.py +9 -5
  264. endoreg_db/models/other/resource.py +6 -4
  265. endoreg_db/models/other/tag.py +10 -5
  266. endoreg_db/models/other/transport_route.py +13 -8
  267. endoreg_db/models/other/unit.py +10 -6
  268. endoreg_db/models/other/waste.py +6 -5
  269. endoreg_db/models/requirement/requirement.py +580 -272
  270. endoreg_db/models/requirement/requirement_error.py +85 -0
  271. endoreg_db/models/requirement/requirement_evaluation/evaluate_with_dependencies.py +268 -0
  272. endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +3 -6
  273. endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +90 -64
  274. endoreg_db/models/requirement/requirement_operator.py +36 -33
  275. endoreg_db/models/requirement/requirement_set.py +74 -57
  276. endoreg_db/models/state/__init__.py +4 -4
  277. endoreg_db/models/state/abstract.py +2 -2
  278. endoreg_db/models/state/anonymization.py +12 -0
  279. endoreg_db/models/state/audit_ledger.py +46 -47
  280. endoreg_db/models/state/label_video_segment.py +9 -0
  281. endoreg_db/models/state/raw_pdf.py +40 -46
  282. endoreg_db/models/state/sensitive_meta.py +6 -2
  283. endoreg_db/models/state/video.py +58 -53
  284. endoreg_db/models/upload_job.py +32 -55
  285. endoreg_db/models/utils.py +1 -2
  286. endoreg_db/root_urls.py +21 -2
  287. endoreg_db/serializers/__init__.py +0 -2
  288. endoreg_db/serializers/anonymization.py +18 -10
  289. endoreg_db/serializers/meta/report_meta.py +1 -1
  290. endoreg_db/serializers/meta/sensitive_meta_detail.py +63 -118
  291. endoreg_db/serializers/misc/file_overview.py +11 -99
  292. endoreg_db/serializers/requirements/requirement_sets.py +92 -22
  293. endoreg_db/serializers/video/segmentation.py +2 -1
  294. endoreg_db/serializers/video/video_processing_history.py +20 -5
  295. endoreg_db/services/anonymization.py +75 -73
  296. endoreg_db/services/lookup_service.py +37 -24
  297. endoreg_db/services/pdf_import.py +166 -68
  298. endoreg_db/services/storage_aware_video_processor.py +140 -114
  299. endoreg_db/services/video_import.py +193 -283
  300. endoreg_db/urls/__init__.py +7 -20
  301. endoreg_db/urls/media.py +108 -67
  302. endoreg_db/urls/root_urls.py +29 -0
  303. endoreg_db/utils/__init__.py +15 -5
  304. endoreg_db/utils/ai/multilabel_classification_net.py +116 -20
  305. endoreg_db/utils/case_generator/__init__.py +3 -0
  306. endoreg_db/utils/dataloader.py +88 -16
  307. endoreg_db/utils/defaults/set_default_center.py +32 -0
  308. endoreg_db/utils/names.py +22 -16
  309. endoreg_db/utils/permissions.py +2 -1
  310. endoreg_db/utils/pipelines/process_video_dir.py +1 -1
  311. endoreg_db/utils/requirement_operator_logic/model_evaluators.py +414 -127
  312. endoreg_db/utils/setup_config.py +8 -5
  313. endoreg_db/utils/storage.py +115 -0
  314. endoreg_db/utils/validate_endo_roi.py +8 -2
  315. endoreg_db/utils/video/ffmpeg_wrapper.py +184 -188
  316. endoreg_db/views/__init__.py +0 -10
  317. endoreg_db/views/anonymization/media_management.py +198 -163
  318. endoreg_db/views/anonymization/overview.py +4 -1
  319. endoreg_db/views/anonymization/validate.py +174 -40
  320. endoreg_db/views/media/__init__.py +2 -0
  321. endoreg_db/views/media/pdf_media.py +131 -152
  322. endoreg_db/views/media/sensitive_metadata.py +46 -6
  323. endoreg_db/views/media/video_media.py +89 -82
  324. endoreg_db/views/media/video_segments.py +2 -3
  325. endoreg_db/views/meta/sensitive_meta_detail.py +0 -63
  326. endoreg_db/views/patient/patient.py +5 -4
  327. endoreg_db/views/pdf/pdf_stream.py +20 -21
  328. endoreg_db/views/pdf/reimport.py +11 -32
  329. endoreg_db/views/requirement/evaluate.py +188 -187
  330. endoreg_db/views/requirement/lookup.py +17 -3
  331. endoreg_db/views/requirement/requirement_utils.py +89 -0
  332. endoreg_db/views/video/__init__.py +0 -2
  333. endoreg_db/views/video/correction.py +2 -2
  334. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.0.dist-info}/METADATA +7 -3
  335. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.0.dist-info}/RECORD +341 -245
  336. endoreg_db/models/administration/permissions/__init__.py +0 -44
  337. endoreg_db/models/media/video/video_file_frames.py +0 -0
  338. endoreg_db/models/metadata/frame_ocr_result.py +0 -0
  339. endoreg_db/models/rule/__init__.py +0 -13
  340. endoreg_db/models/rule/rule.py +0 -27
  341. endoreg_db/models/rule/rule_applicator.py +0 -224
  342. endoreg_db/models/rule/rule_attribute_dtype.py +0 -17
  343. endoreg_db/models/rule/rule_type.py +0 -20
  344. endoreg_db/models/rule/ruleset.py +0 -17
  345. endoreg_db/serializers/video/video_metadata.py +0 -105
  346. endoreg_db/urls/report.py +0 -48
  347. endoreg_db/urls/video.py +0 -61
  348. endoreg_db/utils/case_generator/case_generator.py +0 -159
  349. endoreg_db/utils/case_generator/utils.py +0 -30
  350. endoreg_db/views/report/__init__.py +0 -9
  351. endoreg_db/views/report/report_list.py +0 -112
  352. endoreg_db/views/report/report_with_secure_url.py +0 -28
  353. endoreg_db/views/report/start_examination.py +0 -7
  354. endoreg_db/views.py +0 -0
  355. /endoreg_db/data/{requirement_set → _examples/requirement_set}/endoscopy_bleeding_risk.yaml +0 -0
  356. /endoreg_db/migrations/{0002_add_video_correction_models.py → _old/0002_add_video_correction_models.py} +0 -0
  357. /endoreg_db/migrations/{0003_add_center_display_name.py → _old/0003_add_center_display_name.py} +0 -0
  358. /endoreg_db/{models/media/video/refactor_plan.md → views/pdf/pdf_stream_views.py} +0 -0
  359. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.0.dist-info}/WHEEL +0 -0
  360. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,12 +1,16 @@
1
- from django.db import models
1
+ import numbers
2
2
  from typing import TYPE_CHECKING, Optional
3
3
 
4
+ from django.db import models
5
+
4
6
  if TYPE_CHECKING:
7
+ from endoreg_db.utils.links.requirement_link import RequirementLinks # Added import
8
+
5
9
  from ...administration.person.patient import Patient
6
- from ..laboratory import LabValue
7
10
  from ...other.unit import Unit
11
+ from ..laboratory import LabValue
8
12
  from .patient_lab_sample import PatientLabSample
9
- from endoreg_db.utils.links.requirement_link import RequirementLinks # Added import
13
+
10
14
 
11
15
  class PatientLabValue(models.Model):
12
16
  """
@@ -18,50 +22,55 @@ class PatientLabValue(models.Model):
18
22
  value (float): The value of the lab value.
19
23
  date (datetime): The date of the lab value.
20
24
  """
21
- patient = models.ForeignKey('Patient', on_delete=models.CASCADE,
22
- related_name="lab_values", blank=True, null=True
23
- )
24
- lab_value = models.ForeignKey('LabValue', on_delete=models.CASCADE)
25
+
26
+ patient = models.ForeignKey("Patient", on_delete=models.CASCADE, related_name="lab_values", blank=True, null=True)
27
+ lab_value = models.ForeignKey("LabValue", on_delete=models.CASCADE)
25
28
  value = models.FloatField(blank=True, null=True)
26
29
  value_str = models.CharField(max_length=255, blank=True, null=True)
27
- sample: models.ForeignKey["PatientLabSample"] = models.ForeignKey(
28
- 'PatientLabSample', on_delete=models.CASCADE,
29
- blank=True, null=True,
30
- related_name='values'
31
- )
32
- datetime = models.DateTimeField(# if not set, use now
33
- auto_now_add=True
30
+ sample = models.ForeignKey("PatientLabSample", on_delete=models.CASCADE, blank=True, null=True, related_name="values")
31
+ datetime = models.DateTimeField( # if not set, use now
32
+ auto_now_add=True
34
33
  )
35
- normal_range = models.JSONField(
36
- default = dict
37
- )
38
- unit = models.ForeignKey('Unit', on_delete=models.CASCADE, blank=True, null=True)
34
+ normal_range = models.JSONField(default=dict)
35
+ unit = models.ForeignKey("Unit", on_delete=models.CASCADE, blank=True, null=True)
39
36
 
40
- if TYPE_CHECKING:
37
+ @property
38
+ def lab_value_safe(self) -> "LabValue":
39
+ """Returns the lab value, raises error if not set."""
40
+ if not self.lab_value:
41
+ raise ValueError("Lab value is not set.")
42
+ return self.lab_value
43
+
44
+ @property
45
+ def patient_safe(self) -> "Patient":
46
+ """Returns the patient, raises error if not set."""
47
+ if not self.patient:
48
+ raise ValueError("Patient is not set.")
49
+ return self.patient
41
50
 
42
- patient: "Patient"
43
- lab_value: "LabValue"
44
- unit: "Unit"
45
- sample: "PatientLabSample"
51
+ if TYPE_CHECKING:
52
+ patient: models.ForeignKey["Patient|None"]
53
+ lab_value: models.ForeignKey["LabValue"]
54
+ unit: models.ForeignKey["Unit|None"]
55
+ sample: models.ForeignKey["PatientLabSample|None"]
56
+ normal_range: models.JSONField[dict]
46
57
 
47
58
  @classmethod
48
59
  def create_lab_value_by_sample(
49
- cls, sample:"PatientLabSample", lab_value_name:str,
50
- value:Optional[float]=None, value_str:Optional[str]=None,
51
- unit:Optional["Unit"]=None
60
+ cls, sample: "PatientLabSample", lab_value_name: str, value: Optional[float] = None, value_str: Optional[str] = None, unit: Optional["Unit"] = None
52
61
  ):
53
62
  from ..laboratory import LabValue
63
+
54
64
  patient = sample.patient
55
65
  lab_value = LabValue.objects.get(name=lab_value_name)
56
66
 
57
-
58
67
  pat_lab_val = cls.objects.create(
59
- patient = patient,
60
- lab_value = lab_value,
61
- value = value,
62
- value_str = value_str,
63
- sample = sample,
64
- unit = unit,
68
+ patient=patient,
69
+ lab_value=lab_value,
70
+ value=value,
71
+ value_str=value_str,
72
+ sample=sample,
73
+ unit=unit,
65
74
  )
66
75
 
67
76
  pat_lab_val.save()
@@ -69,44 +78,41 @@ class PatientLabValue(models.Model):
69
78
  return pat_lab_val
70
79
 
71
80
  def __str__(self):
72
- formatted_datetime = self.datetime.strftime('%Y-%m-%d %H:%M')
81
+ formatted_datetime = self.datetime.strftime("%Y-%m-%d %H:%M")
73
82
  # normal_range = self.get_normal_range()
74
- norm_range_string = f'[{self.normal_range.get("min", "")} - {self.normal_range.get("max", "")}]'
75
- _str = f'{self.lab_value} - {self.value} {self.unit} - {norm_range_string} ({formatted_datetime})'
83
+ norm_range_string = f"[{self.normal_range.get('min', '')} - {self.normal_range.get('max', '')}]"
84
+ _str = f"{self.lab_value} - {self.value} {self.unit} - {norm_range_string} ({formatted_datetime})"
76
85
  return _str
77
-
86
+
78
87
  def get_normal_range(self):
79
- lab_value = self.lab_value
80
- patient = self.patient
88
+ lab_value = self.lab_value_safe
89
+ patient = self.patient_safe
81
90
 
82
- age = patient.age()
91
+ age = patient.age_safe
83
92
  gender = patient.gender
84
93
 
85
- normal_range_dict = lab_value.get_normal_range(
86
- age,gender
87
- )
94
+ normal_range_dict = lab_value.get_normal_range(age, gender)
88
95
  return normal_range_dict
89
96
 
90
-
91
- def set_min_norm_value(self, value, save = True):
97
+ def set_min_norm_value(self, value, save=True):
92
98
  self.normal_range["min"] = value
93
99
  if save:
94
100
  self.save()
95
101
 
96
- def set_max_norm_value(self, value, save = True):
102
+ def set_max_norm_value(self, value, save=True):
97
103
  self.normal_range["max"] = value
98
104
  if save:
99
105
  self.save()
100
106
 
101
107
  def set_norm_values_from_default(self):
102
-
103
108
  normal_range_dict = self.get_normal_range()
104
- self.set_min_norm_value(normal_range_dict["min"], save = False)
105
- self.set_max_norm_value(normal_range_dict["max"], save = False)
109
+ self.set_min_norm_value(normal_range_dict["min"], save=False)
110
+ self.set_max_norm_value(normal_range_dict["max"], save=False)
106
111
  self.save()
107
112
 
108
113
  def set_unit_from_default(self):
109
- self.unit = self.lab_value.default_unit
114
+ _default_unit = self.lab_value_safe.default_unit
115
+ self.unit = _default_unit
110
116
  self.save()
111
117
 
112
118
  def get_value(self):
@@ -114,65 +120,57 @@ class PatientLabValue(models.Model):
114
120
  return self.value
115
121
  else:
116
122
  return self.value_str
117
-
123
+
118
124
  def get_value_field_name(self):
119
125
  if self.value:
120
126
  return "value"
121
127
  else:
122
128
  return "value_str"
123
-
129
+
124
130
  # customize save method so that if a numeric value exists, we round it to the precision of the lab value
125
131
  def save(self, *args, **kwargs):
126
- if self.value:
127
- precision = self.lab_value.numeric_precision
128
- self.value = round(self.value, precision)
132
+ if self.value is not None:
133
+ # only attempt rounding for real numeric types (ints/floats/compatible)
134
+
135
+ precision = getattr(self.lab_value_safe, "numeric_precision", None)
136
+ if isinstance(self.value, numbers.Real) and precision is not None:
137
+ # ensure a plain float is passed to built-in round to satisfy type checkers
138
+ self.value = round(float(self.value), int(precision))
129
139
  super().save(*args, **kwargs)
130
140
 
131
- def set_value_by_distribution(self, distribution=None, save = True):
132
- from ...administration.person.patient import Patient
133
- from ..laboratory import LabValue
141
+ def set_value_by_distribution(self, distribution=None, save=True):
142
+ import warnings
143
+
134
144
  from ...other.distribution import (
135
145
  DateValueDistribution,
136
- SingleCategoricalValueDistribution,
137
- NumericValueDistribution,
138
146
  MultipleCategoricalValueDistribution,
139
- )
140
- import warnings
141
-
142
- patient:Patient = self.patient
147
+ NumericValueDistribution,
148
+ SingleCategoricalValueDistribution,
149
+ )
143
150
 
144
- lab_value:LabValue = self.lab_value
151
+ patient = self.patient_safe
152
+ lab_value = self.lab_value_safe
145
153
 
146
- assert self.lab_value, "Lab value must be set to set value by distribution"
147
- self.unit = self.lab_value.default_unit
154
+ self.unit = self.lab_value_safe.default_unit
148
155
 
149
156
  if not distribution:
150
157
  distribution = lab_value.get_default_default_distribution()
151
158
 
152
159
  if not distribution:
153
- warnings.warn(
154
- f"No distribution set for lab value {lab_value}, assuming uniform numeric distribution based on normal values"
155
- )
160
+ warnings.warn(f"No distribution set for lab value {lab_value}, assuming uniform numeric distribution based on normal values")
156
161
 
157
162
  if not self.normal_range.get("min", None) or not self.normal_range.get("max", None):
158
163
  self.set_norm_values_from_default()
159
-
160
- self.normal_range:dict
161
164
  _min = self.normal_range.get("min", 0.0001)
162
165
  _max = self.normal_range.get("max", 100)
163
- _name = "auto-" + self.lab_value.name + "-distribution-default-uniform"
164
- distribution = NumericValueDistribution(
165
- name = _name,
166
- min_descriptor = _min,
167
- max_max_desciptor = _max,
168
- distribution_type = "uniform"
169
- )
166
+ _name = "auto-" + self.lab_value_safe.name + "-distribution-default-uniform"
167
+ distribution = NumericValueDistribution(name=_name, min_descriptor=_min, max_max_desciptor=_max, distribution_type="uniform")
170
168
 
171
169
  value = distribution.generate_value(lab_value=lab_value, patient=patient)
172
170
  self.value = value
173
171
  if save:
174
172
  self.save()
175
-
173
+
176
174
  return value
177
175
 
178
176
  if isinstance(distribution, SingleCategoricalValueDistribution):
@@ -181,17 +179,14 @@ class PatientLabValue(models.Model):
181
179
  if save:
182
180
  self.save()
183
181
  return value
184
-
182
+
185
183
  elif isinstance(distribution, NumericValueDistribution):
186
- value = distribution.generate_value(
187
- lab_value=lab_value,
188
- patient=patient
189
- )
184
+ value = distribution.generate_value(lab_value=lab_value, patient=patient)
190
185
  self.value = value
191
186
  if save:
192
187
  self.save()
193
188
  return value
194
-
189
+
195
190
  elif isinstance(distribution, MultipleCategoricalValueDistribution):
196
191
  value = distribution.generate_value()
197
192
  self.value_str = value
@@ -216,7 +211,5 @@ class PatientLabValue(models.Model):
216
211
  from endoreg_db.utils.links.requirement_link import RequirementLinks
217
212
 
218
213
  return RequirementLinks(
219
- patient_lab_values=[self] # Include the lab value itself
214
+ patient_lab_values=[self] # Include the lab value itself
220
215
  )
221
-
222
-
@@ -1,12 +1,14 @@
1
+ from typing import TYPE_CHECKING, List, Optional, cast # Added List
2
+
1
3
  from django.db import models
2
- from typing import TYPE_CHECKING, Optional, List # Added List
3
4
 
4
5
  # Added imports for type hints
5
6
  if TYPE_CHECKING:
7
+ from ....utils.links.requirement_link import RequirementLinks # Added RequirementLinks
6
8
  from ...administration.person.patient import Patient
7
- from ..medication import MedicationIndication, Medication, MedicationIntakeTime
8
9
  from ...other.unit import Unit
9
- from ....utils.links.requirement_link import RequirementLinks # Added RequirementLinks
10
+ from ..medication import Medication, MedicationIndication, MedicationIntakeTime
11
+
10
12
 
11
13
  class PatientMedication(models.Model):
12
14
  """
@@ -14,42 +16,32 @@ class PatientMedication(models.Model):
14
16
 
15
17
  Links a patient to a medication, its indication, dosage, intake times, and unit.
16
18
  """
19
+
17
20
  patient = models.ForeignKey("Patient", on_delete=models.CASCADE)
18
- medication_indication = models.ForeignKey(
19
- "MedicationIndication", on_delete=models.CASCADE,
20
- related_name="indication_patient_medications", null=True
21
- )
21
+ medication_indication = models.ForeignKey("MedicationIndication", on_delete=models.CASCADE, related_name="indication_patient_medications", null=True)
22
22
 
23
- medication = models.ForeignKey(
24
- 'Medication', on_delete=models.CASCADE,
25
- blank=True,
26
- related_name='medication_patient_medications'
27
- )
23
+ medication = models.ForeignKey("Medication", on_delete=models.CASCADE, blank=True, related_name="medication_patient_medications")
28
24
 
29
25
  intake_times = models.ManyToManyField(
30
- 'MedicationIntakeTime',
31
- related_name='intake_time_patient_medications',
26
+ "MedicationIntakeTime",
27
+ related_name="intake_time_patient_medications",
32
28
  blank=True,
33
29
  )
34
30
 
35
- unit = models.ForeignKey(
36
- 'Unit', on_delete=models.CASCADE,
37
- null=True, blank=True
38
- )
39
- dosage = models.JSONField(
40
- null=True, blank=True
41
- )
31
+ unit = models.ForeignKey("Unit", on_delete=models.CASCADE, null=True, blank=True)
32
+ dosage = models.JSONField(null=True, blank=True)
42
33
  active = models.BooleanField(default=True)
43
34
 
44
35
  objects = models.Manager()
45
36
 
46
37
  if TYPE_CHECKING: # Added type hints block
47
- patient: "Patient"
48
- medication_indication: Optional["MedicationIndication"]
49
- medication: Optional["Medication"]
50
- intake_times: models.QuerySet["MedicationIntakeTime"]
51
- unit: Optional["Unit"]
52
- dosage: Optional[dict]
38
+ patient: models.ForeignKey["Patient"]
39
+ medication_indication: models.ForeignKey["MedicationIndication|None"]
40
+ medication: models.ForeignKey["Medication|None"]
41
+
42
+ intake_times = cast(models.manager.RelatedManager["MedicationIntakeTime"], intake_times)
43
+ unit: models.ForeignKey["Unit|None"]
44
+ dosage = cast(models.JSONField, dosage)
53
45
 
54
46
  @property
55
47
  def links(self) -> "RequirementLinks":
@@ -58,11 +50,11 @@ class PatientMedication(models.Model):
58
50
  This is used during requirement evaluation.
59
51
  """
60
52
  from ....utils.links.requirement_link import RequirementLinks
61
-
53
+
62
54
  meds: List["Medication"] = []
63
55
  if self.medication:
64
56
  meds.append(self.medication)
65
-
57
+
66
58
  indications: List["MedicationIndication"] = []
67
59
  if self.medication_indication:
68
60
  indications.append(self.medication_indication)
@@ -73,23 +65,21 @@ class PatientMedication(models.Model):
73
65
  medications=meds,
74
66
  medication_indications=indications,
75
67
  medication_intake_times=intake_times_list,
76
- patient_medications=[self] # Include self in patient_medications
68
+ patient_medications=[self], # Include self in patient_medications
77
69
  )
78
70
 
79
71
  class Meta:
80
- verbose_name = 'Patient Medication'
81
- verbose_name_plural = 'Patient Medications'
72
+ verbose_name = "Patient Medication"
73
+ verbose_name_plural = "Patient Medications"
82
74
 
83
75
  @classmethod
84
- def create_by_patient_and_indication(cls, patient, medication_indication):
76
+ def create_by_patient_and_indication(cls, patient, medication_indication: "MedicationIndication"):
85
77
  """Creates a PatientMedication instance linking a patient and an indication."""
86
- from ..medication import MedicationIndication
87
- medication_indication: MedicationIndication
78
+
88
79
  patient_medication = cls.objects.create(patient=patient, medication_indication=medication_indication)
89
80
  patient_medication.save()
90
-
91
- return patient_medication
92
81
 
82
+ return patient_medication
93
83
 
94
84
  def __str__(self):
95
85
  """Returns a string representation including medication, indication, dosage, and intake times."""
@@ -101,4 +91,3 @@ class PatientMedication(models.Model):
101
91
  out += f"{intake_time} - "
102
92
 
103
93
  return out
104
-
@@ -1,32 +1,30 @@
1
1
  from django.db import models
2
- from typing import TYPE_CHECKING, List # Added List
2
+ from typing import TYPE_CHECKING, List, cast # Added List
3
3
  from datetime import datetime as dt
4
4
 
5
5
  if TYPE_CHECKING:
6
6
  from ...administration.person.patient import Patient
7
7
  from .patient_medication import PatientMedication
8
8
  from ..medication import MedicationSchedule
9
- from ....utils.links.requirement_link import RequirementLinks # Added
10
- from ..medication import Medication, MedicationIndication, MedicationIntakeTime # Added
9
+ from ....utils.links.requirement_link import RequirementLinks # Added
10
+ from ..medication import Medication, MedicationIndication, MedicationIntakeTime # Added
11
11
 
12
12
 
13
13
  class PatientMedicationSchedule(models.Model):
14
14
  """
15
15
  Represents a collection of medications associated with a patient, forming their schedule.
16
16
  """
17
- patient = models.ForeignKey("Patient", on_delete= models.CASCADE)
18
- medication = models.ManyToManyField(
19
- 'PatientMedication',
20
- related_name='patient_medication_schedules',
21
- blank=True
22
- )
17
+
18
+ patient = models.ForeignKey("Patient", on_delete=models.CASCADE)
19
+ medication = models.ManyToManyField("PatientMedication", related_name="patient_medication_schedules", blank=True)
23
20
 
24
21
  created_at = models.DateTimeField(auto_now_add=True)
25
22
  updated_at = models.DateTimeField(auto_now=True)
26
23
 
27
24
  if TYPE_CHECKING:
28
- patient: "Patient"
29
- medication: models.QuerySet["PatientMedication"]
25
+ patient: models.ForeignKey["Patient"]
26
+
27
+ medication = cast(models.manager.RelatedManager["PatientMedication"], medication)
30
28
 
31
29
  @property
32
30
  def links(self) -> "RequirementLinks":
@@ -38,12 +36,12 @@ class PatientMedicationSchedule(models.Model):
38
36
  aggregated_medications: List["Medication"] = []
39
37
  aggregated_medication_indications: List["MedicationIndication"] = []
40
38
  aggregated_medication_intake_times: List["MedicationIntakeTime"] = []
41
-
39
+
42
40
  patient_meds_in_schedule: List["PatientMedication"] = list(self.medication.all())
43
41
 
44
42
  for pm_instance in patient_meds_in_schedule:
45
- pm_links_obj = pm_instance.links
46
-
43
+ pm_links_obj = pm_instance.links
44
+
47
45
  aggregated_medications.extend(pm_links_obj.medications)
48
46
  aggregated_medication_indications.extend(pm_links_obj.medication_indications)
49
47
  aggregated_medication_intake_times.extend(pm_links_obj.medication_intake_times)
@@ -53,13 +51,13 @@ class PatientMedicationSchedule(models.Model):
53
51
  medication_indications=list(set(aggregated_medication_indications)),
54
52
  medication_intake_times=list(set(aggregated_medication_intake_times)),
55
53
  patient_medications=patient_meds_in_schedule,
56
- patient_medication_schedules=[self]
54
+ patient_medication_schedules=[self],
57
55
  )
58
56
 
59
57
  def __str__(self):
60
58
  """Returns a string representation including the patient and associated medications."""
61
- return f'{self.patient} - {self.medication.all()}'
62
-
59
+ return f"{self.patient} - {self.medication.all()}"
60
+
63
61
  @classmethod
64
62
  def create_by_patient_and_indication_type(cls, patient, indication_type):
65
63
  """Creates a schedule and adds a medication based on a random indication of a given type."""
@@ -76,7 +74,7 @@ class PatientMedicationSchedule(models.Model):
76
74
  patient_medication_schedule.save()
77
75
 
78
76
  return patient_medication_schedule
79
-
77
+
80
78
  @classmethod
81
79
  def create_by_patient_and_indication(cls, patient, medication_indication):
82
80
  """Creates a schedule and adds a medication based on a specific indication."""
@@ -84,7 +82,6 @@ class PatientMedicationSchedule(models.Model):
84
82
  from .patient_medication import PatientMedication
85
83
  from ...administration.person.patient import Patient
86
84
 
87
-
88
85
  assert isinstance(medication_indication, MedicationIndication)
89
86
  assert isinstance(patient, Patient)
90
87
  patient_medication_schedule = cls.objects.create(patient=patient)
@@ -95,17 +92,17 @@ class PatientMedicationSchedule(models.Model):
95
92
  patient_medication_schedule.save()
96
93
 
97
94
  return patient_medication_schedule
98
-
95
+
99
96
  def create_patient_medication_from_medication_schedule(
100
- self,
101
- medication_schedule: "MedicationSchedule",
102
- medication_indication=None,
103
- start_date=None,
104
- ):
97
+ self,
98
+ medication_schedule: "MedicationSchedule",
99
+ medication_indication=None,
100
+ start_date=None,
101
+ ):
105
102
  """Creates and adds a PatientMedication based on a generic MedicationSchedule template."""
106
-
103
+
107
104
  from .patient_medication import PatientMedication
108
-
105
+
109
106
  if not start_date:
110
107
  start_date = dt.now()
111
108
 
@@ -115,22 +112,17 @@ class PatientMedicationSchedule(models.Model):
115
112
  intake_times = medication_schedule.get_intake_times()
116
113
 
117
114
  patient_medication = PatientMedication.objects.create(
118
- patient=self.patient,
119
- medication=drug,
120
- medication_indication=medication_indication,
121
- unit=unit,
122
- dosage=dosage
115
+ patient=self.patient, medication=drug, medication_indication=medication_indication, unit=unit, dosage=dosage
123
116
  )
124
117
 
125
118
  patient_medication.intake_times.set(intake_times)
126
119
  patient_medication.save()
127
120
 
128
121
  self.medication.add(patient_medication)
129
- self.save()
122
+ self.save()
130
123
 
131
124
  return patient_medication
132
-
133
-
125
+
134
126
  def get_patient_medication(self):
135
127
  """Returns all PatientMedication instances associated with this schedule."""
136
- return self.medication.all()
128
+ return self.medication.all()
@@ -1,15 +1,16 @@
1
+ from typing import TYPE_CHECKING
2
+
1
3
  from django.db import models
2
- from typing import List, TYPE_CHECKING
3
4
 
4
5
 
5
6
  class RiskManager(models.Manager):
6
7
  def get_by_natural_key(self, name):
7
8
  """
8
9
  Retrieve a risk instance using its natural key.
9
-
10
+
10
11
  Args:
11
12
  name: The unique name identifying the risk instance.
12
-
13
+
13
14
  Returns:
14
15
  The risk instance with the matching name.
15
16
  """
@@ -49,14 +50,14 @@ class Risk(models.Model):
49
50
  objects = RiskManager()
50
51
 
51
52
  if TYPE_CHECKING:
52
- from endoreg_db.models.risk.risk_type import RiskType
53
+ from endoreg_db.models import RiskType
53
54
 
54
55
  risk_types: RiskType
55
56
 
56
57
  def natural_key(self):
57
58
  """
58
59
  Return a tuple containing the natural key of the risk instance.
59
-
60
+
60
61
  The tuple consists of the unique 'name' attribute, which enables natural key lookups
61
62
  and serialization within Django.
62
63
  """
@@ -65,7 +66,7 @@ class Risk(models.Model):
65
66
  def __str__(self):
66
67
  """
67
68
  Return the string representation of the risk.
68
-
69
+
69
70
  Returns:
70
71
  str: The risk's name.
71
72
  """
@@ -1,15 +1,18 @@
1
- from django.db import models
2
1
  from typing import TYPE_CHECKING
3
2
 
3
+ from django.db import models
4
+
5
+ # Deorecate ?
6
+
4
7
 
5
8
  class RiskTypeManager(models.Manager):
6
9
  def get_by_natural_key(self, name):
7
10
  """
8
11
  Retrieves a RiskType instance using its natural key.
9
-
12
+
10
13
  Args:
11
14
  name (str): The unique name identifying the RiskType instance.
12
-
15
+
13
16
  Returns:
14
17
  RiskType: The matching instance with the provided name.
15
18
  """
@@ -31,14 +34,14 @@ class RiskType(models.Model):
31
34
  objects = RiskTypeManager()
32
35
 
33
36
  if TYPE_CHECKING:
34
- from endoreg_db.models.risk.risk import Risk
37
+ from endoreg_db.models import Risk
35
38
 
36
39
  risks: models.QuerySet[Risk]
37
40
 
38
41
  def natural_key(self):
39
42
  """
40
43
  Return the natural key for this risk type.
41
-
44
+
42
45
  This method returns a tuple containing only the risk type's unique name, which is used
43
46
  to identify the instance naturally.
44
47
  """