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,15 +0,0 @@
1
-
2
- from rest_framework.viewsets import ReadOnlyModelViewSet
3
- from rest_framework.permissions import IsAuthenticatedOrReadOnly
4
- from endoreg_db.models import (
5
- Label,
6
- )
7
- from endoreg_db.serializers.label import LabelSerializer
8
-
9
-
10
-
11
- class LabelViewSet(ReadOnlyModelViewSet):
12
- queryset = Label.objects.all()
13
- serializer_class = LabelSerializer
14
- permission_classes = [IsAuthenticatedOrReadOnly]
15
-
@@ -1,16 +0,0 @@
1
- from .create_lvs_from_annotation import create_video_segment_annotation
2
- from .label_video_segment_by_label import video_segments_by_label_id_view, video_segments_by_label_name_view
3
- from .label_video_segment_detail import video_segment_detail_view
4
- from .label_video_segment import video_segments_view
5
- from .update_lvs_from_annotation import update_label_video_segment
6
- from .get_lvs_by_name_and_video import get_lvs_by_name_and_video_id
7
-
8
- __all__ = [
9
- 'create_video_segment_annotation',
10
- 'video_segments_by_label_id_view',
11
- 'video_segments_by_label_name_view',
12
- 'video_segment_detail_view',
13
- 'video_segments_view',
14
- 'update_label_video_segment',
15
- "get_lvs_by_name_and_video_id"
16
- ]
@@ -1,44 +0,0 @@
1
- from endoreg_db.models import LabelVideoSegment
2
- from endoreg_db.serializers.label_video_segment.label_video_segment_annotation import LabelVideoSegmentAnnotationSerializer
3
-
4
- from django.db import transaction
5
- from rest_framework import status
6
- from rest_framework.decorators import api_view, permission_classes
7
- from rest_framework.permissions import IsAuthenticated
8
- from rest_framework.response import Response
9
-
10
- import logging
11
-
12
- logger = logging.getLogger(__name__)
13
-
14
- @api_view(['POST'])
15
- @permission_classes([IsAuthenticated])
16
- def create_video_segment_annotation(request):
17
- """
18
- Create a new annotation.
19
- If annotation type is 'segment', creates a user-source LabelVideoSegment.
20
- """
21
- logger.info(f"Creating annotation with data: {request.data}")
22
-
23
- with transaction.atomic():
24
- serializer = LabelVideoSegmentAnnotationSerializer(data=request.data)
25
- if serializer.is_valid():
26
- annotation = serializer.save()
27
-
28
- # If the annotation type is 'segment', create a new LabelVideoSegment
29
- if annotation.type == 'segment':
30
- metadata = annotation.metadata or {}
31
- #TODO @coderabbitai we should create a followup issue for @Hamzaukw so we adress this naming inconsistency in future
32
- LabelVideoSegment.objects.create(
33
- video_id=annotation.video_id,
34
- start_frame=metadata.get('start_frame'),
35
- end_frame=metadata.get('end_frame'),
36
- label=metadata.get('label'),
37
- source='user'
38
- )
39
-
40
- logger.info(f"Successfully created annotation {annotation.id}")
41
- return Response(serializer.data, status=status.HTTP_201_CREATED)
42
-
43
- logger.error(f"Failed to create annotation with data: {request.data}, errors: {serializer.errors}")
44
- return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@@ -1,50 +0,0 @@
1
- from endoreg_db.models import Label, LabelVideoSegment, VideoFile
2
- from endoreg_db.serializers.label_video_segment.label_video_segment import LabelVideoSegmentSerializer
3
-
4
- from rest_framework import status
5
- from rest_framework.decorators import api_view, permission_classes
6
- from rest_framework.response import Response
7
-
8
- from endoreg_db.utils.permissions import EnvironmentAwarePermission
9
- import logging
10
- logger = logging.getLogger(__name__)
11
-
12
- @api_view(['GET'])
13
- @permission_classes([EnvironmentAwarePermission])
14
- def get_lvs_by_name_and_video_id(request, label_name, video_id):
15
- """
16
- Handles creation and retrieval of labeled video segments.
17
- GET lists all labeled video segments, filtered by video ID and label name.
18
- Returns appropriate error responses for invalid input or missing referenced objects.
19
- """
20
-
21
- # Check if label exists
22
- try:
23
- _label = Label.objects.get(name=label_name)
24
- except Label.DoesNotExist:
25
- logger.error(f"Label with name '{label_name}' does not exist.")
26
- return Response(
27
- {"error": f"Label with name '{label_name}' does not exist."},
28
- status=status.HTTP_404_NOT_FOUND
29
- )
30
-
31
- # Check if video exists
32
- try:
33
- _video = VideoFile.objects.get(id=video_id)
34
- except VideoFile.DoesNotExist:
35
- logger.error(f"Video with ID '{video_id}' does not exist.")
36
- return Response(
37
- {"error": f"Video with ID '{video_id}' does not exist."},
38
- status=status.HTTP_404_NOT_FOUND
39
- )
40
-
41
- # get all segments for the given video and label name
42
- queryset = LabelVideoSegment.objects.filter(
43
- video_file__id=video_id,
44
- label__name=label_name
45
- )
46
-
47
- # Order by video and start time for consistent results
48
- segments = queryset.order_by('video_file__id', 'start_frame_number')
49
- serializer = LabelVideoSegmentSerializer(segments, many=True)
50
- return Response(serializer.data)
@@ -1,77 +0,0 @@
1
- from endoreg_db.models import Label, LabelVideoSegment, VideoFile
2
- from endoreg_db.serializers.label_video_segment.label_video_segment import LabelVideoSegmentSerializer
3
-
4
- from django.db import transaction
5
- from rest_framework import status
6
- from rest_framework.decorators import api_view, permission_classes
7
- from rest_framework.response import Response
8
-
9
- from endoreg_db.utils.permissions import EnvironmentAwarePermission
10
- import logging
11
- logger = logging.getLogger(__name__)
12
-
13
- @api_view(['POST', 'GET'])
14
- @permission_classes([EnvironmentAwarePermission])
15
- def video_segments_view(request):
16
- """
17
- Handles creation and retrieval of labeled video segments.
18
-
19
- POST creates a new labeled video segment with validated data and returns the created segment. GET lists all labeled video segments, optionally filtered by video ID and/or label ID. Returns appropriate error responses for invalid input or missing referenced objects.
20
- """
21
- if request.method == 'POST':
22
- logger.info(f"Creating new video segment with data: {request.data}")
23
-
24
- with transaction.atomic():
25
- serializer = LabelVideoSegmentSerializer(data=request.data)
26
- if serializer.is_valid():
27
- try:
28
- segment = serializer.save()
29
- logger.info(f"Successfully created video segment {segment.pk}")
30
- return Response(
31
- LabelVideoSegmentSerializer(segment).data,
32
- status=status.HTTP_201_CREATED
33
- )
34
- except Exception as e:
35
- logger.error(f"Error creating video segment: {str(e)}")
36
- return Response(
37
- {'error': f'Failed to create segment: {str(e)}'},
38
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
39
- )
40
- else:
41
- logger.warning(f"Invalid data for video segment creation: {serializer.errors}")
42
- return Response(
43
- {'error': 'Invalid data', 'details': serializer.errors},
44
- status=status.HTTP_400_BAD_REQUEST
45
- )
46
-
47
- elif request.method == 'GET':
48
- # Optional filtering by video_id
49
- video_id = request.GET.get('video_id')
50
- label_id = request.GET.get('label_id')
51
-
52
- queryset = LabelVideoSegment.objects.all()
53
-
54
- if video_id:
55
- try:
56
- video = VideoFile.objects.get(id=video_id)
57
- queryset = queryset.filter(video_file=video)
58
- except VideoFile.DoesNotExist:
59
- return Response(
60
- {'error': f'Video with id {video_id} not found'},
61
- status=status.HTTP_404_NOT_FOUND
62
- )
63
-
64
- if label_id:
65
- try:
66
- label = Label.objects.get(id=label_id)
67
- queryset = queryset.filter(label=label)
68
- except Label.DoesNotExist:
69
- return Response(
70
- {'error': f'Label with id {label_id} not found'},
71
- status=status.HTTP_404_NOT_FOUND
72
- )
73
-
74
- # Order by video and start time for consistent results
75
- segments = queryset.order_by('video_file__id', 'start_frame_number')
76
- serializer = LabelVideoSegmentSerializer(segments, many=True)
77
- return Response(serializer.data)
@@ -1,174 +0,0 @@
1
- from endoreg_db.models import Label, LabelVideoSegment, VideoFile
2
- from django.shortcuts import get_object_or_404
3
- from django.http import Http404
4
- from rest_framework import status
5
- from rest_framework.decorators import api_view, permission_classes
6
- from rest_framework.response import Response
7
-
8
- from endoreg_db.utils.permissions import DEBUG_PERMISSIONS
9
-
10
- import logging
11
-
12
- logger = logging.getLogger(__name__)
13
-
14
- DEFAULT_FPS = 50 #TODO move to settings or config
15
-
16
- @api_view(['GET'])
17
- @permission_classes(DEBUG_PERMISSIONS) #TODO: Uncomment this line if authentication is set up
18
- def video_segments_by_label_id_view(request, video_id, label_id):
19
- """
20
- Retrieves all labeled segments for a given video and label by their IDs.
21
-
22
- Returns a list of time segments for the specified video and label, including start and end frames and their corresponding times in seconds. If no segments exist, returns an empty list. Responds with 404 if the video or label is not found.
23
- """
24
- try:
25
- video = get_object_or_404(VideoFile, id=video_id)
26
- label = get_object_or_404(Label, id=label_id)
27
-
28
- # Get all segments for this video and label combination
29
- segments = LabelVideoSegment.objects.filter(
30
- video_file=video,
31
- label=label
32
- ).order_by('start_frame_number')
33
-
34
- # Build response in the expected format
35
- if segments.exists():
36
- # Get video properties for time calculation
37
- fps = video.get_fps() or DEFAULT_FPS # Use module-level constant
38
-
39
- time_segments = []
40
- for segment in segments:
41
- # Convert frame numbers to time
42
- start_time = segment.start_frame_number / fps
43
- end_time = segment.end_frame_number / fps
44
-
45
- time_segments.append({
46
- 'segment_start': segment.start_frame_number,
47
- 'segment_end': segment.end_frame_number,
48
- 'start_time': start_time,
49
- 'end_time': end_time,
50
- 'frames': {} # Empty for now, can be populated if needed
51
- })
52
-
53
- response_data = {
54
- 'label': label.name,
55
- 'label_id': label.id,
56
- 'time_segments': time_segments
57
- }
58
- else:
59
- # Return empty response if no segments found
60
- response_data = {
61
- 'label': label.name,
62
- 'label_id': label.id,
63
- 'time_segments': []
64
- }
65
-
66
- return Response(response_data)
67
- except Http404 as e:
68
- return Response({'error': str(e)}, status=status.HTTP_404_NOT_FOUND)
69
- except VideoFile.DoesNotExist:
70
- return Response(
71
- {'error': f'Video with id {video_id} not found'},
72
- status=status.HTTP_404_NOT_FOUND
73
- )
74
- except Label.DoesNotExist:
75
- return Response(
76
- {'error': f'Label with id {label_id} not found'},
77
- status=status.HTTP_404_NOT_FOUND
78
- )
79
- except Exception as e:
80
- logger.error(f"Error fetching segments for video {video_id} and label {label_id}: {str(e)}")
81
- return Response(
82
- {'error': f'Internal server error: {str(e)}'},
83
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
84
- )
85
-
86
-
87
- @api_view(['GET'])
88
- @permission_classes(DEBUG_PERMISSIONS) #TODO: Uncomment this line if authentication is set up
89
- def video_segments_by_label_name_view(request, video_id, label_name):
90
- """
91
- Retrieves labeled video segments for a given video and label name.
92
-
93
- Handles cases where multiple labels share the same name by returning a conflict response with details of all matching labels and a suggestion to use the label ID endpoint. If a unique label is found, returns a list of segments for the specified video and label, including frame and time information. Returns appropriate error responses if the video or label is not found, or if an internal error occurs.
94
- """
95
- try:
96
- video = get_object_or_404(VideoFile, id=video_id)
97
-
98
- # Find all labels with this name
99
- labels_with_name = Label.objects.filter(name=label_name)
100
-
101
- if not labels_with_name.exists():
102
- return Response(
103
- {'error': f'No labels found with name "{label_name}"'},
104
- status=status.HTTP_404_NOT_FOUND
105
- )
106
-
107
- if labels_with_name.count() > 1:
108
- # Multiple labels with same name - log warning and return info about all
109
- logger.warning(f"Multiple labels found with name '{label_name}': {[l.id for l in labels_with_name]}")
110
-
111
- return Response({
112
- 'error': f'Multiple labels found with name "{label_name}"',
113
- 'suggestion': 'Use the label-id endpoint instead for unambiguous results',
114
- 'available_labels': [
115
- {'id': label.id, 'name': label.name, 'description': label.description}
116
- for label in labels_with_name
117
- ]
118
- }, status=status.HTTP_409_CONFLICT)
119
-
120
- # Single label found - proceed normally
121
- label = labels_with_name.first()
122
-
123
- # Get all segments for this video and label combination
124
- segments = LabelVideoSegment.objects.filter(
125
- video_file=video,
126
- label=label
127
- ).order_by('start_frame_number')
128
-
129
- # Build response in the expected format
130
- if segments.exists():
131
- # Get video properties for time calculation
132
- fps = video.get_fps() or DEFAULT_FPS # Use module-level constant
133
-
134
- time_segments = []
135
- for segment in segments:
136
- # Convert frame numbers to time
137
- start_time = segment.start_frame_number / fps
138
- end_time = segment.end_frame_number / fps
139
-
140
- time_segments.append({
141
- 'segment_start': segment.start_frame_number,
142
- 'segment_end': segment.end_frame_number,
143
- 'start_time': start_time,
144
- 'end_time': end_time,
145
- 'frames': {} # Empty for now, can be populated if needed
146
- })
147
-
148
- response_data = {
149
- 'label': label.name,
150
- 'label_id': label.id,
151
- 'time_segments': time_segments
152
- }
153
- else:
154
- # Return empty response if no segments found
155
- response_data = {
156
- 'label': label.name,
157
- 'label_id': label.id,
158
- 'time_segments': []
159
- }
160
-
161
- return Response(response_data)
162
- except Http404 as e:
163
- return Response({'error': str(e)}, status=status.HTTP_404_NOT_FOUND)
164
- except VideoFile.DoesNotExist:
165
- return Response(
166
- {'error': f'Video with id {video_id} not found'},
167
- status=status.HTTP_404_NOT_FOUND
168
- )
169
- except Exception as e:
170
- logger.error(f"Error fetching segments for video {video_id} and label '{label_name}': {str(e)}")
171
- return Response(
172
- {'error': f'Internal server error: {str(e)}'},
173
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
174
- )
@@ -1,73 +0,0 @@
1
- from endoreg_db.models import LabelVideoSegment
2
- from endoreg_db.serializers.label_video_segment.label_video_segment import LabelVideoSegmentSerializer
3
- from django.db import transaction
4
- from django.shortcuts import get_object_or_404
5
- from rest_framework import status
6
- from rest_framework.decorators import api_view, permission_classes
7
- from rest_framework.response import Response
8
-
9
- from endoreg_db.utils.permissions import DEBUG_PERMISSIONS
10
-
11
- import logging
12
- logger = logging.getLogger(__name__)
13
-
14
- @api_view(['GET', 'PUT', 'DELETE', 'PATCH'])
15
- @permission_classes(DEBUG_PERMISSIONS)
16
- def video_segment_detail_view(request, segment_id):
17
- """
18
- Handles retrieval, update, and deletion of a single labeled video segment.
19
-
20
- Supports:
21
- - GET: Returns details of the specified video segment.
22
- - PUT: Partially updates the segment with validated data.
23
- - DELETE: Removes the segment from the database.
24
-
25
- Returns appropriate HTTP status codes and error messages for invalid data or exceptions.
26
- """
27
- segment = get_object_or_404(LabelVideoSegment, id=segment_id)
28
-
29
- if request.method == 'GET':
30
- serializer = LabelVideoSegmentSerializer(segment)
31
- return Response(serializer.data)
32
-
33
- elif request.method in ('PUT', 'PATCH'):
34
- logger.info(f"Updating video segment {segment_id} with data: {request.data}")
35
-
36
- partial = request.method == 'PATCH' # Allow partial updates with PATCH
37
-
38
- with transaction.atomic():
39
- serializer = LabelVideoSegmentSerializer(segment, data=request.data, partial=partial)
40
- if serializer.is_valid():
41
- try:
42
- segment = serializer.save()
43
- logger.info(f"Successfully updated video segment {segment_id}")
44
- return Response(LabelVideoSegmentSerializer(segment).data)
45
- except Exception as e:
46
- logger.error(f"Error updating video segment {segment_id}: {str(e)}")
47
- return Response(
48
- {'error': f'Failed to update segment: {str(e)}'},
49
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
50
- )
51
- else:
52
- logger.warning(f"Invalid data for video segment update: {serializer.errors}")
53
- return Response(
54
- {'error': 'Invalid data', 'details': serializer.errors},
55
- status=status.HTTP_400_BAD_REQUEST
56
- )
57
-
58
- elif request.method == 'DELETE':
59
- logger.info(f"Deleting video segment {segment_id}")
60
- try:
61
- with transaction.atomic():
62
- segment.delete()
63
- logger.info(f"Successfully deleted video segment {segment_id}")
64
- return Response(
65
- {'message': f'Segment {segment_id} deleted successfully'},
66
- status=status.HTTP_204_NO_CONTENT
67
- )
68
- except Exception as e:
69
- logger.error(f"Error deleting video segment {segment_id}: {str(e)}")
70
- return Response(
71
- {'error': f'Failed to delete segment: {str(e)}'},
72
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
73
- )
@@ -1,46 +0,0 @@
1
- from endoreg_db.models import LabelVideoSegment, InformationSource
2
- from endoreg_db.serializers import LabelVideoSegmentSerializer
3
- from rest_framework import status
4
- from rest_framework.decorators import api_view, permission_classes
5
- from rest_framework.permissions import IsAuthenticated
6
- from rest_framework.response import Response
7
- import logging
8
-
9
- logger = logging.getLogger(__name__)
10
-
11
- @api_view(['PATCH'])
12
- @permission_classes([IsAuthenticated])
13
- def update_label_video_segment(request, annotation_id) -> Response:
14
- """
15
- Update an existing LabelVideoSegment, treating it as a manual annotation.
16
- """
17
- logger.info(f"Updating LabelVideoSegment {annotation_id} with data: {request.data}")
18
-
19
- try:
20
- segment = LabelVideoSegment.objects.get(id=annotation_id)
21
- except LabelVideoSegment.DoesNotExist:
22
- logger.error(f"LabelVideoSegment {annotation_id} not found")
23
- return Response(
24
- {'error': 'Segment not found'},
25
- status=status.HTTP_404_NOT_FOUND
26
- )
27
-
28
- data = request.data
29
- updated = False
30
-
31
- if 'start_frame' in data:
32
- segment.start_frame_number = data['start_frame']
33
- updated = True
34
-
35
- if 'end_frame' in data:
36
- segment.end_frame_number = data['end_frame']
37
- updated = True
38
-
39
- if updated:
40
- # Ensure the source is correct for a manual annotation
41
- manual_source, _ = InformationSource.objects.get_or_create(name="manual_annotation")
42
- segment.source = manual_source
43
- segment.save()
44
-
45
- serializer = LabelVideoSegmentSerializer(segment)
46
- return Response(serializer.data)