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,73 +1,113 @@
1
1
  # Modern Media Framework: Sensitive Metadata Management
2
- from rest_framework.decorators import api_view, permission_classes
3
- from rest_framework.response import Response
4
- from rest_framework import status
2
+ import string
3
+
5
4
  from django.db import transaction
6
5
  from django.db.models import Q
7
6
  from django.shortcuts import get_object_or_404
8
- from endoreg_db.utils.permissions import EnvironmentAwarePermission
9
- from endoreg_db.models import VideoFile, RawPdfFile, SensitiveMeta
7
+ from numpy import number
8
+ from rest_framework import status
9
+ from rest_framework.decorators import api_view, permission_classes
10
+ from rest_framework.response import Response
11
+
12
+ from endoreg_db.models import RawPdfFile, SensitiveMeta, VideoFile
10
13
  from endoreg_db.serializers.meta import (
11
14
  SensitiveMetaDetailSerializer,
12
15
  SensitiveMetaUpdateSerializer,
13
16
  )
17
+ from endoreg_db.utils.permissions import EnvironmentAwarePermission
14
18
 
15
19
  # === VIDEO SENSITIVE METADATA ===
16
20
 
17
- @api_view(['GET', 'PATCH'])
21
+
22
+ @api_view(["GET"])
23
+ @permission_classes([EnvironmentAwarePermission])
24
+ def get_sensitive_metadata_pk(request, pk: number, mediaType: str) -> Response | None:
25
+ """
26
+ A route to get the sensitive meta pk for a media type quickly.
27
+
28
+ GET api/media/sensitive-media-id/<pk>/<str:mediaType>
29
+
30
+ Args:
31
+ request (_type_): _description_
32
+ id (_type_): _description_
33
+
34
+ Returns:
35
+ Response | None: _description_
36
+ """
37
+
38
+ if mediaType == "video":
39
+ video = get_object_or_404(VideoFile, pk=pk)
40
+ if not video.sensitive_meta:
41
+ return Response(
42
+ {"error": f"No sensitive metadata found for video {pk}"},
43
+ status=status.HTTP_404_NOT_FOUND,
44
+ )
45
+ sm_id = video.sensitive_meta.pk
46
+ return Response({"sm": sm_id})
47
+ if mediaType == "pdf":
48
+ pdf = get_object_or_404(RawPdfFile, pk=pk)
49
+ if not pdf.sensitive_meta:
50
+ return Response(
51
+ {"error": f"No sensitive metadata found for report {pk}"},
52
+ status=status.HTTP_404_NOT_FOUND,
53
+ )
54
+ sm_id = pdf.sensitive_meta.pk
55
+ return Response({"sm": sm_id})
56
+
57
+
58
+ @api_view(["GET", "PATCH"])
18
59
  @permission_classes([EnvironmentAwarePermission])
19
60
  def video_sensitive_metadata(request, pk):
20
61
  """
21
62
  GET /api/media/videos/<pk>/sensitive-metadata/
22
63
  PATCH /api/media/videos/<pk>/sensitive-metadata/
23
-
64
+
24
65
  Get or update sensitive metadata for a video.
25
- Video-scoped: Uses video ID to locate related sensitive metadata.
66
+ Video-scoped: Uses sensitive meta ID to locate related sensitive metadata.
26
67
  """
27
- video = get_object_or_404(VideoFile, pk=pk)
28
-
68
+ sensitive_meta = get_object_or_404(SensitiveMeta, pk=pk)
69
+
29
70
  # Get related sensitive metadata
30
- if not video.sensitive_meta:
71
+ if not sensitive_meta:
31
72
  return Response(
32
73
  {"error": f"No sensitive metadata found for video {pk}"},
33
- status=status.HTTP_404_NOT_FOUND
74
+ status=status.HTTP_404_NOT_FOUND,
34
75
  )
35
-
36
- sensitive_meta = video.sensitive_meta
37
-
38
- if request.method == 'GET':
76
+
77
+ if request.method == "GET":
39
78
  serializer = SensitiveMetaDetailSerializer(sensitive_meta)
40
79
  return Response(serializer.data, status=status.HTTP_200_OK)
41
-
42
- elif request.method == 'PATCH':
80
+
81
+ elif request.method == "PATCH":
43
82
  serializer = SensitiveMetaUpdateSerializer(
44
- sensitive_meta,
45
- data=request.data,
46
- partial=True
83
+ sensitive_meta, data=request.data, partial=True
47
84
  )
48
-
85
+
49
86
  if serializer.is_valid():
50
87
  updated_instance = serializer.save()
51
88
  response_serializer = SensitiveMetaDetailSerializer(updated_instance)
52
-
53
- return Response({
54
- "message": "Sensitive metadata updated successfully",
55
- "sensitive_meta": response_serializer.data,
56
- "video_id": pk
57
- }, status=status.HTTP_200_OK)
58
-
89
+
90
+ return Response(
91
+ {
92
+ "message": "Sensitive metadata updated successfully",
93
+ "sensitive_meta": response_serializer.data,
94
+ "video_id": pk,
95
+ },
96
+ status=status.HTTP_200_OK,
97
+ )
98
+
59
99
  return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
60
100
 
61
101
 
62
- @api_view(['POST'])
102
+ @api_view(["POST"])
63
103
  @permission_classes([EnvironmentAwarePermission])
64
104
  @transaction.atomic
65
105
  def video_sensitive_metadata_verify(request, pk):
66
106
  """
67
107
  POST /api/media/videos/<pk>/sensitive-metadata/verify/
68
-
108
+
69
109
  Update verification state for video sensitive metadata.
70
-
110
+
71
111
  Expected payload:
72
112
  {
73
113
  "dob_verified": true,
@@ -75,98 +115,103 @@ def video_sensitive_metadata_verify(request, pk):
75
115
  }
76
116
  """
77
117
  video = get_object_or_404(VideoFile, pk=pk)
78
-
118
+
79
119
  if not video.sensitive_meta:
80
120
  return Response(
81
121
  {"error": f"No sensitive metadata found for video {pk}"},
82
- status=status.HTTP_404_NOT_FOUND
122
+ status=status.HTTP_404_NOT_FOUND,
83
123
  )
84
-
124
+
85
125
  sensitive_meta = video.sensitive_meta
86
-
87
- dob_verified = request.data.get('dob_verified')
88
- names_verified = request.data.get('names_verified')
89
-
126
+
127
+ dob_verified = request.data.get("dob_verified")
128
+ names_verified = request.data.get("names_verified")
129
+
90
130
  if dob_verified is None and names_verified is None:
91
131
  return Response(
92
- {"error": "At least one of dob_verified or names_verified must be provided"},
93
- status=status.HTTP_400_BAD_REQUEST
132
+ {
133
+ "error": "At least one of dob_verified or names_verified must be provided"
134
+ },
135
+ status=status.HTTP_400_BAD_REQUEST,
94
136
  )
95
-
137
+
96
138
  state = sensitive_meta.get_or_create_state()
97
-
139
+
98
140
  if dob_verified is not None:
99
141
  state.dob_verified = dob_verified
100
142
  if names_verified is not None:
101
143
  state.names_verified = names_verified
102
-
144
+
103
145
  state.save()
104
-
146
+
105
147
  response_serializer = SensitiveMetaDetailSerializer(sensitive_meta)
106
- return Response({
107
- "message": "Verification state updated successfully",
108
- "sensitive_meta": response_serializer.data,
109
- "video_id": pk,
110
- "state_verified": state.is_verified
111
- }, status=status.HTTP_200_OK)
148
+ return Response(
149
+ {
150
+ "message": "Verification state updated successfully",
151
+ "sensitive_meta": response_serializer.data,
152
+ "video_id": pk,
153
+ "state_verified": state.is_verified,
154
+ },
155
+ status=status.HTTP_200_OK,
156
+ )
157
+
112
158
 
159
+ # === report SENSITIVE METADATA ===
113
160
 
114
- # === PDF SENSITIVE METADATA ===
115
161
 
116
- @api_view(['GET', 'PATCH'])
162
+ @api_view(["GET", "PATCH"])
117
163
  @permission_classes([EnvironmentAwarePermission])
118
164
  def pdf_sensitive_metadata(request, pk):
119
165
  """
120
166
  GET /api/media/pdfs/<pk>/sensitive-metadata/
121
167
  PATCH /api/media/pdfs/<pk>/sensitive-metadata/
122
-
123
- Get or update sensitive metadata for a PDF.
124
- PDF-scoped: Uses PDF ID to locate related sensitive metadata.
168
+
169
+ Get or update sensitive metadata for a report.
170
+ report-scoped: Uses report ID to locate related sensitive metadata.
125
171
  """
126
- pdf = get_object_or_404(RawPdfFile, pk=pk)
127
-
172
+ sensitive_meta = get_object_or_404(SensitiveMeta, pk=pk)
173
+
128
174
  # Get related sensitive metadata
129
- if not pdf.sensitive_meta:
175
+ if not sensitive_meta:
130
176
  return Response(
131
- {"error": f"No sensitive metadata found for PDF {pk}"},
132
- status=status.HTTP_404_NOT_FOUND
177
+ {"error": f"No sensitive metadata found for report {pk}"},
178
+ status=status.HTTP_404_NOT_FOUND,
133
179
  )
134
-
135
- sensitive_meta = pdf.sensitive_meta
136
-
137
- if request.method == 'GET':
180
+
181
+ if request.method == "GET":
138
182
  serializer = SensitiveMetaDetailSerializer(sensitive_meta)
139
183
  return Response(serializer.data, status=status.HTTP_200_OK)
140
-
141
- elif request.method == 'PATCH':
184
+
185
+ elif request.method == "PATCH":
142
186
  serializer = SensitiveMetaUpdateSerializer(
143
- sensitive_meta,
144
- data=request.data,
145
- partial=True
187
+ sensitive_meta, data=request.data, partial=True
146
188
  )
147
-
189
+
148
190
  if serializer.is_valid():
149
191
  updated_instance = serializer.save()
150
192
  response_serializer = SensitiveMetaDetailSerializer(updated_instance)
151
-
152
- return Response({
153
- "message": "Sensitive metadata updated successfully",
154
- "sensitive_meta": response_serializer.data,
155
- "pdf_id": pk
156
- }, status=status.HTTP_200_OK)
157
-
193
+
194
+ return Response(
195
+ {
196
+ "message": "Sensitive metadata updated successfully",
197
+ "sensitive_meta": response_serializer.data,
198
+ "pdf_id": pk,
199
+ },
200
+ status=status.HTTP_200_OK,
201
+ )
202
+
158
203
  return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
159
204
 
160
205
 
161
- @api_view(['POST'])
206
+ @api_view(["POST"])
162
207
  @permission_classes([EnvironmentAwarePermission])
163
208
  @transaction.atomic
164
209
  def pdf_sensitive_metadata_verify(request, pk):
165
210
  """
166
211
  POST /api/media/pdfs/<pk>/sensitive-metadata/verify/
167
-
168
- Update verification state for PDF sensitive metadata.
169
-
212
+
213
+ Update verification state for report sensitive metadata.
214
+
170
215
  Expected payload:
171
216
  {
172
217
  "dob_verified": true,
@@ -174,53 +219,59 @@ def pdf_sensitive_metadata_verify(request, pk):
174
219
  }
175
220
  """
176
221
  pdf = get_object_or_404(RawPdfFile, pk=pk)
177
-
222
+
178
223
  if not pdf.sensitive_meta:
179
224
  return Response(
180
- {"error": f"No sensitive metadata found for PDF {pk}"},
181
- status=status.HTTP_404_NOT_FOUND
225
+ {"error": f"No sensitive metadata found for report {pk}"},
226
+ status=status.HTTP_404_NOT_FOUND,
182
227
  )
183
-
228
+
184
229
  sensitive_meta = pdf.sensitive_meta
185
-
186
- dob_verified = request.data.get('dob_verified')
187
- names_verified = request.data.get('names_verified')
188
-
230
+
231
+ dob_verified = request.data.get("dob_verified")
232
+ names_verified = request.data.get("names_verified")
233
+
189
234
  if dob_verified is None and names_verified is None:
190
235
  return Response(
191
- {"error": "At least one of dob_verified or names_verified must be provided"},
192
- status=status.HTTP_400_BAD_REQUEST
236
+ {
237
+ "error": "At least one of dob_verified or names_verified must be provided"
238
+ },
239
+ status=status.HTTP_400_BAD_REQUEST,
193
240
  )
194
-
241
+
195
242
  state = sensitive_meta.get_or_create_state()
196
-
243
+
197
244
  if dob_verified is not None:
198
245
  state.dob_verified = dob_verified
199
246
  if names_verified is not None:
200
247
  state.names_verified = names_verified
201
-
248
+
202
249
  state.save()
203
-
250
+
204
251
  response_serializer = SensitiveMetaDetailSerializer(sensitive_meta)
205
- return Response({
206
- "message": "Verification state updated successfully",
207
- "sensitive_meta": response_serializer.data,
208
- "pdf_id": pk,
209
- "state_verified": state.is_verified
210
- }, status=status.HTTP_200_OK)
252
+ return Response(
253
+ {
254
+ "message": "Verification state updated successfully",
255
+ "sensitive_meta": response_serializer.data,
256
+ "pdf_id": pk,
257
+ "state_verified": state.is_verified,
258
+ },
259
+ status=status.HTTP_200_OK,
260
+ )
211
261
 
212
262
 
213
263
  # === LIST ENDPOINTS (Collection-Level) ===
214
264
 
215
- @api_view(['GET'])
265
+
266
+ @api_view(["GET"])
216
267
  @permission_classes([EnvironmentAwarePermission])
217
268
  def sensitive_metadata_list(request):
218
269
  """
219
270
  GET /api/media/sensitive-metadata/
220
-
271
+
221
272
  List all sensitive metadata (combined PDFs and Videos).
222
273
  Supports filtering by content_type, status, etc.
223
-
274
+
224
275
  Query parameters:
225
276
  - content_type: 'pdf' | 'video' (optional)
226
277
  - verified: Filter by verification status
@@ -228,87 +279,91 @@ def sensitive_metadata_list(request):
228
279
  - search: Search in patient names
229
280
  """
230
281
  from endoreg_db.serializers.meta import SensitiveMetaDetailSerializer
231
-
282
+
232
283
  # Get all sensitive metadata
233
- queryset = SensitiveMeta.objects.select_related('state').all()
234
-
284
+ queryset = SensitiveMeta.objects.select_related("state").all()
285
+
235
286
  # Filter by content type
236
- content_type = request.query_params.get('content_type')
237
- if content_type == 'pdf':
287
+ content_type = request.query_params.get("content_type")
288
+ if content_type == "pdf":
238
289
  # Only PDFs - filter by existence of related PDFs
239
290
  queryset = queryset.filter(raw_pdf_files__isnull=False).distinct()
240
- elif content_type == 'video':
291
+ elif content_type == "video":
241
292
  # Only Videos - filter by existence of related video
242
293
  queryset = queryset.filter(video_file__isnull=False).distinct()
243
-
294
+
244
295
  # Filter by verification status
245
- verified = request.query_params.get('verified')
296
+ verified = request.query_params.get("verified")
246
297
  if verified is not None:
247
- verified_bool = verified.lower() in ('true', '1', 'yes')
298
+ verified_bool = verified.lower() in ("true", "1", "yes")
248
299
  queryset = queryset.filter(state__is_verified=verified_bool)
249
-
300
+
250
301
  # Search in patient names
251
- search = request.query_params.get('search')
302
+ search = request.query_params.get("search")
252
303
  if search:
253
304
  queryset = queryset.filter(
254
- Q(patient_first_name__icontains=search) |
255
- Q(patient_last_name__icontains=search)
305
+ Q(patient_first_name__icontains=search)
306
+ | Q(patient_last_name__icontains=search)
256
307
  )
257
-
308
+
258
309
  # Ordering
259
- ordering = request.query_params.get('ordering', '-id')
310
+ ordering = request.query_params.get("ordering", "-id")
260
311
  queryset = queryset.order_by(ordering)
261
-
312
+
262
313
  # Pagination
263
314
  from rest_framework.pagination import PageNumberPagination
315
+
264
316
  paginator = PageNumberPagination()
265
317
  paginator.page_size = 20
266
318
  page = paginator.paginate_queryset(queryset, request)
267
-
319
+
268
320
  if page is not None:
269
321
  serializer = SensitiveMetaDetailSerializer(page, many=True)
270
322
  return paginator.get_paginated_response(serializer.data)
271
-
323
+
272
324
  serializer = SensitiveMetaDetailSerializer(queryset, many=True)
273
325
  return Response(serializer.data, status=status.HTTP_200_OK)
274
326
 
275
327
 
276
- @api_view(['GET'])
328
+ @api_view(["GET"])
277
329
  @permission_classes([EnvironmentAwarePermission])
278
330
  def pdf_sensitive_metadata_list(request):
279
331
  """
280
332
  GET /api/media/pdfs/sensitive-metadata/
281
-
333
+
282
334
  List sensitive metadata for PDFs only.
283
335
  Replaces legacy /api/pdf/sensitivemeta/list/
284
336
  """
285
337
  from endoreg_db.serializers.meta import SensitiveMetaDetailSerializer
286
-
338
+
287
339
  # Get all PDFs with sensitive metadata
288
- queryset = SensitiveMeta.objects.select_related('state').filter(
289
- raw_pdf_files__isnull=False
290
- ).distinct()
291
-
340
+ queryset = (
341
+ SensitiveMeta.objects.select_related("state")
342
+ .filter(raw_pdf_files__isnull=False)
343
+ .distinct()
344
+ )
345
+
292
346
  # Apply filters
293
- search = request.query_params.get('search')
347
+ search = request.query_params.get("search")
294
348
  if search:
295
349
  queryset = queryset.filter(
296
- Q(patient_first_name__icontains=search) |
297
- Q(patient_last_name__icontains=search)
350
+ Q(patient_first_name__icontains=search)
351
+ | Q(patient_last_name__icontains=search)
298
352
  )
299
-
300
- ordering = request.query_params.get('ordering', '-id')
353
+
354
+ ordering = request.query_params.get("ordering", "-id")
301
355
  queryset = queryset.order_by(ordering)
302
-
356
+
303
357
  # Pagination
304
358
  from rest_framework.pagination import PageNumberPagination
359
+
305
360
  paginator = PageNumberPagination()
306
361
  paginator.page_size = 20
307
362
  page = paginator.paginate_queryset(queryset, request)
308
-
363
+
309
364
  if page is not None:
310
365
  serializer = SensitiveMetaDetailSerializer(page, many=True)
311
366
  return paginator.get_paginated_response(serializer.data)
312
-
367
+
313
368
  serializer = SensitiveMetaDetailSerializer(queryset, many=True)
314
369
  return Response(serializer.data, status=status.HTTP_200_OK)