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,8 +1,11 @@
1
1
  # stats/models.py
2
- import hashlib, json, uuid
2
+ import hashlib
3
+ import json
4
+ import uuid
5
+
6
+ from django.conf import settings
3
7
  from django.db import models
4
8
  from django.utils import timezone
5
- from django.conf import settings
6
9
 
7
10
  """
8
11
 
@@ -31,33 +34,35 @@ Returns:
31
34
  _type_: _description_
32
35
  """
33
36
 
37
+ # TODO implement later on
38
+
34
39
 
35
40
  class AuditLedger(models.Model):
36
- id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
37
- ts = models.DateTimeField(default=timezone.now, editable=False)
38
- user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)
39
- object_type = models.CharField(max_length=80) # e.g. 'VideoFile'
40
- object_pk = models.CharField(max_length=40) # UUID or int
41
- action = models.CharField(max_length=40) # 'created' | 'validated' | …
42
- data = models.JSONField() # snapshot / diff / metadata
43
- prev_hash = models.CharField(max_length=64, editable=False)
44
- hash = models.CharField(max_length=64, editable=False)
41
+ id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
42
+ ts = models.DateTimeField(default=timezone.now, editable=False)
43
+ user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)
44
+ object_type = models.CharField(max_length=80) # e.g. 'VideoFile'
45
+ object_pk = models.CharField(max_length=40) # UUID or int
46
+ action = models.CharField(max_length=40) # 'created' | 'validated' | …
47
+ data = models.JSONField() # snapshot / diff / metadata
48
+ prev_hash = models.CharField(max_length=64, editable=False)
49
+ hash = models.CharField(max_length=64, editable=False)
45
50
 
46
51
  class Meta:
47
- ordering = ['ts']
48
- indexes = [models.Index(fields=['object_type', 'object_pk'])]
52
+ ordering = ["ts"]
53
+ indexes = [models.Index(fields=["object_type", "object_pk"])]
49
54
 
50
55
  # ------------------------------------------------------
51
56
  def save(self, *args, **kw):
52
57
  """
53
58
  Saves a new immutable audit record, computing and linking cryptographic hashes.
54
-
59
+
55
60
  Raises:
56
61
  RuntimeError: If an attempt is made to modify an existing audit record.
57
62
  """
58
- if self._state.adding: # only on INSERT
63
+ if self._state.adding: # only on INSERT
59
64
  self.prev_hash = self._last_hash()
60
- self.hash = self._compute_hash()
65
+ self.hash = self._compute_hash()
61
66
  else:
62
67
  raise RuntimeError("AuditLedger rows are immutable")
63
68
  super().save(*args, **kw)
@@ -66,36 +71,36 @@ class AuditLedger(models.Model):
66
71
  def _last_hash(self) -> str:
67
72
  """
68
73
  Retrieves the hash of the most recent audit record.
69
-
74
+
70
75
  Returns:
71
76
  The SHA-256 hash of the latest `AuditLedger` entry by timestamp, or a string of 64 zeros if no records exist.
72
77
  """
73
- last = AuditLedger.objects.order_by('-ts').first()
74
- return last.hash if last else '0' * 64
78
+ last = AuditLedger.objects.order_by("-ts").first()
79
+ return last.hash if last else "0" * 64
75
80
 
76
81
  def _compute_hash(self) -> str:
77
82
  """
78
83
  Computes the SHA-256 hash of the current audit record's data.
79
-
84
+
80
85
  The hash is generated from a JSON-serialized payload containing the timestamp, user ID, object type and primary key, action, associated data, and the previous record's hash. This ensures the integrity and immutability of the audit trail.
81
-
86
+
82
87
  Returns:
83
88
  The hexadecimal SHA-256 hash string representing the current audit record.
84
89
  """
85
90
  payload = {
86
- 'ts': self.ts.isoformat(),
87
- 'uid': str(self.user_id),
88
- 'obj': f'{self.object_type}:{self.object_pk}',
89
- 'act': self.action,
90
- 'data': self.data,
91
- 'prev': self.prev_hash,
91
+ "ts": self.ts.isoformat(),
92
+ "uid": str(self.user_id),
93
+ "obj": f"{self.object_type}:{self.object_pk}",
94
+ "act": self.action,
95
+ "data": self.data,
96
+ "prev": self.prev_hash,
92
97
  }
93
98
  return hashlib.sha256(json.dumps(payload, sort_keys=True).encode()).hexdigest()
94
-
99
+
95
100
  def log_validation(user, instance, action: str, extra=None):
96
101
  """
97
102
  Creates an audit record for a validation action performed by a user on a specific model instance.
98
-
103
+
99
104
  Args:
100
105
  user: The user performing the action.
101
106
  instance: The model instance being validated.
@@ -113,38 +118,32 @@ class AuditLedger(models.Model):
113
118
  def _distinct(object_type: str, action: str):
114
119
  """
115
120
  Returns the number of distinct objects of a given type that have a specific audit action recorded.
116
-
121
+
117
122
  Args:
118
123
  object_type: The type of object to filter by (e.g., 'VideoFile').
119
124
  action: The audit action to filter by (e.g., 'validated').
120
-
125
+
121
126
  Returns:
122
127
  The count of unique object primary keys matching the specified type and action.
123
128
  """
124
- return (
125
- AuditLedger.objects
126
- .filter(object_type=object_type, action=action)
127
- .values('object_pk')
128
- .distinct()
129
- .count()
130
- )
129
+ return AuditLedger.objects.filter(object_type=object_type, action=action).values("object_pk").distinct().count()
131
130
 
132
- def collect_counters():
131
+ def collect_counters(self):
133
132
  """
134
133
  Aggregates and returns summary statistics for audit actions and object types.
135
-
134
+
136
135
  Returns:
137
136
  dict: A dictionary containing counts of distinct cases, videos, annotations,
138
137
  anonymizations, images, and breakdowns of video statuses based on audit records.
139
138
  """
140
139
  return {
141
- "totalCases": AuditLedger._distinct("VideoFile", "created"),
142
- "totalVideos": AuditLedger._distinct("VideoFile", "created"),
143
- "totalAnnotations": AuditLedger.objects.filter(action="annotation_added").count(),
144
- "totalAnonymizations": AuditLedger._distinct("VideoFile", "anonymized"),
145
- "totalImages": AuditLedger._distinct("Image", "created"),
140
+ "totalCases": AuditLedger._distinct("VideoFile", "created"),
141
+ "totalVideos": AuditLedger._distinct("VideoFile", "created"),
142
+ "totalAnnotations": AuditLedger.objects.filter(action="annotation_added").count(),
143
+ "totalAnonymizations": AuditLedger._distinct("VideoFile", "anonymized"),
144
+ "totalImages": AuditLedger._distinct("Image", "created"),
146
145
  # video breakdown
147
- "videosCompleted": AuditLedger._distinct("VideoFile", "validated"),
148
- "videosAnonym": AuditLedger._distinct("VideoFile", "anonymized"),
146
+ "videosCompleted": AuditLedger._distinct("VideoFile", "validated"),
147
+ "videosAnonym": AuditLedger._distinct("VideoFile", "anonymized"),
149
148
  # add more as needed …
150
149
  }
@@ -1,6 +1,10 @@
1
+ from typing import TYPE_CHECKING
2
+
1
3
  from django.db import models
4
+
2
5
  from .abstract import AbstractState
3
6
 
7
+
4
8
  class LabelVideoSegmentState(AbstractState):
5
9
  """State for label video segment data."""
6
10
 
@@ -20,3 +24,8 @@ class LabelVideoSegmentState(AbstractState):
20
24
  class Meta:
21
25
  verbose_name = "Label Video Segment State"
22
26
  verbose_name_plural = "Label Video Segment States"
27
+
28
+ if TYPE_CHECKING:
29
+ from endoreg_db.models import LabelVideoSegment
30
+
31
+ origin: models.OneToOneField["LabelVideoSegment|None"]
@@ -1,24 +1,19 @@
1
1
  """
2
2
  Defines state tracking models related to PDF processing, including extraction of text and metadata, AI predictions, and anonymization status for RawPdfFile instances.
3
3
  """
4
- from django.db import models
5
- from typing import TYPE_CHECKING
4
+
6
5
  import logging
7
6
  from enum import Enum
7
+ from typing import TYPE_CHECKING
8
+
9
+ from django.db import models
10
+
11
+ from endoreg_db.models.state.anonymization import AnonymizationState
8
12
 
9
13
  logger = logging.getLogger(__name__)
10
14
 
11
15
  if TYPE_CHECKING:
12
16
  from ..media import RawPdfFile
13
-
14
-
15
- class AnonymizationStatus(str, Enum):
16
- NOT_STARTED = "not_started"
17
- PROCESSING_ANONYMIZING = "processing_anonymization"
18
- DONE = "done"
19
- VALIDATED = "validated"
20
- FAILED = "failed"
21
- STARTED = "started"
22
17
 
23
18
 
24
19
  class RawPdfState(models.Model):
@@ -26,30 +21,37 @@ class RawPdfState(models.Model):
26
21
  Tracks the processing state of a RawPdfFile instance.
27
22
  Uses BooleanFields for clear, distinct states.
28
23
  """
24
+
29
25
  text_meta_extracted = models.BooleanField(default=False, help_text="True if text metadata (OCR) has been extracted.")
30
26
 
31
27
  # AI / Annotation related states
32
- initial_prediction_completed = models.BooleanField(default=False, help_text="True if initial AI prediction has run.")
28
+ initial_prediction_completed = models.BooleanField(
29
+ default=False, help_text="True if initial AI prediction has run."
30
+ )
33
31
 
34
32
  # Processing state
35
- sensitive_meta_processed = models.BooleanField(default=False, help_text="True if the video has been fully processed, meaning a anonymized person was created.")
33
+ sensitive_meta_processed = models.BooleanField(
34
+ default=False, help_text="True if the video has been fully processed, meaning a anonymized person was created."
35
+ )
36
36
 
37
37
  # Anonymization state
38
38
  anonymized = models.BooleanField(default=False, help_text="True if the anonymized video file has been created.")
39
39
  anonymization_validated = models.BooleanField(default=False, help_text="True if the anonymization process has been validated and confirmed.")
40
-
40
+
41
41
  # Processing state
42
42
  processing_started = models.BooleanField(default=False, help_text="True if the processing has started, but not yet completed.")
43
43
  processing_error = models.BooleanField(default=False, help_text="True if an error occurred during processing.")
44
-
44
+
45
45
  # Timestamps
46
46
  date_created = models.DateTimeField(auto_now_add=True)
47
47
  date_modified = models.DateTimeField(auto_now=True)
48
-
48
+
49
49
  was_created = models.BooleanField(default=True, help_text="True if this state was created for the first time.")
50
50
 
51
51
  # PDF metadata extraction state
52
- pdf_meta_extracted = models.BooleanField(default=False, help_text="True if PDF metadata has been extracted.")
52
+ pdf_meta_extracted = models.BooleanField(
53
+ default=False, help_text="True if PDF metadata has been extracted."
54
+ )
53
55
 
54
56
  if TYPE_CHECKING:
55
57
  raw_pdf_file: "RawPdfFile"
@@ -59,7 +61,7 @@ class RawPdfState(models.Model):
59
61
  Return a string summarizing the RawPdfState instance, including the related PDF file UUID and key processing state flags with timestamps.
60
62
  """
61
63
  try:
62
- uuid = self.raw_pdf_file.id
64
+ uuid = self.raw_pdf_file.pk
63
65
  except Exception:
64
66
  uuid = None
65
67
 
@@ -70,40 +72,36 @@ class RawPdfState(models.Model):
70
72
  f"AnonymizationValidated={self.anonymization_validated}",
71
73
  f"SensitiveMetaProcessed={self.sensitive_meta_processed}",
72
74
  f"DateCreated={self.date_created.isoformat()}",
73
- f"DateModified={self.date_modified.isoformat()}"
75
+ f"DateModified={self.date_modified.isoformat()}",
74
76
  ]
75
77
  return f"RawPdfState(Pdf:{uuid}): {', '.join(states)}"
76
78
 
77
79
  @property
78
- def anonymization_status(self) -> AnonymizationStatus:
80
+ def anonymization_status(self) -> AnonymizationState:
79
81
  """
80
82
  Determines the current anonymization workflow status for the PDF processing state.
81
-
83
+
82
84
  Returns:
83
85
  AnonymizationStatus: The current status, reflecting progress or failure in the anonymization process.
84
86
  """
85
- if getattr(self, "processing_error", False):
86
- return AnonymizationStatus.FAILED
87
87
  if self.anonymization_validated:
88
- return AnonymizationStatus.VALIDATED
88
+ return AnonymizationState.VALIDATED # Validation in Frontend completed -> Views related to this /home/admin/endoreg-db/endoreg_db/views/anonymization/validate.py
89
89
  if self.sensitive_meta_processed:
90
- return AnonymizationStatus.DONE
91
- if self.anonymized:
92
- return AnonymizationStatus.DONE
93
- if self.initial_prediction_completed:
94
- return AnonymizationStatus.PROCESSING_ANONYMIZING
95
- if self.pdf_meta_extracted:
96
- return AnonymizationStatus.NOT_STARTED
90
+ return AnonymizationState.DONE_PROCESSING_ANONYMIZATION # /home/admin/endoreg-db/endoreg_db/services/pdf_import.py
91
+ if self.processing_started and not self.processing_error and not self.anonymized:
92
+ return AnonymizationState.PROCESSING_ANONYMIZING
93
+ if getattr(self, "processing_error", False):
94
+ return AnonymizationState.FAILED # /home/admin/endoreg-db/endoreg_db/services/pdf_import.py
97
95
  if self.processing_started:
98
- return AnonymizationStatus.STARTED
99
- return AnonymizationStatus.NOT_STARTED
100
-
96
+ return AnonymizationState.STARTED # /home/admin/endoreg-db/endoreg_db/services/pdf_import.py
97
+ if self.anonymized:
98
+ return AnonymizationState.ANONYMIZED
99
+ return AnonymizationState.NOT_STARTED
101
100
 
102
-
103
101
  def mark_processing_started(self, *, save: bool = True) -> None:
104
102
  """
105
103
  Mark the processing as started and optionally save the updated state.
106
-
104
+
107
105
  Parameters:
108
106
  save (bool): If True, persist the change to the database immediately. Defaults to True.
109
107
  """
@@ -115,7 +113,7 @@ class RawPdfState(models.Model):
115
113
  def mark_sensitive_meta_processed(self, *, save: bool = True) -> None:
116
114
  """
117
115
  Mark the sensitive metadata processing step as completed for this PDF state.
118
-
116
+
119
117
  Parameters:
120
118
  save (bool): If True, immediately saves the updated state to the database.
121
119
  """
@@ -126,7 +124,7 @@ class RawPdfState(models.Model):
126
124
  def mark_anonymization_validated(self, *, save: bool = True) -> None:
127
125
  """
128
126
  Mark the anonymization as validated for this PDF processing state.
129
-
127
+
130
128
  Parameters:
131
129
  save (bool): If True, immediately saves the updated state to the database.
132
130
  """
@@ -137,7 +135,7 @@ class RawPdfState(models.Model):
137
135
  def mark_anonymized(self, *, save: bool = True) -> None:
138
136
  """
139
137
  Mark the PDF as anonymized and optionally save the updated state.
140
-
138
+
141
139
  Parameters:
142
140
  save (bool): If True, persist the change to the database immediately. Defaults to True.
143
141
  """
@@ -148,7 +146,7 @@ class RawPdfState(models.Model):
148
146
  def mark_initial_prediction_completed(self, *, save: bool = True) -> None:
149
147
  """
150
148
  Mark the initial AI prediction step as completed for this PDF processing state.
151
-
149
+
152
150
  Parameters:
153
151
  save (bool): If True, immediately saves the updated state to the database.
154
152
  """
@@ -159,7 +157,7 @@ class RawPdfState(models.Model):
159
157
  def mark_pdf_meta_extracted(self, *, save: bool = True) -> None:
160
158
  """
161
159
  Mark the PDF metadata extraction step as completed for this state.
162
-
160
+
163
161
  Parameters:
164
162
  save (bool): If True, immediately saves the updated state to the database.
165
163
  """
@@ -170,18 +168,14 @@ class RawPdfState(models.Model):
170
168
  def mark_text_meta_extracted(self, *, save: bool = True) -> None:
171
169
  """
172
170
  Mark the text metadata extraction step as completed for this PDF processing state.
173
-
171
+
174
172
  Parameters:
175
173
  save (bool): If True, immediately saves the updated state to the database.
176
174
  """
177
175
  self.text_meta_extracted = True
178
176
  if save:
179
177
  self.save(update_fields=["text_meta_extracted", "date_modified"])
180
-
181
-
182
178
 
183
179
  class Meta:
184
180
  verbose_name = "Raw PDF Processing State"
185
181
  verbose_name_plural = "Raw PDF Processing States"
186
-
187
-
@@ -1,6 +1,9 @@
1
+ from typing import TYPE_CHECKING
2
+
1
3
  from django.db import models
4
+
2
5
  from .abstract import AbstractState
3
- from typing import TYPE_CHECKING
6
+
4
7
 
5
8
  class SensitiveMetaState(AbstractState):
6
9
  """State for sensitive meta data."""
@@ -19,7 +22,7 @@ class SensitiveMetaState(AbstractState):
19
22
  if TYPE_CHECKING:
20
23
  from endoreg_db.models import SensitiveMeta
21
24
 
22
- origin: "SensitiveMeta"
25
+ origin: models.OneToOneField["SensitiveMeta|None"]
23
26
 
24
27
  @property
25
28
  def is_verified(self) -> bool:
@@ -41,6 +44,7 @@ class SensitiveMetaState(AbstractState):
41
44
  """
42
45
  self.names_verified = True
43
46
  self.save(update_fields=["names_verified"])
47
+
44
48
  class Meta:
45
49
  verbose_name = "Sensitive Meta State"
46
50
  verbose_name_plural = "Sensitive Meta States"