endoreg-db 0.8.8.9__py3-none-any.whl → 0.8.9.10__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 (453) hide show
  1. endoreg_db/admin.py +10 -5
  2. endoreg_db/apps.py +4 -7
  3. endoreg_db/authz/auth.py +1 -0
  4. endoreg_db/authz/backends.py +1 -1
  5. endoreg_db/authz/management/commands/list_routes.py +2 -0
  6. endoreg_db/authz/middleware.py +8 -7
  7. endoreg_db/authz/permissions.py +21 -10
  8. endoreg_db/authz/policy.py +14 -19
  9. endoreg_db/authz/views_auth.py +14 -10
  10. endoreg_db/codemods/rename_datetime_fields.py +8 -1
  11. endoreg_db/exceptions.py +5 -2
  12. endoreg_db/forms/__init__.py +0 -1
  13. endoreg_db/forms/examination_form.py +4 -3
  14. endoreg_db/forms/patient_finding_intervention_form.py +30 -8
  15. endoreg_db/forms/patient_form.py +9 -13
  16. endoreg_db/forms/questionnaires/__init__.py +1 -1
  17. endoreg_db/forms/settings/__init__.py +4 -1
  18. endoreg_db/forms/unit.py +2 -1
  19. endoreg_db/helpers/count_db.py +17 -14
  20. endoreg_db/helpers/default_objects.py +2 -1
  21. endoreg_db/helpers/download_segmentation_model.py +4 -3
  22. endoreg_db/helpers/interact.py +0 -5
  23. endoreg_db/helpers/test_video_helper.py +33 -25
  24. endoreg_db/import_files/__init__.py +1 -1
  25. endoreg_db/import_files/context/__init__.py +1 -1
  26. endoreg_db/import_files/context/default_sensitive_meta.py +11 -9
  27. endoreg_db/import_files/context/ensure_center.py +4 -4
  28. endoreg_db/import_files/context/file_lock.py +3 -3
  29. endoreg_db/import_files/context/import_context.py +11 -12
  30. endoreg_db/import_files/context/validate_directories.py +1 -0
  31. endoreg_db/import_files/file_storage/create_report_file.py +57 -34
  32. endoreg_db/import_files/file_storage/create_video_file.py +64 -35
  33. endoreg_db/import_files/file_storage/sensitive_meta_storage.py +5 -2
  34. endoreg_db/import_files/file_storage/state_management.py +146 -83
  35. endoreg_db/import_files/file_storage/storage.py +5 -1
  36. endoreg_db/import_files/processing/report_processing/report_anonymization.py +24 -19
  37. endoreg_db/import_files/processing/sensitive_meta_adapter.py +3 -3
  38. endoreg_db/import_files/processing/video_processing/video_anonymization.py +18 -18
  39. endoreg_db/import_files/pseudonymization/k_anonymity.py +8 -9
  40. endoreg_db/import_files/pseudonymization/k_pseudonymity.py +16 -5
  41. endoreg_db/import_files/report_import_service.py +36 -30
  42. endoreg_db/import_files/video_import_service.py +27 -23
  43. endoreg_db/logger_conf.py +56 -40
  44. endoreg_db/management/__init__.py +1 -1
  45. endoreg_db/management/commands/__init__.py +1 -1
  46. endoreg_db/management/commands/check_auth.py +45 -38
  47. endoreg_db/management/commands/create_model_meta_from_huggingface.py +53 -2
  48. endoreg_db/management/commands/create_multilabel_model_meta.py +54 -19
  49. endoreg_db/management/commands/fix_missing_patient_data.py +105 -71
  50. endoreg_db/management/commands/fix_video_paths.py +75 -54
  51. endoreg_db/management/commands/import_report.py +1 -3
  52. endoreg_db/management/commands/list_routes.py +2 -0
  53. endoreg_db/management/commands/load_ai_model_data.py +8 -2
  54. endoreg_db/management/commands/load_ai_model_label_data.py +0 -1
  55. endoreg_db/management/commands/load_center_data.py +3 -3
  56. endoreg_db/management/commands/load_distribution_data.py +35 -38
  57. endoreg_db/management/commands/load_endoscope_data.py +0 -3
  58. endoreg_db/management/commands/load_examination_data.py +20 -4
  59. endoreg_db/management/commands/load_finding_data.py +18 -3
  60. endoreg_db/management/commands/load_gender_data.py +17 -24
  61. endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +95 -85
  62. endoreg_db/management/commands/load_information_source.py +0 -3
  63. endoreg_db/management/commands/load_lab_value_data.py +14 -3
  64. endoreg_db/management/commands/load_legacy_data.py +303 -0
  65. endoreg_db/management/commands/load_name_data.py +1 -2
  66. endoreg_db/management/commands/load_pdf_type_data.py +4 -8
  67. endoreg_db/management/commands/load_profession_data.py +0 -1
  68. endoreg_db/management/commands/load_report_reader_flag_data.py +0 -4
  69. endoreg_db/management/commands/load_requirement_data.py +6 -2
  70. endoreg_db/management/commands/load_unit_data.py +0 -4
  71. endoreg_db/management/commands/load_user_groups.py +5 -7
  72. endoreg_db/management/commands/model_input.py +169 -0
  73. endoreg_db/management/commands/register_ai_model.py +22 -16
  74. endoreg_db/management/commands/setup_endoreg_db.py +110 -32
  75. endoreg_db/management/commands/storage_management.py +14 -8
  76. endoreg_db/management/commands/summarize_db_content.py +154 -63
  77. endoreg_db/management/commands/train_image_multilabel_model.py +144 -0
  78. endoreg_db/management/commands/validate_video_files.py +82 -50
  79. endoreg_db/management/commands/video_validation.py +4 -6
  80. endoreg_db/migrations/0001_initial.py +112 -63
  81. endoreg_db/migrations/__init__.py +0 -0
  82. endoreg_db/models/__init__.py +8 -0
  83. endoreg_db/models/administration/ai/active_model.py +5 -5
  84. endoreg_db/models/administration/ai/ai_model.py +41 -18
  85. endoreg_db/models/administration/ai/model_type.py +1 -0
  86. endoreg_db/models/administration/case/case.py +22 -22
  87. endoreg_db/models/administration/center/__init__.py +5 -5
  88. endoreg_db/models/administration/center/center.py +6 -2
  89. endoreg_db/models/administration/center/center_resource.py +18 -4
  90. endoreg_db/models/administration/center/center_shift.py +3 -1
  91. endoreg_db/models/administration/center/center_waste.py +6 -2
  92. endoreg_db/models/administration/person/__init__.py +1 -1
  93. endoreg_db/models/administration/person/employee/__init__.py +1 -1
  94. endoreg_db/models/administration/person/employee/employee_type.py +3 -1
  95. endoreg_db/models/administration/person/examiner/__init__.py +1 -1
  96. endoreg_db/models/administration/person/examiner/examiner.py +10 -2
  97. endoreg_db/models/administration/person/names/first_name.py +6 -4
  98. endoreg_db/models/administration/person/names/last_name.py +4 -3
  99. endoreg_db/models/administration/person/patient/__init__.py +1 -1
  100. endoreg_db/models/administration/person/patient/patient.py +0 -1
  101. endoreg_db/models/administration/person/patient/patient_external_id.py +0 -1
  102. endoreg_db/models/administration/person/person.py +1 -1
  103. endoreg_db/models/administration/product/__init__.py +7 -6
  104. endoreg_db/models/administration/product/product.py +6 -2
  105. endoreg_db/models/administration/product/product_group.py +9 -7
  106. endoreg_db/models/administration/product/product_material.py +9 -2
  107. endoreg_db/models/administration/product/reference_product.py +64 -15
  108. endoreg_db/models/administration/qualification/qualification.py +3 -1
  109. endoreg_db/models/administration/shift/shift.py +3 -1
  110. endoreg_db/models/administration/shift/shift_type.py +12 -4
  111. endoreg_db/models/aidataset/__init__.py +5 -0
  112. endoreg_db/models/aidataset/aidataset.py +193 -0
  113. endoreg_db/models/label/__init__.py +1 -1
  114. endoreg_db/models/label/label.py +10 -2
  115. endoreg_db/models/label/label_set.py +3 -1
  116. endoreg_db/models/label/label_video_segment/_create_from_video.py +6 -2
  117. endoreg_db/models/label/label_video_segment/label_video_segment.py +148 -44
  118. endoreg_db/models/media/__init__.py +12 -5
  119. endoreg_db/models/media/frame/__init__.py +1 -1
  120. endoreg_db/models/media/frame/frame.py +34 -8
  121. endoreg_db/models/media/pdf/__init__.py +2 -1
  122. endoreg_db/models/media/pdf/raw_pdf.py +11 -4
  123. endoreg_db/models/media/pdf/report_file.py +6 -2
  124. endoreg_db/models/media/pdf/report_reader/__init__.py +3 -3
  125. endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +15 -5
  126. endoreg_db/models/media/video/create_from_file.py +20 -41
  127. endoreg_db/models/media/video/pipe_1.py +75 -30
  128. endoreg_db/models/media/video/pipe_2.py +37 -12
  129. endoreg_db/models/media/video/video_file.py +36 -24
  130. endoreg_db/models/media/video/video_file_ai.py +235 -70
  131. endoreg_db/models/media/video/video_file_anonymize.py +240 -65
  132. endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +6 -1
  133. endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +3 -1
  134. endoreg_db/models/media/video/video_file_frames/_delete_frames.py +30 -9
  135. endoreg_db/models/media/video/video_file_frames/_extract_frames.py +95 -29
  136. endoreg_db/models/media/video/video_file_frames/_get_frame.py +13 -3
  137. endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +4 -1
  138. endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +15 -3
  139. endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +15 -3
  140. endoreg_db/models/media/video/video_file_frames/_get_frames.py +7 -2
  141. endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +109 -23
  142. endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +111 -27
  143. endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +46 -13
  144. endoreg_db/models/media/video/video_file_io.py +85 -33
  145. endoreg_db/models/media/video/video_file_meta/__init__.py +6 -6
  146. endoreg_db/models/media/video/video_file_meta/get_crop_template.py +17 -4
  147. endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +28 -7
  148. endoreg_db/models/media/video/video_file_meta/get_fps.py +46 -13
  149. endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +81 -20
  150. endoreg_db/models/media/video/video_file_meta/text_meta.py +61 -20
  151. endoreg_db/models/media/video/video_file_meta/video_meta.py +40 -12
  152. endoreg_db/models/media/video/video_file_segments.py +118 -27
  153. endoreg_db/models/media/video/video_metadata.py +25 -6
  154. endoreg_db/models/media/video/video_processing.py +54 -15
  155. endoreg_db/models/medical/__init__.py +3 -13
  156. endoreg_db/models/medical/contraindication/__init__.py +3 -1
  157. endoreg_db/models/medical/disease.py +18 -6
  158. endoreg_db/models/medical/event.py +6 -2
  159. endoreg_db/models/medical/examination/__init__.py +5 -1
  160. endoreg_db/models/medical/examination/examination.py +22 -6
  161. endoreg_db/models/medical/examination/examination_indication.py +23 -7
  162. endoreg_db/models/medical/examination/examination_time.py +6 -2
  163. endoreg_db/models/medical/finding/__init__.py +3 -1
  164. endoreg_db/models/medical/finding/finding.py +37 -12
  165. endoreg_db/models/medical/finding/finding_classification.py +27 -8
  166. endoreg_db/models/medical/finding/finding_intervention.py +19 -6
  167. endoreg_db/models/medical/finding/finding_type.py +3 -1
  168. endoreg_db/models/medical/hardware/__init__.py +1 -1
  169. endoreg_db/models/medical/hardware/endoscope.py +14 -2
  170. endoreg_db/models/medical/laboratory/__init__.py +1 -1
  171. endoreg_db/models/medical/laboratory/lab_value.py +139 -39
  172. endoreg_db/models/medical/medication/__init__.py +7 -3
  173. endoreg_db/models/medical/medication/medication.py +3 -1
  174. endoreg_db/models/medical/medication/medication_indication.py +3 -1
  175. endoreg_db/models/medical/medication/medication_indication_type.py +11 -3
  176. endoreg_db/models/medical/medication/medication_intake_time.py +3 -1
  177. endoreg_db/models/medical/medication/medication_schedule.py +3 -1
  178. endoreg_db/models/medical/patient/__init__.py +2 -10
  179. endoreg_db/models/medical/patient/medication_examples.py +3 -14
  180. endoreg_db/models/medical/patient/patient_disease.py +17 -5
  181. endoreg_db/models/medical/patient/patient_event.py +12 -4
  182. endoreg_db/models/medical/patient/patient_examination.py +52 -15
  183. endoreg_db/models/medical/patient/patient_examination_indication.py +15 -4
  184. endoreg_db/models/medical/patient/patient_finding.py +105 -29
  185. endoreg_db/models/medical/patient/patient_finding_classification.py +41 -12
  186. endoreg_db/models/medical/patient/patient_finding_intervention.py +11 -3
  187. endoreg_db/models/medical/patient/patient_lab_sample.py +6 -2
  188. endoreg_db/models/medical/patient/patient_lab_value.py +42 -10
  189. endoreg_db/models/medical/patient/patient_medication.py +25 -7
  190. endoreg_db/models/medical/patient/patient_medication_schedule.py +34 -10
  191. endoreg_db/models/metadata/model_meta.py +40 -12
  192. endoreg_db/models/metadata/model_meta_logic.py +51 -16
  193. endoreg_db/models/metadata/sensitive_meta.py +65 -28
  194. endoreg_db/models/metadata/sensitive_meta_logic.py +28 -26
  195. endoreg_db/models/metadata/video_meta.py +146 -39
  196. endoreg_db/models/metadata/video_prediction_logic.py +70 -21
  197. endoreg_db/models/metadata/video_prediction_meta.py +80 -27
  198. endoreg_db/models/operation_log.py +63 -0
  199. endoreg_db/models/other/__init__.py +10 -10
  200. endoreg_db/models/other/distribution/__init__.py +9 -7
  201. endoreg_db/models/other/distribution/base_value_distribution.py +3 -1
  202. endoreg_db/models/other/distribution/date_value_distribution.py +19 -5
  203. endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +3 -1
  204. endoreg_db/models/other/distribution/numeric_value_distribution.py +34 -9
  205. endoreg_db/models/other/emission/__init__.py +1 -1
  206. endoreg_db/models/other/emission/emission_factor.py +9 -3
  207. endoreg_db/models/other/information_source.py +15 -5
  208. endoreg_db/models/other/material.py +3 -1
  209. endoreg_db/models/other/transport_route.py +3 -1
  210. endoreg_db/models/other/unit.py +6 -2
  211. endoreg_db/models/report/report.py +0 -1
  212. endoreg_db/models/requirement/requirement.py +84 -27
  213. endoreg_db/models/requirement/requirement_error.py +5 -6
  214. endoreg_db/models/requirement/requirement_evaluation/__init__.py +1 -1
  215. endoreg_db/models/requirement/requirement_evaluation/evaluate_with_dependencies.py +8 -8
  216. endoreg_db/models/requirement/requirement_evaluation/get_values.py +3 -3
  217. endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +24 -8
  218. endoreg_db/models/requirement/requirement_operator.py +28 -8
  219. endoreg_db/models/requirement/requirement_set.py +34 -11
  220. endoreg_db/models/state/__init__.py +1 -0
  221. endoreg_db/models/state/audit_ledger.py +9 -2
  222. endoreg_db/models/{media → state}/processing_history/__init__.py +1 -3
  223. endoreg_db/models/state/processing_history/processing_history.py +136 -0
  224. endoreg_db/models/state/raw_pdf.py +0 -1
  225. endoreg_db/models/state/video.py +2 -3
  226. endoreg_db/models/utils.py +4 -2
  227. endoreg_db/queries/__init__.py +2 -6
  228. endoreg_db/queries/annotations/__init__.py +1 -3
  229. endoreg_db/queries/annotations/legacy.py +37 -26
  230. endoreg_db/root_urls.py +3 -4
  231. endoreg_db/schemas/examination_evaluation.py +3 -0
  232. endoreg_db/serializers/Frames_NICE_and_PARIS_classifications.py +249 -163
  233. endoreg_db/serializers/__init__.py +2 -8
  234. endoreg_db/serializers/administration/__init__.py +1 -2
  235. endoreg_db/serializers/administration/ai/__init__.py +0 -1
  236. endoreg_db/serializers/administration/ai/active_model.py +3 -1
  237. endoreg_db/serializers/administration/ai/ai_model.py +5 -3
  238. endoreg_db/serializers/administration/ai/model_type.py +3 -1
  239. endoreg_db/serializers/administration/center.py +7 -2
  240. endoreg_db/serializers/administration/gender.py +4 -2
  241. endoreg_db/serializers/anonymization.py +13 -13
  242. endoreg_db/serializers/evaluation/examination_evaluation.py +0 -1
  243. endoreg_db/serializers/examination/__init__.py +1 -1
  244. endoreg_db/serializers/examination/base.py +12 -13
  245. endoreg_db/serializers/examination/dropdown.py +6 -7
  246. endoreg_db/serializers/examination_serializer.py +3 -6
  247. endoreg_db/serializers/finding/__init__.py +1 -1
  248. endoreg_db/serializers/finding/finding.py +14 -7
  249. endoreg_db/serializers/finding_classification/__init__.py +3 -3
  250. endoreg_db/serializers/finding_classification/choice.py +3 -3
  251. endoreg_db/serializers/finding_classification/classification.py +2 -4
  252. endoreg_db/serializers/label_video_segment/__init__.py +5 -3
  253. endoreg_db/serializers/{label → label_video_segment}/image_classification_annotation.py +5 -5
  254. endoreg_db/serializers/label_video_segment/label/__init__.py +6 -0
  255. endoreg_db/serializers/{label → label_video_segment/label}/label.py +1 -1
  256. endoreg_db/serializers/label_video_segment/label_video_segment.py +338 -228
  257. endoreg_db/serializers/meta/__init__.py +1 -2
  258. endoreg_db/serializers/meta/sensitive_meta_detail.py +28 -13
  259. endoreg_db/serializers/meta/sensitive_meta_update.py +51 -46
  260. endoreg_db/serializers/meta/sensitive_meta_verification.py +19 -16
  261. endoreg_db/serializers/misc/__init__.py +2 -2
  262. endoreg_db/serializers/misc/file_overview.py +11 -7
  263. endoreg_db/serializers/misc/stats.py +10 -8
  264. endoreg_db/serializers/misc/translatable_field_mix_in.py +6 -6
  265. endoreg_db/serializers/misc/upload_job.py +32 -29
  266. endoreg_db/serializers/patient/__init__.py +2 -1
  267. endoreg_db/serializers/patient/patient.py +32 -15
  268. endoreg_db/serializers/patient/patient_dropdown.py +11 -3
  269. endoreg_db/serializers/patient_examination/__init__.py +1 -1
  270. endoreg_db/serializers/patient_examination/patient_examination.py +67 -40
  271. endoreg_db/serializers/patient_finding/__init__.py +1 -1
  272. endoreg_db/serializers/patient_finding/patient_finding.py +2 -1
  273. endoreg_db/serializers/patient_finding/patient_finding_classification.py +17 -9
  274. endoreg_db/serializers/patient_finding/patient_finding_detail.py +26 -17
  275. endoreg_db/serializers/patient_finding/patient_finding_intervention.py +7 -5
  276. endoreg_db/serializers/patient_finding/patient_finding_list.py +10 -11
  277. endoreg_db/serializers/patient_finding/patient_finding_write.py +36 -27
  278. endoreg_db/serializers/pdf/__init__.py +1 -3
  279. endoreg_db/serializers/requirements/requirement_schema.py +1 -6
  280. endoreg_db/serializers/sensitive_meta_serializer.py +100 -81
  281. endoreg_db/serializers/video/__init__.py +2 -2
  282. endoreg_db/serializers/video/{segmentation.py → video_file.py} +66 -47
  283. endoreg_db/serializers/video/video_file_brief.py +6 -2
  284. endoreg_db/serializers/video/video_file_detail.py +36 -23
  285. endoreg_db/serializers/video/video_file_list.py +4 -2
  286. endoreg_db/serializers/video/video_processing_history.py +54 -50
  287. endoreg_db/services/__init__.py +1 -1
  288. endoreg_db/services/anonymization.py +2 -2
  289. endoreg_db/services/examination_evaluation.py +40 -17
  290. endoreg_db/services/model_meta_from_hf.py +76 -0
  291. endoreg_db/services/polling_coordinator.py +101 -70
  292. endoreg_db/services/pseudonym_service.py +27 -22
  293. endoreg_db/services/report_import.py +6 -3
  294. endoreg_db/services/segment_sync.py +75 -59
  295. endoreg_db/services/video_import.py +6 -7
  296. endoreg_db/urls/__init__.py +2 -2
  297. endoreg_db/urls/ai.py +7 -25
  298. endoreg_db/urls/anonymization.py +61 -15
  299. endoreg_db/urls/auth.py +4 -4
  300. endoreg_db/urls/classification.py +4 -9
  301. endoreg_db/urls/examination.py +27 -18
  302. endoreg_db/urls/media.py +27 -34
  303. endoreg_db/urls/patient.py +11 -7
  304. endoreg_db/urls/requirements.py +3 -1
  305. endoreg_db/urls/root_urls.py +2 -3
  306. endoreg_db/urls/stats.py +24 -16
  307. endoreg_db/urls/upload.py +3 -11
  308. endoreg_db/utils/__init__.py +14 -15
  309. endoreg_db/utils/ai/__init__.py +1 -1
  310. endoreg_db/utils/ai/data_loader_for_model_input.py +262 -0
  311. endoreg_db/utils/ai/data_loader_for_model_training.py +262 -0
  312. endoreg_db/utils/ai/get.py +2 -1
  313. endoreg_db/utils/ai/inference_dataset.py +14 -15
  314. endoreg_db/utils/ai/model_training/config.py +117 -0
  315. endoreg_db/utils/ai/model_training/dataset.py +74 -0
  316. endoreg_db/utils/ai/model_training/losses.py +68 -0
  317. endoreg_db/utils/ai/model_training/metrics.py +78 -0
  318. endoreg_db/utils/ai/model_training/model_backbones.py +155 -0
  319. endoreg_db/utils/ai/model_training/model_gastronet_resnet.py +118 -0
  320. endoreg_db/utils/ai/model_training/trainer_gastronet_multilabel.py +771 -0
  321. endoreg_db/utils/ai/multilabel_classification_net.py +21 -6
  322. endoreg_db/utils/ai/predict.py +4 -4
  323. endoreg_db/utils/ai/preprocess.py +19 -11
  324. endoreg_db/utils/calc_duration_seconds.py +4 -4
  325. endoreg_db/utils/case_generator/lab_sample_factory.py +3 -4
  326. endoreg_db/utils/check_video_files.py +74 -47
  327. endoreg_db/utils/cropping.py +10 -9
  328. endoreg_db/utils/dataloader.py +11 -3
  329. endoreg_db/utils/dates.py +3 -4
  330. endoreg_db/utils/defaults/set_default_center.py +7 -6
  331. endoreg_db/utils/env.py +6 -2
  332. endoreg_db/utils/extract_specific_frames.py +24 -9
  333. endoreg_db/utils/file_operations.py +30 -18
  334. endoreg_db/utils/fix_video_path_direct.py +57 -41
  335. endoreg_db/utils/frame_anonymization_utils.py +157 -157
  336. endoreg_db/utils/hashs.py +3 -18
  337. endoreg_db/utils/links/requirement_link.py +96 -52
  338. endoreg_db/utils/ocr.py +30 -25
  339. endoreg_db/utils/operation_log.py +61 -0
  340. endoreg_db/utils/parse_and_generate_yaml.py +12 -13
  341. endoreg_db/utils/paths.py +6 -6
  342. endoreg_db/utils/permissions.py +40 -24
  343. endoreg_db/utils/pipelines/process_video_dir.py +50 -26
  344. endoreg_db/utils/product/sum_emissions.py +5 -3
  345. endoreg_db/utils/product/sum_weights.py +4 -2
  346. endoreg_db/utils/pydantic_models/__init__.py +3 -4
  347. endoreg_db/utils/requirement_operator_logic/_old/lab_value_operators.py +207 -107
  348. endoreg_db/utils/requirement_operator_logic/_old/model_evaluators.py +252 -65
  349. endoreg_db/utils/requirement_operator_logic/new_operator_logic.py +27 -10
  350. endoreg_db/utils/setup_config.py +21 -5
  351. endoreg_db/utils/storage.py +3 -1
  352. endoreg_db/utils/translation.py +19 -15
  353. endoreg_db/utils/uuid.py +1 -0
  354. endoreg_db/utils/validate_endo_roi.py +12 -4
  355. endoreg_db/utils/validate_subcategory_dict.py +26 -24
  356. endoreg_db/utils/validate_video_detailed.py +207 -149
  357. endoreg_db/utils/video/__init__.py +7 -3
  358. endoreg_db/utils/video/extract_frames.py +30 -18
  359. endoreg_db/utils/video/ffmpeg_wrapper.py +217 -52
  360. endoreg_db/utils/video/names.py +11 -6
  361. endoreg_db/utils/video/streaming_processor.py +175 -101
  362. endoreg_db/utils/video/video_splitter.py +30 -19
  363. endoreg_db/views/Frames_NICE_and_PARIS_classifications_views.py +59 -50
  364. endoreg_db/views/__init__.py +0 -20
  365. endoreg_db/views/anonymization/__init__.py +6 -2
  366. endoreg_db/views/anonymization/media_management.py +2 -6
  367. endoreg_db/views/anonymization/overview.py +34 -1
  368. endoreg_db/views/anonymization/validate.py +79 -18
  369. endoreg_db/views/auth/__init__.py +1 -1
  370. endoreg_db/views/auth/keycloak.py +16 -14
  371. endoreg_db/views/examination/__init__.py +12 -15
  372. endoreg_db/views/examination/examination.py +5 -5
  373. endoreg_db/views/examination/examination_manifest_cache.py +5 -5
  374. endoreg_db/views/examination/get_finding_classification_choices.py +8 -5
  375. endoreg_db/views/examination/get_finding_classifications.py +9 -7
  376. endoreg_db/views/examination/get_findings.py +8 -10
  377. endoreg_db/views/examination/get_instruments.py +3 -2
  378. endoreg_db/views/examination/get_interventions.py +1 -1
  379. endoreg_db/views/finding/__init__.py +2 -2
  380. endoreg_db/views/finding/finding.py +58 -54
  381. endoreg_db/views/finding/get_classifications.py +1 -1
  382. endoreg_db/views/finding/get_interventions.py +1 -1
  383. endoreg_db/views/finding_classification/__init__.py +5 -5
  384. endoreg_db/views/finding_classification/finding_classification.py +5 -6
  385. endoreg_db/views/finding_classification/get_classification_choices.py +3 -4
  386. endoreg_db/views/media/__init__.py +13 -13
  387. endoreg_db/views/media/pdf_media.py +9 -9
  388. endoreg_db/views/media/sensitive_metadata.py +10 -7
  389. endoreg_db/views/media/video_media.py +4 -4
  390. endoreg_db/views/meta/__init__.py +1 -1
  391. endoreg_db/views/meta/sensitive_meta_list.py +20 -22
  392. endoreg_db/views/meta/sensitive_meta_verification.py +14 -11
  393. endoreg_db/views/misc/__init__.py +6 -34
  394. endoreg_db/views/misc/center.py +2 -1
  395. endoreg_db/views/misc/csrf.py +2 -1
  396. endoreg_db/views/misc/gender.py +2 -1
  397. endoreg_db/views/misc/stats.py +141 -106
  398. endoreg_db/views/patient/__init__.py +1 -3
  399. endoreg_db/views/patient/patient.py +141 -99
  400. endoreg_db/views/patient_examination/__init__.py +5 -5
  401. endoreg_db/views/patient_examination/patient_examination.py +43 -42
  402. endoreg_db/views/patient_examination/patient_examination_create.py +10 -15
  403. endoreg_db/views/patient_examination/patient_examination_detail.py +12 -15
  404. endoreg_db/views/patient_examination/patient_examination_list.py +21 -17
  405. endoreg_db/views/patient_examination/video.py +114 -80
  406. endoreg_db/views/patient_finding/__init__.py +1 -1
  407. endoreg_db/views/patient_finding/patient_finding.py +17 -10
  408. endoreg_db/views/patient_finding/patient_finding_optimized.py +127 -95
  409. endoreg_db/views/patient_finding_classification/__init__.py +1 -1
  410. endoreg_db/views/patient_finding_classification/pfc_create.py +35 -27
  411. endoreg_db/views/report/reimport.py +1 -1
  412. endoreg_db/views/report/report_stream.py +5 -8
  413. endoreg_db/views/requirement/__init__.py +2 -1
  414. endoreg_db/views/requirement/evaluate.py +7 -9
  415. endoreg_db/views/requirement/lookup.py +2 -3
  416. endoreg_db/views/requirement/lookup_store.py +0 -1
  417. endoreg_db/views/requirement/requirement_utils.py +2 -4
  418. endoreg_db/views/stats/__init__.py +4 -4
  419. endoreg_db/views/stats/stats_views.py +152 -115
  420. endoreg_db/views/video/__init__.py +18 -27
  421. endoreg_db/views/{ai → video/ai}/__init__.py +2 -2
  422. endoreg_db/views/{ai → video/ai}/label.py +20 -16
  423. endoreg_db/views/video/correction.py +5 -6
  424. endoreg_db/views/video/reimport.py +134 -99
  425. endoreg_db/views/video/segments_crud.py +134 -44
  426. endoreg_db/views/video/video_apply_mask.py +13 -12
  427. endoreg_db/views/video/video_correction.py +2 -1
  428. endoreg_db/views/video/video_download_processed.py +15 -15
  429. endoreg_db/views/video/video_meta_stats.py +7 -6
  430. endoreg_db/views/video/video_processing_history.py +3 -2
  431. endoreg_db/views/video/video_remove_frames.py +13 -12
  432. endoreg_db/views/video/video_stream.py +110 -82
  433. {endoreg_db-0.8.8.9.dist-info → endoreg_db-0.8.9.10.dist-info}/METADATA +9 -3
  434. {endoreg_db-0.8.8.9.dist-info → endoreg_db-0.8.9.10.dist-info}/RECORD +436 -433
  435. endoreg_db/import_files/processing/video_processing/video_cleanup_on_error.py +0 -119
  436. endoreg_db/management/commands/import_fallback_video.py +0 -203
  437. endoreg_db/management/commands/import_video.py +0 -422
  438. endoreg_db/management/commands/import_video_with_classification.py +0 -367
  439. endoreg_db/models/media/processing_history/processing_history.py +0 -96
  440. endoreg_db/serializers/label/__init__.py +0 -7
  441. endoreg_db/serializers/label_video_segment/_lvs_create.py +0 -149
  442. endoreg_db/serializers/label_video_segment/_lvs_update.py +0 -138
  443. endoreg_db/serializers/label_video_segment/_lvs_validate.py +0 -149
  444. endoreg_db/serializers/label_video_segment/label_video_segment_annotation.py +0 -99
  445. endoreg_db/serializers/label_video_segment/label_video_segment_update.py +0 -163
  446. endoreg_db/services/__old/pdf_import.py +0 -1487
  447. endoreg_db/services/__old/video_import.py +0 -1306
  448. endoreg_db/tasks/upload_tasks.py +0 -216
  449. endoreg_db/tasks/video_ingest.py +0 -161
  450. endoreg_db/tasks/video_processing_tasks.py +0 -327
  451. endoreg_db/views/misc/translation.py +0 -182
  452. {endoreg_db-0.8.8.9.dist-info → endoreg_db-0.8.9.10.dist-info}/WHEEL +0 -0
  453. {endoreg_db-0.8.8.9.dist-info → endoreg_db-0.8.9.10.dist-info}/licenses/LICENSE +0 -0
@@ -10,7 +10,9 @@ if TYPE_CHECKING:
10
10
 
11
11
  class ReferenceProductManager(models.Manager):
12
12
  def get_by_natural_key(self, product_name: str, product_group_name: str):
13
- return self.get(product__name=product_name, product_group__name=product_group_name)
13
+ return self.get(
14
+ product__name=product_name, product_group__name=product_group_name
15
+ )
14
16
 
15
17
 
16
18
  class ReferenceProduct(models.Model):
@@ -25,9 +27,25 @@ class ReferenceProduct(models.Model):
25
27
  on_delete=models.CASCADE,
26
28
  related_name="reference_product", # Changed from "reference_products"
27
29
  )
28
- emission_factor_total = models.ForeignKey("EmissionFactor", on_delete=models.SET_NULL, null=True, blank=True, related_name="reference_products")
29
- emission_factor_package = models.ForeignKey("EmissionFactor", on_delete=models.SET_NULL, null=True, related_name="reference_product_package")
30
- emission_factor_product = models.ForeignKey("EmissionFactor", on_delete=models.SET_NULL, null=True, related_name="reference_product_product")
30
+ emission_factor_total = models.ForeignKey(
31
+ "EmissionFactor",
32
+ on_delete=models.SET_NULL,
33
+ null=True,
34
+ blank=True,
35
+ related_name="reference_products",
36
+ )
37
+ emission_factor_package = models.ForeignKey(
38
+ "EmissionFactor",
39
+ on_delete=models.SET_NULL,
40
+ null=True,
41
+ related_name="reference_product_package",
42
+ )
43
+ emission_factor_product = models.ForeignKey(
44
+ "EmissionFactor",
45
+ on_delete=models.SET_NULL,
46
+ null=True,
47
+ related_name="reference_product_product",
48
+ )
31
49
 
32
50
  if TYPE_CHECKING:
33
51
  product: models.ForeignKey["Product"]
@@ -45,39 +63,70 @@ class ReferenceProduct(models.Model):
45
63
  from ...other.emission import EmissionFactor
46
64
 
47
65
  product = self.product
48
- emission_factor_name = f"{self.product_group.name}_{product.name}_total_emission_factor"
49
- emission_factor_package_name = f"{self.product_group.name}_{product.name}_package_emission_factor"
50
- emission_factor_product_name = f"{self.product_group.name}_{product.name}_product_emission_factor"
66
+ emission_factor_name = (
67
+ f"{self.product_group.name}_{product.name}_total_emission_factor"
68
+ )
69
+ emission_factor_package_name = (
70
+ f"{self.product_group.name}_{product.name}_package_emission_factor"
71
+ )
72
+ emission_factor_product_name = (
73
+ f"{self.product_group.name}_{product.name}_product_emission_factor"
74
+ )
51
75
 
52
76
  product_weight, product_weight_unit = product.get_product_material_weight()
53
77
  package_weight, package_weight_unit = product.get_package_material_weight()
54
- product_emission, product_emission_unit = product.get_product_material_emission()
55
- package_emission, package_emission_unit = product.get_package_material_emission()
78
+ product_emission, product_emission_unit = (
79
+ product.get_product_material_emission()
80
+ )
81
+ package_emission, package_emission_unit = (
82
+ product.get_package_material_emission()
83
+ )
56
84
 
57
85
  total_weight = product_weight + package_weight
58
86
  total_emission = product_emission + package_emission
59
87
 
60
88
  reference_unit = product_weight_unit
61
- assert reference_unit == package_weight_unit, "Package weight units do not match"
62
- assert reference_unit == product_emission_unit, "Product emission units do not match"
63
- assert reference_unit == package_emission_unit, "Package emission units do not match"
89
+ assert reference_unit == package_weight_unit, (
90
+ "Package weight units do not match"
91
+ )
92
+ assert reference_unit == product_emission_unit, (
93
+ "Product emission units do not match"
94
+ )
95
+ assert reference_unit == package_emission_unit, (
96
+ "Package emission units do not match"
97
+ )
64
98
 
65
99
  product_emission_factor_value = product_emission / product_weight
66
100
  package_emission_factor_value = package_emission / package_weight
67
101
  total_emission_factor_value = total_emission / total_weight
68
102
 
69
103
  emission_factor, created = EmissionFactor.objects.get_or_create(
70
- name=emission_factor_name, defaults={"name": emission_factor_name, "value": total_emission_factor_value, "unit": reference_unit}
104
+ name=emission_factor_name,
105
+ defaults={
106
+ "name": emission_factor_name,
107
+ "value": total_emission_factor_value,
108
+ "unit": reference_unit,
109
+ },
71
110
  )
72
111
  self.emission_factor_total = emission_factor
73
112
 
74
113
  emission_factor_package, created = EmissionFactor.objects.get_or_create(
75
- name=emission_factor_package_name, defaults={"name": emission_factor_package_name, "value": package_emission_factor_value, "unit": reference_unit}
114
+ name=emission_factor_package_name,
115
+ defaults={
116
+ "name": emission_factor_package_name,
117
+ "value": package_emission_factor_value,
118
+ "unit": reference_unit,
119
+ },
76
120
  )
77
121
  self.emission_factor_package = emission_factor_package
78
122
 
79
123
  emission_factor_product, created = EmissionFactor.objects.get_or_create(
80
- name=emission_factor_product_name, defaults={"name": emission_factor_product_name, "value": product_emission_factor_value, "unit": reference_unit}
124
+ name=emission_factor_product_name,
125
+ defaults={
126
+ "name": emission_factor_product_name,
127
+ "value": product_emission_factor_value,
128
+ "unit": reference_unit,
129
+ },
81
130
  )
82
131
  self.emission_factor_product = emission_factor_product
83
132
 
@@ -30,7 +30,9 @@ class Qualification(models.Model):
30
30
  related_name="qualifications",
31
31
  )
32
32
  if TYPE_CHECKING:
33
- qualification_types = cast(models.manager.RelatedManager["QualificationType"], qualification_types)
33
+ qualification_types = cast(
34
+ models.manager.RelatedManager["QualificationType"], qualification_types
35
+ )
34
36
 
35
37
  objects = QualificationManager()
36
38
 
@@ -41,7 +41,9 @@ class Shift(models.Model):
41
41
 
42
42
  if TYPE_CHECKING:
43
43
  shift_types = cast(models.QuerySet["ShiftType"], shift_types)
44
- required_qualifications = cast(models.QuerySet["Qualification"], required_qualifications)
44
+ required_qualifications = cast(
45
+ models.QuerySet["Qualification"], required_qualifications
46
+ )
45
47
 
46
48
  @property
47
49
  def center_shifts(self) -> models.QuerySet["CenterShift"]: ...
@@ -54,7 +54,9 @@ class ShiftType(models.Model):
54
54
  try:
55
55
  return cls.objects.get(name=NAME_REGULAR)
56
56
  except cls.DoesNotExist:
57
- logger.error(f"ShiftType with name '{NAME_REGULAR}' does not exist. Base data might be missing.")
57
+ logger.error(
58
+ f"ShiftType with name '{NAME_REGULAR}' does not exist. Base data might be missing."
59
+ )
58
60
  return None
59
61
 
60
62
  @classmethod
@@ -68,7 +70,9 @@ class ShiftType(models.Model):
68
70
  try:
69
71
  return cls.objects.get(name=NAME_ON_CALL)
70
72
  except cls.DoesNotExist:
71
- logger.error(f"ShiftType with name '{NAME_ON_CALL}' does not exist. Base data might be missing.")
73
+ logger.error(
74
+ f"ShiftType with name '{NAME_ON_CALL}' does not exist. Base data might be missing."
75
+ )
72
76
  return None
73
77
 
74
78
  @classmethod
@@ -82,7 +86,9 @@ class ShiftType(models.Model):
82
86
  try:
83
87
  return cls.objects.get(name=NAME_WARD)
84
88
  except cls.DoesNotExist:
85
- logger.error(f"ShiftType with name '{NAME_WARD}' does not exist. Base data might be missing.")
89
+ logger.error(
90
+ f"ShiftType with name '{NAME_WARD}' does not exist. Base data might be missing."
91
+ )
86
92
  return None
87
93
 
88
94
  @classmethod
@@ -96,5 +102,7 @@ class ShiftType(models.Model):
96
102
  try:
97
103
  return cls.objects.get(name=NAME_OFF_HOURS)
98
104
  except cls.DoesNotExist:
99
- logger.error(f"ShiftType with name '{NAME_OFF_HOURS}' does not exist. Base data might be missing.")
105
+ logger.error(
106
+ f"ShiftType with name '{NAME_OFF_HOURS}' does not exist. Base data might be missing."
107
+ )
100
108
  return None
@@ -0,0 +1,5 @@
1
+ from .aidataset import AIDataSet
2
+
3
+ __all__ = [
4
+ "AIDataSet",
5
+ ]
@@ -0,0 +1,193 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from django.db import models
4
+
5
+ if TYPE_CHECKING:
6
+ from endoreg_db.models import ImageClassificationAnnotation
7
+ # later:
8
+ # from endoreg_db.models import VideoSegmentationAnnotation
9
+ # from endoreg_db.models import TextAnnotation # example name
10
+
11
+
12
+ class AIDataSet(models.Model):
13
+ """
14
+ AIDataSet stores the definition of a training dataset for an AI model.
15
+
16
+ It does NOT store annotation vectors directly.
17
+
18
+ Instead, it stores:
19
+ - which AI model family it is for (ai_model_type)
20
+ - which type of data it is based on (dataset_type)
21
+ - which annotations belong to it (image/video/text *_annotations)
22
+
23
+ For now:
24
+ dataset_type == "image"
25
+ -> image_annotations contains ImageClassificationAnnotation rows
26
+ (each with frame_id and label_id)
27
+
28
+ Later:
29
+ dataset_type == "video"
30
+ -> video_annotations will contain video-level annotation rows
31
+
32
+ dataset_type == "text"
33
+ -> text_annotations will contain text-level annotation rows
34
+ """
35
+
36
+ # ------------------------------------------------------------------
37
+ # CHOICES
38
+ # ------------------------------------------------------------------
39
+ DATASET_TYPE_IMAGE = "image"
40
+ DATASET_TYPE_VIDEO = "video"
41
+ DATASET_TYPE_TEXT = "text"
42
+
43
+ DATASET_TYPE_CHOICES = [
44
+ (DATASET_TYPE_IMAGE, "Image"),
45
+ # later, when implemented:
46
+ # (DATASET_TYPE_VIDEO, "Video"),
47
+ # (DATASET_TYPE_TEXT, "Text"),
48
+ ]
49
+
50
+ AI_MODEL_TYPE_IMAGE_MULTILABEL = "image_multilabel_classification"
51
+ # later: add more ai_model_type values as needed, e.g.
52
+ # AI_MODEL_TYPE_VIDEO_SEGMENTATION = "video_segmentation"
53
+ # AI_MODEL_TYPE_TEXT_CLASSIFICATION = "text_classification"
54
+
55
+ # ------------------------------------------------------------------
56
+ # BASIC FIELDS
57
+ # ------------------------------------------------------------------
58
+
59
+ name = models.CharField(
60
+ max_length=255,
61
+ blank=True,
62
+ null=True,
63
+ help_text='Human-readable identifier, e.g. "Legacy multilabel dataset v1".',
64
+ )
65
+
66
+ description = models.TextField(
67
+ blank=True,
68
+ null=True,
69
+ help_text="Optional notes / explanation about this dataset.",
70
+ )
71
+
72
+ ai_model_type = models.CharField(
73
+ max_length=255,
74
+ default=AI_MODEL_TYPE_IMAGE_MULTILABEL,
75
+ help_text=(
76
+ "AI model family this dataset is for, e.g. "
77
+ '"image_multilabel_classification". '
78
+ "Used to pick the correct architecture and output dimension logic."
79
+ ),
80
+ )
81
+
82
+ dataset_type = models.CharField(
83
+ max_length=32,
84
+ choices=DATASET_TYPE_CHOICES,
85
+ default=DATASET_TYPE_IMAGE,
86
+ help_text=(
87
+ "Controls which annotation table will be used. "
88
+ 'Currently only "image" is implemented; later "video", "text", etc.'
89
+ ),
90
+ )
91
+
92
+ # ------------------------------------------------------------------
93
+ # TYPE-SPECIFIC ANNOTATION RELATIONS (Option A)
94
+ # ------------------------------------------------------------------
95
+ # For each dataset_type, we provide a separate M2M field.
96
+ # Only one of them is actually *used* per dataset instance.
97
+ # The others simply remain empty.
98
+
99
+ # IMAGE DATASETS:
100
+ # For dataset_type == "image":
101
+ # - image_annotations defines which ImageClassificationAnnotation rows
102
+ # belong to this dataset.
103
+ image_annotations = models.ManyToManyField(
104
+ "ImageClassificationAnnotation",
105
+ related_name="image_ai_datasets",
106
+ blank=True,
107
+ help_text=(
108
+ "For dataset_type='image', this is the set of ImageClassificationAnnotation "
109
+ "rows that define this AIDataSet. Each annotation has frame_id and label_id."
110
+ ),
111
+ )
112
+
113
+ # VIDEO DATASETS (FUTURE):
114
+ # For dataset_type == "video", you will later add something like:
115
+ #
116
+ # video_annotations = models.ManyToManyField(
117
+ # "VideoSegmentationAnnotation", # or whatever your video annotation model is
118
+ # related_name="video_ai_datasets",
119
+ # blank=True,
120
+ # help_text=(
121
+ # "For dataset_type='video', this will be the set of video-level "
122
+ # "annotation rows that define this AIDataSet."
123
+ # ),
124
+ # )
125
+ #
126
+ # TEXT DATASETS (FUTURE):
127
+ # For dataset_type == "text", you could add:
128
+ #
129
+ # text_annotations = models.ManyToManyField(
130
+ # "TextAnnotation", # placeholder name
131
+ # related_name="text_ai_datasets",
132
+ # blank=True,
133
+ # help_text=(
134
+ # "For dataset_type='text', this will be the set of text-level "
135
+ # "annotation rows that define this AIDataSet."
136
+ # ),
137
+ # )
138
+
139
+ # ------------------------------------------------------------------
140
+ # META FIELDS
141
+ # ------------------------------------------------------------------
142
+ created_at = models.DateTimeField(
143
+ auto_now_add=True,
144
+ help_text="When this AIDataSet was created.",
145
+ )
146
+
147
+ updated_at = models.DateTimeField(
148
+ auto_now=True,
149
+ help_text="When this AIDataSet was last modified.",
150
+ )
151
+
152
+ is_active = models.BooleanField(
153
+ default=True,
154
+ help_text="Soft toggle to enable/disable this dataset for training.",
155
+ )
156
+
157
+ if TYPE_CHECKING:
158
+ # for static type checkers only
159
+ image_annotations: models.ManyToManyField["ImageClassificationAnnotation"]
160
+ # video_annotations: models.ManyToManyField["VideoSegmentationAnnotation"]
161
+ # text_annotations: models.ManyToManyField["TextAnnotation"]
162
+
163
+ # ------------------------------------------------------------------
164
+ # UNIFIED ACCESS HELPERS (USE THESE IN YOUR TRAINING CODE)
165
+ # ------------------------------------------------------------------
166
+
167
+ def get_annotations_queryset(self):
168
+ """
169
+ Return the *active* annotation relation for this dataset, based on dataset_type.
170
+
171
+ - For dataset_type='image' -> returns self.image_annotations
172
+ - For dataset_type='video' -> later: return self.video_annotations
173
+ - For dataset_type='text' -> later: return self.text_annotations
174
+
175
+ This is what your data loader / training code should call.
176
+ """
177
+ if self.dataset_type == self.DATASET_TYPE_IMAGE:
178
+ return self.image_annotations
179
+
180
+ # TODO (future): implement once video/text annotation models exist
181
+ # if self.dataset_type == self.DATASET_TYPE_VIDEO:
182
+ # return self.video_annotations
183
+ #
184
+ # if self.dataset_type == self.DATASET_TYPE_TEXT:
185
+ # return self.text_annotations
186
+
187
+ # Fallback: empty queryset (nothing to train on)
188
+ return self.image_annotations.none()
189
+
190
+ def __str__(self) -> str:
191
+ if self.name:
192
+ return f"AIDataSet(id={self.id}, name={self.name})"
193
+ return f"AIDataSet(id={self.id})"
@@ -19,5 +19,5 @@ __all__ = [
19
19
  "VideoSegmentationLabelSet",
20
20
  "LabelVideoSegment",
21
21
  "ImageClassificationAnnotation",
22
- "VideoSegmentationAnnotation"
22
+ "VideoSegmentationAnnotation",
23
23
  ]
@@ -27,7 +27,13 @@ class Label(models.Model):
27
27
  """
28
28
 
29
29
  name = models.CharField(max_length=255)
30
- label_type = models.ForeignKey("LabelType", on_delete=models.CASCADE, related_name="labels", blank=True, null=True)
30
+ label_type = models.ForeignKey(
31
+ "LabelType",
32
+ on_delete=models.CASCADE,
33
+ related_name="labels",
34
+ blank=True,
35
+ null=True,
36
+ )
31
37
  description = models.TextField(blank=True, null=True)
32
38
 
33
39
  objects = LabelManager()
@@ -66,7 +72,9 @@ class Label(models.Model):
66
72
  try:
67
73
  return cls.objects.get(name="low_quality")
68
74
  except Exception as exc:
69
- raise ValueError("'low_quality' label does not exist in the database") from exc
75
+ raise ValueError(
76
+ "'low_quality' label does not exist in the database"
77
+ ) from exc
70
78
 
71
79
  @classmethod
72
80
  def get_or_create_from_name(cls, name: str):
@@ -21,7 +21,9 @@ class LabelSetManager(models.Manager):
21
21
 
22
22
  labelset = queryset.order_by("-version").first()
23
23
  if not labelset:
24
- raise self.model.DoesNotExist(f"LabelSet with name='{name}' and version='{version}' not found")
24
+ raise self.model.DoesNotExist(
25
+ f"LabelSet with name='{name}' and version='{version}' not found"
26
+ )
25
27
  return labelset
26
28
 
27
29
 
@@ -23,10 +23,14 @@ def _create_from_video(
23
23
  raise ValueError("Source must be a VideoFile instance.")
24
24
 
25
25
  if start_frame_number < 0 or end_frame_number < 0:
26
- raise ValueError(f"Frame numbers must be non-negative: start={start_frame_number}, end={end_frame_number}")
26
+ raise ValueError(
27
+ f"Frame numbers must be non-negative: start={start_frame_number}, end={end_frame_number}"
28
+ )
27
29
 
28
30
  if start_frame_number > end_frame_number:
29
- raise ValueError(f"Start frame number ({start_frame_number}) must be less than or equal to end frame number ({end_frame_number})")
31
+ raise ValueError(
32
+ f"Start frame number ({start_frame_number}) must be less than or equal to end frame number ({end_frame_number})"
33
+ )
30
34
 
31
35
  segment = cls(
32
36
  start_frame_number=start_frame_number,