endoreg-db 0.8.6.1__py3-none-any.whl → 0.8.8.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of endoreg-db might be problematic. Click here for more details.
- endoreg_db/authz/auth.py +74 -0
- endoreg_db/authz/backends.py +168 -0
- endoreg_db/authz/management/commands/list_routes.py +18 -0
- endoreg_db/authz/middleware.py +83 -0
- endoreg_db/authz/permissions.py +127 -0
- endoreg_db/authz/policy.py +218 -0
- endoreg_db/authz/views_auth.py +66 -0
- endoreg_db/config/env.py +13 -8
- endoreg_db/data/__init__.py +2 -11
- endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +3 -3
- endoreg_db/data/event_classification/data.yaml +4 -0
- endoreg_db/data/event_classification_choice/data.yaml +9 -0
- endoreg_db/data/examination/examinations/data.yaml +114 -14
- endoreg_db/data/examination/time-type/data.yaml +0 -3
- endoreg_db/data/examination_indication/endoscopy.yaml +108 -173
- endoreg_db/data/examination_indication_classification/endoscopy.yaml +0 -70
- endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +33 -37
- endoreg_db/data/finding/00_generic.yaml +35 -0
- endoreg_db/data/finding/00_generic_complication.yaml +9 -0
- endoreg_db/data/finding/01_gastroscopy_baseline.yaml +88 -0
- endoreg_db/data/finding/01_gastroscopy_observation.yaml +113 -0
- endoreg_db/data/finding/02_colonoscopy_baseline.yaml +53 -0
- endoreg_db/data/finding/02_colonoscopy_hidden.yaml +119 -0
- endoreg_db/data/finding/02_colonoscopy_observation.yaml +152 -0
- endoreg_db/data/finding_classification/00_generic.yaml +44 -0
- endoreg_db/data/finding_classification/00_generic_histology.yaml +28 -0
- endoreg_db/data/finding_classification/00_generic_lesion.yaml +52 -0
- endoreg_db/data/finding_classification/02_colonoscopy_baseline.yaml +83 -0
- endoreg_db/data/finding_classification/02_colonoscopy_histology.yaml +13 -0
- endoreg_db/data/finding_classification/02_colonoscopy_other.yaml +12 -0
- endoreg_db/data/finding_classification/02_colonoscopy_polyp.yaml +101 -0
- endoreg_db/data/finding_classification_choice/{yes_no_na.yaml → 00_generic.yaml} +5 -1
- endoreg_db/data/finding_classification_choice/{examination_setting_generic_types.yaml → 00_generic_baseline.yaml} +10 -2
- endoreg_db/data/finding_classification_choice/{complication_generic_types.yaml → 00_generic_complication.yaml} +1 -1
- endoreg_db/data/finding_classification_choice/{histology.yaml → 00_generic_histology.yaml} +1 -4
- endoreg_db/data/finding_classification_choice/00_generic_lesion.yaml +158 -0
- endoreg_db/data/finding_classification_choice/{bowel_preparation.yaml → 02_colonoscopy_bowel_preparation.yaml} +1 -30
- endoreg_db/data/finding_classification_choice/{colonoscopy_not_complete_reason.yaml → 02_colonoscopy_generic.yaml} +1 -1
- endoreg_db/data/finding_classification_choice/{histology_polyp.yaml → 02_colonoscopy_histology.yaml} +1 -1
- endoreg_db/data/finding_classification_choice/{colonoscopy_location.yaml → 02_colonoscopy_location.yaml} +23 -4
- endoreg_db/data/finding_classification_choice/02_colonoscopy_other.yaml +34 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_polyp_advanced_imaging.yaml +76 -0
- endoreg_db/data/finding_classification_choice/{colon_lesion_paris.yaml → 02_colonoscopy_polyp_morphology.yaml} +26 -8
- endoreg_db/data/finding_classification_choice/02_colonoscopy_size.yaml +27 -0
- endoreg_db/data/finding_classification_type/{colonoscopy_basic.yaml → 00_generic.yaml} +18 -13
- endoreg_db/data/finding_classification_type/02_colonoscopy.yaml +9 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy.yaml +59 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_ablation.yaml +44 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_bleeding.yaml +55 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_resection.yaml +85 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_stenosis.yaml +17 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_stent.yaml +9 -0
- endoreg_db/data/finding_intervention/01_gastroscopy.yaml +19 -0
- endoreg_db/data/finding_intervention/04_eus.yaml +39 -0
- endoreg_db/data/finding_intervention/05_ercp.yaml +3 -0
- endoreg_db/data/finding_type/data.yaml +8 -12
- endoreg_db/data/requirement/01_patient_data.yaml +93 -0
- endoreg_db/data/requirement/old/colon_polyp_intervention.yaml +49 -0
- endoreg_db/data/requirement/old/coloreg_colon_polyp.yaml +49 -0
- endoreg_db/data/requirement_operator/new_operators.yaml +36 -0
- endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +29 -12
- endoreg_db/data/requirement_set/01_laboratory.yaml +13 -0
- endoreg_db/data/requirement_set/{endoscopy_bleeding_risk.yaml → 02_endoscopy_bleeding_risk.yaml} +0 -6
- endoreg_db/data/requirement_set/90_coloreg.yaml +190 -0
- endoreg_db/data/requirement_set/_old_ +109 -0
- endoreg_db/data/requirement_set_type/data.yaml +21 -0
- endoreg_db/data/setup_config.yaml +4 -4
- endoreg_db/data/tag/requirement_set_tags.yaml +21 -0
- endoreg_db/exceptions.py +4 -2
- endoreg_db/forms/examination_form.py +1 -1
- endoreg_db/helpers/data_loader.py +125 -53
- endoreg_db/helpers/default_objects.py +116 -81
- endoreg_db/import_files/__init__.py +27 -0
- endoreg_db/import_files/context/__init__.py +7 -0
- endoreg_db/import_files/context/default_sensitive_meta.py +81 -0
- endoreg_db/import_files/context/ensure_center.py +17 -0
- endoreg_db/import_files/context/file_lock.py +66 -0
- endoreg_db/import_files/context/import_context.py +43 -0
- endoreg_db/import_files/context/validate_directories.py +56 -0
- endoreg_db/import_files/file_storage/__init__.py +15 -0
- endoreg_db/import_files/file_storage/create_report_file.py +76 -0
- endoreg_db/import_files/file_storage/create_video_file.py +75 -0
- endoreg_db/import_files/file_storage/sensitive_meta_storage.py +39 -0
- endoreg_db/import_files/file_storage/state_management.py +400 -0
- endoreg_db/import_files/file_storage/storage.py +36 -0
- endoreg_db/import_files/import_service.md +26 -0
- endoreg_db/import_files/processing/__init__.py +11 -0
- endoreg_db/import_files/processing/report_processing/report_anonymization.py +94 -0
- endoreg_db/import_files/processing/sensitive_meta_adapter.py +51 -0
- endoreg_db/import_files/processing/video_processing/video_anonymization.py +107 -0
- endoreg_db/import_files/processing/video_processing/video_cleanup_on_error.py +119 -0
- endoreg_db/import_files/pseudonymization/fake.py +52 -0
- endoreg_db/import_files/pseudonymization/k_anonymity.py +182 -0
- endoreg_db/import_files/pseudonymization/k_pseudonymity.py +128 -0
- endoreg_db/import_files/report_import_service.py +141 -0
- endoreg_db/import_files/video_import_service.py +150 -0
- endoreg_db/management/commands/create_model_meta_from_huggingface.py +21 -10
- endoreg_db/management/commands/create_multilabel_model_meta.py +299 -129
- endoreg_db/management/commands/import_report.py +130 -65
- endoreg_db/management/commands/import_video.py +9 -10
- endoreg_db/management/commands/import_video_with_classification.py +2 -2
- endoreg_db/management/commands/list_routes.py +18 -0
- endoreg_db/management/commands/load_ai_model_data.py +5 -5
- endoreg_db/management/commands/load_ai_model_label_data.py +9 -7
- endoreg_db/management/commands/load_base_db_data.py +5 -134
- endoreg_db/management/commands/load_center_data.py +12 -12
- endoreg_db/management/commands/load_contraindication_data.py +14 -16
- endoreg_db/management/commands/load_disease_classification_choices_data.py +15 -18
- endoreg_db/management/commands/load_disease_classification_data.py +15 -18
- endoreg_db/management/commands/load_disease_data.py +25 -28
- endoreg_db/management/commands/load_endoscope_data.py +20 -27
- endoreg_db/management/commands/load_event_data.py +14 -16
- endoreg_db/management/commands/load_examination_data.py +31 -44
- endoreg_db/management/commands/load_examination_indication_data.py +20 -21
- endoreg_db/management/commands/load_finding_data.py +52 -80
- endoreg_db/management/commands/load_information_source.py +21 -23
- endoreg_db/management/commands/load_lab_value_data.py +17 -26
- endoreg_db/management/commands/load_medication_data.py +13 -12
- endoreg_db/management/commands/load_organ_data.py +15 -19
- endoreg_db/management/commands/load_pdf_type_data.py +19 -18
- endoreg_db/management/commands/load_profession_data.py +14 -17
- endoreg_db/management/commands/load_qualification_data.py +20 -23
- endoreg_db/management/commands/load_report_reader_flag_data.py +17 -19
- endoreg_db/management/commands/load_requirement_data.py +62 -39
- endoreg_db/management/commands/load_requirement_set_tags.py +95 -0
- endoreg_db/management/commands/load_risk_data.py +7 -6
- endoreg_db/management/commands/load_shift_data.py +20 -23
- endoreg_db/management/commands/load_tag_data.py +8 -11
- endoreg_db/management/commands/load_unit_data.py +17 -19
- endoreg_db/management/commands/setup_endoreg_db.py +3 -3
- endoreg_db/management/commands/start_filewatcher.py +46 -37
- endoreg_db/management/commands/storage_management.py +271 -203
- endoreg_db/management/commands/validate_video_files.py +1 -5
- endoreg_db/migrations/0001_initial.py +297 -250
- endoreg_db/models/__init__.py +78 -123
- endoreg_db/models/administration/__init__.py +21 -42
- endoreg_db/models/administration/ai/active_model.py +2 -2
- endoreg_db/models/administration/ai/ai_model.py +7 -6
- endoreg_db/models/administration/case/__init__.py +1 -15
- endoreg_db/models/administration/case/case.py +3 -3
- endoreg_db/models/administration/case/case_template/__init__.py +2 -14
- endoreg_db/models/administration/case/case_template/case_template.py +2 -124
- endoreg_db/models/administration/case/case_template/case_template_rule.py +2 -268
- endoreg_db/models/administration/case/case_template/case_template_rule_value.py +2 -85
- endoreg_db/models/administration/case/case_template/case_template_type.py +2 -25
- endoreg_db/models/administration/center/center.py +33 -19
- endoreg_db/models/administration/center/center_product.py +12 -9
- endoreg_db/models/administration/center/center_resource.py +25 -19
- endoreg_db/models/administration/center/center_shift.py +21 -17
- endoreg_db/models/administration/center/center_waste.py +16 -8
- endoreg_db/models/administration/person/__init__.py +2 -0
- endoreg_db/models/administration/person/employee/employee.py +10 -5
- endoreg_db/models/administration/person/employee/employee_qualification.py +9 -4
- endoreg_db/models/administration/person/employee/employee_type.py +12 -6
- endoreg_db/models/administration/person/examiner/examiner.py +13 -11
- endoreg_db/models/administration/person/patient/__init__.py +2 -0
- endoreg_db/models/administration/person/patient/patient.py +129 -100
- endoreg_db/models/administration/person/patient/patient_external_id.py +37 -0
- endoreg_db/models/administration/person/person.py +4 -0
- endoreg_db/models/administration/person/profession/__init__.py +8 -4
- endoreg_db/models/administration/person/user/portal_user_information.py +11 -7
- endoreg_db/models/administration/product/product.py +20 -15
- endoreg_db/models/administration/product/product_material.py +17 -18
- endoreg_db/models/administration/product/product_weight.py +12 -8
- endoreg_db/models/administration/product/reference_product.py +23 -55
- endoreg_db/models/administration/qualification/qualification.py +7 -3
- endoreg_db/models/administration/qualification/qualification_type.py +7 -3
- endoreg_db/models/administration/shift/scheduled_days.py +8 -5
- endoreg_db/models/administration/shift/shift.py +16 -12
- endoreg_db/models/administration/shift/shift_type.py +23 -31
- endoreg_db/models/label/__init__.py +8 -9
- endoreg_db/models/label/annotation/image_classification.py +10 -9
- endoreg_db/models/label/annotation/video_segmentation_annotation.py +23 -28
- endoreg_db/models/label/label.py +15 -15
- endoreg_db/models/label/label_set.py +19 -6
- endoreg_db/models/label/label_type.py +1 -1
- endoreg_db/models/label/label_video_segment/_create_from_video.py +5 -8
- endoreg_db/models/label/label_video_segment/label_video_segment.py +98 -102
- endoreg_db/models/label/video_segmentation_label.py +4 -0
- endoreg_db/models/label/video_segmentation_labelset.py +4 -3
- endoreg_db/models/media/frame/frame.py +22 -22
- endoreg_db/models/media/pdf/raw_pdf.py +194 -194
- endoreg_db/models/media/pdf/report_file.py +25 -29
- endoreg_db/models/media/pdf/report_reader/report_reader_config.py +55 -47
- endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +23 -7
- endoreg_db/models/media/processing_history/__init__.py +5 -0
- endoreg_db/models/media/processing_history/processing_history.py +96 -0
- endoreg_db/models/media/video/__init__.py +1 -0
- endoreg_db/models/media/video/create_from_file.py +139 -77
- endoreg_db/models/media/video/pipe_2.py +8 -9
- endoreg_db/models/media/video/video_file.py +174 -112
- endoreg_db/models/media/video/video_file_ai.py +288 -74
- endoreg_db/models/media/video/video_file_anonymize.py +38 -38
- endoreg_db/models/media/video/video_file_frames/__init__.py +3 -1
- endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +6 -8
- endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +7 -9
- endoreg_db/models/media/video/video_file_frames/_delete_frames.py +9 -8
- endoreg_db/models/media/video/video_file_frames/_extract_frames.py +38 -45
- endoreg_db/models/media/video/video_file_frames/_get_frame.py +6 -8
- endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +4 -18
- endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +4 -3
- endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +7 -6
- endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +6 -8
- endoreg_db/models/media/video/video_file_frames/_get_frames.py +6 -8
- endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +15 -25
- endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +26 -23
- endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +23 -14
- endoreg_db/models/media/video/video_file_io.py +113 -61
- endoreg_db/models/media/video/video_file_meta/get_crop_template.py +3 -3
- endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +5 -3
- endoreg_db/models/media/video/video_file_meta/get_fps.py +37 -34
- endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +19 -25
- endoreg_db/models/media/video/video_file_meta/text_meta.py +41 -38
- endoreg_db/models/media/video/video_file_meta/video_meta.py +14 -7
- endoreg_db/models/media/video/video_file_segments.py +24 -17
- endoreg_db/models/media/video/video_metadata.py +19 -35
- endoreg_db/models/media/video/video_processing.py +96 -95
- endoreg_db/models/medical/contraindication/README.md +1 -0
- endoreg_db/models/medical/contraindication/__init__.py +13 -3
- endoreg_db/models/medical/disease.py +22 -16
- endoreg_db/models/medical/event.py +31 -18
- endoreg_db/models/medical/examination/__init__.py +13 -6
- endoreg_db/models/medical/examination/examination.py +39 -20
- endoreg_db/models/medical/examination/examination_indication.py +30 -95
- endoreg_db/models/medical/examination/examination_time.py +23 -8
- endoreg_db/models/medical/examination/examination_time_type.py +9 -6
- endoreg_db/models/medical/examination/examination_type.py +3 -4
- endoreg_db/models/medical/finding/finding.py +32 -40
- endoreg_db/models/medical/finding/finding_classification.py +42 -72
- endoreg_db/models/medical/finding/finding_intervention.py +25 -22
- endoreg_db/models/medical/finding/finding_type.py +13 -12
- endoreg_db/models/medical/hardware/endoscope.py +26 -26
- endoreg_db/models/medical/hardware/endoscopy_processor.py +2 -2
- endoreg_db/models/medical/laboratory/lab_value.py +62 -91
- endoreg_db/models/medical/medication/medication.py +22 -10
- endoreg_db/models/medical/medication/medication_indication.py +29 -3
- endoreg_db/models/medical/medication/medication_indication_type.py +25 -14
- endoreg_db/models/medical/medication/medication_intake_time.py +31 -19
- endoreg_db/models/medical/medication/medication_schedule.py +27 -16
- endoreg_db/models/medical/organ/__init__.py +15 -12
- endoreg_db/models/medical/patient/medication_examples.py +6 -6
- endoreg_db/models/medical/patient/patient_disease.py +20 -23
- endoreg_db/models/medical/patient/patient_event.py +19 -22
- endoreg_db/models/medical/patient/patient_examination.py +48 -54
- endoreg_db/models/medical/patient/patient_examination_indication.py +16 -14
- endoreg_db/models/medical/patient/patient_finding.py +122 -139
- endoreg_db/models/medical/patient/patient_finding_classification.py +44 -49
- endoreg_db/models/medical/patient/patient_finding_intervention.py +8 -19
- endoreg_db/models/medical/patient/patient_lab_sample.py +28 -23
- endoreg_db/models/medical/patient/patient_lab_value.py +82 -89
- endoreg_db/models/medical/patient/patient_medication.py +27 -38
- endoreg_db/models/medical/patient/patient_medication_schedule.py +28 -36
- endoreg_db/models/medical/risk/risk.py +7 -6
- endoreg_db/models/medical/risk/risk_type.py +8 -5
- endoreg_db/models/metadata/model_meta.py +60 -29
- endoreg_db/models/metadata/model_meta_logic.py +125 -18
- endoreg_db/models/metadata/pdf_meta.py +31 -24
- endoreg_db/models/metadata/sensitive_meta.py +105 -85
- endoreg_db/models/metadata/sensitive_meta_logic.py +198 -103
- endoreg_db/models/metadata/video_meta.py +51 -31
- endoreg_db/models/metadata/video_prediction_logic.py +16 -23
- endoreg_db/models/metadata/video_prediction_meta.py +29 -33
- endoreg_db/models/other/distribution/date_value_distribution.py +89 -29
- endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +21 -5
- endoreg_db/models/other/distribution/numeric_value_distribution.py +114 -53
- endoreg_db/models/other/distribution/single_categorical_value_distribution.py +4 -3
- endoreg_db/models/other/emission/emission_factor.py +18 -8
- endoreg_db/models/other/gender.py +10 -5
- endoreg_db/models/other/information_source.py +50 -29
- endoreg_db/models/other/material.py +9 -5
- endoreg_db/models/other/resource.py +6 -4
- endoreg_db/models/other/tag.py +10 -5
- endoreg_db/models/other/transport_route.py +13 -8
- endoreg_db/models/other/unit.py +10 -6
- endoreg_db/models/other/waste.py +6 -5
- endoreg_db/models/report/report.py +6 -0
- endoreg_db/models/requirement/requirement.py +329 -361
- endoreg_db/models/requirement/requirement_error.py +85 -0
- endoreg_db/models/requirement/requirement_evaluation/evaluate_with_dependencies.py +268 -0
- endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +3 -6
- endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +90 -64
- endoreg_db/models/requirement/requirement_operator.py +103 -112
- endoreg_db/models/requirement/requirement_set.py +74 -57
- endoreg_db/models/state/__init__.py +4 -4
- endoreg_db/models/state/abstract.py +2 -2
- endoreg_db/models/state/anonymization.py +12 -0
- endoreg_db/models/state/audit_ledger.py +49 -51
- endoreg_db/models/state/label_video_segment.py +9 -0
- endoreg_db/models/state/raw_pdf.py +101 -68
- endoreg_db/models/state/sensitive_meta.py +6 -2
- endoreg_db/models/state/video.py +110 -90
- endoreg_db/models/upload_job.py +35 -34
- endoreg_db/models/utils.py +28 -25
- endoreg_db/queries/__init__.py +3 -1
- endoreg_db/root_urls.py +21 -2
- endoreg_db/schemas/examination_evaluation.py +1 -1
- endoreg_db/serializers/__init__.py +2 -10
- endoreg_db/serializers/anonymization.py +18 -10
- endoreg_db/serializers/label_video_segment/label_video_segment.py +2 -29
- endoreg_db/serializers/meta/__init__.py +1 -6
- endoreg_db/serializers/meta/sensitive_meta_detail.py +63 -118
- endoreg_db/serializers/misc/file_overview.py +11 -99
- endoreg_db/serializers/misc/sensitive_patient_data.py +50 -26
- endoreg_db/serializers/patient_examination/patient_examination.py +3 -3
- endoreg_db/serializers/pdf/anony_text_validation.py +39 -23
- endoreg_db/serializers/requirements/requirement_sets.py +92 -22
- endoreg_db/serializers/video/segmentation.py +2 -1
- endoreg_db/serializers/video/video_file_list.py +65 -34
- endoreg_db/serializers/video/video_processing_history.py +20 -5
- endoreg_db/services/__old/pdf_import.py +1487 -0
- endoreg_db/services/__old/video_import.py +1306 -0
- endoreg_db/services/anonymization.py +128 -89
- endoreg_db/services/lookup_service.py +65 -52
- endoreg_db/services/lookup_store.py +2 -2
- endoreg_db/services/pdf_import.py +0 -1382
- endoreg_db/services/report_import.py +10 -0
- endoreg_db/services/video_import.py +6 -1255
- endoreg_db/tasks/upload_tasks.py +79 -70
- endoreg_db/tasks/video_ingest.py +8 -4
- endoreg_db/urls/__init__.py +5 -32
- endoreg_db/urls/ai.py +32 -0
- endoreg_db/urls/media.py +121 -83
- endoreg_db/urls/root_urls.py +29 -0
- endoreg_db/utils/__init__.py +15 -5
- endoreg_db/utils/ai/multilabel_classification_net.py +116 -20
- endoreg_db/utils/case_generator/__init__.py +3 -0
- endoreg_db/utils/dataloader.py +142 -40
- endoreg_db/utils/defaults/set_default_center.py +32 -0
- endoreg_db/utils/names.py +22 -16
- endoreg_db/utils/paths.py +110 -46
- endoreg_db/utils/permissions.py +2 -1
- endoreg_db/utils/pipelines/Readme.md +1 -1
- endoreg_db/utils/pipelines/process_video_dir.py +1 -1
- endoreg_db/utils/requirement_operator_logic/_old/model_evaluators.py +655 -0
- endoreg_db/utils/requirement_operator_logic/new_operator_logic.py +97 -0
- endoreg_db/utils/setup_config.py +8 -5
- endoreg_db/utils/storage.py +115 -0
- endoreg_db/utils/validate_endo_roi.py +8 -2
- endoreg_db/utils/video/ffmpeg_wrapper.py +184 -188
- endoreg_db/views/__init__.py +85 -183
- endoreg_db/views/ai/__init__.py +8 -0
- endoreg_db/views/ai/label.py +155 -0
- endoreg_db/views/anonymization/media_management.py +202 -166
- endoreg_db/views/anonymization/overview.py +99 -67
- endoreg_db/views/anonymization/validate.py +182 -44
- endoreg_db/views/media/__init__.py +7 -20
- endoreg_db/views/media/pdf_media.py +197 -174
- endoreg_db/views/media/sensitive_metadata.py +193 -138
- endoreg_db/views/media/video_media.py +89 -82
- endoreg_db/views/meta/__init__.py +0 -8
- endoreg_db/views/misc/__init__.py +1 -7
- endoreg_db/views/misc/upload_views.py +94 -93
- endoreg_db/views/patient/patient.py +5 -4
- endoreg_db/views/report/__init__.py +5 -7
- endoreg_db/views/{pdf → report}/reimport.py +22 -22
- endoreg_db/views/{pdf/pdf_stream.py → report/report_stream.py} +46 -39
- endoreg_db/views/requirement/evaluate.py +188 -187
- endoreg_db/views/requirement/lookup.py +17 -3
- endoreg_db/views/requirement/lookup_store.py +22 -90
- endoreg_db/views/requirement/requirement_utils.py +89 -0
- endoreg_db/views/video/__init__.py +23 -24
- endoreg_db/views/video/correction.py +201 -172
- endoreg_db/views/video/reimport.py +1 -1
- endoreg_db/views/{media/video_segments.py → video/segments_crud.py} +77 -40
- endoreg_db/views/video/{video_meta.py → video_meta_stats.py} +2 -2
- endoreg_db/views/video/video_stream.py +7 -8
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/METADATA +7 -3
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/RECORD +391 -413
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/WHEEL +1 -1
- endoreg_db/data/finding/anatomy_colon.yaml +0 -128
- endoreg_db/data/finding/colonoscopy.yaml +0 -40
- endoreg_db/data/finding/colonoscopy_bowel_prep.yaml +0 -56
- endoreg_db/data/finding/complication.yaml +0 -16
- endoreg_db/data/finding/data.yaml +0 -105
- endoreg_db/data/finding/examination_setting.yaml +0 -16
- endoreg_db/data/finding/medication_related.yaml +0 -18
- endoreg_db/data/finding/outcome.yaml +0 -12
- endoreg_db/data/finding_classification/colonoscopy_bowel_preparation.yaml +0 -95
- endoreg_db/data/finding_classification/colonoscopy_jnet.yaml +0 -22
- endoreg_db/data/finding_classification/colonoscopy_kudo.yaml +0 -25
- endoreg_db/data/finding_classification/colonoscopy_lesion_circularity.yaml +0 -20
- endoreg_db/data/finding_classification/colonoscopy_lesion_planarity.yaml +0 -24
- endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +0 -68
- endoreg_db/data/finding_classification/colonoscopy_lesion_surface.yaml +0 -20
- endoreg_db/data/finding_classification/colonoscopy_location.yaml +0 -80
- endoreg_db/data/finding_classification/colonoscopy_lst.yaml +0 -21
- endoreg_db/data/finding_classification/colonoscopy_nice.yaml +0 -20
- endoreg_db/data/finding_classification/colonoscopy_paris.yaml +0 -26
- endoreg_db/data/finding_classification/colonoscopy_sano.yaml +0 -22
- endoreg_db/data/finding_classification/colonoscopy_summary.yaml +0 -53
- endoreg_db/data/finding_classification/complication_generic.yaml +0 -25
- endoreg_db/data/finding_classification/examination_setting_generic.yaml +0 -40
- endoreg_db/data/finding_classification/histology_colo.yaml +0 -51
- endoreg_db/data/finding_classification/intervention_required.yaml +0 -26
- endoreg_db/data/finding_classification/medication_related.yaml +0 -23
- endoreg_db/data/finding_classification/visualized.yaml +0 -33
- endoreg_db/data/finding_classification_choice/colon_lesion_circularity_default.yaml +0 -32
- endoreg_db/data/finding_classification_choice/colon_lesion_jnet.yaml +0 -15
- endoreg_db/data/finding_classification_choice/colon_lesion_kudo.yaml +0 -23
- endoreg_db/data/finding_classification_choice/colon_lesion_lst.yaml +0 -15
- endoreg_db/data/finding_classification_choice/colon_lesion_nice.yaml +0 -17
- endoreg_db/data/finding_classification_choice/colon_lesion_planarity_default.yaml +0 -49
- endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +0 -14
- endoreg_db/data/finding_classification_choice/colon_lesion_surface_intact_default.yaml +0 -36
- endoreg_db/data/finding_classification_choice/colonoscopy_size.yaml +0 -82
- endoreg_db/data/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +0 -15
- endoreg_db/data/finding_classification_choice/outcome.yaml +0 -19
- endoreg_db/data/finding_intervention/endoscopy.yaml +0 -43
- endoreg_db/data/finding_intervention/endoscopy_colonoscopy.yaml +0 -168
- endoreg_db/data/finding_intervention/endoscopy_egd.yaml +0 -128
- endoreg_db/data/finding_intervention/endoscopy_ercp.yaml +0 -32
- endoreg_db/data/finding_intervention/endoscopy_eus_lower.yaml +0 -9
- endoreg_db/data/finding_intervention/endoscopy_eus_upper.yaml +0 -36
- endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +0 -79
- endoreg_db/data/requirement/age.yaml +0 -26
- endoreg_db/data/requirement/gender.yaml +0 -25
- endoreg_db/management/commands/init_default_ai_model.py +0 -112
- endoreg_db/management/commands/reset_celery_schedule.py +0 -9
- endoreg_db/management/commands/validate_video.py +0 -204
- endoreg_db/migrations/0002_add_video_correction_models.py +0 -52
- endoreg_db/migrations/0003_add_center_display_name.py +0 -30
- endoreg_db/models/administration/permissions/__init__.py +0 -44
- endoreg_db/models/rule/__init__.py +0 -13
- endoreg_db/models/rule/rule.py +0 -27
- endoreg_db/models/rule/rule_applicator.py +0 -224
- endoreg_db/models/rule/rule_attribute_dtype.py +0 -17
- endoreg_db/models/rule/rule_type.py +0 -20
- endoreg_db/models/rule/ruleset.py +0 -17
- endoreg_db/renames.yml +0 -8
- endoreg_db/serializers/_old/raw_pdf_meta_validation.py +0 -223
- endoreg_db/serializers/_old/raw_video_meta_validation.py +0 -179
- endoreg_db/serializers/_old/video.py +0 -71
- endoreg_db/serializers/meta/pdf_file_meta_extraction.py +0 -115
- endoreg_db/serializers/meta/report_meta.py +0 -53
- endoreg_db/serializers/report/__init__.py +0 -9
- endoreg_db/serializers/report/mixins.py +0 -45
- endoreg_db/serializers/report/report.py +0 -105
- endoreg_db/serializers/report/report_list.py +0 -22
- endoreg_db/serializers/report/secure_file_url.py +0 -26
- endoreg_db/serializers/video/video_metadata.py +0 -105
- endoreg_db/services/requirements_object.py +0 -147
- endoreg_db/services/storage_aware_video_processor.py +0 -344
- endoreg_db/urls/files.py +0 -6
- endoreg_db/urls/label_video_segment_validate.py +0 -33
- endoreg_db/urls/label_video_segments.py +0 -46
- endoreg_db/urls/report.py +0 -48
- endoreg_db/urls/video.py +0 -61
- endoreg_db/utils/case_generator/case_generator.py +0 -159
- endoreg_db/utils/case_generator/utils.py +0 -30
- endoreg_db/utils/requirement_operator_logic/model_evaluators.py +0 -368
- endoreg_db/views/label/__init__.py +0 -5
- endoreg_db/views/label/label.py +0 -15
- endoreg_db/views/label_video_segment/__init__.py +0 -16
- endoreg_db/views/label_video_segment/create_lvs_from_annotation.py +0 -44
- endoreg_db/views/label_video_segment/get_lvs_by_name_and_video.py +0 -50
- endoreg_db/views/label_video_segment/label_video_segment.py +0 -77
- endoreg_db/views/label_video_segment/label_video_segment_by_label.py +0 -174
- endoreg_db/views/label_video_segment/label_video_segment_detail.py +0 -73
- endoreg_db/views/label_video_segment/update_lvs_from_annotation.py +0 -46
- endoreg_db/views/label_video_segment/validate.py +0 -226
- endoreg_db/views/media/segments.py +0 -71
- endoreg_db/views/meta/available_files_list.py +0 -146
- endoreg_db/views/meta/report_meta.py +0 -53
- endoreg_db/views/meta/sensitive_meta_detail.py +0 -148
- endoreg_db/views/misc/secure_file_serving_view.py +0 -80
- endoreg_db/views/misc/secure_file_url_view.py +0 -84
- endoreg_db/views/misc/secure_url_validate.py +0 -79
- endoreg_db/views/patient_examination/DEPRECATED_video_backup.py +0 -164
- endoreg_db/views/patient_finding_location/__init__.py +0 -5
- endoreg_db/views/patient_finding_location/pfl_create.py +0 -70
- endoreg_db/views/patient_finding_morphology/__init__.py +0 -5
- endoreg_db/views/patient_finding_morphology/pfm_create.py +0 -70
- endoreg_db/views/pdf/__init__.py +0 -8
- endoreg_db/views/report/report_list.py +0 -112
- endoreg_db/views/report/report_with_secure_url.py +0 -28
- endoreg_db/views/report/start_examination.py +0 -7
- endoreg_db/views/video/segmentation.py +0 -274
- endoreg_db/views/video/task_status.py +0 -49
- endoreg_db/views/video/timeline.py +0 -46
- endoreg_db/views/video/video_analyze.py +0 -52
- endoreg_db/views.py +0 -0
- /endoreg_db/data/requirement/{colonoscopy_baseline_austria.yaml → old/colonoscopy_baseline_austria.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_cardiovascular.yaml → old/disease_cardiovascular.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_classification_choice_cardiovascular.yaml → old/disease_classification_choice_cardiovascular.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_hepatology.yaml → old/disease_hepatology.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_misc.yaml → old/disease_misc.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_renal.yaml → old/disease_renal.yaml} +0 -0
- /endoreg_db/data/requirement/{endoscopy_bleeding_risk.yaml → old/endoscopy_bleeding_risk.yaml} +0 -0
- /endoreg_db/data/requirement/{event_cardiology.yaml → old/event_cardiology.yaml} +0 -0
- /endoreg_db/data/requirement/{event_requirements.yaml → old/event_requirements.yaml} +0 -0
- /endoreg_db/data/requirement/{finding_colon_polyp.yaml → old/finding_colon_polyp.yaml} +0 -0
- /endoreg_db/{migrations/__init__.py → data/requirement/old/gender.yaml} +0 -0
- /endoreg_db/data/requirement/{lab_value.yaml → old/lab_value.yaml} +0 -0
- /endoreg_db/data/requirement/{medication.yaml → old/medication.yaml} +0 -0
- /endoreg_db/data/requirement_operator/{age.yaml → _old/age.yaml} +0 -0
- /endoreg_db/data/requirement_operator/{lab_operators.yaml → _old/lab_operators.yaml} +0 -0
- /endoreg_db/data/requirement_operator/{model_operators.yaml → _old/model_operators.yaml} +0 -0
- /endoreg_db/{models/media/video/refactor_plan.md → import_files/pseudonymization/__init__.py} +0 -0
- /endoreg_db/{models/media/video/video_file_frames.py → import_files/pseudonymization/pseudonymize.py} +0 -0
- /endoreg_db/models/{metadata/frame_ocr_result.py → report/__init__.py} +0 -0
- /endoreg_db/{urls/sensitive_meta.py → models/report/images.py} +0 -0
- /endoreg_db/utils/requirement_operator_logic/{lab_value_operators.py → _old/lab_value_operators.py} +0 -0
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/licenses/LICENSE +0 -0
endoreg_db/models/state/video.py
CHANGED
|
@@ -1,117 +1,139 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Defines state tracking models related to video processing.
|
|
3
3
|
"""
|
|
4
|
-
|
|
5
|
-
from .abstract import AbstractState
|
|
6
|
-
from typing import TYPE_CHECKING, Optional
|
|
4
|
+
|
|
7
5
|
import logging
|
|
8
6
|
from enum import Enum
|
|
7
|
+
from typing import TYPE_CHECKING, Optional
|
|
8
|
+
|
|
9
|
+
from django.db import models, transaction
|
|
10
|
+
|
|
11
|
+
from endoreg_db.models.state.anonymization import AnonymizationState
|
|
9
12
|
|
|
10
13
|
logger = logging.getLogger(__name__)
|
|
11
14
|
|
|
12
15
|
if TYPE_CHECKING:
|
|
13
16
|
from ..media import VideoFile
|
|
14
|
-
|
|
15
17
|
|
|
16
|
-
class AnonymizationStatus(str, Enum):
|
|
17
|
-
NOT_STARTED = "not_started"
|
|
18
|
-
EXTRACTING_FRAMES = "extracting_frames"
|
|
19
|
-
PROCESSING_ANONYMIZING = "processing_anonymization"
|
|
20
|
-
DONE = "done"
|
|
21
|
-
VALIDATED = "validated"
|
|
22
|
-
FAILED = "failed"
|
|
23
|
-
STARTED = "started"
|
|
24
18
|
|
|
25
19
|
class VideoState(models.Model):
|
|
26
20
|
"""
|
|
27
21
|
Tracks the processing state of a VideoFile instance.
|
|
28
22
|
Uses BooleanFields for clear, distinct states.
|
|
29
23
|
"""
|
|
24
|
+
|
|
30
25
|
# Frame related states
|
|
31
26
|
if TYPE_CHECKING:
|
|
32
|
-
video_file:
|
|
33
|
-
|
|
34
|
-
frames_extracted = models.BooleanField(
|
|
35
|
-
|
|
36
|
-
|
|
27
|
+
video_file: models.OneToOneField["VideoFile"]
|
|
28
|
+
|
|
29
|
+
frames_extracted = models.BooleanField(
|
|
30
|
+
default=False, help_text="True if raw frames have been extracted to files."
|
|
31
|
+
)
|
|
32
|
+
frames_initialized = models.BooleanField(
|
|
33
|
+
default=False, help_text="True if Frame DB objects have been created."
|
|
34
|
+
)
|
|
35
|
+
frame_count = models.PositiveIntegerField(
|
|
36
|
+
null=True, blank=True, help_text="Number of frames extracted/initialized."
|
|
37
|
+
)
|
|
37
38
|
|
|
38
39
|
# Metadata related states
|
|
39
|
-
video_meta_extracted = models.BooleanField(
|
|
40
|
-
|
|
40
|
+
video_meta_extracted = models.BooleanField(
|
|
41
|
+
default=False,
|
|
42
|
+
help_text="True if VideoMeta (technical specs) has been extracted.",
|
|
43
|
+
)
|
|
44
|
+
text_meta_extracted = models.BooleanField(
|
|
45
|
+
default=False, help_text="True if text metadata (OCR) has been extracted."
|
|
46
|
+
)
|
|
41
47
|
|
|
42
48
|
# AI / Annotation related states
|
|
43
|
-
initial_prediction_completed = models.BooleanField(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
initial_prediction_completed = models.BooleanField(
|
|
50
|
+
default=False, help_text="True if initial AI prediction has run."
|
|
51
|
+
)
|
|
52
|
+
lvs_created = models.BooleanField(
|
|
53
|
+
default=False,
|
|
54
|
+
help_text="True if LabelVideoSegments have been created from predictions.",
|
|
55
|
+
)
|
|
56
|
+
frame_annotations_generated = models.BooleanField(
|
|
57
|
+
default=False,
|
|
58
|
+
help_text="True if frame-level annotations have been generated from segments.",
|
|
59
|
+
)
|
|
60
|
+
|
|
47
61
|
# Processing state
|
|
48
|
-
sensitive_meta_processed = models.BooleanField(
|
|
62
|
+
sensitive_meta_processed = models.BooleanField(
|
|
63
|
+
default=False,
|
|
64
|
+
help_text="True if the video has been fully processed, meaning a anonymized person was created.",
|
|
65
|
+
)
|
|
49
66
|
|
|
50
67
|
# Anonymization state
|
|
51
|
-
anonymized = models.BooleanField(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
68
|
+
anonymized = models.BooleanField(
|
|
69
|
+
default=False, help_text="True if the anonymized video file has been created."
|
|
70
|
+
)
|
|
71
|
+
anonymization_validated = models.BooleanField(
|
|
72
|
+
default=False,
|
|
73
|
+
help_text="True if the anonymization process has been validated and confirmed.",
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
processing_started = models.BooleanField(
|
|
77
|
+
default=False,
|
|
78
|
+
help_text="True if the processing has started, but not yet completed.",
|
|
79
|
+
)
|
|
80
|
+
|
|
57
81
|
# Timestamps
|
|
58
82
|
date_created = models.DateTimeField(auto_now_add=True)
|
|
59
83
|
date_modified = models.DateTimeField(auto_now=True)
|
|
60
|
-
|
|
84
|
+
|
|
61
85
|
# Segment Annotation State
|
|
62
|
-
segment_annotations_created = models.BooleanField(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
86
|
+
segment_annotations_created = models.BooleanField(
|
|
87
|
+
default=False,
|
|
88
|
+
help_text="True if segment annotations have been created from LabelVideoSegments.",
|
|
89
|
+
)
|
|
90
|
+
segment_annotations_validated = models.BooleanField(
|
|
91
|
+
default=False, help_text="True if segment annotations have been validated."
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
was_created = models.BooleanField(
|
|
95
|
+
default=True, help_text="True if this state was created for the first time."
|
|
96
|
+
)
|
|
97
|
+
|
|
67
98
|
objects = models.Manager()
|
|
68
99
|
|
|
69
|
-
def __str__(self):
|
|
70
|
-
# Find the related VideoFile's UUID if possible
|
|
71
|
-
video_uuid = "Unknown"
|
|
72
|
-
try:
|
|
73
|
-
# Access the related VideoFile via the reverse relation 'video_file'
|
|
74
|
-
if hasattr(self, 'video_file') and self.video_file:
|
|
75
|
-
video_uuid = self.video_file.uuid
|
|
76
|
-
except Exception:
|
|
77
|
-
pass # Ignore errors if relation doesn't exist or causes issues
|
|
78
|
-
|
|
79
|
-
states = [
|
|
80
|
-
f"FramesExtracted={self.frames_extracted}",
|
|
81
|
-
f"FramesInit={self.frames_initialized}",
|
|
82
|
-
f"VideoMetaExtracted={self.video_meta_extracted}",
|
|
83
|
-
f"TextMetaExtracted={self.text_meta_extracted}",
|
|
84
|
-
f"PredictionDone={self.initial_prediction_completed}",
|
|
85
|
-
f"LvsCreated={self.lvs_created}",
|
|
86
|
-
f"Anonymized={self.anonymized}",
|
|
87
|
-
f"AnonymizationValidated={self.anonymization_validated}",
|
|
88
|
-
f"SensitiveMetaProcessed={self.sensitive_meta_processed}",
|
|
89
|
-
f"FrameCount={self.frame_count}" if self.frame_count is not None else "FrameCount=None",
|
|
90
|
-
f"SegmentAnnotationsCreated={self.segment_annotations_created}",
|
|
91
|
-
f"SegmentAnnotationsValidated={self.segment_annotations_validated}",
|
|
92
|
-
f"DateCreated={self.date_created.isoformat()}",
|
|
93
|
-
f"DateModified={self.date_modified.isoformat()}"
|
|
94
|
-
]
|
|
95
|
-
return f"VideoState(Video:{video_uuid}): {', '.join(states)}"
|
|
96
100
|
|
|
97
101
|
@property
|
|
98
|
-
def anonymization_status(self) ->
|
|
102
|
+
def anonymization_status(self) -> AnonymizationState:
|
|
99
103
|
"""
|
|
100
104
|
Fast, side‑effect‑free status resolution used by API & UI.
|
|
101
105
|
"""
|
|
102
106
|
if self.anonymization_validated:
|
|
103
|
-
return
|
|
107
|
+
return AnonymizationState.VALIDATED # Validation in Frontend completed -> Views related to this /home/admin/endoreg-db/endoreg_db/views/anonymization/validate.py
|
|
104
108
|
if self.sensitive_meta_processed:
|
|
105
|
-
return
|
|
109
|
+
return AnonymizationState.DONE_PROCESSING_ANONYMIZATION # /home/admin/endoreg-db/endoreg_db/services/video_import.py /home/admin/endoreg-db/endoreg_db/views/video/reimport.py
|
|
106
110
|
if self.frames_extracted and not self.anonymized:
|
|
107
|
-
return
|
|
111
|
+
return AnonymizationState.PROCESSING_ANONYMIZING
|
|
108
112
|
if self.was_created and not self.frames_extracted:
|
|
109
|
-
return
|
|
113
|
+
return AnonymizationState.EXTRACTING_FRAMES
|
|
110
114
|
if getattr(self, "processing_error", False):
|
|
111
|
-
return
|
|
115
|
+
return AnonymizationState.FAILED
|
|
112
116
|
if self.processing_started:
|
|
113
|
-
return
|
|
114
|
-
|
|
117
|
+
return AnonymizationState.STARTED
|
|
118
|
+
if self.anonymized:
|
|
119
|
+
return AnonymizationState.ANONYMIZED
|
|
120
|
+
return AnonymizationState.NOT_STARTED
|
|
121
|
+
|
|
122
|
+
def mark_processing_not_started(self) -> None:
|
|
123
|
+
"""
|
|
124
|
+
Mark the processing as not started and optionally save the updated state.
|
|
125
|
+
|
|
126
|
+
Parameters:
|
|
127
|
+
save (bool): If True, persist the change to the database immediately. Defaults to True.
|
|
128
|
+
"""
|
|
129
|
+
with transaction.atomic():
|
|
130
|
+
self.processing_started = False
|
|
131
|
+
self.anonymized = False
|
|
132
|
+
self.was_created = False
|
|
133
|
+
self.sensitive_meta_processed = False
|
|
134
|
+
self.anonymization_validated = False
|
|
135
|
+
self.frames_extracted = False
|
|
136
|
+
self.save()
|
|
115
137
|
|
|
116
138
|
# ---- Single‑responsibility mutators ---------------------------------
|
|
117
139
|
def mark_sensitive_meta_processed(self, *, save: bool = True) -> None:
|
|
@@ -122,7 +144,7 @@ class VideoState(models.Model):
|
|
|
122
144
|
def mark_anonymization_validated(self, *, save: bool = True) -> None:
|
|
123
145
|
"""
|
|
124
146
|
Mark the anonymization process as validated for this video state.
|
|
125
|
-
|
|
147
|
+
|
|
126
148
|
Parameters:
|
|
127
149
|
save (bool): If True, persist the change to the database immediately.
|
|
128
150
|
"""
|
|
@@ -133,7 +155,7 @@ class VideoState(models.Model):
|
|
|
133
155
|
def mark_frames_extracted(self, *, save: bool = True) -> None:
|
|
134
156
|
"""
|
|
135
157
|
Mark the video as having its frames extracted.
|
|
136
|
-
|
|
158
|
+
|
|
137
159
|
Parameters:
|
|
138
160
|
save (bool): If True, persist the change to the database immediately.
|
|
139
161
|
"""
|
|
@@ -144,7 +166,7 @@ class VideoState(models.Model):
|
|
|
144
166
|
def mark_frames_not_extracted(self, *, save: bool = True) -> None:
|
|
145
167
|
"""
|
|
146
168
|
Mark the video as having no extracted frames.
|
|
147
|
-
|
|
169
|
+
|
|
148
170
|
If `save` is True, updates the database record for this state.
|
|
149
171
|
"""
|
|
150
172
|
self.frames_extracted = False
|
|
@@ -154,18 +176,18 @@ class VideoState(models.Model):
|
|
|
154
176
|
def mark_anonymized(self, *, save: bool = True) -> None:
|
|
155
177
|
"""
|
|
156
178
|
Mark the video as anonymized by setting the anonymized flag to True.
|
|
157
|
-
|
|
179
|
+
|
|
158
180
|
Parameters:
|
|
159
181
|
save (bool): If True, immediately saves the updated state to the database.
|
|
160
182
|
"""
|
|
161
|
-
|
|
162
|
-
|
|
183
|
+
with transaction.atomic():
|
|
184
|
+
self.anonymized = True
|
|
163
185
|
self.save(update_fields=["anonymized", "date_modified"])
|
|
164
186
|
|
|
165
187
|
def mark_initial_prediction_completed(self, *, save: bool = True) -> None:
|
|
166
188
|
"""
|
|
167
189
|
Mark the initial AI prediction as completed for this video state.
|
|
168
|
-
|
|
190
|
+
|
|
169
191
|
Parameters:
|
|
170
192
|
save (bool): If True, persist the change to the database immediately.
|
|
171
193
|
"""
|
|
@@ -176,7 +198,7 @@ class VideoState(models.Model):
|
|
|
176
198
|
def mark_video_meta_extracted(self, *, save: bool = True) -> None:
|
|
177
199
|
"""
|
|
178
200
|
Mark the video metadata as extracted for this video state.
|
|
179
|
-
|
|
201
|
+
|
|
180
202
|
Parameters:
|
|
181
203
|
save (bool): If True, immediately saves the updated state to the database.
|
|
182
204
|
"""
|
|
@@ -187,45 +209,43 @@ class VideoState(models.Model):
|
|
|
187
209
|
def mark_text_meta_extracted(self, *, save: bool = True) -> None:
|
|
188
210
|
"""
|
|
189
211
|
Mark the video as having its text metadata extracted.
|
|
190
|
-
|
|
212
|
+
|
|
191
213
|
Parameters:
|
|
192
|
-
|
|
214
|
+
save (bool): If True, immediately saves the updated state to the database.
|
|
193
215
|
"""
|
|
194
216
|
self.text_meta_extracted = True
|
|
195
217
|
if save:
|
|
196
218
|
self.save(update_fields=["text_meta_extracted", "date_modified"])
|
|
197
|
-
|
|
219
|
+
|
|
198
220
|
def get_or_create_state(self):
|
|
199
221
|
"""
|
|
200
222
|
Get the current state of the video, or create a new one if it doesn't exist.
|
|
201
|
-
|
|
223
|
+
|
|
202
224
|
Returns:
|
|
203
225
|
VideoState: The current or newly created state.
|
|
204
226
|
"""
|
|
205
|
-
if not hasattr(self,
|
|
227
|
+
if not hasattr(self, "video_file"):
|
|
206
228
|
raise ValueError("This method requires a related VideoFile instance.")
|
|
207
|
-
|
|
229
|
+
|
|
208
230
|
# If the state already exists, return it
|
|
209
231
|
if self.video_file.state:
|
|
210
232
|
return self.video_file.state
|
|
211
|
-
|
|
233
|
+
|
|
212
234
|
# Otherwise, create a new state
|
|
213
235
|
new_state = VideoState(video_file=self.video_file)
|
|
214
236
|
new_state.save()
|
|
215
237
|
return new_state
|
|
216
|
-
|
|
238
|
+
|
|
217
239
|
def mark_processing_started(self, *, save: bool = True) -> None:
|
|
218
240
|
"""
|
|
219
241
|
Mark the processing as started for this video state.
|
|
220
|
-
|
|
242
|
+
|
|
221
243
|
Parameters:
|
|
222
244
|
save (bool): If True, immediately saves the updated state to the database.
|
|
223
245
|
"""
|
|
224
246
|
self.processing_started = True
|
|
225
247
|
if save:
|
|
226
248
|
self.save(update_fields=["processing_started", "date_modified"])
|
|
227
|
-
|
|
228
|
-
|
|
229
249
|
|
|
230
250
|
class Meta:
|
|
231
251
|
verbose_name = "Video Processing State"
|
endoreg_db/models/upload_job.py
CHANGED
|
@@ -1,69 +1,70 @@
|
|
|
1
1
|
import uuid
|
|
2
|
+
from typing import TYPE_CHECKING, cast
|
|
3
|
+
|
|
2
4
|
from django.db import models
|
|
3
5
|
|
|
4
6
|
|
|
5
7
|
class UploadJob(models.Model):
|
|
6
8
|
"""
|
|
7
9
|
Tracks file upload jobs and their processing status.
|
|
8
|
-
Supports both
|
|
10
|
+
Supports both report and video file uploads with asynchronous processing.
|
|
9
11
|
"""
|
|
10
|
-
|
|
12
|
+
|
|
11
13
|
class Status(models.TextChoices):
|
|
12
|
-
PENDING =
|
|
13
|
-
PROCESSING =
|
|
14
|
-
ANONYMIZED =
|
|
15
|
-
ERROR =
|
|
14
|
+
PENDING = "pending", "Pending"
|
|
15
|
+
PROCESSING = "processing", "Processing"
|
|
16
|
+
ANONYMIZED = "anonymized", "Anonymized"
|
|
17
|
+
ERROR = "error", "Error"
|
|
16
18
|
|
|
17
19
|
id = models.UUIDField(
|
|
18
|
-
primary_key=True,
|
|
19
|
-
default=uuid.uuid4,
|
|
20
|
+
primary_key=True,
|
|
21
|
+
default=uuid.uuid4,
|
|
20
22
|
editable=False,
|
|
21
|
-
help_text="Unique identifier for the upload job"
|
|
23
|
+
help_text="Unique identifier for the upload job",
|
|
22
24
|
)
|
|
23
|
-
|
|
25
|
+
|
|
24
26
|
file = models.FileField(
|
|
25
|
-
upload_to=
|
|
26
|
-
help_text="Uploaded file (PDF or video)"
|
|
27
|
+
upload_to="uploads/%Y/%m/%d/", help_text="Uploaded file (report or video)"
|
|
27
28
|
)
|
|
28
|
-
|
|
29
|
+
|
|
29
30
|
status = models.CharField(
|
|
30
31
|
max_length=20,
|
|
31
32
|
choices=Status.choices,
|
|
32
33
|
default=Status.PENDING,
|
|
33
|
-
help_text="Current processing status of the upload"
|
|
34
|
+
help_text="Current processing status of the upload",
|
|
34
35
|
)
|
|
35
|
-
|
|
36
|
+
|
|
36
37
|
content_type = models.CharField(
|
|
37
|
-
max_length=100,
|
|
38
|
-
blank=True,
|
|
39
|
-
help_text="MIME type of the uploaded file"
|
|
38
|
+
max_length=100, blank=True, help_text="MIME type of the uploaded file"
|
|
40
39
|
)
|
|
41
|
-
|
|
40
|
+
|
|
42
41
|
sensitive_meta = models.ForeignKey(
|
|
43
|
-
|
|
42
|
+
"SensitiveMeta",
|
|
44
43
|
null=True,
|
|
45
44
|
blank=True,
|
|
46
45
|
on_delete=models.SET_NULL,
|
|
47
|
-
help_text="Link to the created SensitiveMeta record after processing"
|
|
46
|
+
help_text="Link to the created SensitiveMeta record after processing",
|
|
48
47
|
)
|
|
49
|
-
|
|
48
|
+
|
|
50
49
|
error_detail = models.TextField(
|
|
51
|
-
blank=True,
|
|
52
|
-
help_text="Error message if processing failed"
|
|
50
|
+
blank=True, help_text="Error message if processing failed"
|
|
53
51
|
)
|
|
54
|
-
|
|
52
|
+
|
|
55
53
|
created_at = models.DateTimeField(
|
|
56
|
-
auto_now_add=True,
|
|
57
|
-
help_text="When the upload job was created"
|
|
54
|
+
auto_now_add=True, help_text="When the upload job was created"
|
|
58
55
|
)
|
|
59
|
-
|
|
56
|
+
|
|
60
57
|
updated_at = models.DateTimeField(
|
|
61
|
-
auto_now=True,
|
|
62
|
-
help_text="When the upload job was last updated"
|
|
58
|
+
auto_now=True, help_text="When the upload job was last updated"
|
|
63
59
|
)
|
|
64
60
|
|
|
61
|
+
if TYPE_CHECKING:
|
|
62
|
+
from django.db.models.fields.files import FieldFile
|
|
63
|
+
|
|
64
|
+
file = cast(FieldFile, file)
|
|
65
|
+
|
|
65
66
|
class Meta:
|
|
66
|
-
ordering = [
|
|
67
|
+
ordering = ["-created_at"]
|
|
67
68
|
verbose_name = "Upload Job"
|
|
68
69
|
verbose_name_plural = "Upload Jobs"
|
|
69
70
|
|
|
@@ -83,17 +84,17 @@ class UploadJob(models.Model):
|
|
|
83
84
|
def mark_processing(self):
|
|
84
85
|
"""Mark the job as processing."""
|
|
85
86
|
self.status = self.Status.PROCESSING
|
|
86
|
-
self.save(update_fields=[
|
|
87
|
+
self.save(update_fields=["status", "updated_at"])
|
|
87
88
|
|
|
88
89
|
def mark_completed(self, sensitive_meta=None):
|
|
89
90
|
"""Mark the job as successfully completed."""
|
|
90
91
|
self.status = self.Status.ANONYMIZED
|
|
91
92
|
if sensitive_meta:
|
|
92
93
|
self.sensitive_meta = sensitive_meta
|
|
93
|
-
self.save(update_fields=[
|
|
94
|
+
self.save(update_fields=["status", "sensitive_meta", "updated_at"])
|
|
94
95
|
|
|
95
96
|
def mark_error(self, error_detail: str):
|
|
96
97
|
"""Mark the job as failed with error details."""
|
|
97
98
|
self.status = self.Status.ERROR
|
|
98
99
|
self.error_detail = error_detail
|
|
99
|
-
self.save(update_fields=[
|
|
100
|
+
self.save(update_fields=["status", "error_detail", "updated_at"])
|
endoreg_db/models/utils.py
CHANGED
|
@@ -1,32 +1,29 @@
|
|
|
1
|
-
from ..utils import (
|
|
2
|
-
data_paths,
|
|
3
|
-
DJANGO_NAME_SALT,
|
|
4
|
-
)
|
|
5
|
-
from django.core.files import File
|
|
6
|
-
from django.core.files.storage import FileSystemStorage
|
|
7
1
|
import io
|
|
8
2
|
import os
|
|
9
|
-
from tqdm import tqdm
|
|
10
|
-
import numpy as np
|
|
11
|
-
import cv2
|
|
12
|
-
from typing import TYPE_CHECKING, List, Tuple
|
|
13
3
|
from pathlib import Path
|
|
4
|
+
from typing import TYPE_CHECKING, List, Tuple
|
|
5
|
+
|
|
6
|
+
import cv2
|
|
7
|
+
import numpy as np
|
|
8
|
+
from django.core.files import File
|
|
9
|
+
from django.core.files.storage import FileSystemStorage
|
|
10
|
+
|
|
11
|
+
from ..utils import DJANGO_NAME_SALT, data_paths
|
|
12
|
+
|
|
14
13
|
if TYPE_CHECKING:
|
|
15
|
-
|
|
14
|
+
pass
|
|
16
15
|
|
|
17
16
|
from logging import getLogger
|
|
18
17
|
|
|
19
18
|
logger = getLogger(__name__)
|
|
20
19
|
|
|
21
20
|
STORAGE_DIR = data_paths["storage"]
|
|
22
|
-
FILE_STORAGE = FileSystemStorage(location
|
|
23
|
-
|
|
24
|
-
TMP_VIDEO_DIR = VIDEO_DIR / "tmp"
|
|
25
|
-
ANONYM_VIDEO_DIR = data_paths["video_export"]
|
|
21
|
+
FILE_STORAGE = FileSystemStorage(location=str(STORAGE_DIR))
|
|
22
|
+
TRANSCODING_DIR = data_paths["transcoding"]
|
|
26
23
|
FRAME_DIR = data_paths["frame"]
|
|
27
24
|
WEIGHTS_DIR = data_paths["weights"]
|
|
28
|
-
|
|
29
|
-
DOCUMENT_DIR = data_paths["
|
|
25
|
+
REPORT_DIR = data_paths["import_report"]
|
|
26
|
+
DOCUMENT_DIR = data_paths["documents"] #TODO Verify if this is still used and assign correct dir
|
|
30
27
|
|
|
31
28
|
TEST_RUN = os.environ.get("TEST_RUN", "False")
|
|
32
29
|
TEST_RUN = TEST_RUN.lower() == "true"
|
|
@@ -71,8 +68,13 @@ def find_segments_in_prediction_array(prediction_array: np.array, min_frame_len:
|
|
|
71
68
|
|
|
72
69
|
return segments
|
|
73
70
|
|
|
71
|
+
|
|
74
72
|
def anonymize_frame(
|
|
75
|
-
raw_frame_path: Path,
|
|
73
|
+
raw_frame_path: Path,
|
|
74
|
+
target_frame_path: Path,
|
|
75
|
+
endo_roi,
|
|
76
|
+
all_black: bool = False,
|
|
77
|
+
censor_color: Tuple[int, int, int] = (0, 0, 0), # Added censor_color param
|
|
76
78
|
):
|
|
77
79
|
"""
|
|
78
80
|
Anonymize the frame by blacking out pixels outside the endoscope ROI or making the whole frame black.
|
|
@@ -89,7 +91,9 @@ def anonymize_frame(
|
|
|
89
91
|
# Validate ROI dictionary keys
|
|
90
92
|
required_keys = {"x", "y", "width", "height"}
|
|
91
93
|
if not required_keys.issubset(endo_roi):
|
|
92
|
-
raise ValueError(
|
|
94
|
+
raise ValueError(
|
|
95
|
+
f"Invalid endo_roi dictionary provided: {endo_roi}. Missing keys."
|
|
96
|
+
)
|
|
93
97
|
|
|
94
98
|
x = endo_roi["x"]
|
|
95
99
|
y = endo_roi["y"]
|
|
@@ -102,7 +106,9 @@ def anonymize_frame(
|
|
|
102
106
|
x2, y2 = min(w_orig, x + width), min(h_orig, y + height)
|
|
103
107
|
|
|
104
108
|
if x1 >= x2 or y1 >= y2:
|
|
105
|
-
logger.warning(
|
|
109
|
+
logger.warning(
|
|
110
|
+
f"ROI [{x},{y},{width},{height}] is outside or invalid for frame dimensions {w_orig}x{h_orig}. Resulting frame might be all black."
|
|
111
|
+
)
|
|
106
112
|
else:
|
|
107
113
|
# copy valid endoscope roi part to black frame
|
|
108
114
|
new_frame[y1:y2, x1:x2] = frame[y1:y2, x1:x2]
|
|
@@ -120,16 +126,13 @@ __all__ = [
|
|
|
120
126
|
"DJANGO_NAME_SALT",
|
|
121
127
|
"data_paths",
|
|
122
128
|
"FILE_STORAGE",
|
|
123
|
-
"VIDEO_DIR",
|
|
124
|
-
"TMP_VIDEO_DIR",
|
|
125
129
|
"ANONYM_VIDEO_DIR",
|
|
126
130
|
"FRAME_DIR",
|
|
127
131
|
"WEIGHTS_DIR",
|
|
128
|
-
"
|
|
129
|
-
"DOCUMENT_DIR",
|
|
132
|
+
"REPORT_DIR",
|
|
130
133
|
"prepare_bulk_frames",
|
|
131
134
|
"anonymize_frame",
|
|
132
135
|
"find_segments_in_prediction_array",
|
|
133
136
|
"TEST_RUN",
|
|
134
137
|
"TEST_RUN_FRAME_NUMBER",
|
|
135
|
-
]
|
|
138
|
+
]
|
endoreg_db/queries/__init__.py
CHANGED
endoreg_db/root_urls.py
CHANGED
|
@@ -1,9 +1,28 @@
|
|
|
1
|
+
# endoreg_db/root_urls.py
|
|
2
|
+
from django.contrib import admin
|
|
1
3
|
from django.urls import include, path
|
|
4
|
+
from django.http import HttpResponse
|
|
5
|
+
from django.conf import settings
|
|
6
|
+
from django.conf.urls.static import static
|
|
2
7
|
|
|
3
|
-
# Import raw API urlpatterns (no prefix) from
|
|
8
|
+
# Import raw API urlpatterns (no prefix) from your API urls package
|
|
4
9
|
from endoreg_db.urls import urlpatterns as api_urlpatterns
|
|
5
10
|
|
|
6
|
-
|
|
11
|
+
def public_home(_request):
|
|
12
|
+
return HttpResponse("Public home – no login required.")
|
|
13
|
+
|
|
7
14
|
urlpatterns = [
|
|
15
|
+
path("", public_home, name="public_home"),
|
|
16
|
+
#path("admin/", admin.site.urls),
|
|
17
|
+
|
|
18
|
+
# Mount ALL API endpoints under /api/
|
|
8
19
|
path("api/", include((api_urlpatterns, "endoreg_db"), namespace="api")),
|
|
20
|
+
|
|
21
|
+
# OIDC (mozilla-django-oidc provides /oidc/authenticate/ and /oidc/callback/)
|
|
22
|
+
path("oidc/", include("mozilla_django_oidc.urls")),
|
|
9
23
|
]
|
|
24
|
+
|
|
25
|
+
# Serve static/media only in DEBUG (at root, not under /api/)
|
|
26
|
+
if settings.DEBUG:
|
|
27
|
+
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
|
28
|
+
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
|
@@ -19,7 +19,7 @@ class RequirementSetEval(BaseModel):
|
|
|
19
19
|
linked_sets: List["RequirementSetEval"] = Field(default_factory=list)
|
|
20
20
|
|
|
21
21
|
class ExaminationEvalReport(BaseModel):
|
|
22
|
-
examination_id: int
|
|
22
|
+
examination_id: int | None = None
|
|
23
23
|
summary: dict
|
|
24
24
|
sets: List[RequirementSetEval]
|
|
25
25
|
errors: List[str] = Field(default_factory=list)
|
|
@@ -12,8 +12,7 @@ from .examination import (
|
|
|
12
12
|
)
|
|
13
13
|
from .finding import FindingSerializer
|
|
14
14
|
from .finding_classification import (
|
|
15
|
-
FindingClassificationChoiceSerializer,
|
|
16
|
-
FindingClassificationSerializer,
|
|
15
|
+
FindingClassificationSerializer, # FindingClassificationChoiceSerializer,
|
|
17
16
|
)
|
|
18
17
|
from .label import ImageClassificationAnnotationSerializer, LabelSerializer
|
|
19
18
|
from .label_video_segment import (
|
|
@@ -21,8 +20,6 @@ from .label_video_segment import (
|
|
|
21
20
|
LabelVideoSegmentSerializer,
|
|
22
21
|
)
|
|
23
22
|
from .meta import (
|
|
24
|
-
PDFFileForMetaSerializer,
|
|
25
|
-
ReportMetaSerializer,
|
|
26
23
|
SensitiveMetaDetailSerializer,
|
|
27
24
|
SensitiveMetaUpdateSerializer,
|
|
28
25
|
SensitiveMetaVerificationSerializer,
|
|
@@ -47,8 +44,6 @@ from .patient_finding import (
|
|
|
47
44
|
PatientFindingWriteSerializer,
|
|
48
45
|
)
|
|
49
46
|
from .pdf import RawPdfAnonyTextSerializer
|
|
50
|
-
from .report import ReportDataSerializer, ReportListSerializer, SecureFileUrlSerializer
|
|
51
|
-
from .video.video_metadata import VideoMetadataSerializer
|
|
52
47
|
from .video.video_processing_history import VideoProcessingHistorySerializer
|
|
53
48
|
from .video_examination import (
|
|
54
49
|
VideoExaminationCreateSerializer,
|
|
@@ -77,8 +72,6 @@ __all__ = [
|
|
|
77
72
|
"LabelVideoSegmentSerializer",
|
|
78
73
|
"LabelVideoSegmentAnnotationSerializer",
|
|
79
74
|
# Meta
|
|
80
|
-
"PDFFileForMetaSerializer",
|
|
81
|
-
"ReportMetaSerializer",
|
|
82
75
|
"SensitiveMetaDetailSerializer",
|
|
83
76
|
"SensitiveMetaUpdateSerializer",
|
|
84
77
|
"SensitiveMetaVerificationSerializer",
|
|
@@ -102,14 +95,13 @@ __all__ = [
|
|
|
102
95
|
"PatientFindingInterventionSerializer",
|
|
103
96
|
"PatientFindingListSerializer",
|
|
104
97
|
"PatientFindingWriteSerializer",
|
|
105
|
-
#
|
|
98
|
+
# report
|
|
106
99
|
"RawPdfAnonyTextSerializer",
|
|
107
100
|
# Report
|
|
108
101
|
"ReportListSerializer",
|
|
109
102
|
"ReportDataSerializer",
|
|
110
103
|
"SecureFileUrlSerializer",
|
|
111
104
|
# Video Correction (Phase 1.1)
|
|
112
|
-
"VideoMetadataSerializer",
|
|
113
105
|
"VideoProcessingHistorySerializer",
|
|
114
106
|
# Video Examination
|
|
115
107
|
"VideoExaminationSerializer",
|