endoreg-db 0.6.3__py3-none-any.whl → 0.8.1__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 (798) hide show
  1. endoreg_db/admin.py +26 -26
  2. endoreg_db/api_urls.py +4 -0
  3. endoreg_db/apps.py +12 -0
  4. endoreg_db/assets/dummy_model.ckpt +1 -0
  5. endoreg_db/codemods/readme.md +88 -0
  6. endoreg_db/codemods/rename_datetime_fields.py +92 -0
  7. endoreg_db/config/env.py +101 -0
  8. endoreg_db/data/__init__.py +26 -0
  9. endoreg_db/data/ai_model/data.yaml +1 -1
  10. endoreg_db/data/ai_model_label/label/polyp_classification.yaml +52 -0
  11. endoreg_db/data/ai_model_label/label-set/data.yaml +20 -1
  12. endoreg_db/data/ai_model_label/label-set/polyp_classifications.yaml +25 -0
  13. endoreg_db/data/center/data.yaml +13 -12
  14. endoreg_db/data/center_shift/ukw.yaml +9 -0
  15. endoreg_db/data/db_summary.csv +58 -0
  16. endoreg_db/data/db_summary.xlsx +0 -0
  17. endoreg_db/data/disease/misc.yaml +1 -2
  18. endoreg_db/data/disease_classification/chronic_kidney_disease.yaml +2 -2
  19. endoreg_db/data/disease_classification_choice/chronic_kidney_disease.yaml +6 -6
  20. endoreg_db/data/endoscopy_processor/data.yaml +3 -0
  21. endoreg_db/data/event/cardiology.yaml +0 -13
  22. endoreg_db/data/examination/examinations/data.yaml +34 -28
  23. endoreg_db/data/examination/type/data.yaml +12 -0
  24. endoreg_db/data/examination_indication/endoscopy.yaml +418 -2
  25. endoreg_db/data/examination_indication_classification/endoscopy.yaml +157 -5
  26. endoreg_db/data/examination_requirement_set/colonoscopy.yaml +15 -0
  27. endoreg_db/data/finding/anatomy_colon.yaml +128 -0
  28. endoreg_db/data/finding/colonoscopy.yaml +40 -0
  29. endoreg_db/data/finding/colonoscopy_bowel_prep.yaml +56 -0
  30. endoreg_db/data/finding/complication.yaml +16 -0
  31. endoreg_db/data/finding/data.yaml +8 -44
  32. endoreg_db/data/finding/examination_setting.yaml +16 -0
  33. endoreg_db/data/finding/medication_related.yaml +18 -0
  34. endoreg_db/data/finding/outcome.yaml +12 -0
  35. endoreg_db/data/finding_classification/colonoscopy_bowel_preparation.yaml +95 -0
  36. endoreg_db/data/finding_classification/colonoscopy_jnet.yaml +22 -0
  37. endoreg_db/data/finding_classification/colonoscopy_kudo.yaml +25 -0
  38. endoreg_db/data/finding_classification/colonoscopy_lesion_circularity.yaml +20 -0
  39. endoreg_db/data/finding_classification/colonoscopy_lesion_planarity.yaml +24 -0
  40. endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +68 -0
  41. endoreg_db/data/finding_classification/colonoscopy_lesion_surface.yaml +20 -0
  42. endoreg_db/data/finding_classification/colonoscopy_location.yaml +80 -0
  43. endoreg_db/data/finding_classification/colonoscopy_lst.yaml +21 -0
  44. endoreg_db/data/finding_classification/colonoscopy_nice.yaml +20 -0
  45. endoreg_db/data/finding_classification/colonoscopy_paris.yaml +26 -0
  46. endoreg_db/data/finding_classification/colonoscopy_sano.yaml +22 -0
  47. endoreg_db/data/finding_classification/colonoscopy_summary.yaml +53 -0
  48. endoreg_db/data/finding_classification/complication_generic.yaml +25 -0
  49. endoreg_db/data/finding_classification/examination_setting_generic.yaml +40 -0
  50. endoreg_db/data/finding_classification/histology_colo.yaml +51 -0
  51. endoreg_db/data/finding_classification/intervention_required.yaml +26 -0
  52. endoreg_db/data/finding_classification/medication_related.yaml +23 -0
  53. endoreg_db/data/finding_classification/visualized.yaml +33 -0
  54. endoreg_db/data/finding_classification_choice/bowel_preparation.yaml +78 -0
  55. endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_circularity_default.yaml +0 -2
  56. endoreg_db/data/finding_classification_choice/colon_lesion_jnet.yaml +15 -0
  57. endoreg_db/data/finding_classification_choice/colon_lesion_kudo.yaml +23 -0
  58. endoreg_db/data/finding_classification_choice/colon_lesion_lst.yaml +15 -0
  59. endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_nice.yaml +4 -7
  60. endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_paris.yaml +0 -8
  61. endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_planarity_default.yaml +6 -13
  62. endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +14 -0
  63. endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_surface_intact_default.yaml +3 -6
  64. endoreg_db/data/{finding_location_classification_choice/colonoscopy.yaml → finding_classification_choice/colonoscopy_location.yaml} +11 -22
  65. endoreg_db/data/finding_classification_choice/colonoscopy_not_complete_reason.yaml +19 -0
  66. endoreg_db/data/finding_classification_choice/colonoscopy_size.yaml +82 -0
  67. endoreg_db/data/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +15 -0
  68. endoreg_db/data/finding_classification_choice/complication_generic_types.yaml +15 -0
  69. endoreg_db/data/finding_classification_choice/examination_setting_generic_types.yaml +15 -0
  70. endoreg_db/data/finding_classification_choice/histology.yaml +24 -0
  71. endoreg_db/data/finding_classification_choice/histology_polyp.yaml +20 -0
  72. endoreg_db/data/finding_classification_choice/outcome.yaml +19 -0
  73. endoreg_db/data/finding_classification_choice/yes_no_na.yaml +11 -0
  74. endoreg_db/data/finding_classification_type/colonoscopy_basic.yaml +48 -0
  75. endoreg_db/data/finding_intervention/endoscopy.yaml +26 -121
  76. endoreg_db/data/finding_intervention/endoscopy_colonoscopy.yaml +168 -0
  77. endoreg_db/data/finding_intervention/endoscopy_egd.yaml +128 -0
  78. endoreg_db/data/finding_intervention/endoscopy_ercp.yaml +32 -0
  79. endoreg_db/data/finding_intervention/endoscopy_eus_lower.yaml +9 -0
  80. endoreg_db/data/finding_intervention/endoscopy_eus_upper.yaml +36 -0
  81. endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +6 -6
  82. endoreg_db/data/finding_type/data.yaml +23 -10
  83. endoreg_db/data/gender/data.yaml +8 -1
  84. endoreg_db/data/information_source/annotation.yaml +6 -0
  85. endoreg_db/data/information_source/endoscopy_guidelines.yaml +7 -0
  86. endoreg_db/data/information_source/prediction.yaml +7 -0
  87. endoreg_db/data/information_source_type/data.yaml +8 -0
  88. endoreg_db/data/lab_value/misc.yaml +43 -0
  89. endoreg_db/data/medication/anticoagulation.yaml +5 -5
  90. endoreg_db/data/medication/tah.yaml +5 -5
  91. endoreg_db/data/medication_indication/anticoagulation.yaml +4 -4
  92. endoreg_db/data/medication_intake_time/base.yaml +4 -4
  93. endoreg_db/data/names_first/first_names.yaml +3 -0
  94. endoreg_db/data/pdf_type/data.yaml +27 -10
  95. endoreg_db/data/qualification/endoscopy.yaml +36 -0
  96. endoreg_db/data/qualification/m2.yaml +39 -0
  97. endoreg_db/data/qualification/outpatient_clinic.yaml +35 -0
  98. endoreg_db/data/qualification/sonography.yaml +36 -0
  99. endoreg_db/data/qualification_type/base.yaml +29 -0
  100. endoreg_db/data/report_reader_flag/rkh-histology-generic.yaml +10 -0
  101. endoreg_db/data/report_reader_flag/ukw-histology-generic.yaml +5 -0
  102. endoreg_db/data/requirement/age.yaml +26 -0
  103. endoreg_db/data/requirement/colonoscopy_baseline_austria.yaml +45 -0
  104. endoreg_db/data/requirement/disease_cardiovascular.yaml +79 -0
  105. endoreg_db/data/requirement/disease_classification_choice_cardiovascular.yaml +41 -0
  106. endoreg_db/data/requirement/disease_hepatology.yaml +12 -0
  107. endoreg_db/data/requirement/disease_misc.yaml +12 -0
  108. endoreg_db/data/requirement/disease_renal.yaml +96 -0
  109. endoreg_db/data/requirement/endoscopy_bleeding_risk.yaml +59 -0
  110. endoreg_db/data/requirement/event_cardiology.yaml +251 -0
  111. endoreg_db/data/requirement/event_requirements.yaml +145 -0
  112. endoreg_db/data/requirement/finding_colon_polyp.yaml +50 -0
  113. endoreg_db/data/requirement/gender.yaml +25 -0
  114. endoreg_db/data/requirement/lab_value.yaml +441 -0
  115. endoreg_db/data/requirement/medication.yaml +93 -0
  116. endoreg_db/data/requirement_operator/age.yaml +13 -0
  117. endoreg_db/data/requirement_operator/lab_operators.yaml +129 -0
  118. endoreg_db/data/requirement_operator/model_operators.yaml +96 -0
  119. endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +48 -0
  120. endoreg_db/data/requirement_set/colonoscopy_austria_screening.yaml +57 -0
  121. endoreg_db/data/requirement_set/endoscopy_bleeding_risk.yaml +52 -0
  122. endoreg_db/data/requirement_set_type/data.yaml +20 -0
  123. endoreg_db/data/requirement_type/requirement_types.yaml +165 -0
  124. endoreg_db/data/risk/bleeding.yaml +26 -0
  125. endoreg_db/data/risk/thrombosis.yaml +37 -0
  126. endoreg_db/data/risk_type/data.yaml +27 -0
  127. endoreg_db/data/shift/endoscopy.yaml +21 -0
  128. endoreg_db/data/shift_type/base.yaml +35 -0
  129. endoreg_db/data/tag/requirement_set_tags.yaml +11 -0
  130. endoreg_db/data/unit/concentration.yaml +23 -0
  131. endoreg_db/data/unit/time.yaml +36 -1
  132. endoreg_db/exceptions.py +19 -0
  133. endoreg_db/forms/patient_finding_intervention_form.py +4 -5
  134. endoreg_db/forms/patient_form.py +7 -6
  135. endoreg_db/forms/questionnaires/__init__.py +1 -1
  136. endoreg_db/forms/questionnaires/tto_questionnaire.py +19 -19
  137. endoreg_db/helpers/count_db.py +45 -0
  138. endoreg_db/helpers/data_loader.py +208 -0
  139. endoreg_db/helpers/default_objects.py +359 -0
  140. endoreg_db/helpers/interact.py +6 -0
  141. endoreg_db/helpers/test_video_helper.py +119 -0
  142. endoreg_db/logger_conf.py +140 -0
  143. endoreg_db/management/__init__.py +1 -0
  144. endoreg_db/management/commands/__init__.py +1 -0
  145. endoreg_db/management/commands/anonymize_video.py +0 -0
  146. endoreg_db/management/commands/check_auth.py +125 -0
  147. endoreg_db/management/commands/create_multilabel_model_meta.py +214 -0
  148. endoreg_db/management/commands/fix_missing_patient_data.py +172 -0
  149. endoreg_db/management/commands/fix_video_paths.py +165 -0
  150. endoreg_db/management/commands/import_fallback_video.py +203 -0
  151. endoreg_db/management/commands/import_report.py +298 -0
  152. endoreg_db/management/commands/import_video.py +422 -0
  153. endoreg_db/management/commands/import_video_with_classification.py +367 -0
  154. endoreg_db/management/commands/init_default_ai_model.py +112 -0
  155. endoreg_db/management/commands/load_ai_model_data.py +2 -7
  156. endoreg_db/management/commands/load_base_db_data.py +15 -1
  157. endoreg_db/management/commands/load_center_data.py +46 -21
  158. endoreg_db/management/commands/load_endoscope_data.py +2 -2
  159. endoreg_db/management/commands/load_examination_indication_data.py +49 -28
  160. endoreg_db/management/commands/load_finding_data.py +49 -92
  161. endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +0 -1
  162. endoreg_db/management/commands/load_information_source.py +13 -7
  163. endoreg_db/management/commands/load_qualification_data.py +59 -0
  164. endoreg_db/management/commands/load_requirement_data.py +180 -0
  165. endoreg_db/management/commands/load_risk_data.py +56 -0
  166. endoreg_db/management/commands/load_shift_data.py +60 -0
  167. endoreg_db/management/commands/load_tag_data.py +57 -0
  168. endoreg_db/management/commands/register_ai_model.py +1 -1
  169. endoreg_db/management/commands/start_filewatcher.py +106 -0
  170. endoreg_db/management/commands/storage_management.py +548 -0
  171. endoreg_db/management/commands/summarize_db_content.py +189 -0
  172. endoreg_db/management/commands/validate_video.py +204 -0
  173. endoreg_db/management/commands/validate_video_files.py +161 -0
  174. endoreg_db/management/commands/video_validation.py +22 -0
  175. endoreg_db/migrations/0001_initial.py +625 -813
  176. endoreg_db/migrations/0002_add_video_correction_models.py +52 -0
  177. endoreg_db/models/__init__.py +274 -291
  178. endoreg_db/models/administration/__init__.py +116 -0
  179. endoreg_db/models/{ai_model → administration/ai}/__init__.py +6 -1
  180. endoreg_db/models/administration/ai/active_model.py +35 -0
  181. endoreg_db/models/administration/ai/ai_model.py +156 -0
  182. endoreg_db/models/{ai_model → administration/ai}/model_type.py +6 -1
  183. endoreg_db/models/administration/case/__init__.py +19 -0
  184. endoreg_db/models/administration/case/case.py +114 -0
  185. endoreg_db/models/{case_template → administration/case/case_template}/case_template.py +3 -3
  186. endoreg_db/models/{case_template → administration/case/case_template}/case_template_rule.py +3 -10
  187. endoreg_db/models/{case_template → administration/case/case_template}/case_template_rule_value.py +2 -4
  188. endoreg_db/models/{case_template → administration/case/case_template}/case_template_type.py +1 -3
  189. endoreg_db/models/{center → administration/center}/__init__.py +3 -1
  190. endoreg_db/models/administration/center/center.py +61 -0
  191. endoreg_db/models/administration/center/center_product.py +64 -0
  192. endoreg_db/models/{center → administration/center}/center_resource.py +19 -3
  193. endoreg_db/models/administration/center/center_shift.py +88 -0
  194. endoreg_db/models/administration/center/center_waste.py +30 -0
  195. endoreg_db/models/administration/permissions/__init__.py +44 -0
  196. endoreg_db/models/administration/person/__init__.py +24 -0
  197. endoreg_db/models/administration/person/employee/__init__.py +3 -0
  198. endoreg_db/models/administration/person/employee/employee.py +35 -0
  199. endoreg_db/models/administration/person/employee/employee_qualification.py +39 -0
  200. endoreg_db/models/administration/person/employee/employee_type.py +42 -0
  201. endoreg_db/models/administration/person/examiner/__init__.py +4 -0
  202. endoreg_db/models/administration/person/examiner/examiner.py +54 -0
  203. endoreg_db/models/administration/person/names/__init__.py +0 -0
  204. endoreg_db/models/{persons → administration/person/names}/first_name.py +1 -1
  205. endoreg_db/models/{persons → administration/person/names}/last_name.py +2 -3
  206. endoreg_db/models/administration/person/patient/__init__.py +5 -0
  207. endoreg_db/models/administration/person/patient/patient.py +460 -0
  208. endoreg_db/models/administration/person/profession/__init__.py +24 -0
  209. endoreg_db/models/administration/person/user/__init__.py +5 -0
  210. endoreg_db/models/administration/person/user/portal_user_information.py +37 -0
  211. endoreg_db/models/administration/product/product.py +97 -0
  212. endoreg_db/models/administration/product/product_group.py +39 -0
  213. endoreg_db/models/administration/product/product_material.py +54 -0
  214. endoreg_db/models/{product → administration/product}/product_weight.py +9 -0
  215. endoreg_db/models/{product → administration/product}/reference_product.py +26 -11
  216. endoreg_db/models/administration/qualification/__init__.py +7 -0
  217. endoreg_db/models/administration/qualification/qualification.py +37 -0
  218. endoreg_db/models/administration/qualification/qualification_type.py +35 -0
  219. endoreg_db/models/administration/shift/__init__.py +9 -0
  220. endoreg_db/models/administration/shift/scheduled_days.py +69 -0
  221. endoreg_db/models/administration/shift/shift.py +51 -0
  222. endoreg_db/models/administration/shift/shift_type.py +108 -0
  223. endoreg_db/models/label/__init__.py +24 -1
  224. endoreg_db/models/label/annotation/__init__.py +12 -0
  225. endoreg_db/models/label/annotation/image_classification.py +84 -0
  226. endoreg_db/models/label/annotation/video_segmentation_annotation.py +66 -0
  227. endoreg_db/models/label/label.py +45 -74
  228. endoreg_db/models/label/label_set.py +53 -0
  229. endoreg_db/models/label/label_type.py +29 -0
  230. endoreg_db/models/label/label_video_segment/__init__.py +3 -0
  231. endoreg_db/models/label/label_video_segment/_create_from_video.py +41 -0
  232. endoreg_db/models/label/label_video_segment/label_video_segment.py +511 -0
  233. endoreg_db/models/label/video_segmentation_label.py +31 -0
  234. endoreg_db/models/{annotation → label}/video_segmentation_labelset.py +7 -0
  235. endoreg_db/models/media/__init__.py +14 -0
  236. endoreg_db/models/media/frame/__init__.py +3 -0
  237. endoreg_db/models/media/frame/frame.py +111 -0
  238. endoreg_db/models/media/pdf/__init__.py +11 -0
  239. endoreg_db/models/media/pdf/raw_pdf.py +608 -0
  240. endoreg_db/models/media/pdf/report_file.py +162 -0
  241. endoreg_db/models/media/pdf/report_reader/report_reader_config.py +77 -0
  242. endoreg_db/models/media/video/__init__.py +4 -0
  243. endoreg_db/models/media/video/create_from_file.py +336 -0
  244. endoreg_db/models/media/video/pipe_1.py +195 -0
  245. endoreg_db/models/media/video/pipe_2.py +105 -0
  246. endoreg_db/models/media/video/refactor_plan.md +0 -0
  247. endoreg_db/models/media/video/video_file.py +680 -0
  248. endoreg_db/models/media/video/video_file_ai.py +443 -0
  249. endoreg_db/models/media/video/video_file_anonymize.py +348 -0
  250. endoreg_db/models/media/video/video_file_frames/__init__.py +47 -0
  251. endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +22 -0
  252. endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +23 -0
  253. endoreg_db/models/media/video/video_file_frames/_delete_frames.py +104 -0
  254. endoreg_db/models/media/video/video_file_frames/_extract_frames.py +174 -0
  255. endoreg_db/models/media/video/video_file_frames/_get_frame.py +28 -0
  256. endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +27 -0
  257. endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +20 -0
  258. endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +27 -0
  259. endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +34 -0
  260. endoreg_db/models/media/video/video_file_frames/_get_frames.py +27 -0
  261. endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +129 -0
  262. endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +129 -0
  263. endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +65 -0
  264. endoreg_db/models/media/video/video_file_frames.py +0 -0
  265. endoreg_db/models/media/video/video_file_io.py +166 -0
  266. endoreg_db/models/media/video/video_file_meta/__init__.py +22 -0
  267. endoreg_db/models/media/video/video_file_meta/get_crop_template.py +45 -0
  268. endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +39 -0
  269. endoreg_db/models/media/video/video_file_meta/get_fps.py +147 -0
  270. endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +143 -0
  271. endoreg_db/models/media/video/video_file_meta/text_meta.py +134 -0
  272. endoreg_db/models/media/video/video_file_meta/video_meta.py +70 -0
  273. endoreg_db/models/media/video/video_file_meta.py +11 -0
  274. endoreg_db/models/media/video/video_file_segments.py +209 -0
  275. endoreg_db/models/medical/__init__.py +146 -0
  276. endoreg_db/models/{contraindication → medical/contraindication}/__init__.py +1 -5
  277. endoreg_db/models/medical/disease.py +156 -0
  278. endoreg_db/models/medical/event.py +137 -0
  279. endoreg_db/models/{examination → medical/examination}/__init__.py +1 -1
  280. endoreg_db/models/medical/examination/examination.py +148 -0
  281. endoreg_db/models/medical/examination/examination_indication.py +278 -0
  282. endoreg_db/models/{examination → medical/examination}/examination_time.py +0 -4
  283. endoreg_db/models/{examination → medical/examination}/examination_time_type.py +1 -8
  284. endoreg_db/models/{examination → medical/examination}/examination_type.py +18 -10
  285. endoreg_db/models/medical/finding/__init__.py +18 -0
  286. endoreg_db/models/medical/finding/finding.py +96 -0
  287. endoreg_db/models/medical/finding/finding_classification.py +142 -0
  288. endoreg_db/models/{finding → medical/finding}/finding_intervention.py +2 -10
  289. endoreg_db/models/medical/finding/finding_type.py +35 -0
  290. endoreg_db/models/medical/hardware/__init__.py +8 -0
  291. endoreg_db/models/{hardware → medical/hardware}/endoscope.py +28 -23
  292. endoreg_db/models/medical/laboratory/__init__.py +5 -0
  293. endoreg_db/models/medical/laboratory/lab_value.py +419 -0
  294. endoreg_db/models/{medication → medical/medication}/medication.py +1 -3
  295. endoreg_db/models/{medication → medical/medication}/medication_indication_type.py +8 -3
  296. endoreg_db/models/{medication → medical/medication}/medication_intake_time.py +21 -3
  297. endoreg_db/models/{medication → medical/medication}/medication_schedule.py +13 -5
  298. endoreg_db/models/{organ → medical/organ}/__init__.py +3 -6
  299. endoreg_db/models/medical/patient/__init__.py +56 -0
  300. endoreg_db/models/medical/patient/medication_examples.py +38 -0
  301. endoreg_db/models/medical/patient/patient_disease.py +63 -0
  302. endoreg_db/models/medical/patient/patient_event.py +75 -0
  303. endoreg_db/models/medical/patient/patient_examination.py +249 -0
  304. endoreg_db/models/{persons → medical}/patient/patient_examination_indication.py +21 -9
  305. endoreg_db/models/medical/patient/patient_finding.py +357 -0
  306. endoreg_db/models/medical/patient/patient_finding_classification.py +207 -0
  307. endoreg_db/models/{patient → medical/patient}/patient_finding_intervention.py +15 -1
  308. endoreg_db/models/medical/patient/patient_lab_sample.py +148 -0
  309. endoreg_db/models/{persons → medical}/patient/patient_lab_value.py +40 -15
  310. endoreg_db/models/medical/patient/patient_medication.py +104 -0
  311. endoreg_db/models/medical/patient/patient_medication_schedule.py +136 -0
  312. endoreg_db/models/medical/risk/__init__.py +7 -0
  313. endoreg_db/models/medical/risk/risk.py +72 -0
  314. endoreg_db/models/medical/risk/risk_type.py +51 -0
  315. endoreg_db/models/{data_file/metadata → metadata}/__init__.py +6 -0
  316. endoreg_db/models/metadata/frame_ocr_result.py +0 -0
  317. endoreg_db/models/metadata/model_meta.py +193 -0
  318. endoreg_db/models/metadata/model_meta_logic.py +236 -0
  319. endoreg_db/models/{data_file/metadata → metadata}/pdf_meta.py +28 -13
  320. endoreg_db/models/metadata/sensitive_meta.py +288 -0
  321. endoreg_db/models/metadata/sensitive_meta_logic.py +643 -0
  322. endoreg_db/models/metadata/video_meta.py +332 -0
  323. endoreg_db/models/metadata/video_prediction_logic.py +190 -0
  324. endoreg_db/models/metadata/video_prediction_meta.py +270 -0
  325. endoreg_db/models/other/__init__.py +17 -0
  326. endoreg_db/models/other/distribution/date_value_distribution.py +0 -2
  327. endoreg_db/models/other/distribution/numeric_value_distribution.py +30 -2
  328. endoreg_db/models/{emission → other/emission}/emission_factor.py +15 -6
  329. endoreg_db/models/{persons → other}/gender.py +8 -3
  330. endoreg_db/models/other/information_source.py +159 -0
  331. endoreg_db/models/other/material.py +10 -2
  332. endoreg_db/models/other/resource.py +6 -2
  333. endoreg_db/models/other/tag.py +27 -0
  334. endoreg_db/models/other/transport_route.py +13 -2
  335. endoreg_db/models/{unit.py → other/unit.py} +16 -6
  336. endoreg_db/models/other/waste.py +10 -3
  337. endoreg_db/models/requirement/__init__.py +11 -0
  338. endoreg_db/models/requirement/requirement.py +767 -0
  339. endoreg_db/models/requirement/requirement_evaluation/__init__.py +6 -0
  340. endoreg_db/models/requirement/requirement_evaluation/get_values.py +40 -0
  341. endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +9 -0
  342. endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +95 -0
  343. endoreg_db/models/requirement/requirement_operator.py +176 -0
  344. endoreg_db/models/requirement/requirement_set.py +287 -0
  345. endoreg_db/models/rule/__init__.py +13 -0
  346. endoreg_db/models/{rules → rule}/rule.py +6 -3
  347. endoreg_db/models/{rules → rule}/rule_attribute_dtype.py +0 -2
  348. endoreg_db/models/{rules → rule}/rule_type.py +0 -2
  349. endoreg_db/models/{rules → rule}/ruleset.py +0 -2
  350. endoreg_db/models/state/__init__.py +12 -0
  351. endoreg_db/models/state/abstract.py +11 -0
  352. endoreg_db/models/state/audit_ledger.py +150 -0
  353. endoreg_db/models/state/label_video_segment.py +22 -0
  354. endoreg_db/models/state/raw_pdf.py +187 -0
  355. endoreg_db/models/state/sensitive_meta.py +46 -0
  356. endoreg_db/models/state/video.py +232 -0
  357. endoreg_db/models/upload_job.py +99 -0
  358. endoreg_db/models/utils.py +135 -0
  359. endoreg_db/models/video_metadata.py +66 -0
  360. endoreg_db/models/video_processing.py +153 -0
  361. endoreg_db/renames.yml +8 -0
  362. endoreg_db/root_urls.py +9 -0
  363. endoreg_db/schemas/__init__.py +0 -0
  364. endoreg_db/schemas/examination_evaluation.py +27 -0
  365. endoreg_db/serializers/Frames_NICE_and_PARIS_classifications.py +775 -0
  366. endoreg_db/serializers/__init__.py +147 -10
  367. endoreg_db/serializers/{raw_pdf_meta_validation.py → _old/raw_pdf_meta_validation.py} +3 -3
  368. endoreg_db/serializers/{raw_video_meta_validation.py → _old/raw_video_meta_validation.py} +18 -14
  369. endoreg_db/serializers/_old/video.py +71 -0
  370. endoreg_db/serializers/administration/__init__.py +14 -0
  371. endoreg_db/serializers/administration/ai/__init__.py +10 -0
  372. endoreg_db/serializers/administration/ai/active_model.py +10 -0
  373. endoreg_db/serializers/administration/ai/ai_model.py +18 -0
  374. endoreg_db/serializers/administration/ai/model_type.py +10 -0
  375. endoreg_db/serializers/administration/center.py +9 -0
  376. endoreg_db/serializers/administration/gender.py +9 -0
  377. endoreg_db/serializers/anonymization.py +66 -0
  378. endoreg_db/serializers/evaluation/examination_evaluation.py +1 -0
  379. endoreg_db/serializers/examination/__init__.py +10 -0
  380. endoreg_db/serializers/examination/base.py +46 -0
  381. endoreg_db/serializers/examination/dropdown.py +21 -0
  382. endoreg_db/serializers/examination_serializer.py +12 -0
  383. endoreg_db/serializers/finding/__init__.py +5 -0
  384. endoreg_db/serializers/finding/finding.py +54 -0
  385. endoreg_db/serializers/finding_classification/__init__.py +7 -0
  386. endoreg_db/serializers/finding_classification/choice.py +19 -0
  387. endoreg_db/serializers/finding_classification/classification.py +13 -0
  388. endoreg_db/serializers/label/__init__.py +7 -0
  389. endoreg_db/serializers/label/image_classification_annotation.py +62 -0
  390. endoreg_db/serializers/label/label.py +15 -0
  391. endoreg_db/serializers/label_video_segment/__init__.py +7 -0
  392. endoreg_db/serializers/label_video_segment/_lvs_create.py +149 -0
  393. endoreg_db/serializers/label_video_segment/_lvs_update.py +138 -0
  394. endoreg_db/serializers/label_video_segment/_lvs_validate.py +149 -0
  395. endoreg_db/serializers/label_video_segment/label_video_segment.py +344 -0
  396. endoreg_db/serializers/label_video_segment/label_video_segment_annotation.py +99 -0
  397. endoreg_db/serializers/label_video_segment/label_video_segment_update.py +163 -0
  398. endoreg_db/serializers/meta/__init__.py +19 -0
  399. endoreg_db/serializers/meta/pdf_file_meta_extraction.py +115 -0
  400. endoreg_db/serializers/meta/report_meta.py +53 -0
  401. endoreg_db/serializers/meta/sensitive_meta_detail.py +162 -0
  402. endoreg_db/serializers/meta/sensitive_meta_update.py +148 -0
  403. endoreg_db/serializers/meta/sensitive_meta_verification.py +59 -0
  404. endoreg_db/serializers/meta/video_meta.py +39 -0
  405. endoreg_db/serializers/misc/__init__.py +14 -0
  406. endoreg_db/serializers/misc/file_overview.py +152 -0
  407. endoreg_db/serializers/misc/stats.py +33 -0
  408. endoreg_db/serializers/misc/translatable_field_mix_in.py +44 -0
  409. endoreg_db/serializers/misc/upload_job.py +71 -0
  410. endoreg_db/serializers/misc/vop_patient_data.py +120 -0
  411. endoreg_db/serializers/patient/__init__.py +11 -0
  412. endoreg_db/serializers/patient/patient.py +86 -0
  413. endoreg_db/serializers/patient/patient_dropdown.py +27 -0
  414. endoreg_db/serializers/patient_examination/__init__.py +7 -0
  415. endoreg_db/serializers/patient_examination/patient_examination.py +141 -0
  416. endoreg_db/serializers/patient_finding/__init__.py +15 -0
  417. endoreg_db/serializers/patient_finding/patient_finding.py +31 -0
  418. endoreg_db/serializers/patient_finding/patient_finding_classification.py +39 -0
  419. endoreg_db/serializers/patient_finding/patient_finding_detail.py +53 -0
  420. endoreg_db/serializers/patient_finding/patient_finding_intervention.py +26 -0
  421. endoreg_db/serializers/patient_finding/patient_finding_list.py +41 -0
  422. endoreg_db/serializers/patient_finding/patient_finding_write.py +126 -0
  423. endoreg_db/serializers/pdf/__init__.py +5 -0
  424. endoreg_db/serializers/pdf/anony_text_validation.py +85 -0
  425. endoreg_db/serializers/report/__init__.py +9 -0
  426. endoreg_db/serializers/report/mixins.py +45 -0
  427. endoreg_db/serializers/report/report.py +105 -0
  428. endoreg_db/serializers/report/report_list.py +22 -0
  429. endoreg_db/serializers/report/secure_file_url.py +26 -0
  430. endoreg_db/serializers/requirements/requirement_schema.py +25 -0
  431. endoreg_db/serializers/requirements/requirement_sets.py +29 -0
  432. endoreg_db/serializers/sensitive_meta_serializer.py +282 -0
  433. endoreg_db/serializers/video/__init__.py +7 -0
  434. endoreg_db/serializers/video/segmentation.py +263 -0
  435. endoreg_db/serializers/video/video_file_brief.py +10 -0
  436. endoreg_db/serializers/video/video_file_detail.py +83 -0
  437. endoreg_db/serializers/video/video_file_list.py +67 -0
  438. endoreg_db/serializers/video/video_metadata.py +105 -0
  439. endoreg_db/serializers/video/video_processing_history.py +153 -0
  440. endoreg_db/services/__init__.py +5 -0
  441. endoreg_db/services/anonymization.py +223 -0
  442. endoreg_db/services/examination_evaluation.py +149 -0
  443. endoreg_db/services/finding_description_service.py +0 -0
  444. endoreg_db/services/lookup_service.py +241 -0
  445. endoreg_db/services/lookup_store.py +122 -0
  446. endoreg_db/services/ollama_api_docs.py +1528 -0
  447. endoreg_db/services/pdf_import.py +993 -0
  448. endoreg_db/services/polling_coordinator.py +288 -0
  449. endoreg_db/services/pseudonym_service.py +89 -0
  450. endoreg_db/services/requirements_object.py +147 -0
  451. endoreg_db/services/segment_sync.py +155 -0
  452. endoreg_db/services/storage_aware_video_processor.py +344 -0
  453. endoreg_db/services/video_import.py +915 -0
  454. endoreg_db/tasks/upload_tasks.py +207 -0
  455. endoreg_db/tasks/video_ingest.py +157 -0
  456. endoreg_db/tasks/video_processing_tasks.py +327 -0
  457. endoreg_db/urls/__init__.py +72 -0
  458. endoreg_db/urls/anonymization.py +32 -0
  459. endoreg_db/urls/auth.py +16 -0
  460. endoreg_db/urls/classification.py +39 -0
  461. endoreg_db/urls/examination.py +54 -0
  462. endoreg_db/urls/files.py +6 -0
  463. endoreg_db/urls/label_video_segment_validate.py +33 -0
  464. endoreg_db/urls/label_video_segments.py +44 -0
  465. endoreg_db/urls/media.py +32 -0
  466. endoreg_db/urls/patient.py +19 -0
  467. endoreg_db/urls/pdf.py +0 -0
  468. endoreg_db/urls/report.py +78 -0
  469. endoreg_db/urls/requirements.py +13 -0
  470. endoreg_db/urls/sensitive_meta.py +36 -0
  471. endoreg_db/urls/stats.py +46 -0
  472. endoreg_db/urls/upload.py +20 -0
  473. endoreg_db/urls/video.py +119 -0
  474. endoreg_db/urls.py +6 -269
  475. endoreg_db/utils/__init__.py +68 -16
  476. endoreg_db/utils/ai/__init__.py +9 -0
  477. endoreg_db/{models/ai_model/utils.py → utils/ai/get.py} +1 -4
  478. endoreg_db/{models/ai_model/lightning → utils/ai}/inference_dataset.py +0 -1
  479. endoreg_db/{models/ai_model/lightning → utils/ai}/multilabel_classification_net.py +14 -10
  480. endoreg_db/{models/ai_model/lightning → utils/ai}/postprocess.py +15 -5
  481. endoreg_db/utils/ai/predict.py +291 -0
  482. endoreg_db/{models/ai_model/lightning → utils/ai}/preprocess.py +1 -1
  483. endoreg_db/utils/calc_duration_seconds.py +24 -0
  484. endoreg_db/utils/case_generator/__init__.py +0 -0
  485. endoreg_db/utils/check_video_files.py +148 -0
  486. endoreg_db/utils/dataloader.py +88 -31
  487. endoreg_db/utils/dates.py +21 -0
  488. endoreg_db/utils/env.py +33 -0
  489. endoreg_db/utils/extract_specific_frames.py +72 -0
  490. endoreg_db/utils/file_operations.py +29 -1
  491. endoreg_db/utils/fix_video_path_direct.py +141 -0
  492. endoreg_db/utils/frame_anonymization_utils.py +463 -0
  493. endoreg_db/utils/hashs.py +1 -0
  494. endoreg_db/utils/links/__init__.py +0 -0
  495. endoreg_db/utils/links/requirement_link.py +193 -0
  496. endoreg_db/utils/mime_types.py +0 -0
  497. endoreg_db/utils/names.py +2 -0
  498. endoreg_db/utils/paths.py +104 -0
  499. endoreg_db/utils/permissions.py +143 -0
  500. endoreg_db/utils/pipelines/Readme.md +235 -0
  501. endoreg_db/utils/pipelines/__init__.py +0 -0
  502. endoreg_db/utils/pipelines/process_video_dir.py +120 -0
  503. endoreg_db/utils/product/__init__.py +0 -0
  504. endoreg_db/utils/product/sum_emissions.py +20 -0
  505. endoreg_db/utils/product/sum_weights.py +18 -0
  506. endoreg_db/utils/pydantic_models/db_config.py +1 -1
  507. endoreg_db/utils/requirement_helpers.py +0 -0
  508. endoreg_db/utils/requirement_operator_logic/__init__.py +0 -0
  509. endoreg_db/utils/requirement_operator_logic/lab_value_operators.py +578 -0
  510. endoreg_db/utils/requirement_operator_logic/model_evaluators.py +368 -0
  511. endoreg_db/utils/translation.py +27 -0
  512. endoreg_db/utils/validate_video_detailed.py +357 -0
  513. endoreg_db/utils/video/__init__.py +19 -6
  514. endoreg_db/utils/video/extract_frames.py +37 -70
  515. endoreg_db/utils/video/ffmpeg_wrapper.py +772 -0
  516. endoreg_db/utils/video/names.py +42 -0
  517. endoreg_db/utils/video/streaming_processor.py +312 -0
  518. endoreg_db/utils/video/video_splitter.py +94 -0
  519. endoreg_db/views/Frames_NICE_and_PARIS_classifications_views.py +238 -0
  520. endoreg_db/views/__init__.py +282 -2
  521. endoreg_db/views/anonymization/__init__.py +27 -0
  522. endoreg_db/views/anonymization/media_management.py +454 -0
  523. endoreg_db/views/anonymization/overview.py +216 -0
  524. endoreg_db/views/anonymization/validate.py +63 -0
  525. endoreg_db/views/auth/__init__.py +13 -0
  526. endoreg_db/views/auth/keycloak.py +113 -0
  527. endoreg_db/views/examination/__init__.py +33 -0
  528. endoreg_db/views/examination/examination.py +37 -0
  529. endoreg_db/views/examination/examination_manifest_cache.py +26 -0
  530. endoreg_db/views/examination/get_finding_classification_choices.py +59 -0
  531. endoreg_db/views/examination/get_finding_classifications.py +36 -0
  532. endoreg_db/views/examination/get_findings.py +41 -0
  533. endoreg_db/views/examination/get_instruments.py +18 -0
  534. endoreg_db/views/examination/get_interventions.py +14 -0
  535. endoreg_db/views/finding/__init__.py +9 -0
  536. endoreg_db/views/finding/finding.py +112 -0
  537. endoreg_db/views/finding/get_classifications.py +14 -0
  538. endoreg_db/views/finding/get_interventions.py +17 -0
  539. endoreg_db/views/finding_classification/__init__.py +13 -0
  540. endoreg_db/views/finding_classification/base.py +0 -0
  541. endoreg_db/views/finding_classification/finding_classification.py +42 -0
  542. endoreg_db/views/finding_classification/get_classification_choices.py +55 -0
  543. endoreg_db/views/label/__init__.py +5 -0
  544. endoreg_db/views/label/label.py +15 -0
  545. endoreg_db/views/label_video_segment/__init__.py +16 -0
  546. endoreg_db/views/label_video_segment/create_lvs_from_annotation.py +44 -0
  547. endoreg_db/views/label_video_segment/get_lvs_by_name_and_video.py +50 -0
  548. endoreg_db/views/label_video_segment/label_video_segment.py +77 -0
  549. endoreg_db/views/label_video_segment/label_video_segment_by_label.py +174 -0
  550. endoreg_db/views/label_video_segment/label_video_segment_detail.py +73 -0
  551. endoreg_db/views/label_video_segment/update_lvs_from_annotation.py +46 -0
  552. endoreg_db/views/label_video_segment/validate.py +226 -0
  553. endoreg_db/views/media/__init__.py +9 -0
  554. endoreg_db/views/media/pdf_media.py +386 -0
  555. endoreg_db/views/media/video_media.py +272 -0
  556. endoreg_db/views/meta/__init__.py +15 -0
  557. endoreg_db/views/meta/available_files_list.py +146 -0
  558. endoreg_db/views/meta/report_meta.py +53 -0
  559. endoreg_db/views/meta/sensitive_meta_detail.py +148 -0
  560. endoreg_db/views/meta/sensitive_meta_list.py +104 -0
  561. endoreg_db/views/meta/sensitive_meta_verification.py +71 -0
  562. endoreg_db/views/misc/__init__.py +63 -0
  563. endoreg_db/views/misc/center.py +13 -0
  564. endoreg_db/views/misc/gender.py +14 -0
  565. endoreg_db/views/misc/secure_file_serving_view.py +80 -0
  566. endoreg_db/views/misc/secure_file_url_view.py +84 -0
  567. endoreg_db/views/misc/secure_url_validate.py +79 -0
  568. endoreg_db/views/misc/stats.py +220 -0
  569. endoreg_db/views/misc/translation.py +182 -0
  570. endoreg_db/views/misc/upload_views.py +240 -0
  571. endoreg_db/views/patient/__init__.py +5 -0
  572. endoreg_db/views/patient/patient.py +210 -0
  573. endoreg_db/views/patient_examination/DEPRECATED_video_backup.py +164 -0
  574. endoreg_db/views/patient_examination/__init__.py +11 -0
  575. endoreg_db/views/patient_examination/patient_examination.py +140 -0
  576. endoreg_db/views/patient_examination/patient_examination_create.py +63 -0
  577. endoreg_db/views/patient_examination/patient_examination_detail.py +66 -0
  578. endoreg_db/views/patient_examination/patient_examination_list.py +68 -0
  579. endoreg_db/views/patient_examination/video.py +194 -0
  580. endoreg_db/views/patient_finding/__init__.py +7 -0
  581. endoreg_db/views/patient_finding/base.py +0 -0
  582. endoreg_db/views/patient_finding/patient_finding.py +64 -0
  583. endoreg_db/views/patient_finding/patient_finding_optimized.py +259 -0
  584. endoreg_db/views/patient_finding_classification/__init__.py +5 -0
  585. endoreg_db/views/patient_finding_classification/pfc_create.py +67 -0
  586. endoreg_db/views/patient_finding_location/__init__.py +5 -0
  587. endoreg_db/views/patient_finding_location/pfl_create.py +70 -0
  588. endoreg_db/views/patient_finding_morphology/__init__.py +5 -0
  589. endoreg_db/views/patient_finding_morphology/pfm_create.py +70 -0
  590. endoreg_db/views/pdf/__init__.py +11 -0
  591. endoreg_db/views/pdf/pdf_media.py +239 -0
  592. endoreg_db/views/pdf/pdf_stream_views.py +127 -0
  593. endoreg_db/views/pdf/reimport.py +151 -0
  594. endoreg_db/views/report/__init__.py +9 -0
  595. endoreg_db/views/report/report_list.py +112 -0
  596. endoreg_db/views/report/report_with_secure_url.py +28 -0
  597. endoreg_db/views/report/start_examination.py +7 -0
  598. endoreg_db/views/requirement/__init__.py +10 -0
  599. endoreg_db/views/requirement/evaluate.py +279 -0
  600. endoreg_db/views/requirement/lookup.py +483 -0
  601. endoreg_db/views/requirement/lookup_store.py +252 -0
  602. endoreg_db/views/requirement_lookup/lookup.py +0 -0
  603. endoreg_db/views/requirement_lookup/lookup_store.py +0 -0
  604. endoreg_db/views/stats/__init__.py +13 -0
  605. endoreg_db/views/stats/stats_views.py +229 -0
  606. endoreg_db/views/video/__init__.py +72 -0
  607. endoreg_db/views/video/correction.py +672 -0
  608. endoreg_db/views/video/media/__init__.py +23 -0
  609. endoreg_db/views/video/media/task_status.py +49 -0
  610. endoreg_db/views/video/media/video_analyze.py +52 -0
  611. endoreg_db/views/video/media/video_apply_mask.py +48 -0
  612. endoreg_db/views/video/media/video_correction.py +21 -0
  613. endoreg_db/views/video/media/video_download_processed.py +58 -0
  614. endoreg_db/views/video/media/video_media.py +158 -0
  615. endoreg_db/views/video/media/video_meta.py +29 -0
  616. endoreg_db/views/video/media/video_processing_history.py +24 -0
  617. endoreg_db/views/video/media/video_remove_frames.py +48 -0
  618. endoreg_db/views/video/media/video_reprocess.py +40 -0
  619. endoreg_db/views/video/reimport.py +192 -0
  620. endoreg_db/views/video/segmentation.py +274 -0
  621. endoreg_db/views/{views_for_timeline.py → video/timeline.py} +3 -3
  622. endoreg_db/views/video/video_examination_viewset.py +329 -0
  623. endoreg_db/views/video/video_stream.py +188 -0
  624. endoreg_db-0.8.1.dist-info/METADATA +384 -0
  625. endoreg_db-0.8.1.dist-info/RECORD +789 -0
  626. endoreg_db/data/agl_service/data.yaml +0 -19
  627. endoreg_db/data/finding_location_classification/colonoscopy.yaml +0 -46
  628. endoreg_db/data/finding_morphology_classification/colonoscopy.yaml +0 -48
  629. endoreg_db/data/finding_morphology_classification_choice/colonoscopy_size.yaml +0 -57
  630. endoreg_db/management/commands/_load_model_template.py +0 -41
  631. endoreg_db/management/commands/delete_all.py +0 -18
  632. endoreg_db/management/commands/fetch_legacy_image_dataset.py +0 -32
  633. endoreg_db/management/commands/fix_auth_permission.py +0 -20
  634. endoreg_db/management/commands/load_active_model_data.py +0 -45
  635. endoreg_db/management/commands/load_g_play_data.py +0 -113
  636. endoreg_db/management/commands/load_logging_data.py +0 -39
  637. endoreg_db/management/commands/load_lx_data.py +0 -64
  638. endoreg_db/management/commands/load_medication_indication_data.py +0 -63
  639. endoreg_db/management/commands/load_medication_indication_type_data.py +0 -41
  640. endoreg_db/management/commands/load_medication_intake_time_data.py +0 -41
  641. endoreg_db/management/commands/load_medication_schedule_data.py +0 -55
  642. endoreg_db/management/commands/load_network_data.py +0 -57
  643. endoreg_db/migrations/0002_alter_frame_image_alter_rawframe_image.py +0 -23
  644. endoreg_db/migrations/0003_alter_frame_image_alter_rawframe_image.py +0 -23
  645. endoreg_db/migrations/0004_alter_rawvideofile_file_alter_video_file.py +0 -25
  646. endoreg_db/migrations/0005_rawvideofile_frame_count_and_more.py +0 -33
  647. endoreg_db/migrations/0006_frame_extracted_rawframe_extracted.py +0 -23
  648. endoreg_db/migrations/0007_rename_pseudo_patient_video_patient_and_more.py +0 -24
  649. endoreg_db/migrations/0008_remove_reportfile_patient_examination_and_more.py +0 -48
  650. endoreg_db/models/ai_model/active_model.py +0 -9
  651. endoreg_db/models/ai_model/ai_model.py +0 -103
  652. endoreg_db/models/ai_model/lightning/__init__.py +0 -3
  653. endoreg_db/models/ai_model/lightning/predict.py +0 -172
  654. endoreg_db/models/ai_model/lightning/prediction_visualizer.py +0 -55
  655. endoreg_db/models/ai_model/lightning/run_visualizer.py +0 -21
  656. endoreg_db/models/ai_model/model_meta.py +0 -250
  657. endoreg_db/models/annotation/__init__.py +0 -32
  658. endoreg_db/models/annotation/anonymized_image_annotation.py +0 -115
  659. endoreg_db/models/annotation/binary_classification_annotation_task.py +0 -117
  660. endoreg_db/models/annotation/image_classification.py +0 -86
  661. endoreg_db/models/annotation/video_segmentation_annotation.py +0 -52
  662. endoreg_db/models/case/__init__.py +0 -1
  663. endoreg_db/models/case/case.py +0 -34
  664. endoreg_db/models/center/center.py +0 -51
  665. endoreg_db/models/center/center_product.py +0 -33
  666. endoreg_db/models/center/center_waste.py +0 -16
  667. endoreg_db/models/data_file/__init__.py +0 -39
  668. endoreg_db/models/data_file/base_classes/__init__.py +0 -7
  669. endoreg_db/models/data_file/base_classes/abstract_frame.py +0 -100
  670. endoreg_db/models/data_file/base_classes/abstract_pdf.py +0 -136
  671. endoreg_db/models/data_file/base_classes/abstract_video.py +0 -807
  672. endoreg_db/models/data_file/base_classes/frame_helpers.py +0 -17
  673. endoreg_db/models/data_file/base_classes/prepare_bulk_frames.py +0 -19
  674. endoreg_db/models/data_file/base_classes/utils.py +0 -80
  675. endoreg_db/models/data_file/frame.py +0 -29
  676. endoreg_db/models/data_file/import_classes/__init__.py +0 -18
  677. endoreg_db/models/data_file/import_classes/processing_functions/__init__.py +0 -35
  678. endoreg_db/models/data_file/import_classes/processing_functions/pdf.py +0 -28
  679. endoreg_db/models/data_file/import_classes/processing_functions/video.py +0 -260
  680. endoreg_db/models/data_file/import_classes/raw_pdf.py +0 -260
  681. endoreg_db/models/data_file/import_classes/raw_video.py +0 -288
  682. endoreg_db/models/data_file/metadata/sensitive_meta.py +0 -290
  683. endoreg_db/models/data_file/metadata/video_meta.py +0 -199
  684. endoreg_db/models/data_file/report_file.py +0 -56
  685. endoreg_db/models/data_file/video/__init__.py +0 -11
  686. endoreg_db/models/data_file/video/import_meta.py +0 -25
  687. endoreg_db/models/data_file/video/video.py +0 -196
  688. endoreg_db/models/data_file/video_segment.py +0 -214
  689. endoreg_db/models/disease.py +0 -79
  690. endoreg_db/models/event.py +0 -73
  691. endoreg_db/models/examination/examination.py +0 -67
  692. endoreg_db/models/examination/examination_indication.py +0 -170
  693. endoreg_db/models/finding/__init__.py +0 -11
  694. endoreg_db/models/finding/finding.py +0 -75
  695. endoreg_db/models/finding/finding_location_classification.py +0 -94
  696. endoreg_db/models/finding/finding_morphology_classification.py +0 -89
  697. endoreg_db/models/finding/finding_type.py +0 -22
  698. endoreg_db/models/hardware/__init__.py +0 -2
  699. endoreg_db/models/information_source.py +0 -29
  700. endoreg_db/models/laboratory/__init__.py +0 -1
  701. endoreg_db/models/laboratory/lab_value.py +0 -111
  702. endoreg_db/models/logging/__init__.py +0 -11
  703. endoreg_db/models/logging/agl_service.py +0 -19
  704. endoreg_db/models/logging/base.py +0 -22
  705. endoreg_db/models/logging/log_type.py +0 -23
  706. endoreg_db/models/logging/network_device.py +0 -27
  707. endoreg_db/models/lx/__init__.py +0 -4
  708. endoreg_db/models/lx/client.py +0 -57
  709. endoreg_db/models/lx/identity.py +0 -34
  710. endoreg_db/models/lx/permission.py +0 -18
  711. endoreg_db/models/lx/user.py +0 -16
  712. endoreg_db/models/network/__init__.py +0 -9
  713. endoreg_db/models/network/agl_service.py +0 -38
  714. endoreg_db/models/network/network_device.py +0 -58
  715. endoreg_db/models/network/network_device_type.py +0 -23
  716. endoreg_db/models/other/distribution.py +0 -5
  717. endoreg_db/models/patient/__init__.py +0 -24
  718. endoreg_db/models/patient/patient_examination.py +0 -182
  719. endoreg_db/models/patient/patient_finding.py +0 -143
  720. endoreg_db/models/patient/patient_finding_location.py +0 -120
  721. endoreg_db/models/patient/patient_finding_morphology.py +0 -166
  722. endoreg_db/models/permissions/__init__.py +0 -44
  723. endoreg_db/models/persons/__init__.py +0 -34
  724. endoreg_db/models/persons/examiner/__init__.py +0 -2
  725. endoreg_db/models/persons/examiner/examiner.py +0 -60
  726. endoreg_db/models/persons/examiner/examiner_type.py +0 -2
  727. endoreg_db/models/persons/patient/__init__.py +0 -8
  728. endoreg_db/models/persons/patient/patient.py +0 -389
  729. endoreg_db/models/persons/patient/patient_disease.py +0 -22
  730. endoreg_db/models/persons/patient/patient_event.py +0 -52
  731. endoreg_db/models/persons/patient/patient_lab_sample.py +0 -108
  732. endoreg_db/models/persons/patient/patient_medication.py +0 -59
  733. endoreg_db/models/persons/patient/patient_medication_schedule.py +0 -88
  734. endoreg_db/models/persons/portal_user_information.py +0 -27
  735. endoreg_db/models/prediction/__init__.py +0 -8
  736. endoreg_db/models/prediction/image_classification.py +0 -51
  737. endoreg_db/models/prediction/video_prediction_meta.py +0 -306
  738. endoreg_db/models/product/product.py +0 -110
  739. endoreg_db/models/product/product_group.py +0 -27
  740. endoreg_db/models/product/product_material.py +0 -28
  741. endoreg_db/models/questionnaires/__init__.py +0 -114
  742. endoreg_db/models/quiz/__init__.py +0 -9
  743. endoreg_db/models/quiz/quiz_answer.py +0 -41
  744. endoreg_db/models/quiz/quiz_question.py +0 -54
  745. endoreg_db/models/report_reader/report_reader_config.py +0 -53
  746. endoreg_db/models/rules/__init__.py +0 -5
  747. endoreg_db/queries/get/__init__.py +0 -6
  748. endoreg_db/queries/get/center.py +0 -42
  749. endoreg_db/queries/get/model.py +0 -13
  750. endoreg_db/queries/get/patient.py +0 -14
  751. endoreg_db/queries/get/patient_examination.py +0 -20
  752. endoreg_db/queries/get/report_file.py +0 -33
  753. endoreg_db/queries/get/video.py +0 -31
  754. endoreg_db/serializers/ai_model.py +0 -19
  755. endoreg_db/serializers/annotation.py +0 -14
  756. endoreg_db/serializers/center.py +0 -11
  757. endoreg_db/serializers/examination.py +0 -33
  758. endoreg_db/serializers/frame.py +0 -9
  759. endoreg_db/serializers/hardware.py +0 -21
  760. endoreg_db/serializers/label.py +0 -22
  761. endoreg_db/serializers/patient.py +0 -33
  762. endoreg_db/serializers/prediction.py +0 -10
  763. endoreg_db/serializers/raw_pdf_anony_text_validation.py +0 -137
  764. endoreg_db/serializers/report_file.py +0 -7
  765. endoreg_db/serializers/video.py +0 -20
  766. endoreg_db/serializers/video_segmentation.py +0 -587
  767. endoreg_db/tests.py +0 -3
  768. endoreg_db/utils/legacy_ocr.py +0 -201
  769. endoreg_db/utils/video/transcode_videofile.py +0 -111
  770. endoreg_db/views/patient_views.py +0 -90
  771. endoreg_db/views/raw_pdf_anony_text_validation_views.py +0 -95
  772. endoreg_db/views/raw_pdf_meta_validation_views.py +0 -111
  773. endoreg_db/views/raw_video_meta_validation_views.py +0 -148
  774. endoreg_db/views/report_views.py +0 -96
  775. endoreg_db/views/video_segmentation_views.py +0 -166
  776. endoreg_db-0.6.3.dist-info/METADATA +0 -161
  777. endoreg_db-0.6.3.dist-info/RECORD +0 -435
  778. /endoreg_db/{case_generator/__init__.py → api/serializers/finding_descriptions.py} +0 -0
  779. /endoreg_db/{queries/get/annotation.py → api/views/finding_descriptions.py} +0 -0
  780. /endoreg_db/{queries/get/prediction.py → data/shift/m2.yaml} +0 -0
  781. /endoreg_db/{queries/get/video_import_meta.py → factories/__init__.py} +0 -0
  782. /endoreg_db/{queries/get/video_prediction_meta.py → helpers/__init__.py} +0 -0
  783. /endoreg_db/models/{case_template → administration/case/case_template}/__init__.py +0 -0
  784. /endoreg_db/models/{persons → administration/person}/person.py +0 -0
  785. /endoreg_db/models/{product → administration/product}/__init__.py +0 -0
  786. /endoreg_db/models/{report_reader → media/pdf/report_reader}/__init__.py +0 -0
  787. /endoreg_db/models/{report_reader → media/pdf/report_reader}/report_reader_flag.py +0 -0
  788. /endoreg_db/models/{hardware → medical/hardware}/endoscopy_processor.py +0 -0
  789. /endoreg_db/models/{medication → medical/medication}/__init__.py +0 -0
  790. /endoreg_db/models/{medication → medical/medication}/medication_indication.py +0 -0
  791. /endoreg_db/models/{emission → other/emission}/__init__.py +0 -0
  792. /endoreg_db/models/{rules → rule}/rule_applicator.py +0 -0
  793. /endoreg_db/{case_generator → utils/case_generator}/case_generator.py +0 -0
  794. /endoreg_db/{case_generator → utils/case_generator}/lab_sample_factory.py +0 -0
  795. /endoreg_db/{case_generator → utils/case_generator}/utils.py +0 -0
  796. /endoreg_db/views/{csrf.py → misc/csrf.py} +0 -0
  797. {endoreg_db-0.6.3.dist-info → endoreg_db-0.8.1.dist-info}/WHEEL +0 -0
  798. {endoreg_db-0.6.3.dist-info → endoreg_db-0.8.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,210 @@
1
+ from django.shortcuts import render
2
+ from django.contrib.admin.views.decorators import staff_member_required
3
+ from django.db import transaction
4
+
5
+ from rest_framework import viewsets, status, serializers
6
+ from rest_framework.response import Response
7
+ from rest_framework.decorators import action
8
+
9
+
10
+ from endoreg_db.models import Patient
11
+ from endoreg_db.serializers.patient import PatientSerializer
12
+ from endoreg_db.models.medical.patient.patient_examination import PatientExamination
13
+
14
+ @staff_member_required # Ensures only staff members can access the page
15
+ def start_examination(request):
16
+ return render(request, 'admin/start_examination.html') # Loads the simple HTML page
17
+
18
+
19
+ #TODO Review this view
20
+ class PatientViewSet(viewsets.ModelViewSet):
21
+ """API endpoint for managing patients."""
22
+ queryset = Patient.objects.all()
23
+ serializer_class = PatientSerializer
24
+ #permission_classes = [IsAuthenticatedOrReadOnly]
25
+
26
+ def perform_create(self, serializer):
27
+ """Erweiterte Validierung beim Erstellen eines Patienten"""
28
+ try:
29
+ # Zusätzliche Validierung falls nötig
30
+ patient = serializer.save()
31
+ return patient
32
+ except Exception as e:
33
+ raise serializers.ValidationError(f"Fehler beim Erstellen des Patienten: {str(e)}")
34
+
35
+ def update(self, request, *args, **kwargs):
36
+ """Erweiterte Logik für das Aktualisieren von Patienten"""
37
+ try:
38
+ return super().update(request, *args, **kwargs)
39
+ except Exception as e:
40
+ return Response(
41
+ {"error": f"Fehler beim Aktualisieren des Patienten: {str(e)}"},
42
+ status=status.HTTP_400_BAD_REQUEST
43
+ )
44
+
45
+ def destroy(self, request, *args, **kwargs):
46
+ """
47
+ Delete a patient with proper error handling and cascade protection.
48
+ """
49
+ patient = self.get_object()
50
+
51
+ try:
52
+ with transaction.atomic():
53
+ # Check if patient has related examinations
54
+ examination_count = patient.patient_examinations.count() if hasattr(patient, 'patient_examinations') else 0
55
+ finding_count = 0
56
+
57
+ if examination_count > 0:
58
+ finding_count = sum(
59
+ exam.patient_findings.count() if hasattr(exam, 'patient_findings') else 0
60
+ for exam in patient.patient_examinations.all()
61
+ )
62
+
63
+ return Response({
64
+ 'error': 'Patient cannot be deleted',
65
+ 'reason': f'Patient has {examination_count} examination(s) and {finding_count} finding(s).',
66
+ 'detail': 'Please remove all related examinations and findings before deleting the patient.'
67
+ }, status=status.HTTP_409_CONFLICT)
68
+
69
+ # Check if this is a real person (additional protection)
70
+ if hasattr(patient, 'is_real_person') and patient.is_real_person:
71
+ return Response({
72
+ 'error': 'Cannot delete real patient',
73
+ 'reason': 'This patient is marked as a real person.',
74
+ 'detail': 'Real patient data cannot be deleted for data protection reasons.'
75
+ }, status=status.HTTP_403_FORBIDDEN)
76
+
77
+ # Perform the deletion
78
+ patient_name = f"{patient.first_name} {patient.last_name}"
79
+ patient.delete()
80
+
81
+ return Response({
82
+ 'message': f'Patient "{patient_name}" has been successfully deleted.'
83
+ }, status=status.HTTP_200_OK)
84
+
85
+ except Exception as e:
86
+ return Response({
87
+ 'error': 'Patient deletion failed',
88
+ 'reason': 'Patient has protected related objects.',
89
+ 'detail': str(e)
90
+ }, status=status.HTTP_409_CONFLICT)
91
+ except Exception as e:
92
+ return Response(
93
+ {"error": f"Fehler beim Löschen des Patienten: {str(e)}"},
94
+ status=status.HTTP_400_BAD_REQUEST
95
+ )
96
+
97
+ def check_pe_exist(self, request, pk=None):
98
+ """Check if a patient examination exists.
99
+
100
+ Args:
101
+ request (id): pk of the PatientExamination
102
+ pk (int, optional): _description_. Defaults to None.
103
+
104
+ Returns:
105
+ _type_: _description_
106
+ """
107
+ try:
108
+ PatientExamination.objects.get(pk=pk)
109
+ return Response({"exists": True}, status=status.HTTP_200_OK)
110
+ except PatientExamination.DoesNotExist:
111
+ return Response({"exists": False}, status=status.HTTP_404_NOT_FOUND)
112
+
113
+ @action(detail=True, methods=['get'])
114
+ def check_deletion_safety(self, request, pk=None):
115
+ """
116
+ Check if a patient can be safely deleted.
117
+ Returns information about related objects.
118
+ """
119
+ patient = self.get_object()
120
+
121
+ examination_count = patient.patient_examinations.count() if hasattr(patient, 'patient_examinations') else 0
122
+ examinations = patient.patient_examinations.all() if hasattr(patient, 'patient_examinations') else []
123
+
124
+ finding_count = sum(
125
+ exam.patient_findings.count() if hasattr(exam, 'patient_findings') else 0
126
+ for exam in examinations
127
+ )
128
+ video_count = sum(
129
+ 1 for exam in examinations
130
+ if hasattr(exam, 'video') and exam.video
131
+ )
132
+ report_count = sum(
133
+ exam.raw_pdf_files.count() if hasattr(exam, 'raw_pdf_files') else 0
134
+ for exam in examinations
135
+ )
136
+
137
+ is_real_person = hasattr(patient, 'is_real_person') and patient.is_real_person
138
+ can_delete = examination_count == 0 and not is_real_person
139
+
140
+ warnings = []
141
+ if is_real_person:
142
+ warnings.append('This patient is marked as a real person')
143
+ if examination_count > 0:
144
+ warnings.append(f'Patient has {examination_count} examination(s)')
145
+ if finding_count > 0:
146
+ warnings.append(f'Patient has {finding_count} finding(s)')
147
+
148
+ return Response({
149
+ 'can_delete': can_delete,
150
+ 'is_real_person': is_real_person,
151
+ 'related_objects': {
152
+ 'examinations': examination_count,
153
+ 'findings': finding_count,
154
+ 'videos': video_count,
155
+ 'reports': report_count
156
+ },
157
+ 'warnings': warnings
158
+ })
159
+
160
+ @action(detail=False, methods=['get'])
161
+ def patient_count(self, request):
162
+ """Gibt die Anzahl der Patienten zurück"""
163
+ count = Patient.objects.count()
164
+ return Response({"count": count})
165
+
166
+ @action(detail=True, methods=['post'], url_path='pseudonym')
167
+ def generate_pseudonym(self, request, pk=None):
168
+ """
169
+ Generate a pseudonym hash for an existing patient.
170
+
171
+ This endpoint generates a deterministic hash based on the patient's
172
+ personal data (name, dob, center) using server-side logic without
173
+ exposing any secrets to the frontend.
174
+ """
175
+ from endoreg_db.services.pseudonym_service import generate_patient_pseudonym, validate_patient_for_pseudonym
176
+
177
+ patient = self.get_object()
178
+
179
+ try:
180
+ # Validate that patient has required fields
181
+ missing_fields = validate_patient_for_pseudonym(patient)
182
+ if missing_fields:
183
+ return Response({
184
+ 'error': 'Missing required fields for pseudonym generation',
185
+ 'missing_fields': missing_fields,
186
+ 'detail': f'Please provide: {", ".join(missing_fields)}'
187
+ }, status=status.HTTP_400_BAD_REQUEST)
188
+
189
+ # Generate the pseudonym
190
+ patient_hash, persisted = generate_patient_pseudonym(patient)
191
+
192
+ return Response({
193
+ 'patient_id': patient.id,
194
+ 'patient_hash': patient_hash,
195
+ 'source': 'server',
196
+ 'persisted': persisted,
197
+ 'message': 'Pseudonym generated successfully'
198
+ }, status=status.HTTP_200_OK)
199
+
200
+ except ValueError as e:
201
+ return Response({
202
+ 'error': 'Pseudonym generation failed',
203
+ 'detail': str(e)
204
+ }, status=status.HTTP_400_BAD_REQUEST)
205
+ except Exception as e:
206
+ return Response({
207
+ 'error': 'Internal server error during pseudonym generation',
208
+ 'detail': str(e)
209
+ }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
210
+
@@ -0,0 +1,164 @@
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([])
@@ -0,0 +1,11 @@
1
+ from .patient_examination_create import ExaminationCreateView
2
+ from .patient_examination_detail import PatientExaminationDetailView
3
+ from .patient_examination_list import PatientExaminationListView
4
+ from .patient_examination import PatientExaminationViewSet
5
+
6
+ __all__ = [
7
+ 'ExaminationCreateView',
8
+ 'PatientExaminationDetailView',
9
+ 'PatientExaminationListView',
10
+ 'PatientExaminationViewSet'
11
+ ]
@@ -0,0 +1,140 @@
1
+ from rest_framework import viewsets, status
2
+ from rest_framework.decorators import action
3
+ from rest_framework.response import Response
4
+ from endoreg_db.models import PatientExamination, Patient, Examination
5
+ from endoreg_db.serializers.patient.patient_dropdown import PatientDropdownSerializer
6
+ from endoreg_db.serializers.patient_examination import (
7
+ PatientExaminationSerializer,
8
+ )
9
+ from endoreg_db.serializers.examination import ExaminationDropdownSerializer
10
+
11
+ class PatientExaminationViewSet(viewsets.ModelViewSet):
12
+ """
13
+ ViewSet für PatientExamination mit vollständiger CRUD-Unterstützung
14
+ """
15
+ queryset = PatientExamination.objects.all().select_related('patient', 'examination')
16
+ serializer_class = PatientExaminationSerializer
17
+
18
+ def get_queryset(self):
19
+ """Optimierte Abfrage mit besserer Performance"""
20
+ return PatientExamination.objects.select_related(
21
+ 'patient', 'examination'
22
+ ).prefetch_related(
23
+ 'patient_findings', 'indications'
24
+ ).order_by('-date_start', '-id')
25
+
26
+ def get_patient_examination_ids(self):
27
+ """Hilfsmethode zum Abrufen mehrerer PatientExamination IDs"""
28
+ return PatientExamination.objects.filter(all=True).values_list('id', flat=True)
29
+
30
+ def get_patient_examination_by_id(self, pk):
31
+ """Hilfsmethode zum Abrufen einer PatientExamination nach ID"""
32
+ if not PatientExamination.objects.filter(pk=pk).exists():
33
+ return None
34
+ else:
35
+ return PatientExamination.objects.select_related(
36
+ 'patient', 'examination'
37
+ ).get(pk=pk)
38
+
39
+
40
+ @action(detail=False, methods=['get'])
41
+ def patients_dropdown(self, request):
42
+ """
43
+ Endpoint für Patient-Dropdown-Daten
44
+ GET /api/patient-examinations/patients_dropdown/
45
+ """
46
+ patients = Patient.objects.all().order_by('first_name', 'last_name')
47
+ serializer = PatientDropdownSerializer(patients, many=True)
48
+ return Response(serializer.data)
49
+
50
+ @action(detail=False, methods=['get'])
51
+ def examinations_dropdown(self, request):
52
+ """
53
+ Endpoint für Examination-Dropdown-Daten
54
+ GET /api/patient-examinations/examinations_dropdown/
55
+ """
56
+ examinations = Examination.objects.all().order_by('name')
57
+ serializer = ExaminationDropdownSerializer(examinations, many=True)
58
+ return Response(serializer.data)
59
+
60
+ @action(detail=False, methods=['get'])
61
+ def recent(self, request):
62
+ """
63
+ Endpoint für die letzten PatientExaminations
64
+ GET /api/patient-examinations/recent/
65
+ """
66
+ limit = int(request.query_params.get('limit', 10))
67
+ recent_examinations = self.get_queryset()[:limit]
68
+ serializer = self.get_serializer(recent_examinations, many=True)
69
+ return Response(serializer.data)
70
+
71
+ @action(detail=True, methods=['get'])
72
+ def details(self, request, pk=None):
73
+ """
74
+ Detaillierte Informationen über eine PatientExamination
75
+ GET /api/patient-examinations/{id}/details/
76
+ """
77
+ examination = self.get_object()
78
+ data = {
79
+ 'examination': PatientExaminationSerializer(examination).data,
80
+ 'findings': examination.get_findings().count(),
81
+ 'indications': examination.get_indications().count(),
82
+ 'patient_age_at_examination': examination.get_patient_age_at_examination() if examination.date_start else None,
83
+ }
84
+ return Response(data)
85
+
86
+ def create(self, request, *args, **kwargs):
87
+ """
88
+ Überschreibt die create-Methode für bessere Fehlerbehandlung
89
+ """
90
+ serializer = self.get_serializer(data=request.data)
91
+ if serializer.is_valid():
92
+ try:
93
+ self.perform_create(serializer)
94
+ headers = self.get_success_headers(serializer.data)
95
+ return Response(
96
+ serializer.data,
97
+ status=status.HTTP_201_CREATED,
98
+ headers=headers
99
+ )
100
+ except Exception as e:
101
+ return Response(
102
+ {'error': f'Fehler beim Erstellen der Untersuchung: {str(e)}'},
103
+ status=status.HTTP_400_BAD_REQUEST
104
+ )
105
+ return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
106
+
107
+ def update(self, request, *args, **kwargs):
108
+ """
109
+ Überschreibt die update-Methode für bessere Fehlerbehandlung
110
+ """
111
+ partial = kwargs.pop('partial', False)
112
+ instance = self.get_object()
113
+ serializer = self.get_serializer(instance, data=request.data, partial=partial)
114
+
115
+ if serializer.is_valid():
116
+ try:
117
+ self.perform_update(serializer)
118
+ return Response(serializer.data)
119
+ except Exception as e:
120
+ return Response(
121
+ {'error': f'Fehler beim Aktualisieren der Untersuchung: {str(e)}'},
122
+ status=status.HTTP_400_BAD_REQUEST
123
+ )
124
+ return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
125
+
126
+ def get_findings_for_examination(self, request, pk=None):
127
+ """
128
+ Endpoint to retrieve findings for a specific PatientExamination
129
+ GET /api/patient-examinations/{pk}/findings/
130
+ """
131
+ examination = self.get_patient_examination_by_id(pk)
132
+ if not examination:
133
+ return Response(
134
+ {'error': 'PatientExamination nicht gefunden'},
135
+ status=status.HTTP_404_NOT_FOUND
136
+ )
137
+
138
+ findings = PatientExaminationSerializer.get_
139
+ finding_data = [{'id': f.id, 'name': str(f)} for f in findings]
140
+ return Response(finding_data)
@@ -0,0 +1,63 @@
1
+ from endoreg_db.serializers.patient_examination import PatientExaminationSerializer
2
+
3
+ from django.db import transaction
4
+ from rest_framework import generics, status
5
+ from rest_framework.response import Response
6
+ from endoreg_db.utils.permissions import EnvironmentAwarePermission
7
+
8
+ import logging
9
+ logger = logging.getLogger(__name__)
10
+
11
+ class ExaminationCreateView(generics.CreateAPIView):
12
+ """
13
+ Create new PatientExamination instances.
14
+ POST /api/examinations/create/
15
+
16
+ Expected payload:
17
+ {
18
+ "patient": "patient_hash_string", # or patient_id integer
19
+ "examination": "examination_name", # examination name string
20
+ "date_start": "2024-01-15",
21
+ }
22
+ """
23
+ serializer_class = PatientExaminationSerializer
24
+ permission_classes = [EnvironmentAwarePermission]
25
+
26
+
27
+ @transaction.atomic
28
+ def create(self, request, *args, **kwargs):
29
+
30
+ try:
31
+ logger.info(f"Creating examination with data: {request.data}")
32
+
33
+ # Use the serializer for validation and creation
34
+ serializer = self.get_serializer(data=request.data)
35
+
36
+ if serializer.is_valid():
37
+ # The serializer handles patient lookup/creation in validate_patient
38
+ instance = serializer.save()
39
+
40
+ response_data = serializer.data
41
+ response_data['message'] = 'Examination created successfully'
42
+
43
+ logger.info(f"Examination created successfully with ID: {instance.id}")
44
+ return Response(response_data, status=status.HTTP_201_CREATED)
45
+ else:
46
+ logger.warning(f"Validation errors: {serializer.errors}")
47
+ return Response(
48
+ {
49
+ 'error': 'Validation failed',
50
+ 'details': serializer.errors
51
+ },
52
+ status=status.HTTP_400_BAD_REQUEST
53
+ )
54
+
55
+ except Exception as e:
56
+ logger.error(f"Error creating examination: {str(e)}")
57
+ return Response(
58
+ {
59
+ 'error': 'Failed to create examination',
60
+ 'message': str(e)
61
+ },
62
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR
63
+ )
@@ -0,0 +1,66 @@
1
+ from endoreg_db.models import PatientExamination
2
+ from endoreg_db.serializers.patient_examination import PatientExaminationSerializer
3
+
4
+ from django.db import transaction
5
+ from rest_framework import generics, status
6
+ from rest_framework.response import Response
7
+
8
+ from endoreg_db.utils.permissions import DEBUG_PERMISSIONS
9
+
10
+ import logging
11
+ logger = logging.getLogger(__name__)
12
+
13
+ class PatientExaminationDetailView(generics.RetrieveUpdateAPIView):
14
+ """
15
+ Retrieve and update PatientExamination instances.
16
+ GET /api/examinations/{id}/
17
+ PATCH /api/examinations/{id}/
18
+ """
19
+ queryset = PatientExamination.objects.select_related('patient', 'examination')
20
+ serializer_class = PatientExaminationSerializer
21
+ permission_classes = DEBUG_PERMISSIONS
22
+
23
+ def get(self, request, *args, **kwargs):
24
+ try:
25
+ instance = self.get_object()
26
+ serializer = self.get_serializer(instance)
27
+ return Response(serializer.data)
28
+ except Exception as e:
29
+ logger.error(f"Error retrieving examination: {str(e)}")
30
+ return Response(
31
+ {'error': 'Failed to retrieve examination'},
32
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR
33
+ )
34
+
35
+ @transaction.atomic
36
+ def patch(self, request, *args, **kwargs):
37
+ try:
38
+ instance = self.get_object()
39
+ serializer = self.get_serializer(instance, data=request.data, partial=True)
40
+
41
+ if serializer.is_valid():
42
+ updated_instance = serializer.save()
43
+
44
+ response_data = serializer.data
45
+ response_data['message'] = 'Examination updated successfully'
46
+
47
+ logger.info(f"Examination {instance.id} updated successfully")
48
+ return Response(response_data, status=status.HTTP_200_OK)
49
+ else:
50
+ return Response(
51
+ {
52
+ 'error': 'Validation failed',
53
+ 'details': serializer.errors
54
+ },
55
+ status=status.HTTP_400_BAD_REQUEST
56
+ )
57
+
58
+ except Exception as e:
59
+ logger.error(f"Error updating examination: {str(e)}")
60
+ return Response(
61
+ {
62
+ 'error': 'Failed to update examination',
63
+ 'message': str(e)
64
+ },
65
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR
66
+ )