endoreg-db 0.8.4.4__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 (372) 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_ai_model_data.py +2 -1
  117. endoreg_db/management/commands/load_center_data.py +12 -12
  118. endoreg_db/management/commands/load_requirement_data.py +60 -31
  119. endoreg_db/management/commands/load_requirement_set_tags.py +95 -0
  120. endoreg_db/management/commands/setup_endoreg_db.py +14 -10
  121. endoreg_db/management/commands/storage_management.py +271 -203
  122. endoreg_db/migrations/0001_initial.py +1799 -1300
  123. endoreg_db/migrations/0002_requirementset_depends_on.py +18 -0
  124. endoreg_db/migrations/_old/0001_initial.py +1857 -0
  125. endoreg_db/migrations/_old/0004_employee_city_employee_post_code_employee_street_and_more.py +68 -0
  126. endoreg_db/migrations/_old/0004_remove_casetemplate_rules_and_more.py +77 -0
  127. endoreg_db/migrations/_old/0005_merge_20251111_1003.py +14 -0
  128. endoreg_db/migrations/_old/0006_sensitivemeta_anonymized_text_and_more.py +68 -0
  129. endoreg_db/migrations/_old/0007_remove_rule_attribute_dtype_remove_rule_rule_type_and_more.py +89 -0
  130. endoreg_db/migrations/_old/0008_remove_event_event_classification_and_more.py +27 -0
  131. endoreg_db/migrations/_old/0009_alter_modelmeta_options_and_more.py +21 -0
  132. endoreg_db/models/__init__.py +78 -123
  133. endoreg_db/models/administration/__init__.py +21 -42
  134. endoreg_db/models/administration/ai/active_model.py +2 -2
  135. endoreg_db/models/administration/ai/ai_model.py +7 -6
  136. endoreg_db/models/administration/case/__init__.py +1 -15
  137. endoreg_db/models/administration/case/case.py +3 -3
  138. endoreg_db/models/administration/case/case_template/__init__.py +2 -14
  139. endoreg_db/models/administration/case/case_template/case_template.py +2 -124
  140. endoreg_db/models/administration/case/case_template/case_template_rule.py +2 -268
  141. endoreg_db/models/administration/case/case_template/case_template_rule_value.py +2 -85
  142. endoreg_db/models/administration/case/case_template/case_template_type.py +2 -25
  143. endoreg_db/models/administration/center/center.py +33 -19
  144. endoreg_db/models/administration/center/center_product.py +12 -9
  145. endoreg_db/models/administration/center/center_resource.py +25 -19
  146. endoreg_db/models/administration/center/center_shift.py +21 -17
  147. endoreg_db/models/administration/center/center_waste.py +16 -8
  148. endoreg_db/models/administration/person/__init__.py +2 -0
  149. endoreg_db/models/administration/person/employee/employee.py +10 -5
  150. endoreg_db/models/administration/person/employee/employee_qualification.py +9 -4
  151. endoreg_db/models/administration/person/employee/employee_type.py +12 -6
  152. endoreg_db/models/administration/person/examiner/examiner.py +13 -11
  153. endoreg_db/models/administration/person/patient/__init__.py +2 -0
  154. endoreg_db/models/administration/person/patient/patient.py +103 -100
  155. endoreg_db/models/administration/person/patient/patient_external_id.py +37 -0
  156. endoreg_db/models/administration/person/person.py +4 -0
  157. endoreg_db/models/administration/person/profession/__init__.py +8 -4
  158. endoreg_db/models/administration/person/user/portal_user_information.py +11 -7
  159. endoreg_db/models/administration/product/product.py +20 -15
  160. endoreg_db/models/administration/product/product_material.py +17 -18
  161. endoreg_db/models/administration/product/product_weight.py +12 -8
  162. endoreg_db/models/administration/product/reference_product.py +23 -55
  163. endoreg_db/models/administration/qualification/qualification.py +7 -3
  164. endoreg_db/models/administration/qualification/qualification_type.py +7 -3
  165. endoreg_db/models/administration/shift/scheduled_days.py +8 -5
  166. endoreg_db/models/administration/shift/shift.py +16 -12
  167. endoreg_db/models/administration/shift/shift_type.py +23 -31
  168. endoreg_db/models/label/__init__.py +7 -8
  169. endoreg_db/models/label/annotation/image_classification.py +10 -9
  170. endoreg_db/models/label/annotation/video_segmentation_annotation.py +8 -5
  171. endoreg_db/models/label/label.py +15 -15
  172. endoreg_db/models/label/label_set.py +19 -6
  173. endoreg_db/models/label/label_type.py +1 -1
  174. endoreg_db/models/label/label_video_segment/_create_from_video.py +5 -8
  175. endoreg_db/models/label/label_video_segment/label_video_segment.py +76 -102
  176. endoreg_db/models/label/video_segmentation_label.py +4 -0
  177. endoreg_db/models/label/video_segmentation_labelset.py +4 -3
  178. endoreg_db/models/media/frame/frame.py +22 -22
  179. endoreg_db/models/media/pdf/raw_pdf.py +249 -177
  180. endoreg_db/models/media/pdf/report_file.py +25 -29
  181. endoreg_db/models/media/pdf/report_reader/report_reader_config.py +30 -46
  182. endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +23 -7
  183. endoreg_db/models/media/video/__init__.py +1 -0
  184. endoreg_db/models/media/video/create_from_file.py +48 -56
  185. endoreg_db/models/media/video/pipe_1.py +30 -33
  186. endoreg_db/models/media/video/pipe_2.py +8 -9
  187. endoreg_db/models/media/video/video_file.py +359 -204
  188. endoreg_db/models/media/video/video_file_ai.py +288 -74
  189. endoreg_db/models/media/video/video_file_anonymize.py +38 -38
  190. endoreg_db/models/media/video/video_file_frames/__init__.py +3 -1
  191. endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +6 -8
  192. endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +7 -9
  193. endoreg_db/models/media/video/video_file_frames/_delete_frames.py +9 -8
  194. endoreg_db/models/media/video/video_file_frames/_extract_frames.py +38 -45
  195. endoreg_db/models/media/video/video_file_frames/_get_frame.py +6 -8
  196. endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +4 -18
  197. endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +4 -3
  198. endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +7 -6
  199. endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +6 -8
  200. endoreg_db/models/media/video/video_file_frames/_get_frames.py +6 -8
  201. endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +15 -25
  202. endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +26 -23
  203. endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +23 -14
  204. endoreg_db/models/media/video/video_file_io.py +109 -62
  205. endoreg_db/models/media/video/video_file_meta/get_crop_template.py +3 -3
  206. endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +5 -3
  207. endoreg_db/models/media/video/video_file_meta/get_fps.py +37 -34
  208. endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +19 -25
  209. endoreg_db/models/media/video/video_file_meta/text_meta.py +41 -38
  210. endoreg_db/models/media/video/video_file_meta/video_meta.py +14 -7
  211. endoreg_db/models/media/video/video_file_segments.py +24 -17
  212. endoreg_db/models/media/video/video_metadata.py +19 -35
  213. endoreg_db/models/media/video/video_processing.py +96 -95
  214. endoreg_db/models/medical/contraindication/__init__.py +13 -3
  215. endoreg_db/models/medical/disease.py +22 -16
  216. endoreg_db/models/medical/event.py +31 -18
  217. endoreg_db/models/medical/examination/__init__.py +13 -6
  218. endoreg_db/models/medical/examination/examination.py +17 -18
  219. endoreg_db/models/medical/examination/examination_indication.py +26 -25
  220. endoreg_db/models/medical/examination/examination_time.py +16 -6
  221. endoreg_db/models/medical/examination/examination_time_type.py +9 -6
  222. endoreg_db/models/medical/examination/examination_type.py +3 -4
  223. endoreg_db/models/medical/finding/finding.py +38 -39
  224. endoreg_db/models/medical/finding/finding_classification.py +37 -48
  225. endoreg_db/models/medical/finding/finding_intervention.py +27 -22
  226. endoreg_db/models/medical/finding/finding_type.py +13 -12
  227. endoreg_db/models/medical/hardware/endoscope.py +20 -26
  228. endoreg_db/models/medical/hardware/endoscopy_processor.py +2 -2
  229. endoreg_db/models/medical/laboratory/lab_value.py +62 -91
  230. endoreg_db/models/medical/medication/medication.py +22 -10
  231. endoreg_db/models/medical/medication/medication_indication.py +29 -3
  232. endoreg_db/models/medical/medication/medication_indication_type.py +25 -14
  233. endoreg_db/models/medical/medication/medication_intake_time.py +31 -19
  234. endoreg_db/models/medical/medication/medication_schedule.py +27 -16
  235. endoreg_db/models/medical/organ/__init__.py +15 -12
  236. endoreg_db/models/medical/patient/medication_examples.py +1 -5
  237. endoreg_db/models/medical/patient/patient_disease.py +20 -23
  238. endoreg_db/models/medical/patient/patient_event.py +19 -22
  239. endoreg_db/models/medical/patient/patient_examination.py +48 -54
  240. endoreg_db/models/medical/patient/patient_examination_indication.py +16 -14
  241. endoreg_db/models/medical/patient/patient_finding.py +122 -139
  242. endoreg_db/models/medical/patient/patient_finding_classification.py +44 -49
  243. endoreg_db/models/medical/patient/patient_finding_intervention.py +8 -19
  244. endoreg_db/models/medical/patient/patient_lab_sample.py +28 -23
  245. endoreg_db/models/medical/patient/patient_lab_value.py +82 -89
  246. endoreg_db/models/medical/patient/patient_medication.py +27 -38
  247. endoreg_db/models/medical/patient/patient_medication_schedule.py +28 -36
  248. endoreg_db/models/medical/risk/risk.py +7 -6
  249. endoreg_db/models/medical/risk/risk_type.py +8 -5
  250. endoreg_db/models/metadata/model_meta.py +60 -29
  251. endoreg_db/models/metadata/model_meta_logic.py +139 -18
  252. endoreg_db/models/metadata/pdf_meta.py +19 -24
  253. endoreg_db/models/metadata/sensitive_meta.py +102 -85
  254. endoreg_db/models/metadata/sensitive_meta_logic.py +383 -43
  255. endoreg_db/models/metadata/video_meta.py +51 -31
  256. endoreg_db/models/metadata/video_prediction_logic.py +16 -23
  257. endoreg_db/models/metadata/video_prediction_meta.py +29 -33
  258. endoreg_db/models/other/distribution/date_value_distribution.py +89 -29
  259. endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +21 -5
  260. endoreg_db/models/other/distribution/numeric_value_distribution.py +114 -53
  261. endoreg_db/models/other/distribution/single_categorical_value_distribution.py +4 -3
  262. endoreg_db/models/other/emission/emission_factor.py +18 -8
  263. endoreg_db/models/other/gender.py +10 -5
  264. endoreg_db/models/other/information_source.py +25 -25
  265. endoreg_db/models/other/material.py +9 -5
  266. endoreg_db/models/other/resource.py +6 -4
  267. endoreg_db/models/other/tag.py +10 -5
  268. endoreg_db/models/other/transport_route.py +13 -8
  269. endoreg_db/models/other/unit.py +10 -6
  270. endoreg_db/models/other/waste.py +6 -5
  271. endoreg_db/models/requirement/requirement.py +580 -272
  272. endoreg_db/models/requirement/requirement_error.py +85 -0
  273. endoreg_db/models/requirement/requirement_evaluation/evaluate_with_dependencies.py +268 -0
  274. endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +3 -6
  275. endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +90 -64
  276. endoreg_db/models/requirement/requirement_operator.py +36 -33
  277. endoreg_db/models/requirement/requirement_set.py +74 -57
  278. endoreg_db/models/state/__init__.py +4 -4
  279. endoreg_db/models/state/abstract.py +2 -2
  280. endoreg_db/models/state/anonymization.py +12 -0
  281. endoreg_db/models/state/audit_ledger.py +46 -47
  282. endoreg_db/models/state/label_video_segment.py +9 -0
  283. endoreg_db/models/state/raw_pdf.py +40 -46
  284. endoreg_db/models/state/sensitive_meta.py +6 -2
  285. endoreg_db/models/state/video.py +58 -53
  286. endoreg_db/models/upload_job.py +32 -55
  287. endoreg_db/models/utils.py +1 -2
  288. endoreg_db/root_urls.py +21 -2
  289. endoreg_db/serializers/__init__.py +26 -57
  290. endoreg_db/serializers/anonymization.py +18 -10
  291. endoreg_db/serializers/meta/report_meta.py +1 -1
  292. endoreg_db/serializers/meta/sensitive_meta_detail.py +63 -118
  293. endoreg_db/serializers/misc/__init__.py +1 -1
  294. endoreg_db/serializers/misc/file_overview.py +33 -91
  295. endoreg_db/serializers/misc/{vop_patient_data.py → sensitive_patient_data.py} +1 -1
  296. endoreg_db/serializers/requirements/requirement_sets.py +92 -22
  297. endoreg_db/serializers/video/segmentation.py +2 -1
  298. endoreg_db/serializers/video/video_processing_history.py +20 -5
  299. endoreg_db/serializers/video_examination.py +198 -0
  300. endoreg_db/services/anonymization.py +75 -73
  301. endoreg_db/services/lookup_service.py +256 -73
  302. endoreg_db/services/lookup_store.py +174 -30
  303. endoreg_db/services/pdf_import.py +711 -310
  304. endoreg_db/services/storage_aware_video_processor.py +140 -114
  305. endoreg_db/services/video_import.py +266 -117
  306. endoreg_db/urls/__init__.py +27 -27
  307. endoreg_db/urls/label_video_segments.py +2 -0
  308. endoreg_db/urls/media.py +108 -66
  309. endoreg_db/urls/root_urls.py +29 -0
  310. endoreg_db/utils/__init__.py +15 -5
  311. endoreg_db/utils/ai/multilabel_classification_net.py +116 -20
  312. endoreg_db/utils/case_generator/__init__.py +3 -0
  313. endoreg_db/utils/dataloader.py +88 -16
  314. endoreg_db/utils/defaults/set_default_center.py +32 -0
  315. endoreg_db/utils/names.py +22 -16
  316. endoreg_db/utils/permissions.py +2 -1
  317. endoreg_db/utils/pipelines/process_video_dir.py +1 -1
  318. endoreg_db/utils/requirement_operator_logic/model_evaluators.py +414 -127
  319. endoreg_db/utils/setup_config.py +8 -5
  320. endoreg_db/utils/storage.py +115 -0
  321. endoreg_db/utils/validate_endo_roi.py +8 -2
  322. endoreg_db/utils/video/ffmpeg_wrapper.py +184 -188
  323. endoreg_db/views/__init__.py +5 -12
  324. endoreg_db/views/anonymization/media_management.py +198 -163
  325. endoreg_db/views/anonymization/overview.py +4 -1
  326. endoreg_db/views/anonymization/validate.py +174 -40
  327. endoreg_db/views/media/__init__.py +2 -0
  328. endoreg_db/views/media/pdf_media.py +131 -150
  329. endoreg_db/views/media/sensitive_metadata.py +46 -6
  330. endoreg_db/views/media/video_media.py +89 -82
  331. endoreg_db/views/media/video_segments.py +187 -260
  332. endoreg_db/views/meta/sensitive_meta_detail.py +0 -63
  333. endoreg_db/views/patient/patient.py +5 -4
  334. endoreg_db/views/pdf/__init__.py +5 -8
  335. endoreg_db/views/pdf/pdf_stream.py +186 -0
  336. endoreg_db/views/pdf/pdf_stream_views.py +0 -127
  337. endoreg_db/views/pdf/reimport.py +86 -91
  338. endoreg_db/views/requirement/evaluate.py +188 -187
  339. endoreg_db/views/requirement/lookup.py +186 -288
  340. endoreg_db/views/requirement/requirement_utils.py +89 -0
  341. endoreg_db/views/video/__init__.py +0 -4
  342. endoreg_db/views/video/correction.py +2 -2
  343. endoreg_db/views/video/video_examination_viewset.py +202 -289
  344. {endoreg_db-0.8.4.4.dist-info → endoreg_db-0.8.8.0.dist-info}/METADATA +7 -3
  345. {endoreg_db-0.8.4.4.dist-info → endoreg_db-0.8.8.0.dist-info}/RECORD +350 -255
  346. endoreg_db/models/administration/permissions/__init__.py +0 -44
  347. endoreg_db/models/media/video/refactor_plan.md +0 -0
  348. endoreg_db/models/media/video/video_file_frames.py +0 -0
  349. endoreg_db/models/metadata/frame_ocr_result.py +0 -0
  350. endoreg_db/models/rule/__init__.py +0 -13
  351. endoreg_db/models/rule/rule.py +0 -27
  352. endoreg_db/models/rule/rule_applicator.py +0 -224
  353. endoreg_db/models/rule/rule_attribute_dtype.py +0 -17
  354. endoreg_db/models/rule/rule_type.py +0 -20
  355. endoreg_db/models/rule/ruleset.py +0 -17
  356. endoreg_db/serializers/video/video_metadata.py +0 -105
  357. endoreg_db/urls/report.py +0 -48
  358. endoreg_db/urls/video.py +0 -61
  359. endoreg_db/utils/case_generator/case_generator.py +0 -159
  360. endoreg_db/utils/case_generator/utils.py +0 -30
  361. endoreg_db/views/pdf/pdf_media.py +0 -239
  362. endoreg_db/views/report/__init__.py +0 -9
  363. endoreg_db/views/report/report_list.py +0 -112
  364. endoreg_db/views/report/report_with_secure_url.py +0 -28
  365. endoreg_db/views/report/start_examination.py +0 -7
  366. endoreg_db/views/video/video_media.py +0 -158
  367. endoreg_db/views.py +0 -0
  368. /endoreg_db/data/{requirement_set → _examples/requirement_set}/endoscopy_bleeding_risk.yaml +0 -0
  369. /endoreg_db/migrations/{0002_add_video_correction_models.py → _old/0002_add_video_correction_models.py} +0 -0
  370. /endoreg_db/migrations/{0003_add_center_display_name.py → _old/0003_add_center_display_name.py} +0 -0
  371. {endoreg_db-0.8.4.4.dist-info → endoreg_db-0.8.8.0.dist-info}/WHEEL +0 -0
  372. {endoreg_db-0.8.4.4.dist-info → endoreg_db-0.8.8.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,50 +1,40 @@
1
- from django.db import models
2
- from typing import TYPE_CHECKING, Dict
3
1
  import random
4
- import numpy as np
2
+ from typing import TYPE_CHECKING, Dict
5
3
 
4
+ import numpy as np
5
+ from django.db import models
6
6
 
7
7
  # Corrected imports for type hints
8
8
  if TYPE_CHECKING:
9
9
  from ..finding import (
10
- FindingClassification,
11
- FindingClassificationChoice,
10
+ FindingClassification,
11
+ FindingClassificationChoice,
12
12
  )
13
13
  from .patient_finding import PatientFinding
14
14
 
15
+
15
16
  class PatientFindingClassification(models.Model):
16
17
  """Represents basic classifications for specific findings in a patient context.
17
18
  Links a PatientFinding to a specific classification and choice, with optional subcategory values.
18
19
  """
19
- finding = models.ForeignKey( # type: ignore[assignment]
20
- "PatientFinding",
21
- on_delete=models.CASCADE,
22
- related_name="classifications"
23
- )
24
- classification = models.ForeignKey( # type: ignore[assignment]
25
- "FindingClassification",
26
- on_delete=models.CASCADE,
27
- related_name="patient_finding_classifications"
28
- )
29
- classification_choice = models.ForeignKey( # type: ignore[assignment]
30
- "FindingClassificationChoice",
31
- on_delete=models.CASCADE,
32
- related_name="patient_finding_classifications"
33
- )
20
+
21
+ finding = models.ForeignKey("PatientFinding", on_delete=models.CASCADE, related_name="classifications")
22
+ classification = models.ForeignKey("FindingClassification", on_delete=models.CASCADE, related_name="patient_finding_classifications")
23
+ classification_choice = models.ForeignKey("FindingClassificationChoice", on_delete=models.CASCADE, related_name="patient_finding_classifications")
34
24
 
35
25
  is_active = models.BooleanField(default=True, help_text="Indicates if the classification is currently active.")
36
26
  subcategories = models.JSONField(blank=True, null=True)
37
27
  numerical_descriptors = models.JSONField(blank=True, null=True)
38
28
 
39
29
  if TYPE_CHECKING:
40
- finding: "PatientFinding"
41
- classification: "FindingClassification"
42
- classification_choice: "FindingClassificationChoice"
30
+ finding: models.ForeignKey["PatientFinding"]
31
+ classification: models.ForeignKey["FindingClassification"]
32
+ classification_choice: models.ForeignKey["FindingClassificationChoice"]
43
33
 
44
34
  class Meta:
45
- verbose_name = 'Patient Finding Classification'
46
- verbose_name_plural = 'Patient Finding Classifications'
47
- ordering = ['finding', 'classification', 'classification_choice']
35
+ verbose_name = "Patient Finding Classification"
36
+ verbose_name_plural = "Patient Finding Classifications"
37
+ ordering = ["finding", "classification", "classification_choice"]
48
38
 
49
39
  def __str__(self):
50
40
  """
@@ -55,7 +45,7 @@ class PatientFindingClassification(models.Model):
55
45
  def save(self, *args, **kwargs):
56
46
  """
57
47
  Saves the model instance after validating and initializing classification-related fields.
58
-
48
+
59
49
  Ensures that the selected classification choice is valid for the associated classification. If subcategories or numerical descriptors are unset, initializes them from the classification choice before saving.
60
50
  """
61
51
  if self.classification_choice not in self.classification.choices.all():
@@ -72,7 +62,7 @@ class PatientFindingClassification(models.Model):
72
62
  def initialize_and_get_subcategories(self):
73
63
  """
74
64
  Ensure the subcategories field is initialized and return its dictionary.
75
-
65
+
76
66
  Returns:
77
67
  dict: The subcategories associated with this classification.
78
68
  """
@@ -83,43 +73,46 @@ class PatientFindingClassification(models.Model):
83
73
  def initialize_and_get_descriptors(self):
84
74
  """
85
75
  Return the numerical descriptors dictionary, initializing it if necessary.
86
-
76
+
87
77
  If the `numerical_descriptors` field is empty or uninitialized, the method triggers model initialization and returns the resulting dictionary.
88
78
  """
89
79
  if not self.numerical_descriptors:
90
80
  self.save()
91
81
  return self.numerical_descriptors
92
82
 
93
- def set_subcategory(self, subcategory_name: str, subcategory_value: Dict):
83
+ def set_subcategory(self, subcategory_name: str, subcategory_value: Dict[str, dict]):
94
84
  """
95
85
  Update the value of a specified subcategory and save the classification.
96
-
86
+
97
87
  Parameters:
98
88
  subcategory_name (str): The name of the subcategory to update.
99
89
  subcategory_value (dict): The value to assign to the subcategory.
100
-
90
+
101
91
  Returns:
102
92
  dict: The updated subcategory dictionary.
103
93
  """
94
+ assert self.subcategories, "Subcategories must be initialized."
104
95
  assert subcategory_name in self.subcategories, "Subcategory must be in subcategories."
105
96
  self.subcategories[subcategory_name]["value"] = subcategory_value
106
97
  self.save()
107
98
 
108
99
  return self.subcategories[subcategory_name]
109
-
100
+
110
101
  def set_random_subcategories(self):
111
102
  """
112
103
  Assign random values to all required subcategories that do not already have a value.
113
-
104
+
114
105
  For each required subcategory without a value, selects a random option from its available choices, updates the subcategory, saves the model, and returns the updated subcategories dictionary.
115
-
106
+
116
107
  Returns:
117
108
  dict: The updated subcategories with random values assigned where needed.
118
109
  """
110
+
119
111
  if not self.subcategories or not self.numerical_descriptors:
120
112
  self.save()
121
-
113
+
122
114
  self.refresh_from_db()
115
+ assert self.subcategories is not None, "Subcategories must be initialized."
123
116
 
124
117
  for subcategory_name, subcategory_dict in self.subcategories.items():
125
118
  if subcategory_dict["required"] and not subcategory_dict.get("value", None):
@@ -129,21 +122,21 @@ class PatientFindingClassification(models.Model):
129
122
  self.save()
130
123
 
131
124
  return self.subcategories
132
-
133
- def get_random_value_for_numerical_descriptor(self, descriptor_name):
134
125
 
126
+ def get_random_value_for_numerical_descriptor(self, descriptor_name):
135
127
  """
136
128
  Generate a random value for the specified numerical descriptor using its defined distribution parameters.
137
-
129
+
138
130
  Parameters:
139
131
  descriptor_name (str): The name of the numerical descriptor to generate a value for.
140
-
132
+
141
133
  Returns:
142
134
  float: A randomly generated value based on the descriptor's distribution, clipped to its min and max range.
143
-
135
+
144
136
  Raises:
145
137
  ValueError: If the descriptor's distribution type is not supported.
146
- """
138
+ """
139
+ assert self.numerical_descriptors is not None, "Numerical descriptors must be initialized."
147
140
  assert descriptor_name in self.numerical_descriptors, "Descriptor must be in numerical descriptors."
148
141
  descriptor = self.numerical_descriptors[descriptor_name]
149
142
  min_val = descriptor.get("min", 0)
@@ -159,20 +152,20 @@ class PatientFindingClassification(models.Model):
159
152
  value = np.random.uniform(min_val, max_val)
160
153
  else:
161
154
  raise ValueError("Distribution not supported")
162
-
155
+
163
156
  return value
164
157
 
165
158
  def set_random_numerical_descriptor(self, descriptor_name, save=True):
166
159
  """
167
160
  Assigns a random value to the specified numerical descriptor and optionally saves the model.
168
-
161
+
169
162
  Parameters:
170
163
  descriptor_name (str): The name of the numerical descriptor to update.
171
164
  save (bool): If True, saves the model after updating the descriptor. Defaults to True.
172
-
165
+
173
166
  Returns:
174
167
  dict: The updated numerical descriptor dictionary with the new random value.
175
-
168
+
176
169
  Raises:
177
170
  ValueError: If the descriptor name is not present in the numerical descriptors.
178
171
  """
@@ -180,23 +173,25 @@ class PatientFindingClassification(models.Model):
180
173
  raise ValueError("Descriptor name must be in numerical descriptors.")
181
174
 
182
175
  value = self.get_random_value_for_numerical_descriptor(descriptor_name)
183
-
176
+ assert self.numerical_descriptors is not None, "Numerical descriptors must be initialized."
184
177
  self.numerical_descriptors[descriptor_name]["value"] = value
185
178
  if save:
186
179
  self.save()
187
180
 
188
181
  return self.numerical_descriptors[descriptor_name]
189
-
182
+
190
183
  def set_random_numerical_descriptors(self):
191
184
  """
192
185
  Assigns random values to all numerical descriptors and saves the model.
193
-
186
+
194
187
  Returns:
195
188
  dict: The updated numerical_descriptors dictionary with assigned random values.
196
189
  """
197
190
  if not self.subcategories or not self.numerical_descriptors:
198
191
  self.save()
199
192
 
193
+ assert self.numerical_descriptors is not None, "Numerical descriptors must be initialized."
194
+
200
195
  numerical_descriptors = self.numerical_descriptors
201
196
 
202
197
  for numerical_descriptor_name, _numerical_descriptor_dict in numerical_descriptors.items():
@@ -1,40 +1,29 @@
1
- from operator import is_
2
- from django.db import models
3
1
  from typing import TYPE_CHECKING
4
2
 
3
+ from django.db import models
4
+
5
5
  if TYPE_CHECKING:
6
6
  from ..finding import FindingIntervention
7
7
  from .patient_finding import PatientFinding
8
8
 
9
+
9
10
  class PatientFindingIntervention(models.Model):
10
- finding = models.ForeignKey(
11
- 'PatientFinding',
12
- on_delete=models.CASCADE,
13
- related_name='interventions'
14
- )
15
- intervention = models.ForeignKey(
16
- 'FindingIntervention',
17
- on_delete=models.CASCADE,
18
- related_name='patient_finding_interventions'
19
- )
20
- is_active = models.BooleanField(
21
- default=True,
22
- help_text="Indicates if the intervention is currently active."
23
- )
11
+ finding = models.ForeignKey("PatientFinding", on_delete=models.CASCADE, related_name="interventions")
12
+ intervention = models.ForeignKey("FindingIntervention", on_delete=models.CASCADE, related_name="patient_finding_interventions")
13
+ is_active = models.BooleanField(default=True, help_text="Indicates if the intervention is currently active.")
24
14
  state = models.CharField(max_length=100, blank=True, null=True)
25
15
  time_start = models.DateTimeField(blank=True, null=True)
26
16
  time_end = models.DateTimeField(blank=True, null=True)
27
17
  date = models.DateField(blank=True, null=True)
28
18
 
29
19
  if TYPE_CHECKING:
30
- finding: "PatientFinding"
31
- intervention: "FindingIntervention"
20
+ finding: models.ForeignKey["PatientFinding"]
21
+ intervention: models.ForeignKey["FindingIntervention"]
32
22
 
33
23
  def __str__(self):
34
24
  return self.intervention.name
35
25
 
36
26
  def natural_key(self):
37
27
  return (self.intervention.name,)
38
-
39
28
 
40
29
  objects = models.Manager()
@@ -1,19 +1,24 @@
1
- from django.db import models
1
+ from datetime import datetime as dt
2
+ from datetime import timezone
2
3
  from typing import TYPE_CHECKING
3
- from datetime import datetime as dt, timezone
4
+
5
+ from django.db import models
4
6
 
5
7
  if TYPE_CHECKING:
6
- from endoreg_db.models import Patient, LabValue, PatientLabValue
7
- from endoreg_db.utils.links.requirement_link import RequirementLinks # Added import
8
+ from endoreg_db.models import LabValue, Patient, PatientLabValue
9
+ from endoreg_db.utils.links.requirement_link import RequirementLinks # Added import
8
10
 
9
11
  DEFAULT_PATIENT_LAB_SAMPLE_TYPE_NAME = "generic"
10
12
 
13
+
11
14
  class PatientLabSampleTypeManager(models.Manager):
12
15
  """Manager for PatientLabSampleType with natural key support."""
16
+
13
17
  def get_by_natural_key(self, name):
14
18
  """Retrieves a PatientLabSampleType instance by its natural key (name)."""
15
19
  return self.get(name=name)
16
20
 
21
+
17
22
  class PatientLabSampleType(models.Model):
18
23
  """
19
24
  Represents the type of a patient lab sample (e.g., Blood, Urine).
@@ -22,6 +27,7 @@ class PatientLabSampleType(models.Model):
22
27
  name (str): The name of the patient lab sample type.
23
28
  description (str): A description of the patient lab sample type.
24
29
  """
30
+
25
31
  name = models.CharField(max_length=255)
26
32
  description = models.TextField(blank=True, null=True)
27
33
 
@@ -34,12 +40,13 @@ class PatientLabSampleType(models.Model):
34
40
  def __str__(self):
35
41
  """Returns the name of the sample type."""
36
42
  return str(self.name)
37
-
43
+
38
44
  @classmethod
39
45
  def get_default_sample_type(cls):
40
46
  """Gets or creates the default patient lab sample type ('default')."""
41
47
  return cls.objects.get_or_create(name="default")[0]
42
48
 
49
+
43
50
  class PatientLabSample(models.Model):
44
51
  """
45
52
  Represents a specific lab sample taken from a patient at a certain date and time.
@@ -52,24 +59,27 @@ class PatientLabSample(models.Model):
52
59
  date (datetime): The date of the lab sample.
53
60
  values (PatientLabValue; One2Many): The value of the lab sample.
54
61
  """
62
+
55
63
  patient = models.ForeignKey("Patient", on_delete=models.CASCADE, related_name="lab_samples")
56
64
  sample_type = models.ForeignKey("PatientLabSampleType", on_delete=models.CASCADE)
57
65
  date = models.DateTimeField()
58
66
 
59
67
  if TYPE_CHECKING:
60
- patient: "Patient"
61
- sample_type: "PatientLabSampleType"
62
- values: models.QuerySet["PatientLabValue"]
68
+ patient: models.ForeignKey["Patient"]
69
+ sample_type: models.ForeignKey["PatientLabSampleType"]
70
+
71
+ @property
72
+ def values(self) -> models.manager.RelatedManager["PatientLabValue"]: ...
63
73
 
64
74
  def __str__(self):
65
75
  """Returns a string representation including patient, type, and date."""
66
- formatted_datetime = self.date.strftime('%Y-%m-%d %H:%M')
76
+ formatted_datetime = self.date.strftime("%Y-%m-%d %H:%M")
67
77
  return f"{self.patient} - {self.sample_type} - {formatted_datetime} ()"
68
-
78
+
69
79
  def get_values(self):
70
80
  """Returns all PatientLabValue instances associated with this sample."""
71
81
  return self.values.all()
72
-
82
+
73
83
  @property
74
84
  def links(self) -> "RequirementLinks":
75
85
  """
@@ -84,11 +94,11 @@ class PatientLabSample(models.Model):
84
94
 
85
95
  return RequirementLinks(
86
96
  patient_lab_values=patient_lab_values,
87
- patient_lab_samples=[self] # Include the sample itself
97
+ patient_lab_samples=[self], # Include the sample itself
88
98
  )
89
99
 
90
100
  @classmethod
91
- def create_by_patient(cls, patient=None, sample_type=None, date=None, save = True):
101
+ def create_by_patient(cls, patient=None, sample_type=None, date=None, save=True):
92
102
  """
93
103
  Creates a new patient lab sample for a given patient.
94
104
 
@@ -115,26 +125,22 @@ class PatientLabSample(models.Model):
115
125
  if not date:
116
126
  date = dt.now(timezone.utc)
117
127
 
118
- patient_lab_sample = cls.objects.create(
119
- patient=patient,
120
- sample_type=sample_type,
121
- date=date
122
- )
128
+ patient_lab_sample = cls.objects.create(patient=patient, sample_type=sample_type, date=date)
123
129
 
124
130
  if save:
125
131
  patient_lab_sample.save()
126
132
 
127
133
  return patient_lab_sample
128
134
 
129
-
130
- def add_empty_value(self, lab_value:"LabValue"):
135
+ def add_empty_value(self, lab_value: "LabValue"):
131
136
  """
132
137
  Adds an empty PatientLabValue for the given lab value to this sample.
133
138
 
134
139
  Args:
135
140
  lab_value (LabValue): The lab value to add.
136
141
  """
137
- from endoreg_db.models import PatientLabValue, LabValue
142
+ from endoreg_db.models import LabValue, PatientLabValue
143
+
138
144
  if not isinstance(lab_value, LabValue):
139
145
  raise ValueError("lab_value must be an instance of LabValue.")
140
146
  patient_lab_value = PatientLabValue.create_lab_value_by_sample(
@@ -142,7 +148,6 @@ class PatientLabSample(models.Model):
142
148
  lab_value_name=lab_value.name,
143
149
  value=None, # Empty value
144
150
  value_str=None, # Empty string
145
- unit=lab_value.default_unit # Use the unit from the lab value
151
+ unit=lab_value.default_unit, # Use the unit from the lab value
146
152
  )
147
153
  return patient_lab_value
148
-