endoreg-db 0.8.6.1__py3-none-any.whl → 0.8.8.9__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 (503) 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 +2 -11
  10. endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +3 -3
  11. endoreg_db/data/event_classification/data.yaml +4 -0
  12. endoreg_db/data/event_classification_choice/data.yaml +9 -0
  13. endoreg_db/data/examination/examinations/data.yaml +114 -14
  14. endoreg_db/data/examination/time-type/data.yaml +0 -3
  15. endoreg_db/data/examination_indication/endoscopy.yaml +108 -173
  16. endoreg_db/data/examination_indication_classification/endoscopy.yaml +0 -70
  17. endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +33 -37
  18. endoreg_db/data/finding/00_generic.yaml +35 -0
  19. endoreg_db/data/finding/00_generic_complication.yaml +9 -0
  20. endoreg_db/data/finding/01_gastroscopy_baseline.yaml +88 -0
  21. endoreg_db/data/finding/01_gastroscopy_observation.yaml +113 -0
  22. endoreg_db/data/finding/02_colonoscopy_baseline.yaml +53 -0
  23. endoreg_db/data/finding/02_colonoscopy_hidden.yaml +119 -0
  24. endoreg_db/data/finding/02_colonoscopy_observation.yaml +152 -0
  25. endoreg_db/data/finding_classification/00_generic.yaml +44 -0
  26. endoreg_db/data/finding_classification/00_generic_histology.yaml +28 -0
  27. endoreg_db/data/finding_classification/00_generic_lesion.yaml +52 -0
  28. endoreg_db/data/finding_classification/02_colonoscopy_baseline.yaml +83 -0
  29. endoreg_db/data/finding_classification/02_colonoscopy_histology.yaml +13 -0
  30. endoreg_db/data/finding_classification/02_colonoscopy_other.yaml +12 -0
  31. endoreg_db/data/finding_classification/02_colonoscopy_polyp.yaml +101 -0
  32. endoreg_db/data/finding_classification_choice/{yes_no_na.yaml → 00_generic.yaml} +5 -1
  33. endoreg_db/data/finding_classification_choice/{examination_setting_generic_types.yaml → 00_generic_baseline.yaml} +10 -2
  34. endoreg_db/data/finding_classification_choice/{complication_generic_types.yaml → 00_generic_complication.yaml} +1 -1
  35. endoreg_db/data/finding_classification_choice/{histology.yaml → 00_generic_histology.yaml} +1 -4
  36. endoreg_db/data/finding_classification_choice/00_generic_lesion.yaml +158 -0
  37. endoreg_db/data/finding_classification_choice/{bowel_preparation.yaml → 02_colonoscopy_bowel_preparation.yaml} +1 -30
  38. endoreg_db/data/finding_classification_choice/{colonoscopy_not_complete_reason.yaml → 02_colonoscopy_generic.yaml} +1 -1
  39. endoreg_db/data/finding_classification_choice/{histology_polyp.yaml → 02_colonoscopy_histology.yaml} +1 -1
  40. endoreg_db/data/finding_classification_choice/{colonoscopy_location.yaml → 02_colonoscopy_location.yaml} +23 -4
  41. endoreg_db/data/finding_classification_choice/02_colonoscopy_other.yaml +34 -0
  42. endoreg_db/data/finding_classification_choice/02_colonoscopy_polyp_advanced_imaging.yaml +76 -0
  43. endoreg_db/data/finding_classification_choice/{colon_lesion_paris.yaml → 02_colonoscopy_polyp_morphology.yaml} +26 -8
  44. endoreg_db/data/finding_classification_choice/02_colonoscopy_size.yaml +27 -0
  45. endoreg_db/data/finding_classification_type/{colonoscopy_basic.yaml → 00_generic.yaml} +18 -13
  46. endoreg_db/data/finding_classification_type/02_colonoscopy.yaml +9 -0
  47. endoreg_db/data/finding_intervention/00_generic_endoscopy.yaml +59 -0
  48. endoreg_db/data/finding_intervention/00_generic_endoscopy_ablation.yaml +44 -0
  49. endoreg_db/data/finding_intervention/00_generic_endoscopy_bleeding.yaml +55 -0
  50. endoreg_db/data/finding_intervention/00_generic_endoscopy_resection.yaml +85 -0
  51. endoreg_db/data/finding_intervention/00_generic_endoscopy_stenosis.yaml +17 -0
  52. endoreg_db/data/finding_intervention/00_generic_endoscopy_stent.yaml +9 -0
  53. endoreg_db/data/finding_intervention/01_gastroscopy.yaml +19 -0
  54. endoreg_db/data/finding_intervention/04_eus.yaml +39 -0
  55. endoreg_db/data/finding_intervention/05_ercp.yaml +3 -0
  56. endoreg_db/data/finding_type/data.yaml +8 -12
  57. endoreg_db/data/requirement/01_patient_data.yaml +93 -0
  58. endoreg_db/data/requirement/old/colon_polyp_intervention.yaml +49 -0
  59. endoreg_db/data/requirement/old/coloreg_colon_polyp.yaml +49 -0
  60. endoreg_db/data/requirement_operator/new_operators.yaml +36 -0
  61. endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +29 -12
  62. endoreg_db/data/requirement_set/01_laboratory.yaml +13 -0
  63. endoreg_db/data/requirement_set/{endoscopy_bleeding_risk.yaml → 02_endoscopy_bleeding_risk.yaml} +0 -6
  64. endoreg_db/data/requirement_set/90_coloreg.yaml +190 -0
  65. endoreg_db/data/requirement_set/_old_ +109 -0
  66. endoreg_db/data/requirement_set_type/data.yaml +21 -0
  67. endoreg_db/data/setup_config.yaml +4 -4
  68. endoreg_db/data/tag/requirement_set_tags.yaml +21 -0
  69. endoreg_db/exceptions.py +4 -2
  70. endoreg_db/forms/examination_form.py +1 -1
  71. endoreg_db/helpers/data_loader.py +125 -53
  72. endoreg_db/helpers/default_objects.py +116 -81
  73. endoreg_db/import_files/__init__.py +27 -0
  74. endoreg_db/import_files/context/__init__.py +7 -0
  75. endoreg_db/import_files/context/default_sensitive_meta.py +81 -0
  76. endoreg_db/import_files/context/ensure_center.py +17 -0
  77. endoreg_db/import_files/context/file_lock.py +66 -0
  78. endoreg_db/import_files/context/import_context.py +43 -0
  79. endoreg_db/import_files/context/validate_directories.py +56 -0
  80. endoreg_db/import_files/file_storage/__init__.py +15 -0
  81. endoreg_db/import_files/file_storage/create_report_file.py +76 -0
  82. endoreg_db/import_files/file_storage/create_video_file.py +75 -0
  83. endoreg_db/import_files/file_storage/sensitive_meta_storage.py +39 -0
  84. endoreg_db/import_files/file_storage/state_management.py +400 -0
  85. endoreg_db/import_files/file_storage/storage.py +36 -0
  86. endoreg_db/import_files/import_service.md +26 -0
  87. endoreg_db/import_files/processing/__init__.py +11 -0
  88. endoreg_db/import_files/processing/report_processing/report_anonymization.py +94 -0
  89. endoreg_db/import_files/processing/sensitive_meta_adapter.py +51 -0
  90. endoreg_db/import_files/processing/video_processing/video_anonymization.py +107 -0
  91. endoreg_db/import_files/processing/video_processing/video_cleanup_on_error.py +119 -0
  92. endoreg_db/import_files/pseudonymization/fake.py +52 -0
  93. endoreg_db/import_files/pseudonymization/k_anonymity.py +182 -0
  94. endoreg_db/import_files/pseudonymization/k_pseudonymity.py +128 -0
  95. endoreg_db/import_files/report_import_service.py +141 -0
  96. endoreg_db/import_files/video_import_service.py +150 -0
  97. endoreg_db/management/commands/create_model_meta_from_huggingface.py +21 -10
  98. endoreg_db/management/commands/create_multilabel_model_meta.py +299 -129
  99. endoreg_db/management/commands/import_report.py +130 -65
  100. endoreg_db/management/commands/import_video.py +9 -10
  101. endoreg_db/management/commands/import_video_with_classification.py +2 -2
  102. endoreg_db/management/commands/list_routes.py +18 -0
  103. endoreg_db/management/commands/load_ai_model_data.py +5 -5
  104. endoreg_db/management/commands/load_ai_model_label_data.py +9 -7
  105. endoreg_db/management/commands/load_base_db_data.py +5 -134
  106. endoreg_db/management/commands/load_center_data.py +12 -12
  107. endoreg_db/management/commands/load_contraindication_data.py +14 -16
  108. endoreg_db/management/commands/load_disease_classification_choices_data.py +15 -18
  109. endoreg_db/management/commands/load_disease_classification_data.py +15 -18
  110. endoreg_db/management/commands/load_disease_data.py +25 -28
  111. endoreg_db/management/commands/load_endoscope_data.py +20 -27
  112. endoreg_db/management/commands/load_event_data.py +14 -16
  113. endoreg_db/management/commands/load_examination_data.py +31 -44
  114. endoreg_db/management/commands/load_examination_indication_data.py +20 -21
  115. endoreg_db/management/commands/load_finding_data.py +52 -80
  116. endoreg_db/management/commands/load_information_source.py +21 -23
  117. endoreg_db/management/commands/load_lab_value_data.py +17 -26
  118. endoreg_db/management/commands/load_medication_data.py +13 -12
  119. endoreg_db/management/commands/load_organ_data.py +15 -19
  120. endoreg_db/management/commands/load_pdf_type_data.py +19 -18
  121. endoreg_db/management/commands/load_profession_data.py +14 -17
  122. endoreg_db/management/commands/load_qualification_data.py +20 -23
  123. endoreg_db/management/commands/load_report_reader_flag_data.py +17 -19
  124. endoreg_db/management/commands/load_requirement_data.py +62 -39
  125. endoreg_db/management/commands/load_requirement_set_tags.py +95 -0
  126. endoreg_db/management/commands/load_risk_data.py +7 -6
  127. endoreg_db/management/commands/load_shift_data.py +20 -23
  128. endoreg_db/management/commands/load_tag_data.py +8 -11
  129. endoreg_db/management/commands/load_unit_data.py +17 -19
  130. endoreg_db/management/commands/setup_endoreg_db.py +3 -3
  131. endoreg_db/management/commands/start_filewatcher.py +46 -37
  132. endoreg_db/management/commands/storage_management.py +271 -203
  133. endoreg_db/management/commands/validate_video_files.py +1 -5
  134. endoreg_db/migrations/0001_initial.py +297 -250
  135. endoreg_db/models/__init__.py +78 -123
  136. endoreg_db/models/administration/__init__.py +21 -42
  137. endoreg_db/models/administration/ai/active_model.py +2 -2
  138. endoreg_db/models/administration/ai/ai_model.py +7 -6
  139. endoreg_db/models/administration/case/__init__.py +1 -15
  140. endoreg_db/models/administration/case/case.py +3 -3
  141. endoreg_db/models/administration/case/case_template/__init__.py +2 -14
  142. endoreg_db/models/administration/case/case_template/case_template.py +2 -124
  143. endoreg_db/models/administration/case/case_template/case_template_rule.py +2 -268
  144. endoreg_db/models/administration/case/case_template/case_template_rule_value.py +2 -85
  145. endoreg_db/models/administration/case/case_template/case_template_type.py +2 -25
  146. endoreg_db/models/administration/center/center.py +33 -19
  147. endoreg_db/models/administration/center/center_product.py +12 -9
  148. endoreg_db/models/administration/center/center_resource.py +25 -19
  149. endoreg_db/models/administration/center/center_shift.py +21 -17
  150. endoreg_db/models/administration/center/center_waste.py +16 -8
  151. endoreg_db/models/administration/person/__init__.py +2 -0
  152. endoreg_db/models/administration/person/employee/employee.py +10 -5
  153. endoreg_db/models/administration/person/employee/employee_qualification.py +9 -4
  154. endoreg_db/models/administration/person/employee/employee_type.py +12 -6
  155. endoreg_db/models/administration/person/examiner/examiner.py +13 -11
  156. endoreg_db/models/administration/person/patient/__init__.py +2 -0
  157. endoreg_db/models/administration/person/patient/patient.py +129 -100
  158. endoreg_db/models/administration/person/patient/patient_external_id.py +37 -0
  159. endoreg_db/models/administration/person/person.py +4 -0
  160. endoreg_db/models/administration/person/profession/__init__.py +8 -4
  161. endoreg_db/models/administration/person/user/portal_user_information.py +11 -7
  162. endoreg_db/models/administration/product/product.py +20 -15
  163. endoreg_db/models/administration/product/product_material.py +17 -18
  164. endoreg_db/models/administration/product/product_weight.py +12 -8
  165. endoreg_db/models/administration/product/reference_product.py +23 -55
  166. endoreg_db/models/administration/qualification/qualification.py +7 -3
  167. endoreg_db/models/administration/qualification/qualification_type.py +7 -3
  168. endoreg_db/models/administration/shift/scheduled_days.py +8 -5
  169. endoreg_db/models/administration/shift/shift.py +16 -12
  170. endoreg_db/models/administration/shift/shift_type.py +23 -31
  171. endoreg_db/models/label/__init__.py +8 -9
  172. endoreg_db/models/label/annotation/image_classification.py +10 -9
  173. endoreg_db/models/label/annotation/video_segmentation_annotation.py +23 -28
  174. endoreg_db/models/label/label.py +15 -15
  175. endoreg_db/models/label/label_set.py +19 -6
  176. endoreg_db/models/label/label_type.py +1 -1
  177. endoreg_db/models/label/label_video_segment/_create_from_video.py +5 -8
  178. endoreg_db/models/label/label_video_segment/label_video_segment.py +98 -102
  179. endoreg_db/models/label/video_segmentation_label.py +4 -0
  180. endoreg_db/models/label/video_segmentation_labelset.py +4 -3
  181. endoreg_db/models/media/frame/frame.py +22 -22
  182. endoreg_db/models/media/pdf/raw_pdf.py +194 -194
  183. endoreg_db/models/media/pdf/report_file.py +25 -29
  184. endoreg_db/models/media/pdf/report_reader/report_reader_config.py +55 -47
  185. endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +23 -7
  186. endoreg_db/models/media/processing_history/__init__.py +5 -0
  187. endoreg_db/models/media/processing_history/processing_history.py +96 -0
  188. endoreg_db/models/media/video/__init__.py +1 -0
  189. endoreg_db/models/media/video/create_from_file.py +139 -77
  190. endoreg_db/models/media/video/pipe_2.py +8 -9
  191. endoreg_db/models/media/video/video_file.py +174 -112
  192. endoreg_db/models/media/video/video_file_ai.py +288 -74
  193. endoreg_db/models/media/video/video_file_anonymize.py +38 -38
  194. endoreg_db/models/media/video/video_file_frames/__init__.py +3 -1
  195. endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +6 -8
  196. endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +7 -9
  197. endoreg_db/models/media/video/video_file_frames/_delete_frames.py +9 -8
  198. endoreg_db/models/media/video/video_file_frames/_extract_frames.py +38 -45
  199. endoreg_db/models/media/video/video_file_frames/_get_frame.py +6 -8
  200. endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +4 -18
  201. endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +4 -3
  202. endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +7 -6
  203. endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +6 -8
  204. endoreg_db/models/media/video/video_file_frames/_get_frames.py +6 -8
  205. endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +15 -25
  206. endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +26 -23
  207. endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +23 -14
  208. endoreg_db/models/media/video/video_file_io.py +113 -61
  209. endoreg_db/models/media/video/video_file_meta/get_crop_template.py +3 -3
  210. endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +5 -3
  211. endoreg_db/models/media/video/video_file_meta/get_fps.py +37 -34
  212. endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +19 -25
  213. endoreg_db/models/media/video/video_file_meta/text_meta.py +41 -38
  214. endoreg_db/models/media/video/video_file_meta/video_meta.py +14 -7
  215. endoreg_db/models/media/video/video_file_segments.py +24 -17
  216. endoreg_db/models/media/video/video_metadata.py +19 -35
  217. endoreg_db/models/media/video/video_processing.py +96 -95
  218. endoreg_db/models/medical/contraindication/README.md +1 -0
  219. endoreg_db/models/medical/contraindication/__init__.py +13 -3
  220. endoreg_db/models/medical/disease.py +22 -16
  221. endoreg_db/models/medical/event.py +31 -18
  222. endoreg_db/models/medical/examination/__init__.py +13 -6
  223. endoreg_db/models/medical/examination/examination.py +39 -20
  224. endoreg_db/models/medical/examination/examination_indication.py +30 -95
  225. endoreg_db/models/medical/examination/examination_time.py +23 -8
  226. endoreg_db/models/medical/examination/examination_time_type.py +9 -6
  227. endoreg_db/models/medical/examination/examination_type.py +3 -4
  228. endoreg_db/models/medical/finding/finding.py +32 -40
  229. endoreg_db/models/medical/finding/finding_classification.py +42 -72
  230. endoreg_db/models/medical/finding/finding_intervention.py +25 -22
  231. endoreg_db/models/medical/finding/finding_type.py +13 -12
  232. endoreg_db/models/medical/hardware/endoscope.py +26 -26
  233. endoreg_db/models/medical/hardware/endoscopy_processor.py +2 -2
  234. endoreg_db/models/medical/laboratory/lab_value.py +62 -91
  235. endoreg_db/models/medical/medication/medication.py +22 -10
  236. endoreg_db/models/medical/medication/medication_indication.py +29 -3
  237. endoreg_db/models/medical/medication/medication_indication_type.py +25 -14
  238. endoreg_db/models/medical/medication/medication_intake_time.py +31 -19
  239. endoreg_db/models/medical/medication/medication_schedule.py +27 -16
  240. endoreg_db/models/medical/organ/__init__.py +15 -12
  241. endoreg_db/models/medical/patient/medication_examples.py +6 -6
  242. endoreg_db/models/medical/patient/patient_disease.py +20 -23
  243. endoreg_db/models/medical/patient/patient_event.py +19 -22
  244. endoreg_db/models/medical/patient/patient_examination.py +48 -54
  245. endoreg_db/models/medical/patient/patient_examination_indication.py +16 -14
  246. endoreg_db/models/medical/patient/patient_finding.py +122 -139
  247. endoreg_db/models/medical/patient/patient_finding_classification.py +44 -49
  248. endoreg_db/models/medical/patient/patient_finding_intervention.py +8 -19
  249. endoreg_db/models/medical/patient/patient_lab_sample.py +28 -23
  250. endoreg_db/models/medical/patient/patient_lab_value.py +82 -89
  251. endoreg_db/models/medical/patient/patient_medication.py +27 -38
  252. endoreg_db/models/medical/patient/patient_medication_schedule.py +28 -36
  253. endoreg_db/models/medical/risk/risk.py +7 -6
  254. endoreg_db/models/medical/risk/risk_type.py +8 -5
  255. endoreg_db/models/metadata/model_meta.py +60 -29
  256. endoreg_db/models/metadata/model_meta_logic.py +125 -18
  257. endoreg_db/models/metadata/pdf_meta.py +31 -24
  258. endoreg_db/models/metadata/sensitive_meta.py +105 -85
  259. endoreg_db/models/metadata/sensitive_meta_logic.py +198 -103
  260. endoreg_db/models/metadata/video_meta.py +51 -31
  261. endoreg_db/models/metadata/video_prediction_logic.py +16 -23
  262. endoreg_db/models/metadata/video_prediction_meta.py +29 -33
  263. endoreg_db/models/other/distribution/date_value_distribution.py +89 -29
  264. endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +21 -5
  265. endoreg_db/models/other/distribution/numeric_value_distribution.py +114 -53
  266. endoreg_db/models/other/distribution/single_categorical_value_distribution.py +4 -3
  267. endoreg_db/models/other/emission/emission_factor.py +18 -8
  268. endoreg_db/models/other/gender.py +10 -5
  269. endoreg_db/models/other/information_source.py +50 -29
  270. endoreg_db/models/other/material.py +9 -5
  271. endoreg_db/models/other/resource.py +6 -4
  272. endoreg_db/models/other/tag.py +10 -5
  273. endoreg_db/models/other/transport_route.py +13 -8
  274. endoreg_db/models/other/unit.py +10 -6
  275. endoreg_db/models/other/waste.py +6 -5
  276. endoreg_db/models/report/report.py +6 -0
  277. endoreg_db/models/requirement/requirement.py +329 -361
  278. endoreg_db/models/requirement/requirement_error.py +85 -0
  279. endoreg_db/models/requirement/requirement_evaluation/evaluate_with_dependencies.py +268 -0
  280. endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +3 -6
  281. endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +90 -64
  282. endoreg_db/models/requirement/requirement_operator.py +103 -112
  283. endoreg_db/models/requirement/requirement_set.py +74 -57
  284. endoreg_db/models/state/__init__.py +4 -4
  285. endoreg_db/models/state/abstract.py +2 -2
  286. endoreg_db/models/state/anonymization.py +12 -0
  287. endoreg_db/models/state/audit_ledger.py +49 -51
  288. endoreg_db/models/state/label_video_segment.py +9 -0
  289. endoreg_db/models/state/raw_pdf.py +101 -68
  290. endoreg_db/models/state/sensitive_meta.py +6 -2
  291. endoreg_db/models/state/video.py +110 -90
  292. endoreg_db/models/upload_job.py +35 -34
  293. endoreg_db/models/utils.py +28 -25
  294. endoreg_db/queries/__init__.py +3 -1
  295. endoreg_db/root_urls.py +21 -2
  296. endoreg_db/schemas/examination_evaluation.py +1 -1
  297. endoreg_db/serializers/__init__.py +2 -10
  298. endoreg_db/serializers/anonymization.py +18 -10
  299. endoreg_db/serializers/label_video_segment/label_video_segment.py +2 -29
  300. endoreg_db/serializers/meta/__init__.py +1 -6
  301. endoreg_db/serializers/meta/sensitive_meta_detail.py +63 -118
  302. endoreg_db/serializers/misc/file_overview.py +11 -99
  303. endoreg_db/serializers/misc/sensitive_patient_data.py +50 -26
  304. endoreg_db/serializers/patient_examination/patient_examination.py +3 -3
  305. endoreg_db/serializers/pdf/anony_text_validation.py +39 -23
  306. endoreg_db/serializers/requirements/requirement_sets.py +92 -22
  307. endoreg_db/serializers/video/segmentation.py +2 -1
  308. endoreg_db/serializers/video/video_file_list.py +65 -34
  309. endoreg_db/serializers/video/video_processing_history.py +20 -5
  310. endoreg_db/services/__old/pdf_import.py +1487 -0
  311. endoreg_db/services/__old/video_import.py +1306 -0
  312. endoreg_db/services/anonymization.py +128 -89
  313. endoreg_db/services/lookup_service.py +65 -52
  314. endoreg_db/services/lookup_store.py +2 -2
  315. endoreg_db/services/pdf_import.py +0 -1382
  316. endoreg_db/services/report_import.py +10 -0
  317. endoreg_db/services/video_import.py +6 -1255
  318. endoreg_db/tasks/upload_tasks.py +79 -70
  319. endoreg_db/tasks/video_ingest.py +8 -4
  320. endoreg_db/urls/__init__.py +5 -32
  321. endoreg_db/urls/ai.py +32 -0
  322. endoreg_db/urls/media.py +121 -83
  323. endoreg_db/urls/root_urls.py +29 -0
  324. endoreg_db/utils/__init__.py +15 -5
  325. endoreg_db/utils/ai/multilabel_classification_net.py +116 -20
  326. endoreg_db/utils/case_generator/__init__.py +3 -0
  327. endoreg_db/utils/dataloader.py +142 -40
  328. endoreg_db/utils/defaults/set_default_center.py +32 -0
  329. endoreg_db/utils/names.py +22 -16
  330. endoreg_db/utils/paths.py +110 -46
  331. endoreg_db/utils/permissions.py +2 -1
  332. endoreg_db/utils/pipelines/Readme.md +1 -1
  333. endoreg_db/utils/pipelines/process_video_dir.py +1 -1
  334. endoreg_db/utils/requirement_operator_logic/_old/model_evaluators.py +655 -0
  335. endoreg_db/utils/requirement_operator_logic/new_operator_logic.py +97 -0
  336. endoreg_db/utils/setup_config.py +8 -5
  337. endoreg_db/utils/storage.py +115 -0
  338. endoreg_db/utils/validate_endo_roi.py +8 -2
  339. endoreg_db/utils/video/ffmpeg_wrapper.py +184 -188
  340. endoreg_db/views/__init__.py +85 -183
  341. endoreg_db/views/ai/__init__.py +8 -0
  342. endoreg_db/views/ai/label.py +155 -0
  343. endoreg_db/views/anonymization/media_management.py +202 -166
  344. endoreg_db/views/anonymization/overview.py +99 -67
  345. endoreg_db/views/anonymization/validate.py +182 -44
  346. endoreg_db/views/media/__init__.py +7 -20
  347. endoreg_db/views/media/pdf_media.py +197 -174
  348. endoreg_db/views/media/sensitive_metadata.py +193 -138
  349. endoreg_db/views/media/video_media.py +89 -82
  350. endoreg_db/views/meta/__init__.py +0 -8
  351. endoreg_db/views/misc/__init__.py +1 -7
  352. endoreg_db/views/misc/upload_views.py +94 -93
  353. endoreg_db/views/patient/patient.py +5 -4
  354. endoreg_db/views/report/__init__.py +5 -7
  355. endoreg_db/views/{pdf → report}/reimport.py +22 -22
  356. endoreg_db/views/{pdf/pdf_stream.py → report/report_stream.py} +46 -39
  357. endoreg_db/views/requirement/evaluate.py +188 -187
  358. endoreg_db/views/requirement/lookup.py +17 -3
  359. endoreg_db/views/requirement/lookup_store.py +22 -90
  360. endoreg_db/views/requirement/requirement_utils.py +89 -0
  361. endoreg_db/views/video/__init__.py +23 -24
  362. endoreg_db/views/video/correction.py +201 -172
  363. endoreg_db/views/video/reimport.py +1 -1
  364. endoreg_db/views/{media/video_segments.py → video/segments_crud.py} +77 -40
  365. endoreg_db/views/video/{video_meta.py → video_meta_stats.py} +2 -2
  366. endoreg_db/views/video/video_stream.py +7 -8
  367. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/METADATA +7 -3
  368. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/RECORD +391 -413
  369. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/WHEEL +1 -1
  370. endoreg_db/data/finding/anatomy_colon.yaml +0 -128
  371. endoreg_db/data/finding/colonoscopy.yaml +0 -40
  372. endoreg_db/data/finding/colonoscopy_bowel_prep.yaml +0 -56
  373. endoreg_db/data/finding/complication.yaml +0 -16
  374. endoreg_db/data/finding/data.yaml +0 -105
  375. endoreg_db/data/finding/examination_setting.yaml +0 -16
  376. endoreg_db/data/finding/medication_related.yaml +0 -18
  377. endoreg_db/data/finding/outcome.yaml +0 -12
  378. endoreg_db/data/finding_classification/colonoscopy_bowel_preparation.yaml +0 -95
  379. endoreg_db/data/finding_classification/colonoscopy_jnet.yaml +0 -22
  380. endoreg_db/data/finding_classification/colonoscopy_kudo.yaml +0 -25
  381. endoreg_db/data/finding_classification/colonoscopy_lesion_circularity.yaml +0 -20
  382. endoreg_db/data/finding_classification/colonoscopy_lesion_planarity.yaml +0 -24
  383. endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +0 -68
  384. endoreg_db/data/finding_classification/colonoscopy_lesion_surface.yaml +0 -20
  385. endoreg_db/data/finding_classification/colonoscopy_location.yaml +0 -80
  386. endoreg_db/data/finding_classification/colonoscopy_lst.yaml +0 -21
  387. endoreg_db/data/finding_classification/colonoscopy_nice.yaml +0 -20
  388. endoreg_db/data/finding_classification/colonoscopy_paris.yaml +0 -26
  389. endoreg_db/data/finding_classification/colonoscopy_sano.yaml +0 -22
  390. endoreg_db/data/finding_classification/colonoscopy_summary.yaml +0 -53
  391. endoreg_db/data/finding_classification/complication_generic.yaml +0 -25
  392. endoreg_db/data/finding_classification/examination_setting_generic.yaml +0 -40
  393. endoreg_db/data/finding_classification/histology_colo.yaml +0 -51
  394. endoreg_db/data/finding_classification/intervention_required.yaml +0 -26
  395. endoreg_db/data/finding_classification/medication_related.yaml +0 -23
  396. endoreg_db/data/finding_classification/visualized.yaml +0 -33
  397. endoreg_db/data/finding_classification_choice/colon_lesion_circularity_default.yaml +0 -32
  398. endoreg_db/data/finding_classification_choice/colon_lesion_jnet.yaml +0 -15
  399. endoreg_db/data/finding_classification_choice/colon_lesion_kudo.yaml +0 -23
  400. endoreg_db/data/finding_classification_choice/colon_lesion_lst.yaml +0 -15
  401. endoreg_db/data/finding_classification_choice/colon_lesion_nice.yaml +0 -17
  402. endoreg_db/data/finding_classification_choice/colon_lesion_planarity_default.yaml +0 -49
  403. endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +0 -14
  404. endoreg_db/data/finding_classification_choice/colon_lesion_surface_intact_default.yaml +0 -36
  405. endoreg_db/data/finding_classification_choice/colonoscopy_size.yaml +0 -82
  406. endoreg_db/data/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +0 -15
  407. endoreg_db/data/finding_classification_choice/outcome.yaml +0 -19
  408. endoreg_db/data/finding_intervention/endoscopy.yaml +0 -43
  409. endoreg_db/data/finding_intervention/endoscopy_colonoscopy.yaml +0 -168
  410. endoreg_db/data/finding_intervention/endoscopy_egd.yaml +0 -128
  411. endoreg_db/data/finding_intervention/endoscopy_ercp.yaml +0 -32
  412. endoreg_db/data/finding_intervention/endoscopy_eus_lower.yaml +0 -9
  413. endoreg_db/data/finding_intervention/endoscopy_eus_upper.yaml +0 -36
  414. endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +0 -79
  415. endoreg_db/data/requirement/age.yaml +0 -26
  416. endoreg_db/data/requirement/gender.yaml +0 -25
  417. endoreg_db/management/commands/init_default_ai_model.py +0 -112
  418. endoreg_db/management/commands/reset_celery_schedule.py +0 -9
  419. endoreg_db/management/commands/validate_video.py +0 -204
  420. endoreg_db/migrations/0002_add_video_correction_models.py +0 -52
  421. endoreg_db/migrations/0003_add_center_display_name.py +0 -30
  422. endoreg_db/models/administration/permissions/__init__.py +0 -44
  423. endoreg_db/models/rule/__init__.py +0 -13
  424. endoreg_db/models/rule/rule.py +0 -27
  425. endoreg_db/models/rule/rule_applicator.py +0 -224
  426. endoreg_db/models/rule/rule_attribute_dtype.py +0 -17
  427. endoreg_db/models/rule/rule_type.py +0 -20
  428. endoreg_db/models/rule/ruleset.py +0 -17
  429. endoreg_db/renames.yml +0 -8
  430. endoreg_db/serializers/_old/raw_pdf_meta_validation.py +0 -223
  431. endoreg_db/serializers/_old/raw_video_meta_validation.py +0 -179
  432. endoreg_db/serializers/_old/video.py +0 -71
  433. endoreg_db/serializers/meta/pdf_file_meta_extraction.py +0 -115
  434. endoreg_db/serializers/meta/report_meta.py +0 -53
  435. endoreg_db/serializers/report/__init__.py +0 -9
  436. endoreg_db/serializers/report/mixins.py +0 -45
  437. endoreg_db/serializers/report/report.py +0 -105
  438. endoreg_db/serializers/report/report_list.py +0 -22
  439. endoreg_db/serializers/report/secure_file_url.py +0 -26
  440. endoreg_db/serializers/video/video_metadata.py +0 -105
  441. endoreg_db/services/requirements_object.py +0 -147
  442. endoreg_db/services/storage_aware_video_processor.py +0 -344
  443. endoreg_db/urls/files.py +0 -6
  444. endoreg_db/urls/label_video_segment_validate.py +0 -33
  445. endoreg_db/urls/label_video_segments.py +0 -46
  446. endoreg_db/urls/report.py +0 -48
  447. endoreg_db/urls/video.py +0 -61
  448. endoreg_db/utils/case_generator/case_generator.py +0 -159
  449. endoreg_db/utils/case_generator/utils.py +0 -30
  450. endoreg_db/utils/requirement_operator_logic/model_evaluators.py +0 -368
  451. endoreg_db/views/label/__init__.py +0 -5
  452. endoreg_db/views/label/label.py +0 -15
  453. endoreg_db/views/label_video_segment/__init__.py +0 -16
  454. endoreg_db/views/label_video_segment/create_lvs_from_annotation.py +0 -44
  455. endoreg_db/views/label_video_segment/get_lvs_by_name_and_video.py +0 -50
  456. endoreg_db/views/label_video_segment/label_video_segment.py +0 -77
  457. endoreg_db/views/label_video_segment/label_video_segment_by_label.py +0 -174
  458. endoreg_db/views/label_video_segment/label_video_segment_detail.py +0 -73
  459. endoreg_db/views/label_video_segment/update_lvs_from_annotation.py +0 -46
  460. endoreg_db/views/label_video_segment/validate.py +0 -226
  461. endoreg_db/views/media/segments.py +0 -71
  462. endoreg_db/views/meta/available_files_list.py +0 -146
  463. endoreg_db/views/meta/report_meta.py +0 -53
  464. endoreg_db/views/meta/sensitive_meta_detail.py +0 -148
  465. endoreg_db/views/misc/secure_file_serving_view.py +0 -80
  466. endoreg_db/views/misc/secure_file_url_view.py +0 -84
  467. endoreg_db/views/misc/secure_url_validate.py +0 -79
  468. endoreg_db/views/patient_examination/DEPRECATED_video_backup.py +0 -164
  469. endoreg_db/views/patient_finding_location/__init__.py +0 -5
  470. endoreg_db/views/patient_finding_location/pfl_create.py +0 -70
  471. endoreg_db/views/patient_finding_morphology/__init__.py +0 -5
  472. endoreg_db/views/patient_finding_morphology/pfm_create.py +0 -70
  473. endoreg_db/views/pdf/__init__.py +0 -8
  474. endoreg_db/views/report/report_list.py +0 -112
  475. endoreg_db/views/report/report_with_secure_url.py +0 -28
  476. endoreg_db/views/report/start_examination.py +0 -7
  477. endoreg_db/views/video/segmentation.py +0 -274
  478. endoreg_db/views/video/task_status.py +0 -49
  479. endoreg_db/views/video/timeline.py +0 -46
  480. endoreg_db/views/video/video_analyze.py +0 -52
  481. endoreg_db/views.py +0 -0
  482. /endoreg_db/data/requirement/{colonoscopy_baseline_austria.yaml → old/colonoscopy_baseline_austria.yaml} +0 -0
  483. /endoreg_db/data/requirement/{disease_cardiovascular.yaml → old/disease_cardiovascular.yaml} +0 -0
  484. /endoreg_db/data/requirement/{disease_classification_choice_cardiovascular.yaml → old/disease_classification_choice_cardiovascular.yaml} +0 -0
  485. /endoreg_db/data/requirement/{disease_hepatology.yaml → old/disease_hepatology.yaml} +0 -0
  486. /endoreg_db/data/requirement/{disease_misc.yaml → old/disease_misc.yaml} +0 -0
  487. /endoreg_db/data/requirement/{disease_renal.yaml → old/disease_renal.yaml} +0 -0
  488. /endoreg_db/data/requirement/{endoscopy_bleeding_risk.yaml → old/endoscopy_bleeding_risk.yaml} +0 -0
  489. /endoreg_db/data/requirement/{event_cardiology.yaml → old/event_cardiology.yaml} +0 -0
  490. /endoreg_db/data/requirement/{event_requirements.yaml → old/event_requirements.yaml} +0 -0
  491. /endoreg_db/data/requirement/{finding_colon_polyp.yaml → old/finding_colon_polyp.yaml} +0 -0
  492. /endoreg_db/{migrations/__init__.py → data/requirement/old/gender.yaml} +0 -0
  493. /endoreg_db/data/requirement/{lab_value.yaml → old/lab_value.yaml} +0 -0
  494. /endoreg_db/data/requirement/{medication.yaml → old/medication.yaml} +0 -0
  495. /endoreg_db/data/requirement_operator/{age.yaml → _old/age.yaml} +0 -0
  496. /endoreg_db/data/requirement_operator/{lab_operators.yaml → _old/lab_operators.yaml} +0 -0
  497. /endoreg_db/data/requirement_operator/{model_operators.yaml → _old/model_operators.yaml} +0 -0
  498. /endoreg_db/{models/media/video/refactor_plan.md → import_files/pseudonymization/__init__.py} +0 -0
  499. /endoreg_db/{models/media/video/video_file_frames.py → import_files/pseudonymization/pseudonymize.py} +0 -0
  500. /endoreg_db/models/{metadata/frame_ocr_result.py → report/__init__.py} +0 -0
  501. /endoreg_db/{urls/sensitive_meta.py → models/report/images.py} +0 -0
  502. /endoreg_db/utils/requirement_operator_logic/{lab_value_operators.py → _old/lab_value_operators.py} +0 -0
  503. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/licenses/LICENSE +0 -0
@@ -1,117 +1,139 @@
1
1
  """
2
2
  Defines state tracking models related to video processing.
3
3
  """
4
- from django.db import models
5
- from .abstract import AbstractState
6
- from typing import TYPE_CHECKING, Optional
4
+
7
5
  import logging
8
6
  from enum import Enum
7
+ from typing import TYPE_CHECKING, Optional
8
+
9
+ from django.db import models, transaction
10
+
11
+ from endoreg_db.models.state.anonymization import AnonymizationState
9
12
 
10
13
  logger = logging.getLogger(__name__)
11
14
 
12
15
  if TYPE_CHECKING:
13
16
  from ..media import VideoFile
14
-
15
17
 
16
- class AnonymizationStatus(str, Enum):
17
- NOT_STARTED = "not_started"
18
- EXTRACTING_FRAMES = "extracting_frames"
19
- PROCESSING_ANONYMIZING = "processing_anonymization"
20
- DONE = "done"
21
- VALIDATED = "validated"
22
- FAILED = "failed"
23
- STARTED = "started"
24
18
 
25
19
  class VideoState(models.Model):
26
20
  """
27
21
  Tracks the processing state of a VideoFile instance.
28
22
  Uses BooleanFields for clear, distinct states.
29
23
  """
24
+
30
25
  # Frame related states
31
26
  if TYPE_CHECKING:
32
- video_file: Optional["VideoFile"]
33
-
34
- frames_extracted = models.BooleanField(default=False, help_text="True if raw frames have been extracted to files.")
35
- frames_initialized = models.BooleanField(default=False, help_text="True if Frame DB objects have been created.")
36
- frame_count = models.PositiveIntegerField(null=True, blank=True, help_text="Number of frames extracted/initialized.")
27
+ video_file: models.OneToOneField["VideoFile"]
28
+
29
+ frames_extracted = models.BooleanField(
30
+ default=False, help_text="True if raw frames have been extracted to files."
31
+ )
32
+ frames_initialized = models.BooleanField(
33
+ default=False, help_text="True if Frame DB objects have been created."
34
+ )
35
+ frame_count = models.PositiveIntegerField(
36
+ null=True, blank=True, help_text="Number of frames extracted/initialized."
37
+ )
37
38
 
38
39
  # Metadata related states
39
- video_meta_extracted = models.BooleanField(default=False, help_text="True if VideoMeta (technical specs) has been extracted.")
40
- text_meta_extracted = models.BooleanField(default=False, help_text="True if text metadata (OCR) has been extracted.")
40
+ video_meta_extracted = models.BooleanField(
41
+ default=False,
42
+ help_text="True if VideoMeta (technical specs) has been extracted.",
43
+ )
44
+ text_meta_extracted = models.BooleanField(
45
+ default=False, help_text="True if text metadata (OCR) has been extracted."
46
+ )
41
47
 
42
48
  # AI / Annotation related states
43
- initial_prediction_completed = models.BooleanField(default=False, help_text="True if initial AI prediction has run.")
44
- lvs_created = models.BooleanField(default=False, help_text="True if LabelVideoSegments have been created from predictions.")
45
- frame_annotations_generated = models.BooleanField(default=False, help_text="True if frame-level annotations have been generated from segments.")
46
-
49
+ initial_prediction_completed = models.BooleanField(
50
+ default=False, help_text="True if initial AI prediction has run."
51
+ )
52
+ lvs_created = models.BooleanField(
53
+ default=False,
54
+ help_text="True if LabelVideoSegments have been created from predictions.",
55
+ )
56
+ frame_annotations_generated = models.BooleanField(
57
+ default=False,
58
+ help_text="True if frame-level annotations have been generated from segments.",
59
+ )
60
+
47
61
  # Processing state
48
- sensitive_meta_processed = models.BooleanField(default=False, help_text="True if the video has been fully processed, meaning a anonymized person was created.")
62
+ sensitive_meta_processed = models.BooleanField(
63
+ default=False,
64
+ help_text="True if the video has been fully processed, meaning a anonymized person was created.",
65
+ )
49
66
 
50
67
  # Anonymization state
51
- anonymized = models.BooleanField(default=False, help_text="True if the anonymized video file has been created.")
52
- anonymization_validated = models.BooleanField(default=False, help_text="True if the anonymization process has been validated and confirmed.")
53
- anonymization_status: AnonymizationStatus
54
-
55
- processing_started = models.BooleanField(default=False, help_text="True if the processing has started, but not yet completed.")
56
-
68
+ anonymized = models.BooleanField(
69
+ default=False, help_text="True if the anonymized video file has been created."
70
+ )
71
+ anonymization_validated = models.BooleanField(
72
+ default=False,
73
+ help_text="True if the anonymization process has been validated and confirmed.",
74
+ )
75
+
76
+ processing_started = models.BooleanField(
77
+ default=False,
78
+ help_text="True if the processing has started, but not yet completed.",
79
+ )
80
+
57
81
  # Timestamps
58
82
  date_created = models.DateTimeField(auto_now_add=True)
59
83
  date_modified = models.DateTimeField(auto_now=True)
60
-
84
+
61
85
  # Segment Annotation State
62
- segment_annotations_created = models.BooleanField(default=False, help_text="True if segment annotations have been created from LabelVideoSegments.")
63
- segment_annotations_validated = models.BooleanField(default=False, help_text="True if segment annotations have been validated.")
64
-
65
- was_created = models.BooleanField(default=True, help_text="True if this state was created for the first time.")
66
-
86
+ segment_annotations_created = models.BooleanField(
87
+ default=False,
88
+ help_text="True if segment annotations have been created from LabelVideoSegments.",
89
+ )
90
+ segment_annotations_validated = models.BooleanField(
91
+ default=False, help_text="True if segment annotations have been validated."
92
+ )
93
+
94
+ was_created = models.BooleanField(
95
+ default=True, help_text="True if this state was created for the first time."
96
+ )
97
+
67
98
  objects = models.Manager()
68
99
 
69
- def __str__(self):
70
- # Find the related VideoFile's UUID if possible
71
- video_uuid = "Unknown"
72
- try:
73
- # Access the related VideoFile via the reverse relation 'video_file'
74
- if hasattr(self, 'video_file') and self.video_file:
75
- video_uuid = self.video_file.uuid
76
- except Exception:
77
- pass # Ignore errors if relation doesn't exist or causes issues
78
-
79
- states = [
80
- f"FramesExtracted={self.frames_extracted}",
81
- f"FramesInit={self.frames_initialized}",
82
- f"VideoMetaExtracted={self.video_meta_extracted}",
83
- f"TextMetaExtracted={self.text_meta_extracted}",
84
- f"PredictionDone={self.initial_prediction_completed}",
85
- f"LvsCreated={self.lvs_created}",
86
- f"Anonymized={self.anonymized}",
87
- f"AnonymizationValidated={self.anonymization_validated}",
88
- f"SensitiveMetaProcessed={self.sensitive_meta_processed}",
89
- f"FrameCount={self.frame_count}" if self.frame_count is not None else "FrameCount=None",
90
- f"SegmentAnnotationsCreated={self.segment_annotations_created}",
91
- f"SegmentAnnotationsValidated={self.segment_annotations_validated}",
92
- f"DateCreated={self.date_created.isoformat()}",
93
- f"DateModified={self.date_modified.isoformat()}"
94
- ]
95
- return f"VideoState(Video:{video_uuid}): {', '.join(states)}"
96
100
 
97
101
  @property
98
- def anonymization_status(self) -> AnonymizationStatus:
102
+ def anonymization_status(self) -> AnonymizationState:
99
103
  """
100
104
  Fast, side‑effect‑free status resolution used by API & UI.
101
105
  """
102
106
  if self.anonymization_validated:
103
- return AnonymizationStatus.VALIDATED
107
+ return AnonymizationState.VALIDATED # Validation in Frontend completed -> Views related to this /home/admin/endoreg-db/endoreg_db/views/anonymization/validate.py
104
108
  if self.sensitive_meta_processed:
105
- return AnonymizationStatus.DONE
109
+ return AnonymizationState.DONE_PROCESSING_ANONYMIZATION # /home/admin/endoreg-db/endoreg_db/services/video_import.py /home/admin/endoreg-db/endoreg_db/views/video/reimport.py
106
110
  if self.frames_extracted and not self.anonymized:
107
- return AnonymizationStatus.PROCESSING_ANONYMIZING
111
+ return AnonymizationState.PROCESSING_ANONYMIZING
108
112
  if self.was_created and not self.frames_extracted:
109
- return AnonymizationStatus.EXTRACTING_FRAMES
113
+ return AnonymizationState.EXTRACTING_FRAMES
110
114
  if getattr(self, "processing_error", False):
111
- return AnonymizationStatus.FAILED
115
+ return AnonymizationState.FAILED
112
116
  if self.processing_started:
113
- return AnonymizationStatus.STARTED
114
- return AnonymizationStatus.NOT_STARTED
117
+ return AnonymizationState.STARTED
118
+ if self.anonymized:
119
+ return AnonymizationState.ANONYMIZED
120
+ return AnonymizationState.NOT_STARTED
121
+
122
+ def mark_processing_not_started(self) -> None:
123
+ """
124
+ Mark the processing as not started and optionally save the updated state.
125
+
126
+ Parameters:
127
+ save (bool): If True, persist the change to the database immediately. Defaults to True.
128
+ """
129
+ with transaction.atomic():
130
+ self.processing_started = False
131
+ self.anonymized = False
132
+ self.was_created = False
133
+ self.sensitive_meta_processed = False
134
+ self.anonymization_validated = False
135
+ self.frames_extracted = False
136
+ self.save()
115
137
 
116
138
  # ---- Single‑responsibility mutators ---------------------------------
117
139
  def mark_sensitive_meta_processed(self, *, save: bool = True) -> None:
@@ -122,7 +144,7 @@ class VideoState(models.Model):
122
144
  def mark_anonymization_validated(self, *, save: bool = True) -> None:
123
145
  """
124
146
  Mark the anonymization process as validated for this video state.
125
-
147
+
126
148
  Parameters:
127
149
  save (bool): If True, persist the change to the database immediately.
128
150
  """
@@ -133,7 +155,7 @@ class VideoState(models.Model):
133
155
  def mark_frames_extracted(self, *, save: bool = True) -> None:
134
156
  """
135
157
  Mark the video as having its frames extracted.
136
-
158
+
137
159
  Parameters:
138
160
  save (bool): If True, persist the change to the database immediately.
139
161
  """
@@ -144,7 +166,7 @@ class VideoState(models.Model):
144
166
  def mark_frames_not_extracted(self, *, save: bool = True) -> None:
145
167
  """
146
168
  Mark the video as having no extracted frames.
147
-
169
+
148
170
  If `save` is True, updates the database record for this state.
149
171
  """
150
172
  self.frames_extracted = False
@@ -154,18 +176,18 @@ class VideoState(models.Model):
154
176
  def mark_anonymized(self, *, save: bool = True) -> None:
155
177
  """
156
178
  Mark the video as anonymized by setting the anonymized flag to True.
157
-
179
+
158
180
  Parameters:
159
181
  save (bool): If True, immediately saves the updated state to the database.
160
182
  """
161
- self.anonymized = True
162
- if save:
183
+ with transaction.atomic():
184
+ self.anonymized = True
163
185
  self.save(update_fields=["anonymized", "date_modified"])
164
186
 
165
187
  def mark_initial_prediction_completed(self, *, save: bool = True) -> None:
166
188
  """
167
189
  Mark the initial AI prediction as completed for this video state.
168
-
190
+
169
191
  Parameters:
170
192
  save (bool): If True, persist the change to the database immediately.
171
193
  """
@@ -176,7 +198,7 @@ class VideoState(models.Model):
176
198
  def mark_video_meta_extracted(self, *, save: bool = True) -> None:
177
199
  """
178
200
  Mark the video metadata as extracted for this video state.
179
-
201
+
180
202
  Parameters:
181
203
  save (bool): If True, immediately saves the updated state to the database.
182
204
  """
@@ -187,45 +209,43 @@ class VideoState(models.Model):
187
209
  def mark_text_meta_extracted(self, *, save: bool = True) -> None:
188
210
  """
189
211
  Mark the video as having its text metadata extracted.
190
-
212
+
191
213
  Parameters:
192
- save (bool): If True, immediately saves the updated state to the database.
214
+ save (bool): If True, immediately saves the updated state to the database.
193
215
  """
194
216
  self.text_meta_extracted = True
195
217
  if save:
196
218
  self.save(update_fields=["text_meta_extracted", "date_modified"])
197
-
219
+
198
220
  def get_or_create_state(self):
199
221
  """
200
222
  Get the current state of the video, or create a new one if it doesn't exist.
201
-
223
+
202
224
  Returns:
203
225
  VideoState: The current or newly created state.
204
226
  """
205
- if not hasattr(self, 'video_file'):
227
+ if not hasattr(self, "video_file"):
206
228
  raise ValueError("This method requires a related VideoFile instance.")
207
-
229
+
208
230
  # If the state already exists, return it
209
231
  if self.video_file.state:
210
232
  return self.video_file.state
211
-
233
+
212
234
  # Otherwise, create a new state
213
235
  new_state = VideoState(video_file=self.video_file)
214
236
  new_state.save()
215
237
  return new_state
216
-
238
+
217
239
  def mark_processing_started(self, *, save: bool = True) -> None:
218
240
  """
219
241
  Mark the processing as started for this video state.
220
-
242
+
221
243
  Parameters:
222
244
  save (bool): If True, immediately saves the updated state to the database.
223
245
  """
224
246
  self.processing_started = True
225
247
  if save:
226
248
  self.save(update_fields=["processing_started", "date_modified"])
227
-
228
-
229
249
 
230
250
  class Meta:
231
251
  verbose_name = "Video Processing State"
@@ -1,69 +1,70 @@
1
1
  import uuid
2
+ from typing import TYPE_CHECKING, cast
3
+
2
4
  from django.db import models
3
5
 
4
6
 
5
7
  class UploadJob(models.Model):
6
8
  """
7
9
  Tracks file upload jobs and their processing status.
8
- Supports both PDF and video file uploads with asynchronous processing.
10
+ Supports both report and video file uploads with asynchronous processing.
9
11
  """
10
-
12
+
11
13
  class Status(models.TextChoices):
12
- PENDING = 'pending', 'Pending'
13
- PROCESSING = 'processing', 'Processing'
14
- ANONYMIZED = 'anonymized', 'Anonymized'
15
- ERROR = 'error', 'Error'
14
+ PENDING = "pending", "Pending"
15
+ PROCESSING = "processing", "Processing"
16
+ ANONYMIZED = "anonymized", "Anonymized"
17
+ ERROR = "error", "Error"
16
18
 
17
19
  id = models.UUIDField(
18
- primary_key=True,
19
- default=uuid.uuid4,
20
+ primary_key=True,
21
+ default=uuid.uuid4,
20
22
  editable=False,
21
- help_text="Unique identifier for the upload job"
23
+ help_text="Unique identifier for the upload job",
22
24
  )
23
-
25
+
24
26
  file = models.FileField(
25
- upload_to='uploads/%Y/%m/%d/',
26
- help_text="Uploaded file (PDF or video)"
27
+ upload_to="uploads/%Y/%m/%d/", help_text="Uploaded file (report or video)"
27
28
  )
28
-
29
+
29
30
  status = models.CharField(
30
31
  max_length=20,
31
32
  choices=Status.choices,
32
33
  default=Status.PENDING,
33
- help_text="Current processing status of the upload"
34
+ help_text="Current processing status of the upload",
34
35
  )
35
-
36
+
36
37
  content_type = models.CharField(
37
- max_length=100,
38
- blank=True,
39
- help_text="MIME type of the uploaded file"
38
+ max_length=100, blank=True, help_text="MIME type of the uploaded file"
40
39
  )
41
-
40
+
42
41
  sensitive_meta = models.ForeignKey(
43
- 'SensitiveMeta',
42
+ "SensitiveMeta",
44
43
  null=True,
45
44
  blank=True,
46
45
  on_delete=models.SET_NULL,
47
- help_text="Link to the created SensitiveMeta record after processing"
46
+ help_text="Link to the created SensitiveMeta record after processing",
48
47
  )
49
-
48
+
50
49
  error_detail = models.TextField(
51
- blank=True,
52
- help_text="Error message if processing failed"
50
+ blank=True, help_text="Error message if processing failed"
53
51
  )
54
-
52
+
55
53
  created_at = models.DateTimeField(
56
- auto_now_add=True,
57
- help_text="When the upload job was created"
54
+ auto_now_add=True, help_text="When the upload job was created"
58
55
  )
59
-
56
+
60
57
  updated_at = models.DateTimeField(
61
- auto_now=True,
62
- help_text="When the upload job was last updated"
58
+ auto_now=True, help_text="When the upload job was last updated"
63
59
  )
64
60
 
61
+ if TYPE_CHECKING:
62
+ from django.db.models.fields.files import FieldFile
63
+
64
+ file = cast(FieldFile, file)
65
+
65
66
  class Meta:
66
- ordering = ['-created_at']
67
+ ordering = ["-created_at"]
67
68
  verbose_name = "Upload Job"
68
69
  verbose_name_plural = "Upload Jobs"
69
70
 
@@ -83,17 +84,17 @@ class UploadJob(models.Model):
83
84
  def mark_processing(self):
84
85
  """Mark the job as processing."""
85
86
  self.status = self.Status.PROCESSING
86
- self.save(update_fields=['status', 'updated_at'])
87
+ self.save(update_fields=["status", "updated_at"])
87
88
 
88
89
  def mark_completed(self, sensitive_meta=None):
89
90
  """Mark the job as successfully completed."""
90
91
  self.status = self.Status.ANONYMIZED
91
92
  if sensitive_meta:
92
93
  self.sensitive_meta = sensitive_meta
93
- self.save(update_fields=['status', 'sensitive_meta', 'updated_at'])
94
+ self.save(update_fields=["status", "sensitive_meta", "updated_at"])
94
95
 
95
96
  def mark_error(self, error_detail: str):
96
97
  """Mark the job as failed with error details."""
97
98
  self.status = self.Status.ERROR
98
99
  self.error_detail = error_detail
99
- self.save(update_fields=['status', 'error_detail', 'updated_at'])
100
+ self.save(update_fields=["status", "error_detail", "updated_at"])
@@ -1,32 +1,29 @@
1
- from ..utils import (
2
- data_paths,
3
- DJANGO_NAME_SALT,
4
- )
5
- from django.core.files import File
6
- from django.core.files.storage import FileSystemStorage
7
1
  import io
8
2
  import os
9
- from tqdm import tqdm
10
- import numpy as np
11
- import cv2
12
- from typing import TYPE_CHECKING, List, Tuple
13
3
  from pathlib import Path
4
+ from typing import TYPE_CHECKING, List, Tuple
5
+
6
+ import cv2
7
+ import numpy as np
8
+ from django.core.files import File
9
+ from django.core.files.storage import FileSystemStorage
10
+
11
+ from ..utils import DJANGO_NAME_SALT, data_paths
12
+
14
13
  if TYPE_CHECKING:
15
- from ..models.media import VideoFile
14
+ pass
16
15
 
17
16
  from logging import getLogger
18
17
 
19
18
  logger = getLogger(__name__)
20
19
 
21
20
  STORAGE_DIR = data_paths["storage"]
22
- FILE_STORAGE = FileSystemStorage(location = STORAGE_DIR)
23
- VIDEO_DIR = data_paths["video"]
24
- TMP_VIDEO_DIR = VIDEO_DIR / "tmp"
25
- ANONYM_VIDEO_DIR = data_paths["video_export"]
21
+ FILE_STORAGE = FileSystemStorage(location=str(STORAGE_DIR))
22
+ TRANSCODING_DIR = data_paths["transcoding"]
26
23
  FRAME_DIR = data_paths["frame"]
27
24
  WEIGHTS_DIR = data_paths["weights"]
28
- PDF_DIR = data_paths["raw_pdf"]
29
- DOCUMENT_DIR = data_paths["pdf"]
25
+ REPORT_DIR = data_paths["import_report"]
26
+ DOCUMENT_DIR = data_paths["documents"] #TODO Verify if this is still used and assign correct dir
30
27
 
31
28
  TEST_RUN = os.environ.get("TEST_RUN", "False")
32
29
  TEST_RUN = TEST_RUN.lower() == "true"
@@ -71,8 +68,13 @@ def find_segments_in_prediction_array(prediction_array: np.array, min_frame_len:
71
68
 
72
69
  return segments
73
70
 
71
+
74
72
  def anonymize_frame(
75
- raw_frame_path: Path, target_frame_path: Path, endo_roi, all_black: bool = False, censor_color: Tuple[int, int, int] = (0, 0, 0) # Added censor_color param
73
+ raw_frame_path: Path,
74
+ target_frame_path: Path,
75
+ endo_roi,
76
+ all_black: bool = False,
77
+ censor_color: Tuple[int, int, int] = (0, 0, 0), # Added censor_color param
76
78
  ):
77
79
  """
78
80
  Anonymize the frame by blacking out pixels outside the endoscope ROI or making the whole frame black.
@@ -89,7 +91,9 @@ def anonymize_frame(
89
91
  # Validate ROI dictionary keys
90
92
  required_keys = {"x", "y", "width", "height"}
91
93
  if not required_keys.issubset(endo_roi):
92
- raise ValueError(f"Invalid endo_roi dictionary provided: {endo_roi}. Missing keys.")
94
+ raise ValueError(
95
+ f"Invalid endo_roi dictionary provided: {endo_roi}. Missing keys."
96
+ )
93
97
 
94
98
  x = endo_roi["x"]
95
99
  y = endo_roi["y"]
@@ -102,7 +106,9 @@ def anonymize_frame(
102
106
  x2, y2 = min(w_orig, x + width), min(h_orig, y + height)
103
107
 
104
108
  if x1 >= x2 or y1 >= y2:
105
- logger.warning(f"ROI [{x},{y},{width},{height}] is outside or invalid for frame dimensions {w_orig}x{h_orig}. Resulting frame might be all black.")
109
+ logger.warning(
110
+ f"ROI [{x},{y},{width},{height}] is outside or invalid for frame dimensions {w_orig}x{h_orig}. Resulting frame might be all black."
111
+ )
106
112
  else:
107
113
  # copy valid endoscope roi part to black frame
108
114
  new_frame[y1:y2, x1:x2] = frame[y1:y2, x1:x2]
@@ -120,16 +126,13 @@ __all__ = [
120
126
  "DJANGO_NAME_SALT",
121
127
  "data_paths",
122
128
  "FILE_STORAGE",
123
- "VIDEO_DIR",
124
- "TMP_VIDEO_DIR",
125
129
  "ANONYM_VIDEO_DIR",
126
130
  "FRAME_DIR",
127
131
  "WEIGHTS_DIR",
128
- "PDF_DIR",
129
- "DOCUMENT_DIR",
132
+ "REPORT_DIR",
130
133
  "prepare_bulk_frames",
131
134
  "anonymize_frame",
132
135
  "find_segments_in_prediction_array",
133
136
  "TEST_RUN",
134
137
  "TEST_RUN_FRAME_NUMBER",
135
- ]
138
+ ]
@@ -2,4 +2,6 @@ from .annotations import (
2
2
  generate_legacy_dataset_output
3
3
  )
4
4
 
5
- from .get import *
5
+ __all__ = [
6
+ "generate_legacy_dataset_output"
7
+ ]
endoreg_db/root_urls.py CHANGED
@@ -1,9 +1,28 @@
1
+ # endoreg_db/root_urls.py
2
+ from django.contrib import admin
1
3
  from django.urls import include, path
4
+ from django.http import HttpResponse
5
+ from django.conf import settings
6
+ from django.conf.urls.static import static
2
7
 
3
- # Import raw API urlpatterns (no prefix) from the URLs package
8
+ # Import raw API urlpatterns (no prefix) from your API urls package
4
9
  from endoreg_db.urls import urlpatterns as api_urlpatterns
5
10
 
6
- # Mount the API under /api/
11
+ def public_home(_request):
12
+ return HttpResponse("Public home – no login required.")
13
+
7
14
  urlpatterns = [
15
+ path("", public_home, name="public_home"),
16
+ #path("admin/", admin.site.urls),
17
+
18
+ # Mount ALL API endpoints under /api/
8
19
  path("api/", include((api_urlpatterns, "endoreg_db"), namespace="api")),
20
+
21
+ # OIDC (mozilla-django-oidc provides /oidc/authenticate/ and /oidc/callback/)
22
+ path("oidc/", include("mozilla_django_oidc.urls")),
9
23
  ]
24
+
25
+ # Serve static/media only in DEBUG (at root, not under /api/)
26
+ if settings.DEBUG:
27
+ urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
28
+ urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
@@ -19,7 +19,7 @@ class RequirementSetEval(BaseModel):
19
19
  linked_sets: List["RequirementSetEval"] = Field(default_factory=list)
20
20
 
21
21
  class ExaminationEvalReport(BaseModel):
22
- examination_id: int
22
+ examination_id: int | None = None
23
23
  summary: dict
24
24
  sets: List[RequirementSetEval]
25
25
  errors: List[str] = Field(default_factory=list)
@@ -12,8 +12,7 @@ from .examination import (
12
12
  )
13
13
  from .finding import FindingSerializer
14
14
  from .finding_classification import (
15
- FindingClassificationChoiceSerializer,
16
- FindingClassificationSerializer,
15
+ FindingClassificationSerializer, # FindingClassificationChoiceSerializer,
17
16
  )
18
17
  from .label import ImageClassificationAnnotationSerializer, LabelSerializer
19
18
  from .label_video_segment import (
@@ -21,8 +20,6 @@ from .label_video_segment import (
21
20
  LabelVideoSegmentSerializer,
22
21
  )
23
22
  from .meta import (
24
- PDFFileForMetaSerializer,
25
- ReportMetaSerializer,
26
23
  SensitiveMetaDetailSerializer,
27
24
  SensitiveMetaUpdateSerializer,
28
25
  SensitiveMetaVerificationSerializer,
@@ -47,8 +44,6 @@ from .patient_finding import (
47
44
  PatientFindingWriteSerializer,
48
45
  )
49
46
  from .pdf import RawPdfAnonyTextSerializer
50
- from .report import ReportDataSerializer, ReportListSerializer, SecureFileUrlSerializer
51
- from .video.video_metadata import VideoMetadataSerializer
52
47
  from .video.video_processing_history import VideoProcessingHistorySerializer
53
48
  from .video_examination import (
54
49
  VideoExaminationCreateSerializer,
@@ -77,8 +72,6 @@ __all__ = [
77
72
  "LabelVideoSegmentSerializer",
78
73
  "LabelVideoSegmentAnnotationSerializer",
79
74
  # Meta
80
- "PDFFileForMetaSerializer",
81
- "ReportMetaSerializer",
82
75
  "SensitiveMetaDetailSerializer",
83
76
  "SensitiveMetaUpdateSerializer",
84
77
  "SensitiveMetaVerificationSerializer",
@@ -102,14 +95,13 @@ __all__ = [
102
95
  "PatientFindingInterventionSerializer",
103
96
  "PatientFindingListSerializer",
104
97
  "PatientFindingWriteSerializer",
105
- # PDF
98
+ # report
106
99
  "RawPdfAnonyTextSerializer",
107
100
  # Report
108
101
  "ReportListSerializer",
109
102
  "ReportDataSerializer",
110
103
  "SecureFileUrlSerializer",
111
104
  # Video Correction (Phase 1.1)
112
- "VideoMetadataSerializer",
113
105
  "VideoProcessingHistorySerializer",
114
106
  # Video Examination
115
107
  "VideoExaminationSerializer",