endoreg-db 0.8.8.0__py3-none-any.whl → 0.8.9.2__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 (402) hide show
  1. endoreg_db/data/__init__.py +22 -8
  2. endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +0 -1
  3. endoreg_db/data/examination/examinations/data.yaml +114 -14
  4. endoreg_db/data/examination/time-type/data.yaml +0 -3
  5. endoreg_db/data/examination_indication/endoscopy.yaml +108 -173
  6. endoreg_db/data/examination_indication_classification/endoscopy.yaml +0 -70
  7. endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +33 -37
  8. endoreg_db/data/finding/00_generic.yaml +35 -0
  9. endoreg_db/data/finding/00_generic_complication.yaml +9 -0
  10. endoreg_db/data/finding/01_gastroscopy_baseline.yaml +88 -0
  11. endoreg_db/data/finding/01_gastroscopy_observation.yaml +113 -0
  12. endoreg_db/data/finding/02_colonoscopy_baseline.yaml +53 -0
  13. endoreg_db/data/finding/02_colonoscopy_hidden.yaml +119 -0
  14. endoreg_db/data/finding/02_colonoscopy_observation.yaml +152 -0
  15. endoreg_db/data/finding_classification/00_generic.yaml +44 -0
  16. endoreg_db/data/finding_classification/00_generic_histology.yaml +28 -0
  17. endoreg_db/data/finding_classification/00_generic_lesion.yaml +52 -0
  18. endoreg_db/data/finding_classification/{colonoscopy_bowel_preparation.yaml → 02_colonoscopy_baseline.yaml} +35 -20
  19. endoreg_db/data/finding_classification/02_colonoscopy_histology.yaml +13 -0
  20. endoreg_db/data/finding_classification/02_colonoscopy_other.yaml +12 -0
  21. endoreg_db/data/finding_classification/02_colonoscopy_polyp.yaml +101 -0
  22. endoreg_db/data/finding_classification_choice/{yes_no_na.yaml → 00_generic.yaml} +5 -1
  23. endoreg_db/data/finding_classification_choice/{examination_setting_generic_types.yaml → 00_generic_baseline.yaml} +10 -2
  24. endoreg_db/data/finding_classification_choice/{complication_generic_types.yaml → 00_generic_complication.yaml} +1 -1
  25. endoreg_db/data/finding_classification_choice/{histology.yaml → 00_generic_histology.yaml} +1 -4
  26. endoreg_db/data/finding_classification_choice/00_generic_lesion.yaml +158 -0
  27. endoreg_db/data/finding_classification_choice/{bowel_preparation.yaml → 02_colonoscopy_bowel_preparation.yaml} +1 -30
  28. endoreg_db/data/{_examples/finding_classification_choice/colonoscopy_not_complete_reason.yaml → finding_classification_choice/02_colonoscopy_generic.yaml} +1 -1
  29. endoreg_db/data/finding_classification_choice/{histology_polyp.yaml → 02_colonoscopy_histology.yaml} +1 -1
  30. endoreg_db/data/{_examples/finding_classification_choice/colonoscopy_location.yaml → finding_classification_choice/02_colonoscopy_location.yaml} +23 -4
  31. endoreg_db/data/finding_classification_choice/02_colonoscopy_other.yaml +34 -0
  32. endoreg_db/data/finding_classification_choice/02_colonoscopy_polyp_advanced_imaging.yaml +76 -0
  33. endoreg_db/data/{_examples/finding_classification_choice/colon_lesion_paris.yaml → finding_classification_choice/02_colonoscopy_polyp_morphology.yaml} +26 -8
  34. endoreg_db/data/finding_classification_choice/02_colonoscopy_size.yaml +27 -0
  35. endoreg_db/data/finding_classification_type/{colonoscopy_basic.yaml → 00_generic.yaml} +18 -13
  36. endoreg_db/data/finding_classification_type/02_colonoscopy.yaml +9 -0
  37. endoreg_db/data/finding_intervention/00_generic_endoscopy.yaml +59 -0
  38. endoreg_db/data/finding_intervention/00_generic_endoscopy_ablation.yaml +44 -0
  39. endoreg_db/data/finding_intervention/00_generic_endoscopy_bleeding.yaml +55 -0
  40. endoreg_db/data/finding_intervention/00_generic_endoscopy_resection.yaml +85 -0
  41. endoreg_db/data/finding_intervention/00_generic_endoscopy_stenosis.yaml +17 -0
  42. endoreg_db/data/finding_intervention/00_generic_endoscopy_stent.yaml +9 -0
  43. endoreg_db/data/finding_intervention/01_gastroscopy.yaml +19 -0
  44. endoreg_db/data/finding_intervention/04_eus.yaml +39 -0
  45. endoreg_db/data/finding_intervention/05_ercp.yaml +3 -0
  46. endoreg_db/data/finding_type/data.yaml +8 -12
  47. endoreg_db/data/requirement/01_patient_data.yaml +93 -0
  48. endoreg_db/data/requirement_operator/new_operators.yaml +36 -0
  49. endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +0 -2
  50. endoreg_db/data/requirement_set/90_coloreg.yaml +20 -8
  51. endoreg_db/exceptions.py +0 -1
  52. endoreg_db/forms/examination_form.py +1 -1
  53. endoreg_db/helpers/data_loader.py +124 -52
  54. endoreg_db/helpers/default_objects.py +116 -81
  55. endoreg_db/import_files/__init__.py +27 -0
  56. endoreg_db/import_files/context/__init__.py +7 -0
  57. endoreg_db/import_files/context/default_sensitive_meta.py +81 -0
  58. endoreg_db/import_files/context/ensure_center.py +17 -0
  59. endoreg_db/import_files/context/file_lock.py +66 -0
  60. endoreg_db/import_files/context/import_context.py +43 -0
  61. endoreg_db/import_files/context/validate_directories.py +56 -0
  62. endoreg_db/import_files/file_storage/__init__.py +15 -0
  63. endoreg_db/import_files/file_storage/create_report_file.py +76 -0
  64. endoreg_db/import_files/file_storage/create_video_file.py +75 -0
  65. endoreg_db/import_files/file_storage/sensitive_meta_storage.py +39 -0
  66. endoreg_db/import_files/file_storage/state_management.py +496 -0
  67. endoreg_db/import_files/file_storage/storage.py +36 -0
  68. endoreg_db/import_files/import_service.md +26 -0
  69. endoreg_db/import_files/processing/__init__.py +11 -0
  70. endoreg_db/import_files/processing/report_processing/report_anonymization.py +94 -0
  71. endoreg_db/import_files/processing/sensitive_meta_adapter.py +51 -0
  72. endoreg_db/import_files/processing/video_processing/video_anonymization.py +107 -0
  73. endoreg_db/import_files/pseudonymization/fake.py +52 -0
  74. endoreg_db/import_files/pseudonymization/k_anonymity.py +182 -0
  75. endoreg_db/import_files/pseudonymization/k_pseudonymity.py +128 -0
  76. endoreg_db/import_files/pseudonymization/pseudonymize.py +0 -0
  77. endoreg_db/import_files/report_import_service.py +141 -0
  78. endoreg_db/import_files/video_import_service.py +150 -0
  79. endoreg_db/management/commands/import_report.py +130 -65
  80. endoreg_db/management/commands/import_video_with_classification.py +1 -1
  81. endoreg_db/management/commands/load_ai_model_data.py +5 -5
  82. endoreg_db/management/commands/load_ai_model_label_data.py +9 -7
  83. endoreg_db/management/commands/load_base_db_data.py +5 -134
  84. endoreg_db/management/commands/load_contraindication_data.py +14 -16
  85. endoreg_db/management/commands/load_disease_classification_choices_data.py +15 -18
  86. endoreg_db/management/commands/load_disease_classification_data.py +15 -18
  87. endoreg_db/management/commands/load_disease_data.py +25 -28
  88. endoreg_db/management/commands/load_endoscope_data.py +20 -27
  89. endoreg_db/management/commands/load_event_data.py +14 -16
  90. endoreg_db/management/commands/load_examination_data.py +31 -44
  91. endoreg_db/management/commands/load_examination_indication_data.py +20 -21
  92. endoreg_db/management/commands/load_finding_data.py +52 -80
  93. endoreg_db/management/commands/load_information_source.py +21 -23
  94. endoreg_db/management/commands/load_lab_value_data.py +17 -26
  95. endoreg_db/management/commands/load_medication_data.py +13 -12
  96. endoreg_db/management/commands/load_organ_data.py +15 -19
  97. endoreg_db/management/commands/load_pdf_type_data.py +19 -18
  98. endoreg_db/management/commands/load_profession_data.py +14 -17
  99. endoreg_db/management/commands/load_qualification_data.py +20 -23
  100. endoreg_db/management/commands/load_report_reader_flag_data.py +17 -19
  101. endoreg_db/management/commands/load_requirement_data.py +14 -20
  102. endoreg_db/management/commands/load_risk_data.py +7 -6
  103. endoreg_db/management/commands/load_shift_data.py +20 -23
  104. endoreg_db/management/commands/load_tag_data.py +8 -11
  105. endoreg_db/management/commands/load_unit_data.py +17 -19
  106. endoreg_db/management/commands/start_filewatcher.py +46 -37
  107. endoreg_db/management/commands/validate_video_files.py +1 -5
  108. endoreg_db/migrations/0001_initial.py +1360 -1812
  109. endoreg_db/models/administration/person/patient/patient.py +72 -46
  110. endoreg_db/models/label/__init__.py +2 -2
  111. endoreg_db/models/label/annotation/video_segmentation_annotation.py +18 -26
  112. endoreg_db/models/label/label_video_segment/label_video_segment.py +23 -1
  113. endoreg_db/models/media/pdf/raw_pdf.py +136 -64
  114. endoreg_db/models/media/pdf/report_reader/report_reader_config.py +34 -10
  115. endoreg_db/models/media/processing_history/__init__.py +5 -0
  116. endoreg_db/models/media/processing_history/processing_history.py +96 -0
  117. endoreg_db/models/media/video/create_from_file.py +101 -31
  118. endoreg_db/models/media/video/video_file.py +125 -105
  119. endoreg_db/models/media/video/video_file_io.py +31 -26
  120. endoreg_db/models/medical/contraindication/README.md +1 -0
  121. endoreg_db/models/medical/examination/examination.py +28 -8
  122. endoreg_db/models/medical/examination/examination_indication.py +13 -79
  123. endoreg_db/models/medical/examination/examination_time.py +8 -3
  124. endoreg_db/models/medical/finding/finding.py +5 -12
  125. endoreg_db/models/medical/finding/finding_classification.py +18 -37
  126. endoreg_db/models/medical/finding/finding_intervention.py +7 -9
  127. endoreg_db/models/medical/hardware/endoscope.py +6 -0
  128. endoreg_db/models/medical/patient/medication_examples.py +5 -1
  129. endoreg_db/models/medical/patient/patient_finding.py +1 -1
  130. endoreg_db/models/metadata/pdf_meta.py +22 -10
  131. endoreg_db/models/metadata/sensitive_meta.py +3 -0
  132. endoreg_db/models/metadata/sensitive_meta_logic.py +200 -124
  133. endoreg_db/models/other/information_source.py +27 -6
  134. endoreg_db/models/report/__init__.py +0 -0
  135. endoreg_db/models/report/images.py +0 -0
  136. endoreg_db/models/report/report.py +6 -0
  137. endoreg_db/models/requirement/requirement.py +59 -399
  138. endoreg_db/models/requirement/requirement_operator.py +86 -98
  139. endoreg_db/models/state/audit_ledger.py +4 -5
  140. endoreg_db/models/state/raw_pdf.py +69 -30
  141. endoreg_db/models/state/video.py +65 -49
  142. endoreg_db/models/upload_job.py +33 -9
  143. endoreg_db/models/utils.py +27 -23
  144. endoreg_db/queries/__init__.py +3 -1
  145. endoreg_db/schemas/examination_evaluation.py +1 -1
  146. endoreg_db/serializers/__init__.py +2 -8
  147. endoreg_db/serializers/label_video_segment/label_video_segment.py +2 -29
  148. endoreg_db/serializers/meta/__init__.py +1 -6
  149. endoreg_db/serializers/misc/sensitive_patient_data.py +50 -26
  150. endoreg_db/serializers/patient_examination/patient_examination.py +3 -3
  151. endoreg_db/serializers/pdf/anony_text_validation.py +39 -23
  152. endoreg_db/serializers/video/video_file_list.py +65 -34
  153. endoreg_db/services/__old/pdf_import.py +1487 -0
  154. endoreg_db/services/__old/video_import.py +1306 -0
  155. endoreg_db/services/anonymization.py +63 -26
  156. endoreg_db/services/lookup_service.py +28 -28
  157. endoreg_db/services/lookup_store.py +2 -2
  158. endoreg_db/services/pdf_import.py +0 -1480
  159. endoreg_db/services/report_import.py +10 -0
  160. endoreg_db/services/video_import.py +6 -1165
  161. endoreg_db/tasks/upload_tasks.py +79 -70
  162. endoreg_db/tasks/video_ingest.py +8 -4
  163. endoreg_db/urls/__init__.py +0 -14
  164. endoreg_db/urls/ai.py +32 -0
  165. endoreg_db/urls/media.py +21 -24
  166. endoreg_db/utils/dataloader.py +87 -57
  167. endoreg_db/utils/paths.py +110 -46
  168. endoreg_db/utils/pipelines/Readme.md +1 -1
  169. endoreg_db/utils/requirement_operator_logic/new_operator_logic.py +97 -0
  170. endoreg_db/utils/video/ffmpeg_wrapper.py +217 -52
  171. endoreg_db/views/__init__.py +85 -173
  172. endoreg_db/views/ai/__init__.py +8 -0
  173. endoreg_db/views/ai/label.py +155 -0
  174. endoreg_db/views/anonymization/media_management.py +8 -7
  175. endoreg_db/views/anonymization/overview.py +97 -68
  176. endoreg_db/views/anonymization/validate.py +25 -21
  177. endoreg_db/views/media/__init__.py +5 -20
  178. endoreg_db/views/media/pdf_media.py +109 -65
  179. endoreg_db/views/media/sensitive_metadata.py +163 -148
  180. endoreg_db/views/meta/__init__.py +0 -8
  181. endoreg_db/views/misc/__init__.py +1 -7
  182. endoreg_db/views/misc/upload_views.py +94 -93
  183. endoreg_db/views/report/__init__.py +7 -0
  184. endoreg_db/views/{pdf → report}/reimport.py +45 -24
  185. endoreg_db/views/{pdf/pdf_stream.py → report/report_stream.py} +40 -32
  186. endoreg_db/views/requirement/lookup_store.py +22 -90
  187. endoreg_db/views/video/__init__.py +23 -22
  188. endoreg_db/views/video/correction.py +201 -172
  189. endoreg_db/views/video/reimport.py +1 -1
  190. endoreg_db/views/{media/video_segments.py → video/segments_crud.py} +75 -37
  191. endoreg_db/views/video/{video_meta.py → video_meta_stats.py} +2 -2
  192. endoreg_db/views/video/video_stream.py +7 -8
  193. {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.9.2.dist-info}/METADATA +2 -2
  194. {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.9.2.dist-info}/RECORD +217 -335
  195. {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.9.2.dist-info}/WHEEL +1 -1
  196. endoreg_db/data/_examples/disease.yaml +0 -55
  197. endoreg_db/data/_examples/disease_classification.yaml +0 -13
  198. endoreg_db/data/_examples/disease_classification_choice.yaml +0 -62
  199. endoreg_db/data/_examples/event.yaml +0 -64
  200. endoreg_db/data/_examples/examination.yaml +0 -72
  201. endoreg_db/data/_examples/finding/anatomy_colon.yaml +0 -128
  202. endoreg_db/data/_examples/finding/colonoscopy.yaml +0 -40
  203. endoreg_db/data/_examples/finding/colonoscopy_bowel_prep.yaml +0 -56
  204. endoreg_db/data/_examples/finding/complication.yaml +0 -16
  205. endoreg_db/data/_examples/finding/data.yaml +0 -105
  206. endoreg_db/data/_examples/finding/examination_setting.yaml +0 -16
  207. endoreg_db/data/_examples/finding/medication_related.yaml +0 -18
  208. endoreg_db/data/_examples/finding/outcome.yaml +0 -12
  209. endoreg_db/data/_examples/finding_classification/colonoscopy_bowel_preparation.yaml +0 -68
  210. endoreg_db/data/_examples/finding_classification/colonoscopy_jnet.yaml +0 -22
  211. endoreg_db/data/_examples/finding_classification/colonoscopy_kudo.yaml +0 -25
  212. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_circularity.yaml +0 -20
  213. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_planarity.yaml +0 -24
  214. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_size.yaml +0 -68
  215. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_surface.yaml +0 -20
  216. endoreg_db/data/_examples/finding_classification/colonoscopy_location.yaml +0 -80
  217. endoreg_db/data/_examples/finding_classification/colonoscopy_lst.yaml +0 -21
  218. endoreg_db/data/_examples/finding_classification/colonoscopy_nice.yaml +0 -20
  219. endoreg_db/data/_examples/finding_classification/colonoscopy_paris.yaml +0 -26
  220. endoreg_db/data/_examples/finding_classification/colonoscopy_sano.yaml +0 -22
  221. endoreg_db/data/_examples/finding_classification/colonoscopy_summary.yaml +0 -53
  222. endoreg_db/data/_examples/finding_classification/complication_generic.yaml +0 -25
  223. endoreg_db/data/_examples/finding_classification/examination_setting_generic.yaml +0 -40
  224. endoreg_db/data/_examples/finding_classification/histology_colo.yaml +0 -51
  225. endoreg_db/data/_examples/finding_classification/intervention_required.yaml +0 -26
  226. endoreg_db/data/_examples/finding_classification/medication_related.yaml +0 -23
  227. endoreg_db/data/_examples/finding_classification/visualized.yaml +0 -33
  228. endoreg_db/data/_examples/finding_classification_choice/bowel_preparation.yaml +0 -78
  229. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_circularity_default.yaml +0 -32
  230. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_jnet.yaml +0 -15
  231. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_kudo.yaml +0 -23
  232. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_lst.yaml +0 -15
  233. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_nice.yaml +0 -17
  234. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_planarity_default.yaml +0 -49
  235. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_sano.yaml +0 -14
  236. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_surface_intact_default.yaml +0 -36
  237. endoreg_db/data/_examples/finding_classification_choice/colonoscopy_size.yaml +0 -82
  238. endoreg_db/data/_examples/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +0 -15
  239. endoreg_db/data/_examples/finding_classification_choice/complication_generic_types.yaml +0 -15
  240. endoreg_db/data/_examples/finding_classification_choice/examination_setting_generic_types.yaml +0 -15
  241. endoreg_db/data/_examples/finding_classification_choice/histology.yaml +0 -24
  242. endoreg_db/data/_examples/finding_classification_choice/histology_polyp.yaml +0 -20
  243. endoreg_db/data/_examples/finding_classification_choice/outcome.yaml +0 -19
  244. endoreg_db/data/_examples/finding_classification_choice/yes_no_na.yaml +0 -11
  245. endoreg_db/data/_examples/finding_classification_type/colonoscopy_basic.yaml +0 -48
  246. endoreg_db/data/_examples/finding_intervention/endoscopy.yaml +0 -43
  247. endoreg_db/data/_examples/finding_intervention/endoscopy_colonoscopy.yaml +0 -168
  248. endoreg_db/data/_examples/finding_intervention/endoscopy_egd.yaml +0 -128
  249. endoreg_db/data/_examples/finding_intervention/endoscopy_ercp.yaml +0 -32
  250. endoreg_db/data/_examples/finding_intervention/endoscopy_eus_lower.yaml +0 -9
  251. endoreg_db/data/_examples/finding_intervention/endoscopy_eus_upper.yaml +0 -36
  252. endoreg_db/data/_examples/finding_intervention_type/endoscopy.yaml +0 -15
  253. endoreg_db/data/_examples/finding_type/data.yaml +0 -43
  254. endoreg_db/data/_examples/requirement/age.yaml +0 -26
  255. endoreg_db/data/_examples/requirement/gender.yaml +0 -25
  256. endoreg_db/data/_examples/requirement_set/01_endoscopy_generic.yaml +0 -48
  257. endoreg_db/data/_examples/requirement_set/colonoscopy_austria_screening.yaml +0 -57
  258. endoreg_db/data/_examples/requirement_set/endoscopy_bleeding_risk.yaml +0 -52
  259. endoreg_db/data/_examples/yaml_examples.xlsx +0 -0
  260. endoreg_db/data/finding/anatomy_colon.yaml +0 -128
  261. endoreg_db/data/finding/colonoscopy.yaml +0 -40
  262. endoreg_db/data/finding/colonoscopy_bowel_prep.yaml +0 -56
  263. endoreg_db/data/finding/complication.yaml +0 -16
  264. endoreg_db/data/finding/data.yaml +0 -105
  265. endoreg_db/data/finding/examination_setting.yaml +0 -16
  266. endoreg_db/data/finding/medication_related.yaml +0 -18
  267. endoreg_db/data/finding/outcome.yaml +0 -12
  268. endoreg_db/data/finding_classification/colonoscopy_jnet.yaml +0 -22
  269. endoreg_db/data/finding_classification/colonoscopy_kudo.yaml +0 -25
  270. endoreg_db/data/finding_classification/colonoscopy_lesion_circularity.yaml +0 -20
  271. endoreg_db/data/finding_classification/colonoscopy_lesion_planarity.yaml +0 -24
  272. endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +0 -38
  273. endoreg_db/data/finding_classification/colonoscopy_lesion_surface.yaml +0 -20
  274. endoreg_db/data/finding_classification/colonoscopy_location.yaml +0 -49
  275. endoreg_db/data/finding_classification/colonoscopy_lst.yaml +0 -21
  276. endoreg_db/data/finding_classification/colonoscopy_nice.yaml +0 -20
  277. endoreg_db/data/finding_classification/colonoscopy_paris.yaml +0 -26
  278. endoreg_db/data/finding_classification/colonoscopy_sano.yaml +0 -22
  279. endoreg_db/data/finding_classification/colonoscopy_summary.yaml +0 -53
  280. endoreg_db/data/finding_classification/complication_generic.yaml +0 -25
  281. endoreg_db/data/finding_classification/examination_setting_generic.yaml +0 -40
  282. endoreg_db/data/finding_classification/histology_colo.yaml +0 -43
  283. endoreg_db/data/finding_classification/intervention_required.yaml +0 -26
  284. endoreg_db/data/finding_classification/medication_related.yaml +0 -23
  285. endoreg_db/data/finding_classification/visualized.yaml +0 -33
  286. endoreg_db/data/finding_classification_choice/colon_lesion_circularity_default.yaml +0 -32
  287. endoreg_db/data/finding_classification_choice/colon_lesion_jnet.yaml +0 -15
  288. endoreg_db/data/finding_classification_choice/colon_lesion_kudo.yaml +0 -23
  289. endoreg_db/data/finding_classification_choice/colon_lesion_lst.yaml +0 -15
  290. endoreg_db/data/finding_classification_choice/colon_lesion_nice.yaml +0 -17
  291. endoreg_db/data/finding_classification_choice/colon_lesion_paris.yaml +0 -57
  292. endoreg_db/data/finding_classification_choice/colon_lesion_planarity_default.yaml +0 -49
  293. endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +0 -14
  294. endoreg_db/data/finding_classification_choice/colon_lesion_surface_intact_default.yaml +0 -36
  295. endoreg_db/data/finding_classification_choice/colonoscopy_location.yaml +0 -229
  296. endoreg_db/data/finding_classification_choice/colonoscopy_not_complete_reason.yaml +0 -19
  297. endoreg_db/data/finding_classification_choice/colonoscopy_size.yaml +0 -82
  298. endoreg_db/data/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +0 -15
  299. endoreg_db/data/finding_classification_choice/outcome.yaml +0 -19
  300. endoreg_db/data/finding_intervention/endoscopy.yaml +0 -43
  301. endoreg_db/data/finding_intervention/endoscopy_colonoscopy.yaml +0 -168
  302. endoreg_db/data/finding_intervention/endoscopy_egd.yaml +0 -128
  303. endoreg_db/data/finding_intervention/endoscopy_ercp.yaml +0 -32
  304. endoreg_db/data/finding_intervention/endoscopy_eus_lower.yaml +0 -9
  305. endoreg_db/data/finding_intervention/endoscopy_eus_upper.yaml +0 -36
  306. endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +0 -79
  307. endoreg_db/data/requirement/age.yaml +0 -26
  308. endoreg_db/data/requirement/colonoscopy_baseline_austria.yaml +0 -45
  309. endoreg_db/data/requirement/disease_cardiovascular.yaml +0 -79
  310. endoreg_db/data/requirement/disease_classification_choice_cardiovascular.yaml +0 -41
  311. endoreg_db/data/requirement/disease_hepatology.yaml +0 -12
  312. endoreg_db/data/requirement/disease_misc.yaml +0 -12
  313. endoreg_db/data/requirement/disease_renal.yaml +0 -96
  314. endoreg_db/data/requirement/endoscopy_bleeding_risk.yaml +0 -59
  315. endoreg_db/data/requirement/event_cardiology.yaml +0 -251
  316. endoreg_db/data/requirement/event_requirements.yaml +0 -145
  317. endoreg_db/data/requirement/finding_colon_polyp.yaml +0 -50
  318. endoreg_db/data/requirement/gender.yaml +0 -25
  319. endoreg_db/data/requirement/lab_value.yaml +0 -441
  320. endoreg_db/data/requirement/medication.yaml +0 -93
  321. endoreg_db/data/requirement_operator/age.yaml +0 -13
  322. endoreg_db/data/requirement_operator/lab_operators.yaml +0 -129
  323. endoreg_db/data/requirement_operator/model_operators.yaml +0 -96
  324. endoreg_db/management/commands/init_default_ai_model.py +0 -112
  325. endoreg_db/management/commands/reset_celery_schedule.py +0 -9
  326. endoreg_db/management/commands/validate_video.py +0 -204
  327. endoreg_db/migrations/0002_requirementset_depends_on.py +0 -18
  328. endoreg_db/migrations/_old/0001_initial.py +0 -1857
  329. endoreg_db/migrations/_old/0002_add_video_correction_models.py +0 -52
  330. endoreg_db/migrations/_old/0003_add_center_display_name.py +0 -30
  331. endoreg_db/migrations/_old/0004_employee_city_employee_post_code_employee_street_and_more.py +0 -68
  332. endoreg_db/migrations/_old/0004_remove_casetemplate_rules_and_more.py +0 -77
  333. endoreg_db/migrations/_old/0005_merge_20251111_1003.py +0 -14
  334. endoreg_db/migrations/_old/0006_sensitivemeta_anonymized_text_and_more.py +0 -68
  335. endoreg_db/migrations/_old/0007_remove_rule_attribute_dtype_remove_rule_rule_type_and_more.py +0 -89
  336. endoreg_db/migrations/_old/0008_remove_event_event_classification_and_more.py +0 -27
  337. endoreg_db/migrations/_old/0009_alter_modelmeta_options_and_more.py +0 -21
  338. endoreg_db/renames.yml +0 -8
  339. endoreg_db/serializers/_old/raw_pdf_meta_validation.py +0 -223
  340. endoreg_db/serializers/_old/raw_video_meta_validation.py +0 -179
  341. endoreg_db/serializers/_old/video.py +0 -71
  342. endoreg_db/serializers/meta/pdf_file_meta_extraction.py +0 -115
  343. endoreg_db/serializers/meta/report_meta.py +0 -53
  344. endoreg_db/serializers/report/__init__.py +0 -9
  345. endoreg_db/serializers/report/mixins.py +0 -45
  346. endoreg_db/serializers/report/report.py +0 -105
  347. endoreg_db/serializers/report/report_list.py +0 -22
  348. endoreg_db/serializers/report/secure_file_url.py +0 -26
  349. endoreg_db/services/requirements_object.py +0 -147
  350. endoreg_db/services/storage_aware_video_processor.py +0 -370
  351. endoreg_db/urls/files.py +0 -6
  352. endoreg_db/urls/label_video_segment_validate.py +0 -33
  353. endoreg_db/urls/label_video_segments.py +0 -46
  354. endoreg_db/views/label/__init__.py +0 -5
  355. endoreg_db/views/label/label.py +0 -15
  356. endoreg_db/views/label_video_segment/__init__.py +0 -16
  357. endoreg_db/views/label_video_segment/create_lvs_from_annotation.py +0 -44
  358. endoreg_db/views/label_video_segment/get_lvs_by_name_and_video.py +0 -50
  359. endoreg_db/views/label_video_segment/label_video_segment.py +0 -77
  360. endoreg_db/views/label_video_segment/label_video_segment_by_label.py +0 -174
  361. endoreg_db/views/label_video_segment/label_video_segment_detail.py +0 -73
  362. endoreg_db/views/label_video_segment/update_lvs_from_annotation.py +0 -46
  363. endoreg_db/views/label_video_segment/validate.py +0 -226
  364. endoreg_db/views/media/segments.py +0 -71
  365. endoreg_db/views/meta/available_files_list.py +0 -146
  366. endoreg_db/views/meta/report_meta.py +0 -53
  367. endoreg_db/views/meta/sensitive_meta_detail.py +0 -85
  368. endoreg_db/views/misc/secure_file_serving_view.py +0 -80
  369. endoreg_db/views/misc/secure_file_url_view.py +0 -84
  370. endoreg_db/views/misc/secure_url_validate.py +0 -79
  371. endoreg_db/views/patient_examination/DEPRECATED_video_backup.py +0 -164
  372. endoreg_db/views/patient_finding_location/__init__.py +0 -5
  373. endoreg_db/views/patient_finding_location/pfl_create.py +0 -70
  374. endoreg_db/views/patient_finding_morphology/__init__.py +0 -5
  375. endoreg_db/views/patient_finding_morphology/pfm_create.py +0 -70
  376. endoreg_db/views/pdf/__init__.py +0 -8
  377. endoreg_db/views/video/segmentation.py +0 -274
  378. endoreg_db/views/video/task_status.py +0 -49
  379. endoreg_db/views/video/timeline.py +0 -46
  380. endoreg_db/views/video/video_analyze.py +0 -52
  381. /endoreg_db/data/requirement/{colon_polyp_intervention.yaml → old/colon_polyp_intervention.yaml} +0 -0
  382. /endoreg_db/data/{_examples/requirement → requirement/old}/colonoscopy_baseline_austria.yaml +0 -0
  383. /endoreg_db/data/requirement/{coloreg_colon_polyp.yaml → old/coloreg_colon_polyp.yaml} +0 -0
  384. /endoreg_db/data/{_examples/requirement → requirement/old}/disease_cardiovascular.yaml +0 -0
  385. /endoreg_db/data/{_examples/requirement → requirement/old}/disease_classification_choice_cardiovascular.yaml +0 -0
  386. /endoreg_db/data/{_examples/requirement → requirement/old}/disease_hepatology.yaml +0 -0
  387. /endoreg_db/data/{_examples/requirement → requirement/old}/disease_misc.yaml +0 -0
  388. /endoreg_db/data/{_examples/requirement → requirement/old}/disease_renal.yaml +0 -0
  389. /endoreg_db/data/{_examples/requirement → requirement/old}/endoscopy_bleeding_risk.yaml +0 -0
  390. /endoreg_db/data/{_examples/requirement → requirement/old}/event_cardiology.yaml +0 -0
  391. /endoreg_db/data/{_examples/requirement → requirement/old}/event_requirements.yaml +0 -0
  392. /endoreg_db/data/{_examples/requirement → requirement/old}/finding_colon_polyp.yaml +0 -0
  393. /endoreg_db/{urls/sensitive_meta.py → data/requirement/old/gender.yaml} +0 -0
  394. /endoreg_db/data/{_examples/requirement → requirement/old}/lab_value.yaml +0 -0
  395. /endoreg_db/data/{_examples/requirement → requirement/old}/medication.yaml +0 -0
  396. /endoreg_db/data/{_examples/requirement_operator → requirement_operator/_old}/age.yaml +0 -0
  397. /endoreg_db/data/{_examples/requirement_operator → requirement_operator/_old}/lab_operators.yaml +0 -0
  398. /endoreg_db/data/{_examples/requirement_operator → requirement_operator/_old}/model_operators.yaml +0 -0
  399. /endoreg_db/{views/pdf/pdf_stream_views.py → import_files/pseudonymization/__init__.py} +0 -0
  400. /endoreg_db/utils/requirement_operator_logic/{lab_value_operators.py → _old/lab_value_operators.py} +0 -0
  401. /endoreg_db/utils/requirement_operator_logic/{model_evaluators.py → _old/model_evaluators.py} +0 -0
  402. {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.9.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,164 +0,0 @@
1
- # from rest_framework import viewsets, status
2
- # from rest_framework.response import Response
3
- # from django.shortcuts import get_object_or_404
4
- # from endoreg_db.models import Examination, VideoFile, Finding, FindingClassification
5
- # from django.db import transaction
6
- # from django.utils import timezone
7
- # import logging
8
-
9
-
10
- # class VideoExaminationViewSet(viewsets.ModelViewSet):
11
- # """
12
- # ViewSet for Video Examination CRUD operations
13
- # Handles POST and PATCH for video examinations at timestamps
14
- # """
15
- # def get_queryset(self):
16
- # return []
17
-
18
- # def create(self, request, *args, **kwargs):
19
-
20
- # logger = logging.getLogger(__name__)
21
- # try:
22
- # data = request.data
23
- # required_fields = ['videoId', 'timestamp', 'examinationTypeId', 'findingId']
24
- # for field in required_fields:
25
- # if field not in data or data[field] is None:
26
- # return Response({'error': f'Missing or null required field: {field}'}, status=status.HTTP_400_BAD_REQUEST)
27
- # try:
28
- # video_id = int(data['videoId'])
29
- # timestamp = float(data['timestamp'])
30
- # examination_type_id = int(data['examinationTypeId'])
31
- # finding_id = int(data['findingId'])
32
- # except (ValueError, TypeError) as e:
33
- # return Response({'error': f'Invalid data type in request: {str(e)}'}, status=status.HTTP_400_BAD_REQUEST)
34
- # if timestamp < 0:
35
- # return Response({'error': 'Timestamp cannot be negative'}, status=status.HTTP_400_BAD_REQUEST)
36
- # with transaction.atomic():
37
- # try:
38
- # video = VideoFile.objects.get(id=video_id)
39
- # except VideoFile.DoesNotExist:
40
- # return Response({'error': 'Video not found'}, status=status.HTTP_404_NOT_FOUND)
41
- # try:
42
- # examination = Examination.objects.get(id=examination_type_id)
43
- # except Examination.DoesNotExist:
44
- # return Response({'error': 'Examination type not found'}, status=status.HTTP_404_NOT_FOUND)
45
- # try:
46
- # finding = Finding.objects.get(id=finding_id)
47
- # except Finding.DoesNotExist:
48
- # return Response({'error': 'Finding not found'}, status=status.HTTP_404_NOT_FOUND)
49
- # if data.get('locationClassificationId'):
50
- # try:
51
- # FindingClassification.objects.get(id=data['locationClassificationId'], classification_types__name__iexact="location")
52
- # except FindingClassification.DoesNotExist:
53
- # return Response({'error': 'Location classification not found'}, status=status.HTTP_404_NOT_FOUND)
54
- # if data.get('morphologyClassificationId'):
55
- # try:
56
- # FindingClassification.objects.get(id=data['morphologyClassificationId'], classification_types__name__iexact="morphology")
57
- # except FindingClassification.DoesNotExist:
58
- # return Response({'error': 'Morphology classification not found'}, status=status.HTTP_404_NOT_FOUND)
59
- # examination_data = {
60
- # 'id': f"exam_{video.id}_{timestamp}_{examination.id}",
61
- # 'video_id': video_id,
62
- # 'timestamp': timestamp,
63
- # 'examination_type': examination.name,
64
- # 'finding': finding.name,
65
- # 'location_classification': data.get('locationClassificationId'),
66
- # 'location_choice': data.get('locationChoiceId'),
67
- # 'morphology_classification': data.get('morphologyClassificationId'),
68
- # 'morphology_choice': data.get('morphologyChoiceId'),
69
- # 'interventions': data.get('interventionIds', []),
70
- # 'notes': data.get('notes', ''),
71
- # 'created_at': timezone.now().isoformat()
72
- # }
73
- # logger.info(f"Created video examination for video {video_id} at timestamp {timestamp}")
74
- # return Response(examination_data, status=status.HTTP_201_CREATED)
75
- # except Exception as e:
76
- # logger.error(f"Unexpected error creating examination: {str(e)}")
77
- # return Response({'error': 'Internal server error while creating examination'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
78
-
79
- # def update(self, request, *args, **kwargs):
80
- # logger = logging.getLogger(__name__)
81
- # try:
82
- # examination_id = kwargs.get('pk')
83
- # if not examination_id:
84
- # return Response({'error': 'Examination ID is required'}, status=status.HTTP_400_BAD_REQUEST)
85
- # data = request.data
86
- # if 'videoId' in data:
87
- # try:
88
- # data['videoId'] = int(data['videoId'])
89
- # except (ValueError, TypeError):
90
- # return Response({'error': 'Invalid videoId format'}, status=status.HTTP_400_BAD_REQUEST)
91
- # if 'timestamp' in data:
92
- # try:
93
- # timestamp = float(data['timestamp'])
94
- # if timestamp < 0:
95
- # return Response({'error': 'Timestamp cannot be negative'}, status=status.HTTP_400_BAD_REQUEST)
96
- # data['timestamp'] = timestamp
97
- # except (ValueError, TypeError):
98
- # return Response({'error': 'Invalid timestamp format'}, status=status.HTTP_400_BAD_REQUEST)
99
- # with transaction.atomic():
100
- # if 'videoId' in data:
101
- # try:
102
- # VideoFile.objects.get(id=data['videoId'])
103
- # except VideoFile.DoesNotExist:
104
- # return Response({'error': 'Video not found'}, status=status.HTTP_404_NOT_FOUND)
105
- # if 'examinationTypeId' in data:
106
- # try:
107
- # examination_type_id = int(data['examinationTypeId'])
108
- # Examination.objects.get(id=examination_type_id)
109
- # except (ValueError, TypeError):
110
- # return Response({'error': 'Invalid examination type ID format'}, status=status.HTTP_400_BAD_REQUEST)
111
- # except Examination.DoesNotExist:
112
- # return Response({'error': 'Examination type not found'}, status=status.HTTP_404_NOT_FOUND)
113
- # if 'findingId' in data:
114
- # try:
115
- # finding_id = int(data['findingId'])
116
- # Finding.objects.get(id=finding_id)
117
- # except (ValueError, TypeError):
118
- # return Response({'error': 'Invalid finding ID format'}, status=status.HTTP_400_BAD_REQUEST)
119
- # except Finding.DoesNotExist:
120
- # return Response({'error': 'Finding not found'}, status=status.HTTP_404_NOT_FOUND)
121
- # examination_data = {
122
- # 'id': examination_id,
123
- # 'video_id': data.get('videoId'),
124
- # 'timestamp': data.get('timestamp'),
125
- # 'examination_type': data.get('examinationTypeId'),
126
- # 'finding': data.get('findingId'),
127
- # 'location_classification': data.get('locationClassificationId'),
128
- # 'location_choice': data.get('locationChoiceId'),
129
- # 'morphology_classification': data.get('morphologyClassificationId'),
130
- # 'morphology_choice': data.get('morphologyChoiceId'),
131
- # 'interventions': data.get('interventionIds', []),
132
- # 'notes': data.get('notes', ''),
133
- # 'updated_at': '2024-01-01T00:00:00Z'
134
- # }
135
- # logger.info(f"Updated video examination {examination_id}")
136
- # return Response(examination_data, status=status.HTTP_200_OK)
137
- # except Exception as e:
138
- # logger.error(f"Unexpected error updating examination {examination_id}: {str(e)}")
139
- # return Response({'error': 'Internal server error while updating examination'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
140
-
141
- # def destroy(self, request, *args, **kwargs):
142
- # logger = logging.getLogger(__name__)
143
- # try:
144
- # examination_id = kwargs.get('pk')
145
- # if not examination_id:
146
- # return Response({'error': 'Examination ID is required'}, status=status.HTTP_400_BAD_REQUEST)
147
- # try:
148
- # if not str(examination_id).strip():
149
- # return Response({'error': 'Invalid examination ID format'}, status=status.HTTP_400_BAD_REQUEST)
150
- # except (ValueError, TypeError):
151
- # return Response({'error': 'Invalid examination ID format'}, status=status.HTTP_400_BAD_REQUEST)
152
- # with transaction.atomic():
153
- # logger.info(f"Deleted video examination {examination_id}")
154
- # return Response({'message': f'Examination {examination_id} deleted successfully'}, status=status.HTTP_204_NO_CONTENT)
155
- # except Exception as e:
156
- # logger.error(f"Unexpected error deleting examination {examination_id}: {str(e)}")
157
- # return Response({'error': 'Internal server error while deleting examination'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
158
-
159
- # from rest_framework.decorators import api_view
160
- # @api_view(["GET"])
161
- # def get_examinations_for_video(request, video_id):
162
- # _video = get_object_or_404(VideoFile, id=video_id)
163
- # #TODO no functionality implemented yet
164
- # return Response([])
@@ -1,5 +0,0 @@
1
- from .pfl_create import create_patient_finding_location
2
-
3
- __all__ = [
4
- "create_patient_finding_location",
5
- ]
@@ -1,70 +0,0 @@
1
- from endoreg_db.serializers.patient_finding.patient_finding import PatientFindingSerializer
2
- from rest_framework.viewsets import ModelViewSet
3
- from rest_framework.decorators import api_view, permission_classes
4
- from rest_framework.response import Response
5
- from rest_framework import status
6
- from endoreg_db.models.medical.patient.patient_finding import PatientFinding
7
- from endoreg_db.models.medical.patient.patient_finding_location import PatientFindingLocation
8
- from endoreg_db.models.medical.patient.patient_finding_morphology import PatientFindingMorphology
9
- from endoreg_db.models import ( FindingLocationClassificationChoice, FindingMorphologyClassificationChoice )
10
- from rest_framework import serializers
11
- from utils.permissions import EnvironmentAwarePermission
12
-
13
- class PatientFindingViewSet(ModelViewSet):
14
- queryset = PatientFinding.objects.all()
15
- serializer_class = PatientFindingSerializer
16
-
17
- @api_view(['POST'])
18
- @permission_classes([EnvironmentAwarePermission])
19
- def create_patient_finding_location(request):
20
- """
21
- Create a patient finding location relationship.
22
- Expected payload: {
23
- "patient_finding_id": 1,
24
- "location_classification_choice_id": 2
25
- }
26
- """
27
- try:
28
- patient_finding_id = request.data.get('patient_finding_id')
29
- choice_id = request.data.get('location_classification_choice_id')
30
-
31
- if not patient_finding_id or not choice_id:
32
- return Response(
33
- {'detail': 'patient_finding_id and location_classification_choice_id are required'},
34
- status=status.HTTP_400_BAD_REQUEST
35
- )
36
-
37
- # Get the objects
38
- try:
39
- patient_finding = PatientFinding.objects.get(id=patient_finding_id)
40
- except PatientFinding.DoesNotExist:
41
- return Response(
42
- {'detail': f'PatientFinding with id {patient_finding_id} not found'},
43
- status=status.HTTP_404_NOT_FOUND
44
- )
45
-
46
- try:
47
- choice = FindingLocationClassificationChoice.objects.get(id=choice_id)
48
- except FindingLocationClassificationChoice.DoesNotExist:
49
- return Response(
50
- {'detail': f'LocationClassificationChoice with id {choice_id} not found'},
51
- status=status.HTTP_404_NOT_FOUND
52
- )
53
-
54
- # Create the relationship
55
- patient_finding_location = PatientFindingLocation.objects.create(
56
- patient_finding=patient_finding,
57
- location_classification_choice=choice
58
- )
59
-
60
- return Response({
61
- 'id': patient_finding_location.id,
62
- 'patient_finding_id': patient_finding.id,
63
- 'location_classification_choice_id': choice.id
64
- }, status=status.HTTP_201_CREATED)
65
-
66
- except Exception as e:
67
- return Response(
68
- {'detail': f'Error creating patient finding location: {str(e)}'},
69
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
70
- )
@@ -1,5 +0,0 @@
1
- from .pfm_create import create_patient_finding_morphology
2
-
3
- __all__ = [
4
- "create_patient_finding_morphology",
5
- ]
@@ -1,70 +0,0 @@
1
- from endoreg_db.serializers.patient_finding.patient_finding import PatientFindingSerializer
2
- from rest_framework.viewsets import ModelViewSet
3
- from rest_framework.decorators import api_view, permission_classes
4
- from rest_framework.response import Response
5
- from rest_framework import status
6
- from endoreg_db.models.medical.patient.patient_finding import PatientFinding
7
- from endoreg_db.models.medical.patient.patient_finding_location import PatientFindingLocation
8
- from endoreg_db.models.medical.patient.patient_finding_morphology import PatientFindingMorphology
9
- from endoreg_db.models import ( FindingLocationClassificationChoice, FindingMorphologyClassificationChoice)
10
- from rest_framework import serializers
11
- from utils.permissions import EnvironmentAwarePermission
12
-
13
- class PatientFindingViewSet(ModelViewSet):
14
- queryset = PatientFinding.objects.all()
15
- serializer_class = PatientFindingSerializer
16
-
17
- @api_view(['POST'])
18
- @permission_classes([EnvironmentAwarePermission])
19
- def create_patient_finding_morphology(request):
20
- """
21
- Create a patient finding morphology relationship.
22
- Expected payload: {
23
- "patient_finding_id": 1,
24
- "morphology_classification_choice_id": 2
25
- }
26
- """
27
- try:
28
- patient_finding_id = request.data.get('patient_finding_id')
29
- choice_id = request.data.get('morphology_classification_choice_id')
30
-
31
- if not patient_finding_id or not choice_id:
32
- return Response(
33
- {'detail': 'patient_finding_id and morphology_classification_choice_id are required'},
34
- status=status.HTTP_400_BAD_REQUEST
35
- )
36
-
37
- # Get the objects
38
- try:
39
- patient_finding = PatientFinding.objects.get(id=patient_finding_id)
40
- except PatientFinding.DoesNotExist:
41
- return Response(
42
- {'detail': f'PatientFinding with id {patient_finding_id} not found'},
43
- status=status.HTTP_404_NOT_FOUND
44
- )
45
-
46
- try:
47
- choice = FindingMorphologyClassificationChoice.objects.get(id=choice_id)
48
- except FindingMorphologyClassificationChoice.DoesNotExist:
49
- return Response(
50
- {'detail': f'MorphologyClassificationChoice with id {choice_id} not found'},
51
- status=status.HTTP_404_NOT_FOUND
52
- )
53
-
54
- # Create the relationship
55
- patient_finding_morphology = PatientFindingMorphology.objects.create(
56
- patient_finding=patient_finding,
57
- morphology_classification_choice=choice
58
- )
59
-
60
- return Response({
61
- 'id': patient_finding_morphology.id,
62
- 'patient_finding_id': patient_finding.id,
63
- 'morphology_classification_choice_id': choice.id
64
- }, status=status.HTTP_201_CREATED)
65
-
66
- except Exception as e:
67
- return Response(
68
- {'detail': f'Error creating patient finding morphology: {str(e)}'},
69
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
70
- )
@@ -1,8 +0,0 @@
1
- from .reimport import PdfReimportView
2
- from .pdf_stream import PdfStreamView
3
-
4
-
5
- __all__ = [
6
- "PdfReimportView",
7
- "PdfStreamView",
8
- ]
@@ -1,274 +0,0 @@
1
- from pathlib import Path
2
- import os
3
- import mimetypes
4
- from django.http import FileResponse, Http404
5
- from rest_framework import viewsets, decorators, status
6
- from rest_framework.views import APIView
7
- from rest_framework.response import Response
8
- from rest_framework.decorators import api_view, permission_classes
9
-
10
- from ...serializers.label_video_segment.label_video_segment_update import LabelSegmentUpdateSerializer
11
-
12
- from ...serializers.label.label import LabelSerializer
13
-
14
- from ...serializers.video.video_file_list import VideoFileListSerializer
15
- from ...models import VideoFile, Label, LabelVideoSegment
16
- from ...serializers.video.segmentation import VideoFileSerializer
17
- from ...utils.permissions import DEBUG_PERMISSIONS
18
-
19
- # Phase 3.2: Import video streaming functionality from dedicated module
20
- # Phase 3.2: VideoStreamView and _stream_video_file moved to video_stream.py
21
- from .video_stream import _stream_video_file
22
-
23
-
24
- class VideoViewSet(viewsets.ReadOnlyModelViewSet):
25
- """
26
- /api/videos/ → list of metadata (JSON)
27
- /api/videos/<id>/ → single metadata (JSON)
28
- /videos/<id>/stream/ → raw file (FileResponse, range-aware)
29
- """
30
- queryset = VideoFile.objects.all()
31
- serializer_class = VideoFileListSerializer # for the list view
32
- permission_classes = DEBUG_PERMISSIONS
33
-
34
- def list(self, request, *args, **kwargs):
35
- """
36
- Returns a JSON response with all video metadata and available labels.
37
-
38
- The response includes serialized lists of all videos and labels in the database.
39
- """
40
- videos = VideoFile.objects.all()
41
- labels = Label.objects.all()
42
-
43
- video_serializer = VideoFileListSerializer(videos, many=True)
44
- label_serializer = LabelSerializer(labels, many=True)
45
-
46
- return Response({
47
- "videos": video_serializer.data,
48
- "labels": label_serializer.data
49
- }, status=status.HTTP_200_OK)
50
-
51
- # ---------- JSON ---------- #
52
- def retrieve(self, request, *args, **kwargs):
53
- """
54
- Retrieves detailed metadata for a specific video as a JSON response.
55
-
56
- Returns:
57
- JSON representation of the requested video's metadata.
58
- """
59
- obj = self.get_object()
60
- return Response(VideoFileSerializer(obj, context={'request': request}).data)
61
-
62
- # ---------- BYTES ---------- #
63
- @decorators.action(methods=['get'], detail=True,
64
- url_path='stream', renderer_classes=[]) # <- disable HTML & JSON renderers
65
- def stream(self, request, pk=None):
66
- """
67
- Streams the raw video file for the specified video with HTTP range and CORS support.
68
- """
69
- try:
70
- vf: VideoFile = self.get_object()
71
- frontend_origin = os.environ.get('FRONTEND_ORIGIN', 'http://localhost:8000')
72
- return _stream_video_file(vf, frontend_origin)
73
- except Http404:
74
- # Re-raise Http404 exceptions as they should bubble up
75
- raise
76
- except Exception as e:
77
- # Log unexpected errors and convert to Http404
78
- import logging
79
- logger = logging.getLogger(__name__)
80
- logger.error(f"Unexpected error in video stream for pk={pk}: {str(e)}")
81
- raise Http404("Video streaming failed")
82
-
83
-
84
- # Phase 3.2: VideoStreamView moved to video_stream.py - imported at top
85
- # Old implementation removed to avoid duplication
86
-
87
-
88
- class VideoLabelView(APIView):
89
- """
90
- API to fetch time segments (start & end times in seconds) for a specific label.
91
- """
92
-
93
- def get(self, request, video_id, label_name):
94
- """
95
- Retrieves time segments and frame-level predictions for a specific label on a video.
96
-
97
- Returns a JSON response containing the label name, a list of time segments (with frame ranges and timestamps), and frame-wise prediction data. Responds with HTTP 404 if the video or label does not exist, or HTTP 200 with empty data if no segments are found. Returns HTTP 500 with an error message for unexpected exceptions.
98
- """
99
- try:
100
- # Verify video exists
101
- video_entry = VideoFile.objects.get(id=video_id)
102
-
103
- # Try to get label by name
104
- try:
105
- label = Label.objects.get(name=label_name)
106
- except Label.DoesNotExist:
107
- return Response({
108
- "error": f"Label '{label_name}' not found in database"
109
- }, status=status.HTTP_404_NOT_FOUND)
110
-
111
- # Get label video segments directly from the database
112
- label_segments = LabelVideoSegment.objects.filter(
113
- video_file=video_entry,
114
- label=label
115
- ).order_by('start_frame_number')
116
-
117
- if not label_segments.exists():
118
- # No segments found for this label, return empty data
119
- return Response({
120
- "label": label_name,
121
- "time_segments": [],
122
- "frame_predictions": {}
123
- }, status=status.HTTP_200_OK)
124
-
125
- # Convert segments to time-based format
126
- # Fix: Ensure fps is a number, not a string
127
- fps_raw = getattr(video_entry, 'fps', None) or (video_entry.get_fps() if hasattr(video_entry, 'get_fps') else 25)
128
-
129
- # Convert fps to float if it's a string
130
- try:
131
- if isinstance(fps_raw, str):
132
- fps = float(fps_raw)
133
- elif isinstance(fps_raw, (int, float)):
134
- fps = float(fps_raw)
135
- else:
136
- fps = 25.0 # Default fallback
137
- except (ValueError, TypeError):
138
- fps = 25.0 # Default fallback if conversion fails
139
-
140
- # Ensure fps is positive
141
- if fps <= 0:
142
- fps = 25.0
143
-
144
- time_segments = []
145
- frame_predictions = {}
146
-
147
- for segment in label_segments:
148
- # Now fps is guaranteed to be a float
149
- start_time = segment.start_frame_number / fps
150
- end_time = segment.end_frame_number / fps
151
-
152
- segment_data = {
153
- "segment_id": segment.id,
154
- "segment_start": segment.start_frame_number,
155
- "segment_end": segment.end_frame_number,
156
- "start_time": round(start_time, 2),
157
- "end_time": round(end_time, 2),
158
- "frames": {}
159
- }
160
-
161
- # Add frame-wise data if available
162
- for frame_num in range(segment.start_frame_number, segment.end_frame_number + 1):
163
- frame_filename = f"frame_{str(frame_num).zfill(7)}.jpg"
164
- frame_predictions[frame_num] = {
165
- "frame_number": frame_num,
166
- "label": label_name,
167
- "confidence": 1.0 # Default confidence
168
- }
169
-
170
- # Fix: Safely construct frame_file_path to avoid string/string division errors
171
- frame_file_path = ""
172
- if hasattr(video_entry, 'frame_dir') and video_entry.frame_dir:
173
- try:
174
- # Ensure frame_dir is converted to Path properly
175
- if isinstance(video_entry.frame_dir, str):
176
- frame_dir = Path(video_entry.frame_dir)
177
- elif isinstance(video_entry.frame_dir, Path):
178
- frame_dir = video_entry.frame_dir
179
- else:
180
- # Try to convert to string first, then to Path
181
- frame_dir = Path(str(video_entry.frame_dir))
182
-
183
- frame_file_path = str(frame_dir / frame_filename)
184
- except (TypeError, ValueError) as e:
185
- # Log warning but don't fail the request
186
- import logging
187
- logger = logging.getLogger(__name__)
188
- logger.warning(f"Could not construct frame path for frame {frame_num}: {e}")
189
- frame_file_path = ""
190
-
191
- segment_data["frames"][frame_num] = {
192
- "frame_filename": frame_filename,
193
- "frame_file_path": frame_file_path,
194
- "predictions": frame_predictions[frame_num]
195
- }
196
-
197
- time_segments.append(segment_data)
198
-
199
- return Response({
200
- "label": label_name,
201
- "time_segments": time_segments,
202
- "frame_predictions": frame_predictions
203
- }, status=status.HTTP_200_OK)
204
-
205
- except VideoFile.DoesNotExist:
206
- return Response({
207
- "error": "Video not found"
208
- }, status=status.HTTP_404_NOT_FOUND)
209
-
210
- except Exception as e:
211
- # Log the error for debugging
212
- import logging
213
- logger = logging.getLogger(__name__)
214
- logger.error(f"Error in VideoLabelView for video {video_id}, label {label_name}: {str(e)}")
215
-
216
- return Response({
217
- "error": f"Internal error: {str(e)}"
218
- }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
219
-
220
- class UpdateLabelSegmentsView(APIView):
221
- """
222
- API to update or create label segments for a video.
223
- """
224
-
225
- def put(self, request, video_id, label_id):
226
- """
227
- Updates segments for a given video & label.
228
- """
229
-
230
- # Prepare data for serializer by combining URL params with request data
231
- serializer_data = {
232
- "video_id": video_id, # From URL parameter
233
- "label_id": label_id, # From URL parameter
234
- "segments": request.data.get("segments", []) # From request body
235
- }
236
-
237
- # Validate input data
238
- serializer = LabelSegmentUpdateSerializer(data=serializer_data)
239
-
240
- if not serializer.is_valid():
241
- return Response({"error": "Invalid segment data", "details": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
242
-
243
- # Process and save segment updates
244
- try:
245
- result = serializer.save()
246
- return Response({
247
- "message": "Segments updated successfully.",
248
- "updated_segments": result["updated_segments"],
249
- "new_segments": result["new_segments"],
250
- "deleted_segments": result["deleted_segments"]
251
- }, status=status.HTTP_200_OK)
252
- except Exception as e:
253
- return Response({
254
- "error": f"Failed to update segments: {str(e)}"
255
- }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
256
-
257
- @api_view(['GET'])
258
- @permission_classes(DEBUG_PERMISSIONS)
259
- def rerun_segmentation(request, video_id):
260
- """
261
- Rerun segmentation for a specific video.
262
- """
263
- try:
264
- video_file = VideoFile.objects.get(id=video_id)
265
- video_file.pipe_1()
266
- video_file.test_after_pipe_1()
267
- return Response({'status': 'success', 'message': 'Segmentation rerun successfully'})
268
- except VideoFile.DoesNotExist:
269
- return Response({'status': 'error', 'message': 'Video file not found'}, status=status.HTTP_404_NOT_FOUND)
270
- except Exception as e:
271
- import logging
272
- logger = logging.getLogger(__name__)
273
- logger.error(f"Error in rerun_segmentation: {e}")
274
- return Response({'status': 'error', 'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@@ -1,49 +0,0 @@
1
- from endoreg_db.utils.permissions import EnvironmentAwarePermission
2
-
3
-
4
- from rest_framework import status
5
- from rest_framework.response import Response
6
- from rest_framework.views import APIView
7
- from celery import current_app
8
-
9
- class TaskStatusView(APIView):
10
- """
11
- GET /api/task-status/{task_id}/ - Get status of async task
12
- """
13
- #TODO refactor, this should be specified as video task status or moved to a more appropriate module
14
- permission_classes = [EnvironmentAwarePermission]
15
-
16
- def get(self, request, task_id):
17
- try:
18
- task_result = current_app.AsyncResult(task_id)
19
-
20
- response_data = {
21
- 'task_id': task_id,
22
- 'status': task_result.status,
23
- 'progress': 0,
24
- 'message': 'Task pending...'
25
- }
26
-
27
- if task_result.status == 'PENDING':
28
- response_data['message'] = 'Task is waiting to be processed'
29
- elif task_result.status == 'PROGRESS':
30
- response_data.update(task_result.result or {})
31
- elif task_result.status == 'SUCCESS':
32
- response_data.update({
33
- 'progress': 100,
34
- 'message': 'Task completed successfully',
35
- 'result': task_result.result
36
- })
37
- elif task_result.status == 'FAILURE':
38
- response_data.update({
39
- 'message': str(task_result.result),
40
- 'error': True
41
- })
42
-
43
- return Response(response_data, status=status.HTTP_200_OK)
44
-
45
- except Exception as e:
46
- return Response(
47
- {"error": f"Failed to get task status: {str(e)}"},
48
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
49
- )