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/urls/media.py
CHANGED
|
@@ -1,37 +1,38 @@
|
|
|
1
|
-
from PIL.PdfParser import PdfStream
|
|
2
1
|
from django.urls import path
|
|
3
2
|
|
|
3
|
+
from endoreg_db.views import VideoStreamView
|
|
4
|
+
from endoreg_db.views.ai import label_list
|
|
4
5
|
from endoreg_db.views.media import (
|
|
5
|
-
VideoMediaView,
|
|
6
6
|
PdfMediaView, # Alias to avoid conflict with legacy pdf.PDFMediaView
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
video_segments_by_video,
|
|
10
|
-
video_segment_detail,
|
|
11
|
-
video_segments_stats,
|
|
12
|
-
video_segment_validate,
|
|
13
|
-
video_segments_validate_bulk,
|
|
14
|
-
video_segments_validation_status,
|
|
15
|
-
video_sensitive_metadata,
|
|
16
|
-
video_sensitive_metadata_verify,
|
|
7
|
+
VideoMediaView,
|
|
8
|
+
get_sensitive_metadata_pk,
|
|
17
9
|
pdf_sensitive_metadata,
|
|
10
|
+
pdf_sensitive_metadata_list,
|
|
18
11
|
pdf_sensitive_metadata_verify,
|
|
19
12
|
sensitive_metadata_list,
|
|
20
|
-
|
|
13
|
+
video_sensitive_metadata,
|
|
14
|
+
video_sensitive_metadata_verify,
|
|
21
15
|
)
|
|
22
|
-
from endoreg_db.views import
|
|
23
|
-
|
|
16
|
+
from endoreg_db.views.report.reimport import ReportReimportView
|
|
17
|
+
from endoreg_db.views.report.report_stream import ReportStreamView
|
|
18
|
+
from endoreg_db.views.video import (
|
|
19
|
+
VideoReimportView,
|
|
20
|
+
video_segment_detail,
|
|
21
|
+
video_segment_validate,
|
|
22
|
+
video_segments_by_video,
|
|
23
|
+
video_segments_collection,
|
|
24
|
+
video_segments_stats,
|
|
25
|
+
video_segments_validate_bulk,
|
|
26
|
+
video_segments_validation_status,
|
|
24
27
|
)
|
|
25
|
-
from endoreg_db.views.pdf.reimport import PdfReimportView
|
|
26
|
-
from endoreg_db.views.pdf.pdf_stream import PdfStreamView
|
|
27
|
-
from endoreg_db.views.video.reimport import VideoReimportView
|
|
28
28
|
from endoreg_db.views.video.correction import (
|
|
29
|
-
VideoMetadataView,
|
|
30
|
-
VideoProcessingHistoryView,
|
|
31
29
|
VideoApplyMaskView,
|
|
32
|
-
VideoRemoveFramesView,
|
|
33
30
|
VideoCorrectionView,
|
|
31
|
+
VideoMetadataStatsView,
|
|
32
|
+
VideoProcessingHistoryView,
|
|
33
|
+
VideoRemoveFramesView,
|
|
34
34
|
)
|
|
35
|
+
|
|
35
36
|
# ---------------------------------------------------------------------------------------
|
|
36
37
|
# ANNOTATION API ENDPOINTS
|
|
37
38
|
#
|
|
@@ -41,19 +42,32 @@ from endoreg_db.views.video.correction import (
|
|
|
41
42
|
# ---------------------------------------------------------------------------------------
|
|
42
43
|
|
|
43
44
|
# Simplified Meta and Validation Endpoints
|
|
44
|
-
|
|
45
|
+
|
|
45
46
|
urlpatterns = [
|
|
47
|
+
path(
|
|
48
|
+
"media/sensitive-media-id/<int:pk>/<str:mediaType>/",
|
|
49
|
+
get_sensitive_metadata_pk,
|
|
50
|
+
name="sm-pk",
|
|
51
|
+
),
|
|
46
52
|
# Video media endpoints
|
|
47
53
|
path("media/videos/", VideoMediaView.as_view(), name="video-list"),
|
|
48
|
-
path(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
path(
|
|
55
|
+
"media/videos/<int:pk>/", VideoStreamView.as_view(), name="video-detail-stream"
|
|
56
|
+
), # Support ?type= params
|
|
57
|
+
path(
|
|
58
|
+
"media/videos/<int:pk>/details/", VideoMediaView.as_view(), name="video-detail"
|
|
59
|
+
), # JSON metadata
|
|
60
|
+
path(
|
|
61
|
+
"media/videos/<int:pk>/stream/", VideoStreamView.as_view(), name="video-stream"
|
|
62
|
+
), # Legacy support
|
|
52
63
|
# Video Re-import API endpoint (modern media framework)
|
|
53
64
|
# POST /api/media/videos/<int:pk>/reimport/
|
|
54
65
|
# Re-imports a video file to regenerate metadata when OCR failed or data is incomplete
|
|
55
|
-
path(
|
|
56
|
-
|
|
66
|
+
path(
|
|
67
|
+
"media/videos/<int:pk>/reimport/",
|
|
68
|
+
VideoReimportView.as_view(),
|
|
69
|
+
name="video-reimport",
|
|
70
|
+
),
|
|
57
71
|
# ---------------------------------------------------------------------------------------
|
|
58
72
|
# VIDEO CORRECTION API ENDPOINTS (Modern Media Framework - October 14, 2025)
|
|
59
73
|
#
|
|
@@ -66,69 +80,88 @@ urlpatterns = [
|
|
|
66
80
|
# - Metadata: View analysis results
|
|
67
81
|
# - History: Track all correction operations
|
|
68
82
|
# ---------------------------------------------------------------------------------------
|
|
69
|
-
|
|
70
83
|
# Video Correction API
|
|
71
84
|
# GET /api/media/videos/video-correction/{id}/ - Get video details for correction
|
|
72
|
-
path(
|
|
73
|
-
|
|
85
|
+
path(
|
|
86
|
+
"media/videos/video-correction/<int:pk>",
|
|
87
|
+
VideoCorrectionView.as_view(),
|
|
88
|
+
name="video-correction",
|
|
89
|
+
),
|
|
74
90
|
# Video Metadata API
|
|
75
91
|
# GET /api/media/videos/<int:pk>/metadata/
|
|
76
92
|
# Returns analysis results (sensitive frame count, ratio, frame IDs)
|
|
77
|
-
path(
|
|
78
|
-
|
|
93
|
+
path(
|
|
94
|
+
"media/videos/<int:pk>/metadata/",
|
|
95
|
+
VideoMetadataStatsView.as_view(),
|
|
96
|
+
name="video-metadata",
|
|
97
|
+
),
|
|
79
98
|
# Video Processing History API
|
|
80
99
|
# GET /api/media/videos/<int:pk>/processing-history/
|
|
81
100
|
# Returns history of all processing operations (masking, frame removal, analysis)
|
|
82
|
-
path(
|
|
83
|
-
|
|
101
|
+
path(
|
|
102
|
+
"media/videos/<int:pk>/processing-history/",
|
|
103
|
+
VideoProcessingHistoryView.as_view(),
|
|
104
|
+
name="video-processing-history",
|
|
105
|
+
),
|
|
84
106
|
# Video Analysis API
|
|
85
107
|
# POST /api/media/videos/<int:pk>/analyze/
|
|
86
108
|
# Analyzes video for sensitive frames using MiniCPM-o 2.6 or OCR+LLM
|
|
87
109
|
# Body: { detection_method: 'minicpm'|'ocr_llm'|'hybrid', sample_interval: 30 }
|
|
88
|
-
|
|
89
110
|
# Video Masking API
|
|
90
111
|
# POST /api/media/videos/<int:pk>/apply-mask/
|
|
91
112
|
# Applies device mask or custom ROI mask to video
|
|
92
113
|
# Body: { mask_type: 'device'|'custom', device_name: 'olympus', roi: {...} }
|
|
93
|
-
path(
|
|
94
|
-
|
|
114
|
+
path(
|
|
115
|
+
"media/videos/<int:pk>/apply-mask/",
|
|
116
|
+
VideoApplyMaskView.as_view(),
|
|
117
|
+
name="video-apply-mask",
|
|
118
|
+
),
|
|
95
119
|
# Video Frame Removal API
|
|
96
120
|
# POST /api/media/videos/<int:pk>/remove-frames/
|
|
97
121
|
# Removes specified frames from video
|
|
98
122
|
# Body: { frame_list: [10,20,30] OR frame_ranges: '10-20,30' OR detection_method: 'automatic' }
|
|
99
|
-
path(
|
|
100
|
-
|
|
123
|
+
path(
|
|
124
|
+
"media/videos/<int:pk>/remove-frames/",
|
|
125
|
+
VideoRemoveFramesView.as_view(),
|
|
126
|
+
name="video-remove-frames",
|
|
127
|
+
),
|
|
128
|
+
path("media/videos/labels/list/", label_list, name="get_lvs_list"),
|
|
101
129
|
# ---------------------------------------------------------------------------------------
|
|
102
130
|
# VIDEO SEGMENT API ENDPOINTS (Modern Media Framework - October 14, 2025)
|
|
103
|
-
#
|
|
104
|
-
# Unified segment management endpoints replacing legacy /api/video-segments/
|
|
105
|
-
# Collection: GET/POST all segments across videos
|
|
106
|
-
# Video-scoped: GET/POST segments for specific video
|
|
107
|
-
# Detail: GET/PATCH/DELETE individual segment
|
|
108
|
-
# ---------------------------------------------------------------------------------------
|
|
109
|
-
|
|
110
131
|
# Video Segments Collection API
|
|
111
132
|
# GET/POST /api/media/videos/segments/
|
|
112
133
|
# List all video segments across videos or create new segment
|
|
113
|
-
path(
|
|
114
|
-
|
|
134
|
+
path(
|
|
135
|
+
"media/videos/segments/",
|
|
136
|
+
video_segments_collection,
|
|
137
|
+
name="video-segments-collection",
|
|
138
|
+
),
|
|
115
139
|
# Video Segments Stats API
|
|
116
140
|
# GET /api/media/videos/segments/stats/
|
|
117
141
|
# Get statistics about video segments
|
|
118
|
-
path(
|
|
119
|
-
|
|
142
|
+
path(
|
|
143
|
+
"media/videos/segments/stats/",
|
|
144
|
+
video_segments_stats,
|
|
145
|
+
name="video-segments-stats",
|
|
146
|
+
),
|
|
120
147
|
# Video-Specific Segments API
|
|
121
148
|
# GET/POST /api/media/videos/<int:pk>/segments/
|
|
122
149
|
# List segments for specific video or create segment for video
|
|
123
|
-
path(
|
|
124
|
-
|
|
150
|
+
path(
|
|
151
|
+
"media/videos/<int:pk>/segments/",
|
|
152
|
+
video_segments_by_video,
|
|
153
|
+
name="video-segments-by-video",
|
|
154
|
+
),
|
|
125
155
|
# Segment Detail API
|
|
126
156
|
# GET /api/media/videos/<int:pk>/segments/<int:segment_id>/
|
|
127
157
|
# PATCH /api/media/videos/<int:pk>/segments/<int:segment_id>/
|
|
128
158
|
# DELETE /api/media/videos/<int:pk>/segments/<int:segment_id>/
|
|
129
159
|
# Manages individual segment operations
|
|
130
|
-
path(
|
|
131
|
-
|
|
160
|
+
path(
|
|
161
|
+
"media/videos/<int:pk>/segments/<int:segment_id>/",
|
|
162
|
+
video_segment_detail,
|
|
163
|
+
name="video-segment-detail",
|
|
164
|
+
),
|
|
132
165
|
# ---------------------------------------------------------------------------------------
|
|
133
166
|
# VIDEO SEGMENT VALIDATION API ENDPOINTS (Modern Media Framework - October 14, 2025)
|
|
134
167
|
#
|
|
@@ -137,65 +170,68 @@ urlpatterns = [
|
|
|
137
170
|
# Bulk: POST validate multiple segments
|
|
138
171
|
# Status: GET/POST validation status for all segments
|
|
139
172
|
# ---------------------------------------------------------------------------------------
|
|
140
|
-
|
|
141
173
|
# Single Segment Validation API
|
|
142
174
|
# POST /api/media/videos/<int:pk>/segments/<int:segment_id>/validate/
|
|
143
175
|
# Validates a single video segment
|
|
144
176
|
# Body: { "is_validated": true, "notes": "..." }
|
|
145
|
-
path(
|
|
146
|
-
|
|
177
|
+
path(
|
|
178
|
+
"media/videos/<int:pk>/segments/<int:segment_id>/validate/",
|
|
179
|
+
video_segment_validate,
|
|
180
|
+
name="video-segment-validate",
|
|
181
|
+
),
|
|
147
182
|
# Bulk Segment Validation API
|
|
148
183
|
# POST /api/media/videos/<int:pk>/segments/validate-bulk/
|
|
149
184
|
# Validates multiple segments at once
|
|
150
185
|
# Body: { "segment_ids": [1,2,3], "is_validated": true, "notes": "..." }
|
|
151
|
-
path(
|
|
152
|
-
|
|
186
|
+
path(
|
|
187
|
+
"media/videos/<int:pk>/segments/validate-bulk/",
|
|
188
|
+
video_segments_validate_bulk,
|
|
189
|
+
name="video-segments-validate-bulk",
|
|
190
|
+
),
|
|
153
191
|
# Segment Validation Status API
|
|
154
192
|
# GET /api/media/videos/<int:pk>/segments/validation-status/
|
|
155
193
|
# Returns validation statistics for all segments
|
|
156
194
|
# POST /api/media/videos/<int:pk>/segments/validation-status/
|
|
157
195
|
# Marks all segments (or filtered by label) as validated
|
|
158
196
|
# Body: { "label_name": "polyp", "notes": "..." }
|
|
159
|
-
path(
|
|
160
|
-
|
|
197
|
+
path(
|
|
198
|
+
"media/videos/<int:pk>/segments/validation-status/",
|
|
199
|
+
video_segments_validation_status,
|
|
200
|
+
name="video-segments-validation-status",
|
|
201
|
+
),
|
|
161
202
|
# ---------------------------------------------------------------------------------------
|
|
162
203
|
# SENSITIVE METADATA ENDPOINTS (Modern Media Framework)
|
|
163
204
|
# ---------------------------------------------------------------------------------------
|
|
164
|
-
|
|
165
205
|
# Video Sensitive Metadata (Resource-Scoped)
|
|
166
206
|
# GET/PATCH /api/media/videos/<pk>/sensitive-metadata/
|
|
167
207
|
# Get or update sensitive patient data for a video
|
|
168
208
|
path(
|
|
169
209
|
"media/videos/<int:pk>/sensitive-metadata/",
|
|
170
210
|
video_sensitive_metadata,
|
|
171
|
-
name="video-sensitive-metadata"
|
|
211
|
+
name="video-sensitive-metadata",
|
|
172
212
|
),
|
|
173
|
-
|
|
174
213
|
# POST /api/media/videos/<pk>/sensitive-metadata/verify/
|
|
175
214
|
# Update verification state (dob_verified, names_verified)
|
|
176
215
|
path(
|
|
177
216
|
"media/videos/<int:pk>/sensitive-metadata/verify/",
|
|
178
217
|
video_sensitive_metadata_verify,
|
|
179
|
-
name="video-sensitive-metadata-verify"
|
|
218
|
+
name="video-sensitive-metadata-verify",
|
|
180
219
|
),
|
|
181
|
-
|
|
182
|
-
# PDF Sensitive Metadata (Resource-Scoped)
|
|
220
|
+
# report Sensitive Metadata (Resource-Scoped)
|
|
183
221
|
# GET/PATCH /api/media/pdfs/<pk>/sensitive-metadata/
|
|
184
|
-
# Get or update sensitive patient data for a
|
|
222
|
+
# Get or update sensitive patient data for a report
|
|
185
223
|
path(
|
|
186
224
|
"media/pdfs/<int:pk>/sensitive-metadata/",
|
|
187
225
|
pdf_sensitive_metadata,
|
|
188
|
-
name="pdf-sensitive-metadata"
|
|
226
|
+
name="pdf-sensitive-metadata",
|
|
189
227
|
),
|
|
190
|
-
|
|
191
228
|
# POST /api/media/pdfs/<pk>/sensitive-metadata/verify/
|
|
192
229
|
# Update verification state (dob_verified, names_verified)
|
|
193
230
|
path(
|
|
194
231
|
"media/pdfs/<int:pk>/sensitive-metadata/verify/",
|
|
195
232
|
pdf_sensitive_metadata_verify,
|
|
196
|
-
name="pdf-sensitive-metadata-verify"
|
|
233
|
+
name="pdf-sensitive-metadata-verify",
|
|
197
234
|
),
|
|
198
|
-
|
|
199
235
|
# List Endpoints (Collection-Level)
|
|
200
236
|
# GET /api/media/sensitive-metadata/
|
|
201
237
|
# List all sensitive metadata (combined PDFs and Videos)
|
|
@@ -203,25 +239,27 @@ urlpatterns = [
|
|
|
203
239
|
path(
|
|
204
240
|
"media/sensitive-metadata/",
|
|
205
241
|
sensitive_metadata_list,
|
|
206
|
-
name="sensitive-metadata-list"
|
|
242
|
+
name="sensitive-metadata-list",
|
|
207
243
|
),
|
|
208
|
-
|
|
209
244
|
# GET /api/media/pdfs/sensitive-metadata/
|
|
210
245
|
# List sensitive metadata for PDFs only
|
|
211
246
|
# Replaces legacy /api/pdf/sensitivemeta/list/
|
|
212
247
|
path(
|
|
213
248
|
"media/pdfs/sensitive-metadata/",
|
|
214
249
|
pdf_sensitive_metadata_list,
|
|
215
|
-
name="pdf-sensitive-metadata-list"
|
|
250
|
+
name="pdf-sensitive-metadata-list",
|
|
216
251
|
),
|
|
217
|
-
|
|
218
|
-
# PDF media endpoints
|
|
252
|
+
# report media endpoints
|
|
219
253
|
path("media/pdfs/", PdfMediaView.as_view(), name="pdf-list"),
|
|
220
254
|
path("media/pdfs/<int:pk>/", PdfMediaView.as_view(), name="pdf-detail"),
|
|
221
|
-
path(
|
|
222
|
-
|
|
255
|
+
path(
|
|
256
|
+
"media/pdfs/<int:pk>/stream/", ReportStreamView.as_view(), name="pdf-stream"
|
|
257
|
+
), # Support ?type=raw|anonymized params
|
|
258
|
+
# report Re-import API endpoint (modern media framework)
|
|
223
259
|
# POST /api/media/pdfs/<int:pk>/reimport/
|
|
224
|
-
# Re-imports a
|
|
225
|
-
path(
|
|
260
|
+
# Re-imports a report file to regenerate metadata when OCR failed or data is incomplete
|
|
261
|
+
path(
|
|
262
|
+
"media/pdfs/<int:pk>/reimport/", ReportReimportView.as_view(), name="report-reimport"
|
|
263
|
+
),
|
|
226
264
|
]
|
|
227
|
-
|
|
265
|
+
# ---------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# endoreg_db/urls/root_urls.py
|
|
2
|
+
from django.contrib import admin
|
|
3
|
+
from django.urls import path, include
|
|
4
|
+
from django.http import HttpResponse
|
|
5
|
+
from django.conf import settings
|
|
6
|
+
from django.conf.urls.static import static
|
|
7
|
+
|
|
8
|
+
def public_home(_request):
|
|
9
|
+
return HttpResponse("Public home – no login required.")
|
|
10
|
+
|
|
11
|
+
urlpatterns = [
|
|
12
|
+
# Public landing page
|
|
13
|
+
path("", public_home, name="public_home"),
|
|
14
|
+
|
|
15
|
+
# Django admin (optional)
|
|
16
|
+
path("admin/", admin.site.urls),
|
|
17
|
+
|
|
18
|
+
# Mount ALL API routes under /api/
|
|
19
|
+
# This pulls the urlpatterns exported by endoreg_db/urls/__init__.py
|
|
20
|
+
path("api/", include("endoreg_db.urls")),
|
|
21
|
+
|
|
22
|
+
# Keycloak OIDC (mozilla-django-oidc provides /oidc/authenticate/ and /oidc/callback/)
|
|
23
|
+
path("oidc/", include("mozilla_django_oidc.urls")),
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
# Serve static/media in DEBUG at the root (NOT under /api/)
|
|
27
|
+
if settings.DEBUG:
|
|
28
|
+
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
|
29
|
+
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
endoreg_db/utils/__init__.py
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# dataloader
|
|
6
6
|
from endoreg_db.utils.video.ffmpeg_wrapper import assemble_video_from_frames, get_stream_info, transcode_video, transcode_videofile_if_required
|
|
7
|
+
|
|
7
8
|
from .dataloader import load_model_data_from_yaml
|
|
8
9
|
|
|
9
10
|
# dates
|
|
@@ -40,18 +41,23 @@ from .paths import data_paths
|
|
|
40
41
|
|
|
41
42
|
# pydantic_models
|
|
42
43
|
from .pydantic_models import DbConfig
|
|
44
|
+
from .storage import (
|
|
45
|
+
delete_field_file,
|
|
46
|
+
ensure_local_file,
|
|
47
|
+
save_local_file,
|
|
48
|
+
)
|
|
49
|
+
from .storage import (
|
|
50
|
+
file_exists as storage_file_exists,
|
|
51
|
+
)
|
|
43
52
|
|
|
44
53
|
# validate_endo_roi
|
|
45
54
|
from .validate_endo_roi import validate_endo_roi
|
|
55
|
+
from .video import split_video
|
|
46
56
|
|
|
47
57
|
# ffmpeg_wrapper
|
|
48
58
|
from .video.ffmpeg_wrapper import (
|
|
49
59
|
extract_frames,
|
|
50
60
|
)
|
|
51
|
-
from .video import (
|
|
52
|
-
split_video
|
|
53
|
-
)
|
|
54
|
-
|
|
55
61
|
|
|
56
62
|
# --- Exports ---
|
|
57
63
|
|
|
@@ -84,5 +90,9 @@ __all__ = [
|
|
|
84
90
|
"transcode_video",
|
|
85
91
|
"transcode_videofile_if_required", # Added
|
|
86
92
|
"extract_frames", # Added
|
|
93
|
+
"split_video",
|
|
94
|
+
"delete_field_file",
|
|
95
|
+
"ensure_local_file",
|
|
96
|
+
"save_local_file",
|
|
97
|
+
"storage_file_exists",
|
|
87
98
|
]
|
|
88
|
-
|
|
@@ -1,10 +1,22 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
1
4
|
import torch
|
|
2
5
|
from torchvision import models
|
|
3
6
|
import torch.nn as nn
|
|
4
7
|
from pytorch_lightning import LightningModule
|
|
5
8
|
import numpy as np
|
|
9
|
+
from safetensors.torch import load_file
|
|
6
10
|
from sklearn.metrics import precision_score, recall_score, f1_score
|
|
7
11
|
|
|
12
|
+
try: # Torchvision >= 0.13 exposes explicit weight enums
|
|
13
|
+
from torchvision.models import EfficientNet_B4_Weights, RegNet_X_800MF_Weights
|
|
14
|
+
except ImportError: # pragma: no cover - compatibility with older torchvision
|
|
15
|
+
EfficientNet_B4_Weights = None
|
|
16
|
+
RegNet_X_800MF_Weights = None
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
8
20
|
METRICS_ON_STEP = False
|
|
9
21
|
|
|
10
22
|
|
|
@@ -41,6 +53,29 @@ def calculate_metrics(pred, target, threshold=0.5):
|
|
|
41
53
|
}
|
|
42
54
|
|
|
43
55
|
|
|
56
|
+
def _load_torchvision_backbone(factory, *, weights_enum=None, load_pretrained=False):
|
|
57
|
+
"""Instantiate a torchvision model without triggering unwanted downloads."""
|
|
58
|
+
if weights_enum is not None:
|
|
59
|
+
try:
|
|
60
|
+
weights = weights_enum.DEFAULT if load_pretrained else None
|
|
61
|
+
return factory(weights=weights)
|
|
62
|
+
except (TypeError, AttributeError):
|
|
63
|
+
# Fall back to legacy keyword on older torchvision versions
|
|
64
|
+
pass
|
|
65
|
+
|
|
66
|
+
try:
|
|
67
|
+
return factory(pretrained=load_pretrained)
|
|
68
|
+
except TypeError:
|
|
69
|
+
# Newer torchvision versions removed the pretrained kwarg; call without hints
|
|
70
|
+
try:
|
|
71
|
+
return factory()
|
|
72
|
+
except Exception as exc: # pragma: no cover - surfaced to caller for visibility
|
|
73
|
+
raise RuntimeError(
|
|
74
|
+
"Failed to instantiate torchvision backbone with load_pretrained="
|
|
75
|
+
f"{load_pretrained}."
|
|
76
|
+
) from exc
|
|
77
|
+
|
|
78
|
+
|
|
44
79
|
class MultiLabelClassificationNet(LightningModule):
|
|
45
80
|
def __init__(
|
|
46
81
|
self,
|
|
@@ -49,26 +84,40 @@ class MultiLabelClassificationNet(LightningModule):
|
|
|
49
84
|
weight_decay=0.001,
|
|
50
85
|
pos_weight=2,
|
|
51
86
|
model_type="EfficientNetB4",
|
|
87
|
+
load_imagenet_weights: bool = False,
|
|
88
|
+
track_hparams: bool = True,
|
|
52
89
|
):
|
|
53
90
|
super().__init__()
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
self.
|
|
91
|
+
if track_hparams:
|
|
92
|
+
self.save_hyperparameters()
|
|
93
|
+
if labels is None:
|
|
94
|
+
raise ValueError("labels must be provided to initialize MultiLabelClassificationNet")
|
|
95
|
+
|
|
96
|
+
self.model_type = model_type
|
|
97
|
+
self.labels = list(labels)
|
|
98
|
+
self.n_classes = len(self.labels)
|
|
99
|
+
self.val_preds: list[np.ndarray] = []
|
|
100
|
+
self.val_targets: list[np.ndarray] = []
|
|
60
101
|
self.pos_weight = pos_weight
|
|
61
102
|
self.weight_decay = weight_decay
|
|
62
103
|
self.lr = lr
|
|
63
104
|
self.sigm = nn.Sigmoid()
|
|
64
105
|
|
|
65
106
|
if model_type == "EfficientNetB4":
|
|
66
|
-
self.model =
|
|
107
|
+
self.model = _load_torchvision_backbone(
|
|
108
|
+
models.efficientnet_b4,
|
|
109
|
+
weights_enum=EfficientNet_B4_Weights,
|
|
110
|
+
load_pretrained=load_imagenet_weights,
|
|
111
|
+
)
|
|
67
112
|
num_ftrs = self.model.classifier[1].in_features
|
|
68
113
|
self.model.classifier[1] = nn.Linear(num_ftrs, len(labels))
|
|
69
114
|
|
|
70
115
|
elif model_type == "RegNetX800MF":
|
|
71
|
-
self.model =
|
|
116
|
+
self.model = _load_torchvision_backbone(
|
|
117
|
+
models.regnet_x_800mf,
|
|
118
|
+
weights_enum=RegNet_X_800MF_Weights,
|
|
119
|
+
load_pretrained=load_imagenet_weights,
|
|
120
|
+
)
|
|
72
121
|
num_ftrs = self.model.fc.in_features
|
|
73
122
|
self.model.fc = nn.Linear(num_ftrs, len(labels))
|
|
74
123
|
|
|
@@ -78,10 +127,47 @@ class MultiLabelClassificationNet(LightningModule):
|
|
|
78
127
|
|
|
79
128
|
@classmethod
|
|
80
129
|
def load_from_checkpoint(cls, checkpoint_path, *args, **kwargs):
|
|
81
|
-
|
|
130
|
+
path = Path(checkpoint_path)
|
|
131
|
+
suffix = path.suffix.lower()
|
|
132
|
+
|
|
133
|
+
if suffix == ".safetensors":
|
|
134
|
+
map_location = kwargs.pop("map_location", "cpu")
|
|
135
|
+
strict = kwargs.pop("strict", True)
|
|
136
|
+
labels = kwargs.pop("labels", None)
|
|
137
|
+
if not labels:
|
|
138
|
+
raise ValueError("labels must be provided when loading .safetensors checkpoints")
|
|
139
|
+
model_type = kwargs.pop("model_type", None) or "EfficientNetB4"
|
|
140
|
+
load_imagenet = kwargs.pop("load_imagenet_weights", False)
|
|
141
|
+
|
|
142
|
+
device = torch.device(map_location) if map_location is not None else torch.device("cpu")
|
|
143
|
+
if isinstance(device, torch.device):
|
|
144
|
+
device_hint = f"{device.type}:{device.index}" if device.index is not None else device.type
|
|
145
|
+
else:
|
|
146
|
+
device_hint = device
|
|
147
|
+
|
|
148
|
+
state_dict = load_file(path, device=device_hint)
|
|
149
|
+
|
|
150
|
+
instance = cls(
|
|
151
|
+
labels=labels,
|
|
152
|
+
model_type=model_type,
|
|
153
|
+
load_imagenet_weights=load_imagenet,
|
|
154
|
+
track_hparams=False,
|
|
155
|
+
*args,
|
|
156
|
+
**kwargs,
|
|
157
|
+
)
|
|
158
|
+
missing, unexpected = instance.load_state_dict(state_dict, strict=strict)
|
|
159
|
+
|
|
160
|
+
if missing:
|
|
161
|
+
logger.warning("Missing parameters when loading %s: %s", path, missing)
|
|
162
|
+
if unexpected:
|
|
163
|
+
logger.warning("Unexpected parameters when loading %s: %s", path, unexpected)
|
|
164
|
+
|
|
165
|
+
instance.to(device)
|
|
166
|
+
return instance
|
|
167
|
+
|
|
168
|
+
return super(MultiLabelClassificationNet, cls).load_from_checkpoint(
|
|
82
169
|
checkpoint_path, *args, **kwargs
|
|
83
170
|
)
|
|
84
|
-
return instance
|
|
85
171
|
|
|
86
172
|
def forward(self, x): # pylint: disable=arguments-differ
|
|
87
173
|
x = self.model(x)
|
|
@@ -113,18 +199,24 @@ class MultiLabelClassificationNet(LightningModule):
|
|
|
113
199
|
|
|
114
200
|
def validation_epoch_end(self, _outputs):
|
|
115
201
|
"""Called at the end of validation to aggregate outputs"""
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
metrics = calculate_metrics(
|
|
120
|
-
for key,
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
202
|
+
val_preds_np = np.concatenate(self.val_preds)
|
|
203
|
+
val_targets_np = np.concatenate(self.val_targets)
|
|
204
|
+
|
|
205
|
+
metrics = calculate_metrics(val_preds_np, val_targets_np, threshold=0.5)
|
|
206
|
+
for key, metric_value in metrics.items():
|
|
207
|
+
if isinstance(metric_value, np.ndarray):
|
|
208
|
+
processed_value = metric_value.tolist()
|
|
209
|
+
elif isinstance(metric_value, (list, tuple)):
|
|
210
|
+
processed_value = list(metric_value)
|
|
211
|
+
else:
|
|
212
|
+
processed_value = float(metric_value)
|
|
213
|
+
|
|
214
|
+
if isinstance(processed_value, list):
|
|
215
|
+
for i, single_value in enumerate(processed_value):
|
|
124
216
|
name = "val/" + f"{key}/{self.labels[i]}"
|
|
125
217
|
self.log(
|
|
126
218
|
name,
|
|
127
|
-
|
|
219
|
+
float(single_value),
|
|
128
220
|
on_epoch=True,
|
|
129
221
|
on_step=METRICS_ON_STEP,
|
|
130
222
|
prog_bar=False,
|
|
@@ -132,7 +224,11 @@ class MultiLabelClassificationNet(LightningModule):
|
|
|
132
224
|
else:
|
|
133
225
|
name = "val/" + f"{key}"
|
|
134
226
|
self.log(
|
|
135
|
-
name,
|
|
227
|
+
name,
|
|
228
|
+
float(processed_value),
|
|
229
|
+
on_epoch=True,
|
|
230
|
+
on_step=METRICS_ON_STEP,
|
|
231
|
+
prog_bar=True,
|
|
136
232
|
)
|
|
137
233
|
|
|
138
234
|
self.val_preds = []
|