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
|
@@ -7,7 +7,6 @@ Unterstützt DD.MM.YYYY als Primärformat und YYYY-MM-DD als Fallback.
|
|
|
7
7
|
from rest_framework import serializers
|
|
8
8
|
from endoreg_db.models.metadata.sensitive_meta_logic import parse_any_date
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
class SensitiveMetaValidateSerializer(serializers.Serializer):
|
|
12
11
|
"""
|
|
13
12
|
Serializer für SensitiveMeta-Validierung mit deutscher Datums-Priorität.
|
|
@@ -19,11 +18,11 @@ class SensitiveMetaValidateSerializer(serializers.Serializer):
|
|
|
19
18
|
Alle Datumsfelder werden in date-Objekte konvertiert.
|
|
20
19
|
"""
|
|
21
20
|
|
|
22
|
-
patient_first_name = serializers.CharField(required=
|
|
23
|
-
patient_last_name = serializers.CharField(required=
|
|
24
|
-
patient_dob = serializers.CharField(required=
|
|
25
|
-
examination_date = serializers.CharField(required=
|
|
26
|
-
casenumber = serializers.CharField(required=
|
|
21
|
+
patient_first_name = serializers.CharField(required=True, allow_blank=True)
|
|
22
|
+
patient_last_name = serializers.CharField(required=True, allow_blank=True)
|
|
23
|
+
patient_dob = serializers.CharField(required=True, allow_blank=True)
|
|
24
|
+
examination_date = serializers.CharField(required=True, allow_blank=True)
|
|
25
|
+
casenumber = serializers.CharField(required=True, allow_blank=True)
|
|
27
26
|
anonymized_text = serializers.CharField(required=False, allow_blank=True)
|
|
28
27
|
patient_gender = serializers.CharField(required=False, allow_blank=True)
|
|
29
28
|
center_name = serializers.CharField(required=False, allow_blank=True)
|
|
@@ -31,6 +30,10 @@ class SensitiveMetaValidateSerializer(serializers.Serializer):
|
|
|
31
30
|
file_type = serializers.ChoiceField(
|
|
32
31
|
choices=['video', 'pdf'], required=False
|
|
33
32
|
) # Optional: "video" oder "pdf"
|
|
33
|
+
center_name = serializers.CharField(required=False, allow_blank=True)
|
|
34
|
+
external_id = serializers.CharField(required=False, allow_blank=True)
|
|
35
|
+
external_id_origin = serializers.CharField(required=False, allow_blank=True)
|
|
36
|
+
|
|
34
37
|
|
|
35
38
|
def validate_patient_dob(self, value):
|
|
36
39
|
"""
|
|
@@ -40,8 +43,11 @@ class SensitiveMetaValidateSerializer(serializers.Serializer):
|
|
|
40
43
|
- DD.MM.YYYY (z.B. "21.03.1994")
|
|
41
44
|
- YYYY-MM-DD (z.B. "1994-03-21")
|
|
42
45
|
"""
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
|
|
47
|
+
if value == '' or not value:
|
|
48
|
+
raise serializers.ValidationError(
|
|
49
|
+
"Ungültiges Datum. Kein Input! Erlaubte Formate: DD.MM.YYYY oder YYYY-MM-DD."
|
|
50
|
+
)
|
|
45
51
|
|
|
46
52
|
parsed_date = parse_any_date(value)
|
|
47
53
|
if not parsed_date:
|
|
@@ -58,8 +64,10 @@ class SensitiveMetaValidateSerializer(serializers.Serializer):
|
|
|
58
64
|
- DD.MM.YYYY (z.B. "15.02.2024")
|
|
59
65
|
- YYYY-MM-DD (z.B. "2024-02-15")
|
|
60
66
|
"""
|
|
61
|
-
if not value:
|
|
62
|
-
|
|
67
|
+
if value == '' or not value:
|
|
68
|
+
raise serializers.ValidationError(
|
|
69
|
+
"Ungültiges Datum. Kein Input! Erlaubte Formate: DD.MM.YYYY oder YYYY-MM-DD."
|
|
70
|
+
)
|
|
63
71
|
|
|
64
72
|
parsed_date = parse_any_date(value)
|
|
65
73
|
if not parsed_date:
|
|
@@ -142,7 +142,7 @@ class LabelVideoSegmentSerializer(serializers.ModelSerializer):
|
|
|
142
142
|
logger.debug(f"Serializer initialized with data: {self.initial_data}")
|
|
143
143
|
|
|
144
144
|
|
|
145
|
-
def get_time_segments(self, obj: LabelVideoSegment) ->
|
|
145
|
+
def get_time_segments(self, obj: LabelVideoSegment) -> dict[str, dict]:
|
|
146
146
|
frames = obj.frames
|
|
147
147
|
time_segments = {
|
|
148
148
|
"segment_id": obj.id,
|
|
@@ -225,34 +225,7 @@ class LabelVideoSegmentSerializer(serializers.ModelSerializer):
|
|
|
225
225
|
"""
|
|
226
226
|
return ImageClassificationAnnotationSerializer(obj.all_frame_annotations, many=True).data
|
|
227
227
|
|
|
228
|
-
|
|
229
|
-
"""
|
|
230
|
-
Return the German translation of the label name for display purposes.
|
|
231
|
-
|
|
232
|
-
If the segment has no label, returns "Unbekannt". If a translation is not available, returns the original label name.
|
|
233
|
-
"""
|
|
234
|
-
if not obj.label:
|
|
235
|
-
return "Unbekannt"
|
|
236
|
-
|
|
237
|
-
label_name = obj.label.name
|
|
238
|
-
#TODO Refactor
|
|
239
|
-
translations = {
|
|
240
|
-
'appendix': 'Appendix',
|
|
241
|
-
'blood': 'Blut',
|
|
242
|
-
'diverticule': 'Divertikel',
|
|
243
|
-
'grasper': 'Greifer',
|
|
244
|
-
'ileocaecalvalve': 'Ileozäkalklappe',
|
|
245
|
-
'ileum': 'Ileum',
|
|
246
|
-
'low_quality': 'Niedrige Bildqualität',
|
|
247
|
-
'nbi': 'Narrow Band Imaging',
|
|
248
|
-
'needle': 'Nadel',
|
|
249
|
-
'outside': 'Außerhalb',
|
|
250
|
-
'polyp': 'Polyp',
|
|
251
|
-
'snare': 'Snare',
|
|
252
|
-
'water_jet': 'Wasserstrahl',
|
|
253
|
-
'wound': 'Wunde'
|
|
254
|
-
}
|
|
255
|
-
return translations.get(label_name, label_name)
|
|
228
|
+
|
|
256
229
|
|
|
257
230
|
def get_video_name(self, obj):
|
|
258
231
|
"""
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
from .report_meta import (
|
|
3
|
-
ReportMetaSerializer,
|
|
4
|
-
)
|
|
1
|
+
|
|
5
2
|
from .sensitive_meta_detail import SensitiveMetaDetailSerializer
|
|
6
3
|
from .sensitive_meta_update import SensitiveMetaUpdateSerializer
|
|
7
4
|
from .sensitive_meta_verification import SensitiveMetaVerificationSerializer
|
|
@@ -10,8 +7,6 @@ from .video_meta import (
|
|
|
10
7
|
)
|
|
11
8
|
|
|
12
9
|
__all__ = [
|
|
13
|
-
"PDFFileForMetaSerializer",
|
|
14
|
-
"ReportMetaSerializer",
|
|
15
10
|
"SensitiveMetaDetailSerializer",
|
|
16
11
|
"SensitiveMetaUpdateSerializer",
|
|
17
12
|
"SensitiveMetaVerificationSerializer",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from rest_framework import serializers
|
|
2
2
|
import logging
|
|
3
|
-
|
|
4
3
|
from ...models import SensitiveMeta
|
|
5
4
|
|
|
6
5
|
logger = logging.getLogger(__name__)
|
|
@@ -10,153 +9,99 @@ class SensitiveMetaDetailSerializer(serializers.ModelSerializer):
|
|
|
10
9
|
Serializer for displaying SensitiveMeta details with verification state.
|
|
11
10
|
Includes all relevant fields for annotation and verification.
|
|
12
11
|
"""
|
|
13
|
-
|
|
12
|
+
|
|
14
13
|
# State verification fields
|
|
15
14
|
is_verified = serializers.SerializerMethodField()
|
|
16
15
|
dob_verified = serializers.SerializerMethodField()
|
|
17
16
|
names_verified = serializers.SerializerMethodField()
|
|
18
|
-
|
|
19
|
-
# Related fields
|
|
17
|
+
|
|
18
|
+
# Related fields
|
|
20
19
|
center_name = serializers.CharField(source="center.name", read_only=True)
|
|
21
20
|
patient_gender_name = serializers.CharField(source="patient_gender.name", read_only=True)
|
|
22
|
-
|
|
23
|
-
# Examiner information
|
|
24
21
|
examiners_display = serializers.SerializerMethodField()
|
|
25
|
-
|
|
26
|
-
# Formatted
|
|
22
|
+
|
|
23
|
+
# Formatted display fields
|
|
27
24
|
patient_dob_display = serializers.SerializerMethodField()
|
|
28
25
|
examination_date_display = serializers.SerializerMethodField()
|
|
29
|
-
|
|
30
|
-
# Hash displays (last 8
|
|
26
|
+
|
|
27
|
+
# Hash displays (last 8 chars)
|
|
31
28
|
patient_hash_display = serializers.SerializerMethodField()
|
|
32
29
|
examination_hash_display = serializers.SerializerMethodField()
|
|
33
30
|
|
|
31
|
+
# Text fields
|
|
32
|
+
text = serializers.SerializerMethodField()
|
|
33
|
+
anonymized_text = serializers.SerializerMethodField()
|
|
34
|
+
|
|
34
35
|
class Meta:
|
|
35
36
|
model = SensitiveMeta
|
|
36
37
|
fields = [
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
38
|
+
"id",
|
|
39
|
+
"casenumber",
|
|
40
|
+
"patient_first_name",
|
|
41
|
+
"patient_last_name",
|
|
42
|
+
"patient_dob",
|
|
43
|
+
"patient_dob_display",
|
|
44
|
+
"examination_date",
|
|
45
|
+
"examination_date_display",
|
|
46
|
+
"examination_time",
|
|
47
|
+
"center_name",
|
|
48
|
+
"patient_gender_name",
|
|
49
|
+
"endoscope_type",
|
|
50
|
+
"endoscope_sn",
|
|
51
|
+
"patient_hash_display",
|
|
52
|
+
"examination_hash_display",
|
|
53
|
+
"examiners_display",
|
|
54
|
+
"is_verified",
|
|
55
|
+
"dob_verified",
|
|
56
|
+
"names_verified",
|
|
57
|
+
"text",
|
|
58
|
+
"anonymized_text",
|
|
59
|
+
"external_id",
|
|
60
|
+
"external_id_origin"
|
|
54
61
|
]
|
|
55
62
|
read_only_fields = [
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
63
|
+
"id",
|
|
64
|
+
"patient_hash_display",
|
|
65
|
+
"examination_hash_display",
|
|
59
66
|
]
|
|
60
67
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
Returns:
|
|
66
|
-
bool: True if the instance is verified; False if the verification attribute is missing.
|
|
67
|
-
|
|
68
|
-
Raises:
|
|
69
|
-
Exception: Propagates unexpected exceptions after logging.
|
|
70
|
-
"""
|
|
71
|
-
try:
|
|
72
|
-
return obj.is_verified
|
|
73
|
-
except AttributeError:
|
|
74
|
-
return False
|
|
75
|
-
except Exception as e:
|
|
76
|
-
logger.exception(f"Unexpected error in get_is_verified for SensitiveMeta {getattr(obj, 'pk', None)}: {e}")
|
|
77
|
-
raise
|
|
78
|
-
|
|
79
|
-
def get_dob_verified(self, obj):
|
|
80
|
-
"""
|
|
81
|
-
Return the date of birth verification status for the given object.
|
|
82
|
-
|
|
83
|
-
Returns:
|
|
84
|
-
bool: True if the date of birth is verified; otherwise, False if unavailable or on error.
|
|
85
|
-
"""
|
|
86
|
-
try:
|
|
87
|
-
return obj.state.dob_verified
|
|
88
|
-
except Exception:
|
|
89
|
-
return False
|
|
90
|
-
|
|
91
|
-
def get_names_verified(self, obj):
|
|
92
|
-
"""
|
|
93
|
-
Return whether the patient's names have been verified.
|
|
94
|
-
|
|
95
|
-
Returns:
|
|
96
|
-
bool: True if the names are verified; False if not verified or if an error occurs.
|
|
97
|
-
"""
|
|
98
|
-
try:
|
|
99
|
-
return obj.state.names_verified
|
|
100
|
-
except Exception:
|
|
101
|
-
return False
|
|
68
|
+
# --- Verification getters ---
|
|
69
|
+
def get_is_verified(self, obj): return getattr(obj, "is_verified", False)
|
|
70
|
+
def get_dob_verified(self, obj): return getattr(getattr(obj, "state", None), "dob_verified", False)
|
|
71
|
+
def get_names_verified(self, obj): return getattr(getattr(obj, "state", None), "names_verified", False)
|
|
102
72
|
|
|
73
|
+
# --- Examiner display ---
|
|
103
74
|
def get_examiners_display(self, obj):
|
|
104
|
-
"""
|
|
105
|
-
Return a list of examiner full names for the given SensitiveMeta instance.
|
|
106
|
-
|
|
107
|
-
Returns:
|
|
108
|
-
list[str]: List of examiner names in "First Last" format, or an empty list if unavailable.
|
|
109
|
-
"""
|
|
110
75
|
try:
|
|
111
|
-
if obj.pk
|
|
112
|
-
examiners = obj.examiners.all()
|
|
113
|
-
return [f"{e.first_name} {e.last_name}" for e in examiners]
|
|
114
|
-
return []
|
|
76
|
+
return [f"{e.first_name} {e.last_name}" for e in obj.examiners.all()] if obj.pk else []
|
|
115
77
|
except Exception as e:
|
|
116
|
-
logger.warning(f"Error
|
|
78
|
+
logger.warning(f"Error fetching examiners for SensitiveMeta {obj.pk}: {e}")
|
|
117
79
|
return []
|
|
118
80
|
|
|
81
|
+
# --- Date formatters ---
|
|
119
82
|
def get_patient_dob_display(self, obj):
|
|
120
|
-
""
|
|
121
|
-
Return the patient's date of birth formatted as "YYYY-MM-DD" for display.
|
|
122
|
-
|
|
123
|
-
Returns:
|
|
124
|
-
str or None: Formatted date string if available, otherwise None.
|
|
125
|
-
"""
|
|
126
|
-
if obj.patient_dob:
|
|
127
|
-
return obj.patient_dob.strftime("%Y-%m-%d")
|
|
128
|
-
return None
|
|
83
|
+
return obj.patient_dob.strftime("%Y-%m-%d") if obj.patient_dob else None
|
|
129
84
|
|
|
130
85
|
def get_examination_date_display(self, obj):
|
|
131
|
-
""
|
|
132
|
-
Return the examination date formatted as "YYYY-MM-DD" for display.
|
|
133
|
-
|
|
134
|
-
Returns:
|
|
135
|
-
str or None: Formatted examination date string, or None if not set.
|
|
136
|
-
"""
|
|
137
|
-
if obj.examination_date:
|
|
138
|
-
return obj.examination_date.strftime("%Y-%m-%d")
|
|
139
|
-
return None
|
|
86
|
+
return obj.examination_date.strftime("%Y-%m-%d") if obj.examination_date else None
|
|
140
87
|
|
|
88
|
+
# --- Hash short forms ---
|
|
141
89
|
def get_patient_hash_display(self, obj):
|
|
142
|
-
""
|
|
143
|
-
Return the last eight characters of the patient's hash, prefixed with ellipsis, or None if not available.
|
|
144
|
-
|
|
145
|
-
Returns:
|
|
146
|
-
str or None: Truncated patient hash for display, or None if the hash is not set.
|
|
147
|
-
"""
|
|
148
|
-
if obj.patient_hash:
|
|
149
|
-
return f"...{obj.patient_hash[-8:]}"
|
|
150
|
-
return None
|
|
90
|
+
return f"...{obj.patient_hash[-8:]}" if obj.patient_hash else None
|
|
151
91
|
|
|
152
92
|
def get_examination_hash_display(self, obj):
|
|
153
|
-
""
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
93
|
+
return f"...{obj.examination_hash[-8:]}" if obj.examination_hash else None
|
|
94
|
+
|
|
95
|
+
# --- Text fields ---
|
|
96
|
+
def get_text(self, obj):
|
|
97
|
+
return obj.text if isinstance(obj.text, str) else None
|
|
98
|
+
|
|
99
|
+
def get_anonymized_text(self, obj):
|
|
100
|
+
return obj.anonymized_text if isinstance(obj.anonymized_text, str) else None
|
|
101
|
+
|
|
102
|
+
def get_external_id(self, obj) -> str | None:
|
|
103
|
+
return obj.external_id if isinstance(obj.external_id, str) else None
|
|
104
|
+
|
|
105
|
+
def get_external_id_origin(self, obj) -> str | None:
|
|
106
|
+
return obj.external_id_origin if isinstance(obj.external_id_origin, str) else None
|
|
162
107
|
|
|
@@ -3,12 +3,8 @@ from typing import TYPE_CHECKING
|
|
|
3
3
|
from rest_framework import serializers
|
|
4
4
|
|
|
5
5
|
from endoreg_db.models.media import RawPdfFile, VideoFile
|
|
6
|
-
from endoreg_db.models.state.
|
|
7
|
-
|
|
8
|
-
)
|
|
9
|
-
from endoreg_db.models.state.video import (
|
|
10
|
-
AnonymizationStatus as VideoAnonymizationStatus,
|
|
11
|
-
)
|
|
6
|
+
from endoreg_db.models.state.anonymization import AnonymizationState as PdfAnonymizationState
|
|
7
|
+
from endoreg_db.models.state.anonymization import AnonymizationState as VideoAnonymizationState
|
|
12
8
|
|
|
13
9
|
if TYPE_CHECKING:
|
|
14
10
|
pass
|
|
@@ -28,10 +24,6 @@ class FileOverviewSerializer(serializers.Serializer):
|
|
|
28
24
|
anonymizationStatus = serializers.CharField(read_only=True)
|
|
29
25
|
annotationStatus = serializers.CharField(read_only=True)
|
|
30
26
|
createdAt = serializers.DateTimeField(read_only=True)
|
|
31
|
-
text = serializers.CharField(required=False, allow_blank=True, read_only=True)
|
|
32
|
-
anonymizedText = serializers.CharField(
|
|
33
|
-
required=False, allow_blank=True, read_only=True
|
|
34
|
-
)
|
|
35
27
|
|
|
36
28
|
# --- converting DB objects to that shape -----------------------
|
|
37
29
|
def to_representation(self, instance):
|
|
@@ -62,110 +54,32 @@ class FileOverviewSerializer(serializers.Serializer):
|
|
|
62
54
|
)
|
|
63
55
|
|
|
64
56
|
# ------- anonymization status using VideoState model
|
|
65
|
-
vs = instance.
|
|
57
|
+
vs = instance.get_or_create_state()
|
|
66
58
|
anonym_status = (
|
|
67
|
-
vs.anonymization_status if vs else
|
|
59
|
+
vs.anonymization_status if vs else VideoAnonymizationState.NOT_STARTED
|
|
68
60
|
)
|
|
69
61
|
|
|
70
62
|
# ------- annotation status (validated label segments)
|
|
71
63
|
if instance.label_video_segments.filter(state__is_validated=True).exists():
|
|
72
|
-
annot_status = "
|
|
64
|
+
annot_status = "validated"
|
|
73
65
|
else:
|
|
74
66
|
annot_status = "not_started"
|
|
75
67
|
|
|
76
|
-
# ------- Extract text from sensitive_meta for videos
|
|
77
|
-
if instance.sensitive_meta:
|
|
78
|
-
sm = instance.sensitive_meta
|
|
79
|
-
# Create a structured text representation from sensitive meta
|
|
80
|
-
text_parts = []
|
|
81
|
-
|
|
82
|
-
# Patient information
|
|
83
|
-
if sm.patient_first_name or sm.patient_last_name:
|
|
84
|
-
patient_name = f"{sm.patient_first_name or ''} {sm.patient_last_name or ''}".strip()
|
|
85
|
-
text_parts.append(f"Patient: {patient_name}")
|
|
86
|
-
|
|
87
|
-
if sm.patient_dob:
|
|
88
|
-
text_parts.append(f"Date of Birth: {sm.patient_dob.date()}")
|
|
89
|
-
|
|
90
|
-
if sm.patient_gender:
|
|
91
|
-
text_parts.append(f"Gender: {sm.patient_gender}")
|
|
92
|
-
|
|
93
|
-
# Examination information
|
|
94
|
-
if sm.examination_date:
|
|
95
|
-
text_parts.append(f"Examination Date: {sm.examination_date}")
|
|
96
|
-
|
|
97
|
-
if sm.center:
|
|
98
|
-
text_parts.append(f"Center: {sm.center.name}")
|
|
99
|
-
|
|
100
|
-
# Equipment information
|
|
101
|
-
if sm.endoscope_type:
|
|
102
|
-
text_parts.append(f"Endoscope Type: {sm.endoscope_type}")
|
|
103
|
-
|
|
104
|
-
if sm.endoscope_sn:
|
|
105
|
-
text_parts.append(f"Endoscope SN: {sm.endoscope_sn}")
|
|
106
|
-
|
|
107
|
-
# Examiner information
|
|
108
|
-
if sm.pk: # Only if saved
|
|
109
|
-
try:
|
|
110
|
-
examiners = list(sm.examiners.all())
|
|
111
|
-
if examiners:
|
|
112
|
-
examiner_names = ", ".join(str(e) for e in examiners)
|
|
113
|
-
text_parts.append(f"Examiners: {examiner_names}")
|
|
114
|
-
except Exception:
|
|
115
|
-
pass # Ignore examiner lookup errors
|
|
116
|
-
|
|
117
|
-
text = "\n".join(text_parts)
|
|
118
|
-
|
|
119
|
-
# Create anonymized version by replacing sensitive data
|
|
120
|
-
anonym_text = text
|
|
121
|
-
if sm.patient_first_name:
|
|
122
|
-
anonym_text = anonym_text.replace(
|
|
123
|
-
sm.patient_first_name, "[FIRST_NAME]"
|
|
124
|
-
)
|
|
125
|
-
if sm.patient_last_name:
|
|
126
|
-
anonym_text = anonym_text.replace(
|
|
127
|
-
sm.patient_last_name, "[LAST_NAME]"
|
|
128
|
-
)
|
|
129
|
-
if sm.patient_dob:
|
|
130
|
-
anonym_text = anonym_text.replace(
|
|
131
|
-
str(sm.patient_dob.date()), "[DOB]"
|
|
132
|
-
)
|
|
133
|
-
if sm.endoscope_sn:
|
|
134
|
-
anonym_text = anonym_text.replace(sm.endoscope_sn, "[ENDOSCOPE_SN]")
|
|
135
|
-
|
|
136
|
-
# Replace examiner names if available
|
|
137
|
-
if sm.pk:
|
|
138
|
-
try:
|
|
139
|
-
examiners = list(sm.examiners.all())
|
|
140
|
-
for examiner in examiners:
|
|
141
|
-
anonym_text = anonym_text.replace(
|
|
142
|
-
str(examiner), "[EXAMINER]"
|
|
143
|
-
)
|
|
144
|
-
except Exception:
|
|
145
|
-
pass
|
|
146
|
-
|
|
147
68
|
elif isinstance(instance, RawPdfFile):
|
|
148
|
-
instance: RawPdfFile
|
|
149
69
|
media_type = "pdf"
|
|
150
70
|
created_at = instance.date_created
|
|
151
71
|
filename = instance.file.name.split("/")[-1] if instance.file else "unknown"
|
|
152
72
|
|
|
153
|
-
# ------- anonymization status using RawPdfState model
|
|
154
|
-
|
|
73
|
+
# ------- anonymization status using RawPdfState model
|
|
74
|
+
rps = instance.get_or_create_state()
|
|
155
75
|
anonym_status = (
|
|
156
|
-
|
|
76
|
+
rps.anonymization_status if rps else PdfAnonymizationState.NOT_STARTED
|
|
157
77
|
)
|
|
158
78
|
|
|
159
|
-
#
|
|
79
|
+
# ------- annotation status (not applicable for PDFs)
|
|
160
80
|
annot_status = (
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
else "not_started"
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
# Extract text content from PDF
|
|
167
|
-
text = instance.text or ""
|
|
168
|
-
anonym_text = instance.anonymized_text or ""
|
|
81
|
+
PdfAnonymizationState.VALIDATED if rps.anonymization_validated else PdfAnonymizationState.NOT_STARTED
|
|
82
|
+
)
|
|
169
83
|
|
|
170
84
|
else: # shouldn't happen
|
|
171
85
|
raise TypeError(f"Unsupported instance for overview: {type(instance)}")
|
|
@@ -177,6 +91,4 @@ class FileOverviewSerializer(serializers.Serializer):
|
|
|
177
91
|
"anonymizationStatus": anonym_status,
|
|
178
92
|
"annotationStatus": annot_status,
|
|
179
93
|
"createdAt": created_at,
|
|
180
|
-
"text": text,
|
|
181
|
-
"anonymizedText": anonym_text,
|
|
182
94
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
from endoreg_db.models.media import RawPdfFile, VideoFile
|
|
2
|
-
|
|
3
|
-
|
|
4
1
|
from rest_framework import serializers
|
|
5
2
|
|
|
6
|
-
|
|
3
|
+
from endoreg_db.models.media import RawPdfFile, VideoFile
|
|
4
|
+
|
|
5
|
+
# TODO add this "naming convention" to the documentation
|
|
7
6
|
# VoP: Video or Pdf
|
|
8
7
|
|
|
8
|
+
|
|
9
9
|
class VoPPatientDataSerializer(serializers.Serializer):
|
|
10
10
|
"""
|
|
11
|
-
Serializer that converts a VideoFile or RawPdfFile to the structure
|
|
11
|
+
Serializer that converts a VideoFile or RawPdfFile to the structure
|
|
12
12
|
the Pinia store needs for validation workflow.
|
|
13
13
|
"""
|
|
14
14
|
|
|
@@ -24,12 +24,12 @@ class VoPPatientDataSerializer(serializers.Serializer):
|
|
|
24
24
|
def to_representation(self, instance):
|
|
25
25
|
"""
|
|
26
26
|
Serialize a VideoFile or RawPdfFile instance into a structured dictionary for validation workflows.
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
Depending on the instance type, constructs a dictionary containing identifiers, sensitive metadata, text summaries, anonymized text, processing status, and error flag. For VideoFile instances, generates a text summary from associated sensitive metadata and anonymizes personal identifiers. For RawPdfFile instances, uses the instance's text fields directly. Raises a TypeError if the instance is neither type.
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
Parameters:
|
|
31
31
|
instance: A VideoFile or RawPdfFile model instance to serialize.
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
Returns:
|
|
34
34
|
dict: A structured representation of the instance suitable for Pinia store consumption.
|
|
35
35
|
"""
|
|
@@ -62,44 +62,62 @@ class VoPPatientDataSerializer(serializers.Serializer):
|
|
|
62
62
|
# Create anonymized version
|
|
63
63
|
anonym_text = text
|
|
64
64
|
if sm.patient_first_name:
|
|
65
|
-
anonym_text = anonym_text.replace(
|
|
65
|
+
anonym_text = anonym_text.replace(
|
|
66
|
+
sm.patient_first_name, "[FIRST_NAME]"
|
|
67
|
+
)
|
|
66
68
|
if sm.patient_last_name:
|
|
67
|
-
anonym_text = anonym_text.replace(
|
|
69
|
+
anonym_text = anonym_text.replace(
|
|
70
|
+
sm.patient_last_name, "[LAST_NAME]"
|
|
71
|
+
)
|
|
68
72
|
if sm.patient_dob:
|
|
69
|
-
anonym_text = anonym_text.replace(
|
|
73
|
+
anonym_text = anonym_text.replace(
|
|
74
|
+
str(sm.patient_dob.date()), "[DOB]"
|
|
75
|
+
)
|
|
70
76
|
|
|
71
77
|
return {
|
|
72
78
|
"id": instance.pk,
|
|
73
|
-
"sensitiveMetaId": instance.sensitive_meta.pk
|
|
79
|
+
"sensitiveMetaId": instance.sensitive_meta.pk
|
|
80
|
+
if instance.sensitive_meta
|
|
81
|
+
else None,
|
|
74
82
|
"text": text,
|
|
75
83
|
"anonymizedText": anonym_text,
|
|
76
|
-
"reportMeta": self._serialize_sensitive_meta(instance.sensitive_meta)
|
|
77
|
-
|
|
84
|
+
"reportMeta": self._serialize_sensitive_meta(instance.sensitive_meta)
|
|
85
|
+
if instance.sensitive_meta
|
|
86
|
+
else None,
|
|
87
|
+
"status": "processing"
|
|
88
|
+
if instance.state and instance.state.frames_extracted
|
|
89
|
+
else "not_started",
|
|
78
90
|
"error": False,
|
|
79
91
|
}
|
|
80
92
|
|
|
81
93
|
elif isinstance(instance, RawPdfFile):
|
|
82
|
-
# Generate
|
|
83
|
-
|
|
84
|
-
|
|
94
|
+
# Generate report streaming URL using pdf_id (RawPdfFile.id)
|
|
95
|
+
report_stream_url = f"/api/media/pdfs/{instance.pk}/stream/"
|
|
96
|
+
|
|
85
97
|
return {
|
|
86
98
|
"id": instance.pk,
|
|
87
|
-
"sensitiveMetaId": instance.sensitive_meta.pk
|
|
99
|
+
"sensitiveMetaId": instance.sensitive_meta.pk
|
|
100
|
+
if instance.sensitive_meta
|
|
101
|
+
else None,
|
|
88
102
|
"text": instance.text or "",
|
|
89
103
|
"anonymizedText": instance.anonymized_text or "",
|
|
90
|
-
"reportMeta": self._serialize_sensitive_meta(instance.sensitive_meta)
|
|
104
|
+
"reportMeta": self._serialize_sensitive_meta(instance.sensitive_meta)
|
|
105
|
+
if instance.sensitive_meta
|
|
106
|
+
else None,
|
|
91
107
|
"status": "done" if instance.anonymized_text else "not_started",
|
|
92
108
|
"error": False,
|
|
93
|
-
"pdfStreamUrl":
|
|
109
|
+
"pdfStreamUrl": report_stream_url,
|
|
94
110
|
}
|
|
95
111
|
|
|
96
112
|
else:
|
|
97
|
-
raise TypeError(
|
|
113
|
+
raise TypeError(
|
|
114
|
+
f"Unsupported instance for VoPPatientDataSerializer: {type(instance)}"
|
|
115
|
+
)
|
|
98
116
|
|
|
99
117
|
def _serialize_sensitive_meta(self, sensitive_meta):
|
|
100
118
|
"""
|
|
101
119
|
Serialize a SensitiveMeta object into a dictionary with patient and examination details.
|
|
102
|
-
|
|
120
|
+
|
|
103
121
|
Returns:
|
|
104
122
|
dict or None: A dictionary containing patient and examination metadata fields, or None if sensitive_meta is not provided.
|
|
105
123
|
"""
|
|
@@ -110,11 +128,17 @@ class VoPPatientDataSerializer(serializers.Serializer):
|
|
|
110
128
|
"id": sensitive_meta.pk,
|
|
111
129
|
"patientFirstName": sensitive_meta.patient_first_name or "",
|
|
112
130
|
"patientLastName": sensitive_meta.patient_last_name or "",
|
|
113
|
-
"patientDob": sensitive_meta.patient_dob.isoformat()
|
|
114
|
-
|
|
115
|
-
|
|
131
|
+
"patientDob": sensitive_meta.patient_dob.isoformat()
|
|
132
|
+
if sensitive_meta.patient_dob
|
|
133
|
+
else "",
|
|
134
|
+
"patientGender": str(sensitive_meta.patient_gender)
|
|
135
|
+
if sensitive_meta.patient_gender
|
|
136
|
+
else "",
|
|
137
|
+
"examinationDate": sensitive_meta.examination_date.isoformat()
|
|
138
|
+
if sensitive_meta.examination_date
|
|
139
|
+
else "",
|
|
116
140
|
"centerName": sensitive_meta.center.name if sensitive_meta.center else "",
|
|
117
141
|
"endoscopeType": sensitive_meta.endoscope_type or "",
|
|
118
142
|
"endoscopeSn": sensitive_meta.endoscope_sn or "",
|
|
119
143
|
"isVerified": getattr(sensitive_meta, "is_verified", False),
|
|
120
|
-
}
|
|
144
|
+
}
|
|
@@ -135,7 +135,7 @@ class PatientExaminationSerializer(serializers.ModelSerializer):
|
|
|
135
135
|
|
|
136
136
|
def get_findings(self, patient_examination_id):
|
|
137
137
|
"""Gibt die zugehörigen Befunde zurück"""
|
|
138
|
-
|
|
138
|
+
pe = PatientExamination()
|
|
139
|
+
obj = pe.get_or_create_patient_examination_by_id(patient_examination_id)
|
|
139
140
|
self.instance = obj
|
|
140
|
-
|
|
141
|
-
return self.instance.patient_findings.all() if self.instance else []
|
|
141
|
+
return self.instance.get_available_findings() if self.instance else []
|