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
|
@@ -13,6 +13,7 @@ from rest_framework.response import Response
|
|
|
13
13
|
from endoreg_db.services import lookup_service as ls
|
|
14
14
|
from endoreg_db.services.lookup_store import DEFAULT_TTL_SECONDS, LookupStore
|
|
15
15
|
from endoreg_db.utils.permissions import EnvironmentAwarePermission
|
|
16
|
+
from endoreg_db.models.other.tag import Tag
|
|
16
17
|
|
|
17
18
|
ORIGIN_MAP_PREFIX = "lookup:origin:"
|
|
18
19
|
ISSUED_MAP_PREFIX = "lookup:issued_for_internal:"
|
|
@@ -53,6 +54,8 @@ class LookupViewSet(viewsets.ViewSet):
|
|
|
53
54
|
"selectedRequirementSetIds",
|
|
54
55
|
"selectedChoices",
|
|
55
56
|
}
|
|
57
|
+
|
|
58
|
+
user_tags = Tag
|
|
56
59
|
|
|
57
60
|
@action(detail=False, methods=["post"])
|
|
58
61
|
def init(self, request):
|
|
@@ -131,7 +134,10 @@ class LookupViewSet(viewsets.ViewSet):
|
|
|
131
134
|
|
|
132
135
|
except Exception:
|
|
133
136
|
pass
|
|
134
|
-
|
|
137
|
+
|
|
138
|
+
user_tags = request.data.get("user_tags", None)
|
|
139
|
+
if user_tags and not isinstance(user_tags, list):
|
|
140
|
+
user_tags = [user_tags]
|
|
135
141
|
# Fallback to query params
|
|
136
142
|
if raw_pe is None:
|
|
137
143
|
raw_pe = request.query_params.get("patient_examination_id")
|
|
@@ -167,7 +173,11 @@ class LookupViewSet(viewsets.ViewSet):
|
|
|
167
173
|
|
|
168
174
|
try:
|
|
169
175
|
# Create internal session via service (may seed its own token/cache)
|
|
170
|
-
|
|
176
|
+
service_kwargs = {}
|
|
177
|
+
if user_tags:
|
|
178
|
+
service_kwargs["user_tags"] = user_tags
|
|
179
|
+
|
|
180
|
+
internal_token = ls.create_lookup_token_for_pe(pe_id, **service_kwargs)
|
|
171
181
|
internal_data = LookupStore(token=internal_token).get_all()
|
|
172
182
|
|
|
173
183
|
issued_key = f"{ISSUED_MAP_PREFIX}{internal_token}"
|
|
@@ -254,7 +264,11 @@ class LookupViewSet(viewsets.ViewSet):
|
|
|
254
264
|
status=status.HTTP_404_NOT_FOUND,
|
|
255
265
|
)
|
|
256
266
|
|
|
257
|
-
|
|
267
|
+
# Hydrate the original token with recovered data and refresh origin TTL
|
|
268
|
+
store.set_many(new_data)
|
|
269
|
+
cache.set(f"{ORIGIN_MAP_PREFIX}{pk}", pe_id, DEFAULT_TTL_SECONDS)
|
|
270
|
+
return Response(store.get_all(), status=status.HTTP_200_OK)
|
|
271
|
+
|
|
258
272
|
|
|
259
273
|
except Exception:
|
|
260
274
|
pass
|
|
@@ -3,36 +3,27 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import uuid
|
|
6
|
-
|
|
7
6
|
from typing import Any, Dict, Iterable, Optional
|
|
8
7
|
|
|
9
|
-
from django.core.cache import cache
|
|
10
|
-
|
|
11
|
-
|
|
12
8
|
from django.conf import settings
|
|
9
|
+
from django.core.cache import cache
|
|
13
10
|
|
|
14
11
|
from endoreg_db.models.medical import PatientExamination
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
|
|
18
13
|
# Align TTL with Django cache TIMEOUT for consistency in tests and runtime
|
|
19
14
|
|
|
20
15
|
|
|
21
16
|
try:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
DEFAULT_TTL_SECONDS = int(
|
|
18
|
+
settings.CACHES.get("default", {}).get("TIMEOUT", 60 * 30)
|
|
19
|
+
)
|
|
25
20
|
|
|
26
21
|
|
|
27
22
|
except Exception:
|
|
28
|
-
|
|
29
|
-
|
|
30
23
|
DEFAULT_TTL_SECONDS = 60 * 30 # 30 minutes fallback
|
|
31
24
|
|
|
32
25
|
|
|
33
|
-
|
|
34
26
|
class LookupStore:
|
|
35
|
-
|
|
36
27
|
"""
|
|
37
28
|
|
|
38
29
|
Server-side lookup dictionary stored in Django cache.
|
|
@@ -42,75 +33,48 @@ class LookupStore:
|
|
|
42
33
|
"""
|
|
43
34
|
|
|
44
35
|
def __init__(self, token: Optional[str] = None):
|
|
45
|
-
|
|
46
36
|
self.token = token or uuid.uuid4().hex
|
|
47
37
|
|
|
48
|
-
|
|
49
|
-
|
|
50
38
|
@property
|
|
51
|
-
|
|
52
39
|
def cache_key(self) -> str:
|
|
53
|
-
|
|
54
40
|
return f"lookup:{self.token}"
|
|
55
41
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
42
|
+
def init(
|
|
43
|
+
self, initial: Optional[Dict[str, Any]] = None, ttl: int = DEFAULT_TTL_SECONDS
|
|
44
|
+
) -> str:
|
|
60
45
|
cache.set(self.cache_key, initial or {}, ttl)
|
|
61
46
|
|
|
62
47
|
return self.token
|
|
63
48
|
|
|
64
|
-
|
|
65
|
-
|
|
66
49
|
def get_all(self) -> Dict[str, Any]:
|
|
67
|
-
|
|
68
50
|
return cache.get(self.cache_key, {})
|
|
69
51
|
|
|
70
|
-
|
|
71
|
-
|
|
72
52
|
def get_many(self, keys: Iterable[str]) -> Dict[str, Any]:
|
|
73
|
-
|
|
74
53
|
data = self.get_all()
|
|
75
54
|
|
|
76
55
|
return {k: data.get(k) for k in keys}
|
|
77
56
|
|
|
78
|
-
|
|
79
|
-
|
|
80
57
|
def set_many(self, updates: Dict[str, Any], ttl: int = DEFAULT_TTL_SECONDS) -> None:
|
|
81
|
-
|
|
82
58
|
data = self.get_all()
|
|
83
59
|
|
|
84
60
|
data.update(updates)
|
|
85
61
|
|
|
86
62
|
cache.set(self.cache_key, data, ttl)
|
|
87
63
|
|
|
88
|
-
|
|
89
|
-
|
|
90
64
|
def get(self, key: str, default: Any = None) -> Any:
|
|
91
|
-
|
|
92
65
|
return self.get_all().get(key, default)
|
|
93
66
|
|
|
94
|
-
|
|
95
|
-
|
|
96
67
|
def set(self, key: str, value: Any, ttl: int = DEFAULT_TTL_SECONDS) -> None:
|
|
97
|
-
|
|
98
68
|
data = self.get_all()
|
|
99
69
|
|
|
100
70
|
data[key] = value
|
|
101
71
|
|
|
102
72
|
cache.set(self.cache_key, data, ttl)
|
|
103
73
|
|
|
104
|
-
|
|
105
|
-
|
|
106
74
|
def delete(self) -> None:
|
|
107
|
-
|
|
108
75
|
cache.delete(self.cache_key)
|
|
109
76
|
|
|
110
|
-
|
|
111
|
-
|
|
112
77
|
def patch(self, updates: Dict[str, Any], ttl: int = DEFAULT_TTL_SECONDS) -> None:
|
|
113
|
-
|
|
114
78
|
"""Patch existing data with updates."""
|
|
115
79
|
|
|
116
80
|
data = self.get_all()
|
|
@@ -119,73 +83,56 @@ class LookupStore:
|
|
|
119
83
|
|
|
120
84
|
cache.set(self.cache_key, data, ttl)
|
|
121
85
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
86
|
def validate_and_recover_data(self, token):
|
|
127
|
-
|
|
128
87
|
"""Validate stored data and attempt recovery if corrupted"""
|
|
129
88
|
|
|
130
89
|
data = self.get_all()
|
|
131
90
|
|
|
132
|
-
|
|
133
|
-
|
|
134
91
|
if not data:
|
|
135
|
-
|
|
136
92
|
return None
|
|
137
93
|
|
|
138
|
-
|
|
139
|
-
|
|
140
94
|
# Check if required fields are present
|
|
141
95
|
|
|
142
|
-
required_fields = [
|
|
96
|
+
required_fields = [
|
|
97
|
+
"patient_examination_id",
|
|
98
|
+
"requirements_by_set",
|
|
99
|
+
"requirement_status",
|
|
100
|
+
]
|
|
143
101
|
|
|
144
102
|
missing_fields = [field for field in required_fields if field not in data]
|
|
145
103
|
|
|
146
|
-
|
|
147
|
-
|
|
148
104
|
if missing_fields:
|
|
149
|
-
|
|
150
105
|
import logging
|
|
151
106
|
|
|
152
107
|
logger = logging.getLogger(__name__)
|
|
153
108
|
|
|
154
|
-
logger.warning(
|
|
155
|
-
|
|
156
|
-
|
|
109
|
+
logger.warning(
|
|
110
|
+
f"Missing fields in lookup data for token {token}: {missing_fields}"
|
|
111
|
+
)
|
|
157
112
|
|
|
158
113
|
# Try to recover patient_examination_id from token or related data
|
|
159
114
|
|
|
160
|
-
if
|
|
161
|
-
|
|
115
|
+
if "patient_examination_id" in missing_fields:
|
|
162
116
|
# Attempt to extract from token or find related examination
|
|
163
117
|
|
|
164
118
|
recovered_id = self._recover_patient_examination_id(token)
|
|
165
119
|
|
|
166
120
|
if recovered_id:
|
|
121
|
+
data["patient_examination_id"] = recovered_id
|
|
167
122
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
123
|
+
logger.info(
|
|
124
|
+
f"Recovered patient_examination_id {recovered_id} for token {token}"
|
|
125
|
+
)
|
|
173
126
|
|
|
174
127
|
# Do not automatically recompute here to avoid loops
|
|
175
128
|
|
|
176
|
-
|
|
177
129
|
# Recompute is only triggered by PATCH or explicit POST /recompute/
|
|
178
130
|
|
|
179
131
|
# For now, just return the data as is
|
|
180
132
|
|
|
181
|
-
|
|
182
|
-
|
|
183
133
|
return data
|
|
184
134
|
|
|
185
|
-
|
|
186
|
-
|
|
187
135
|
def _recover_patient_examination_id(self, token: str) -> Optional[str]:
|
|
188
|
-
|
|
189
136
|
"""
|
|
190
137
|
|
|
191
138
|
Placeholder for recovering patient_examination_id.
|
|
@@ -200,30 +147,21 @@ class LookupStore:
|
|
|
200
147
|
|
|
201
148
|
return None
|
|
202
149
|
|
|
203
|
-
|
|
204
|
-
|
|
205
150
|
def should_recompute(self, token):
|
|
206
|
-
|
|
207
151
|
"""Check if recomputation is needed based on data freshness"""
|
|
208
152
|
|
|
209
153
|
data = self.get_all()
|
|
210
154
|
|
|
211
155
|
if not data:
|
|
212
|
-
|
|
213
156
|
return True
|
|
214
157
|
|
|
215
|
-
|
|
216
|
-
|
|
217
158
|
# Check if we have a last_recompute timestamp
|
|
218
159
|
|
|
219
|
-
last_recompute = data.get(
|
|
160
|
+
last_recompute = data.get("_last_recompute")
|
|
220
161
|
|
|
221
162
|
if not last_recompute:
|
|
222
|
-
|
|
223
163
|
return True
|
|
224
164
|
|
|
225
|
-
|
|
226
|
-
|
|
227
165
|
# Only recompute if it's been more than 30 seconds since last recompute
|
|
228
166
|
|
|
229
167
|
# This prevents excessive recomputation while allowing for updates
|
|
@@ -231,22 +169,16 @@ class LookupStore:
|
|
|
231
169
|
from datetime import datetime, timedelta
|
|
232
170
|
|
|
233
171
|
try:
|
|
234
|
-
|
|
235
172
|
last_recompute_time = datetime.fromisoformat(last_recompute)
|
|
236
173
|
|
|
237
174
|
return datetime.now() - last_recompute_time > timedelta(seconds=30)
|
|
238
175
|
|
|
239
176
|
except (ValueError, TypeError):
|
|
240
|
-
|
|
241
177
|
return True
|
|
242
178
|
|
|
243
|
-
|
|
244
|
-
|
|
245
179
|
def mark_recompute_done(self):
|
|
246
|
-
|
|
247
180
|
"""Mark that recomputation has been completed"""
|
|
248
181
|
|
|
249
182
|
from datetime import datetime
|
|
250
183
|
|
|
251
|
-
self.set(
|
|
252
|
-
|
|
184
|
+
self.set("_last_recompute", datetime.now().isoformat())
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Any, Tuple, TYPE_CHECKING
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
from endoreg_db.models.requirement.requirement_error import (
|
|
6
|
+
RequirementEvaluationError,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from endoreg_db.models.requirement.requirement import Requirement
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def safe_evaluate_requirement(
|
|
16
|
+
requirement: "Requirement",
|
|
17
|
+
*args: Any,
|
|
18
|
+
mode: str = "strict",
|
|
19
|
+
**kwargs: Any,
|
|
20
|
+
) -> Tuple[bool, str, str | None]:
|
|
21
|
+
"""
|
|
22
|
+
Wrapper für Requirement.evaluate / evaluate_with_details, der NIE Exceptions durchlässt.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
met: bool
|
|
26
|
+
details: human-readable explanation (für UI)
|
|
27
|
+
error: technischer Fehlerstring oder None
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
if hasattr(requirement, "evaluate_with_details"):
|
|
32
|
+
met, details = requirement.evaluate_with_details(*args, mode=mode, **kwargs)
|
|
33
|
+
else:
|
|
34
|
+
met = requirement.evaluate(*args, mode=mode, **kwargs)
|
|
35
|
+
details = "Voraussetzung erfüllt" if met else "Voraussetzung nicht erfüllt"
|
|
36
|
+
error = None
|
|
37
|
+
|
|
38
|
+
except RequirementEvaluationError as e:
|
|
39
|
+
ctx = e.context
|
|
40
|
+
req_obj = ctx.requirement or requirement
|
|
41
|
+
|
|
42
|
+
# sprechbarer Name aus DB (Beschreibung bevorzugen, sonst name)
|
|
43
|
+
display_name = (
|
|
44
|
+
getattr(req_obj, "description", None)
|
|
45
|
+
or getattr(req_obj, "name", None)
|
|
46
|
+
or "unbekannte Voraussetzung"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
# falls Exception schon eine user_message mitbringt: die nehmen
|
|
50
|
+
if ctx.user_message:
|
|
51
|
+
details = ctx.user_message
|
|
52
|
+
else:
|
|
53
|
+
details = (
|
|
54
|
+
f"Die Voraussetzung „{display_name}“ konnte nicht ausgewertet werden."
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# technischer Fehlerstring für Logs/Debug
|
|
58
|
+
error = f"{ctx.code}: {ctx.technical_message}"
|
|
59
|
+
logger.warning(
|
|
60
|
+
"Requirement '%s' (code=%s) validation error: %s",
|
|
61
|
+
getattr(req_obj, "name", "unknown"),
|
|
62
|
+
ctx.code,
|
|
63
|
+
ctx.technical_message,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
met = False
|
|
67
|
+
|
|
68
|
+
except Exception as e:
|
|
69
|
+
met = False
|
|
70
|
+
display_name = getattr(requirement, "description", None) or getattr(
|
|
71
|
+
requirement, "name", "unbekannte Voraussetzung"
|
|
72
|
+
)
|
|
73
|
+
details = (
|
|
74
|
+
f"Bei der Auswertung der Voraussetzung „{display_name}“ ist ein interner Fehler aufgetreten."
|
|
75
|
+
)
|
|
76
|
+
error = f"{e.__class__.__name__}: {e}"
|
|
77
|
+
logger.exception(
|
|
78
|
+
"Requirement '%s' unexpected error",
|
|
79
|
+
getattr(requirement, "name", "unknown"),
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# normalize details to string
|
|
83
|
+
if not isinstance(details, str):
|
|
84
|
+
try:
|
|
85
|
+
details = json.dumps(details, ensure_ascii=False, default=str)
|
|
86
|
+
except Exception:
|
|
87
|
+
details = str(details)
|
|
88
|
+
|
|
89
|
+
return bool(met), details, error
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from .correction import (
|
|
2
|
-
VideoMetadataView,
|
|
3
2
|
VideoProcessingHistoryView,
|
|
4
3
|
VideoApplyMaskView,
|
|
5
4
|
VideoRemoveFramesView,
|
|
@@ -11,49 +10,49 @@ from ..media.video_media import VideoMediaView
|
|
|
11
10
|
from .reimport import (
|
|
12
11
|
VideoReimportView
|
|
13
12
|
)
|
|
14
|
-
|
|
15
|
-
from .segmentation import (
|
|
16
|
-
VideoViewSet,
|
|
17
|
-
VideoLabelView,
|
|
18
|
-
UpdateLabelSegmentsView,
|
|
19
|
-
rerun_segmentation,
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
# Phase 3.2: VideoStreamView moved to dedicated module
|
|
23
13
|
from .video_stream import VideoStreamView
|
|
14
|
+
from .video_examination_viewset import VideoExaminationViewSet
|
|
15
|
+
from .video_meta_stats import VideoMetadataStatsView
|
|
24
16
|
|
|
25
|
-
from .timeline import (
|
|
26
|
-
video_timeline_view
|
|
27
|
-
)
|
|
28
17
|
|
|
29
|
-
from .
|
|
18
|
+
from .segments_crud import (
|
|
19
|
+
video_segments_collection,
|
|
20
|
+
video_segments_by_video,
|
|
21
|
+
video_segment_detail,
|
|
22
|
+
video_segments_stats,
|
|
23
|
+
video_segment_validate,
|
|
24
|
+
video_segments_validate_bulk,
|
|
25
|
+
video_segments_validation_status,
|
|
26
|
+
)
|
|
27
|
+
from ..ai.label import label_list
|
|
30
28
|
|
|
31
29
|
__all__ = [
|
|
32
30
|
# Video Correction (Phase 1.1) - Implemented
|
|
33
|
-
'VideoMetadataView',
|
|
34
31
|
'VideoProcessingHistoryView',
|
|
35
32
|
'VideoApplyMaskView',
|
|
36
33
|
'VideoRemoveFramesView',
|
|
34
|
+
'VideoMetadataStatsView',
|
|
37
35
|
|
|
38
36
|
'VideoMediaView',
|
|
39
37
|
|
|
40
38
|
'VideoCorrectionView',
|
|
41
|
-
# 'TaskStatusView',
|
|
42
|
-
# 'VideoDownloadProcessedView',
|
|
43
39
|
|
|
44
40
|
# Reimport views
|
|
45
41
|
'VideoReimportView',
|
|
46
42
|
|
|
47
43
|
# Segmentation views
|
|
48
|
-
'VideoViewSet',
|
|
49
44
|
'VideoStreamView',
|
|
50
|
-
'VideoLabelView',
|
|
51
|
-
'UpdateLabelSegmentsView',
|
|
52
|
-
'rerun_segmentation',
|
|
53
|
-
|
|
54
|
-
# Timeline views
|
|
55
|
-
'video_timeline_view',
|
|
56
45
|
|
|
57
46
|
# Video Examination ViewSet
|
|
58
47
|
"VideoExaminationViewSet",
|
|
48
|
+
|
|
49
|
+
'video_segments_collection',
|
|
50
|
+
'video_segments_by_video',
|
|
51
|
+
'video_segment_detail',
|
|
52
|
+
'video_segments_stats',
|
|
53
|
+
'video_segment_validate',
|
|
54
|
+
'video_segments_validate_bulk',
|
|
55
|
+
'video_segments_validation_status',
|
|
56
|
+
|
|
57
|
+
'label_list',
|
|
59
58
|
]
|