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
|
@@ -4,148 +4,149 @@ Video Processing History Model
|
|
|
4
4
|
Tracks all video correction operations (masking, frame removal, reprocessing).
|
|
5
5
|
Created as part of Phase 1.1: Video Correction API Endpoints.
|
|
6
6
|
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
from django.conf import settings
|
|
7
12
|
from django.db import models
|
|
8
13
|
from django.utils import timezone
|
|
14
|
+
|
|
9
15
|
from .video_file import VideoFile
|
|
10
16
|
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
11
20
|
class VideoProcessingHistory(models.Model):
|
|
12
21
|
"""
|
|
13
22
|
History of all video processing operations.
|
|
14
|
-
|
|
23
|
+
|
|
15
24
|
Stores configuration and results of masking, frame removal, and reprocessing
|
|
16
25
|
operations for audit trail and download access.
|
|
17
26
|
"""
|
|
18
|
-
|
|
27
|
+
|
|
19
28
|
# Operation Types
|
|
20
|
-
OPERATION_MASKING =
|
|
21
|
-
OPERATION_FRAME_REMOVAL =
|
|
22
|
-
OPERATION_ANALYSIS =
|
|
23
|
-
OPERATION_REPROCESSING =
|
|
24
|
-
|
|
29
|
+
OPERATION_MASKING = "mask_overlay"
|
|
30
|
+
OPERATION_FRAME_REMOVAL = "frame_removal"
|
|
31
|
+
OPERATION_ANALYSIS = "analysis"
|
|
32
|
+
OPERATION_REPROCESSING = "reprocessing"
|
|
33
|
+
|
|
25
34
|
OPERATION_CHOICES = [
|
|
26
|
-
(OPERATION_MASKING,
|
|
27
|
-
(OPERATION_FRAME_REMOVAL,
|
|
28
|
-
(OPERATION_ANALYSIS,
|
|
29
|
-
(OPERATION_REPROCESSING,
|
|
35
|
+
(OPERATION_MASKING, "Mask Overlay"),
|
|
36
|
+
(OPERATION_FRAME_REMOVAL, "Frame Removal"),
|
|
37
|
+
(OPERATION_ANALYSIS, "Sensitivity Analysis"),
|
|
38
|
+
(OPERATION_REPROCESSING, "Full Reprocessing"),
|
|
30
39
|
]
|
|
31
|
-
|
|
40
|
+
|
|
32
41
|
# Status Types
|
|
33
|
-
STATUS_PENDING =
|
|
34
|
-
STATUS_RUNNING =
|
|
35
|
-
STATUS_SUCCESS =
|
|
36
|
-
STATUS_FAILURE =
|
|
37
|
-
STATUS_CANCELLED =
|
|
38
|
-
|
|
42
|
+
STATUS_PENDING = "pending"
|
|
43
|
+
STATUS_RUNNING = "running"
|
|
44
|
+
STATUS_SUCCESS = "success"
|
|
45
|
+
STATUS_FAILURE = "failure"
|
|
46
|
+
STATUS_CANCELLED = "cancelled"
|
|
47
|
+
|
|
39
48
|
STATUS_CHOICES = [
|
|
40
|
-
(STATUS_PENDING,
|
|
41
|
-
(STATUS_RUNNING,
|
|
42
|
-
(STATUS_SUCCESS,
|
|
43
|
-
(STATUS_FAILURE,
|
|
44
|
-
(STATUS_CANCELLED,
|
|
49
|
+
(STATUS_PENDING, "Pending"),
|
|
50
|
+
(STATUS_RUNNING, "Running"),
|
|
51
|
+
(STATUS_SUCCESS, "Success"),
|
|
52
|
+
(STATUS_FAILURE, "Failure"),
|
|
53
|
+
(STATUS_CANCELLED, "Cancelled"),
|
|
45
54
|
]
|
|
46
|
-
|
|
47
|
-
video = models.ForeignKey(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
operation = models.CharField(
|
|
55
|
-
max_length=50,
|
|
56
|
-
choices=OPERATION_CHOICES,
|
|
57
|
-
help_text="Type of processing operation"
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
status = models.CharField(
|
|
61
|
-
max_length=20,
|
|
62
|
-
choices=STATUS_CHOICES,
|
|
63
|
-
default=STATUS_PENDING,
|
|
64
|
-
help_text="Current status of the operation"
|
|
65
|
-
)
|
|
66
|
-
|
|
55
|
+
|
|
56
|
+
video = models.ForeignKey(VideoFile, on_delete=models.CASCADE, related_name="processing_history", help_text="Video file this operation was performed on")
|
|
57
|
+
|
|
58
|
+
operation = models.CharField(max_length=50, choices=OPERATION_CHOICES, help_text="Type of processing operation")
|
|
59
|
+
|
|
60
|
+
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default=STATUS_PENDING, help_text="Current status of the operation")
|
|
61
|
+
|
|
67
62
|
# Configuration & Results
|
|
68
|
-
config = models.JSONField(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
max_length=500,
|
|
75
|
-
blank=True,
|
|
76
|
-
help_text="Path to output file (relative to MEDIA_ROOT)"
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
details = models.TextField(
|
|
80
|
-
blank=True,
|
|
81
|
-
help_text="Additional details or error messages"
|
|
82
|
-
)
|
|
83
|
-
|
|
63
|
+
config = models.JSONField(default=dict, help_text="Operation configuration (mask settings, frame list, etc.)")
|
|
64
|
+
|
|
65
|
+
output_file = models.CharField(max_length=500, blank=True, help_text="Path to output file (relative to MEDIA_ROOT)")
|
|
66
|
+
|
|
67
|
+
details = models.TextField(blank=True, help_text="Additional details or error messages")
|
|
68
|
+
|
|
84
69
|
# Celery Integration
|
|
85
|
-
task_id = models.CharField(
|
|
86
|
-
|
|
87
|
-
blank=True,
|
|
88
|
-
help_text="Celery task ID for progress tracking"
|
|
89
|
-
)
|
|
90
|
-
|
|
70
|
+
task_id = models.CharField(max_length=100, blank=True, help_text="Celery task ID for progress tracking")
|
|
71
|
+
|
|
91
72
|
# Timestamps
|
|
92
|
-
created_at = models.DateTimeField(
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
completed_at = models.DateTimeField(
|
|
98
|
-
null=True,
|
|
99
|
-
blank=True,
|
|
100
|
-
help_text="When the operation completed (success or failure)"
|
|
101
|
-
)
|
|
102
|
-
|
|
73
|
+
created_at = models.DateTimeField(auto_now_add=True, help_text="When the operation was started")
|
|
74
|
+
|
|
75
|
+
completed_at = models.DateTimeField(null=True, blank=True, help_text="When the operation completed (success or failure)")
|
|
76
|
+
|
|
103
77
|
class Meta:
|
|
104
|
-
db_table =
|
|
105
|
-
verbose_name =
|
|
106
|
-
verbose_name_plural =
|
|
107
|
-
ordering = [
|
|
78
|
+
db_table = "video_processing_history"
|
|
79
|
+
verbose_name = "Video Processing History"
|
|
80
|
+
verbose_name_plural = "Video Processing Histories"
|
|
81
|
+
ordering = ["-created_at"]
|
|
108
82
|
indexes = [
|
|
109
|
-
models.Index(fields=[
|
|
110
|
-
models.Index(fields=[
|
|
111
|
-
models.Index(fields=[
|
|
83
|
+
models.Index(fields=["video", "-created_at"]),
|
|
84
|
+
models.Index(fields=["task_id"]),
|
|
85
|
+
models.Index(fields=["status"]),
|
|
112
86
|
]
|
|
113
|
-
|
|
87
|
+
|
|
114
88
|
def __str__(self):
|
|
115
|
-
|
|
116
|
-
|
|
89
|
+
operation_display = getattr(self, "get_operation_display", None)
|
|
90
|
+
status_display = getattr(self, "get_status_display", None)
|
|
91
|
+
|
|
92
|
+
operation = operation_display() if callable(operation_display) else self.operation
|
|
93
|
+
status = status_display() if callable(status_display) else self.status
|
|
94
|
+
return f"{operation} on {self.video.uuid} - {status}"
|
|
95
|
+
|
|
117
96
|
def mark_running(self, save=True):
|
|
118
97
|
"""Mark operation as running."""
|
|
119
98
|
self.status = self.STATUS_RUNNING
|
|
120
99
|
if save:
|
|
121
|
-
self.save(update_fields=[
|
|
122
|
-
|
|
100
|
+
self.save(update_fields=["status"])
|
|
101
|
+
|
|
102
|
+
@staticmethod
|
|
103
|
+
def _normalize_output_path(path: str | Path | None) -> str:
|
|
104
|
+
"""Return a path relative to MEDIA_ROOT when possible."""
|
|
105
|
+
if not path:
|
|
106
|
+
return ""
|
|
107
|
+
|
|
108
|
+
raw_path = Path(path)
|
|
109
|
+
if not raw_path.is_absolute():
|
|
110
|
+
return raw_path.as_posix()
|
|
111
|
+
media_root = Path(settings.MEDIA_ROOT)
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
relative = raw_path.resolve().relative_to(media_root.resolve())
|
|
115
|
+
return relative.as_posix()
|
|
116
|
+
except (ValueError, RuntimeError):
|
|
117
|
+
logger.warning(
|
|
118
|
+
"Storing absolute output path '%s' because it is outside MEDIA_ROOT (%s).",
|
|
119
|
+
raw_path,
|
|
120
|
+
media_root,
|
|
121
|
+
)
|
|
122
|
+
return raw_path.as_posix()
|
|
123
|
+
|
|
123
124
|
def mark_success(self, output_file=None, details=None, save=True):
|
|
124
125
|
"""Mark operation as successful."""
|
|
125
126
|
self.status = self.STATUS_SUCCESS
|
|
126
127
|
self.completed_at = timezone.now()
|
|
127
128
|
if output_file:
|
|
128
|
-
self.output_file = output_file
|
|
129
|
+
self.output_file = self._normalize_output_path(output_file)
|
|
129
130
|
if details:
|
|
130
131
|
self.details = details
|
|
131
132
|
if save:
|
|
132
|
-
self.save(update_fields=[
|
|
133
|
-
|
|
133
|
+
self.save(update_fields=["status", "completed_at", "output_file", "details"])
|
|
134
|
+
|
|
134
135
|
def mark_failure(self, error_message, save=True):
|
|
135
136
|
"""Mark operation as failed."""
|
|
136
137
|
self.status = self.STATUS_FAILURE
|
|
137
138
|
self.completed_at = timezone.now()
|
|
138
139
|
self.details = error_message
|
|
139
140
|
if save:
|
|
140
|
-
self.save(update_fields=[
|
|
141
|
-
|
|
141
|
+
self.save(update_fields=["status", "completed_at", "details"])
|
|
142
|
+
|
|
142
143
|
@property
|
|
143
144
|
def duration(self):
|
|
144
145
|
"""Calculate operation duration if completed."""
|
|
145
146
|
if self.completed_at and self.created_at:
|
|
146
147
|
return (self.completed_at - self.created_at).total_seconds()
|
|
147
148
|
return None
|
|
148
|
-
|
|
149
|
+
|
|
149
150
|
@property
|
|
150
151
|
def is_complete(self) -> bool:
|
|
151
152
|
"""Check if operation is in a terminal state."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
not yet properly implemented
|
|
@@ -1,17 +1,27 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
1
3
|
from django.db import models
|
|
2
4
|
|
|
5
|
+
|
|
3
6
|
class ContraindicationManager(models.Manager):
|
|
4
7
|
def get_by_natural_key(self, name):
|
|
5
8
|
return self.get(name=name)
|
|
6
|
-
|
|
9
|
+
|
|
10
|
+
|
|
7
11
|
class Contraindication(models.Model):
|
|
8
12
|
name = models.CharField(max_length=100, unique=True)
|
|
9
13
|
description = models.TextField(blank=True, null=True)
|
|
10
14
|
|
|
11
15
|
objects = ContraindicationManager()
|
|
12
|
-
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from endoreg_db.models import FindingIntervention
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def contraindicating_finding_interventions(self) -> "models.manager.RelatedManager[FindingIntervention]": ...
|
|
22
|
+
|
|
13
23
|
def natural_key(self):
|
|
14
24
|
return (self.name,)
|
|
15
|
-
|
|
25
|
+
|
|
16
26
|
def __str__(self):
|
|
17
27
|
return str(self.name)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, List
|
|
2
|
+
|
|
1
3
|
from django.db import models
|
|
2
|
-
from typing import List, TYPE_CHECKING
|
|
3
4
|
|
|
4
5
|
if TYPE_CHECKING:
|
|
5
6
|
from .patient import PatientDisease
|
|
@@ -27,6 +28,7 @@ class Disease(models.Model):
|
|
|
27
28
|
|
|
28
29
|
Can define associated subcategories and numerical descriptors applicable to the disease itself.
|
|
29
30
|
"""
|
|
31
|
+
|
|
30
32
|
name = models.CharField(max_length=255, unique=True)
|
|
31
33
|
subcategories = models.JSONField(default=dict)
|
|
32
34
|
numerical_descriptors = models.JSONField(default=dict)
|
|
@@ -34,8 +36,12 @@ class Disease(models.Model):
|
|
|
34
36
|
objects = DiseaseManager()
|
|
35
37
|
|
|
36
38
|
if TYPE_CHECKING:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def disease_classifications(self) -> models.QuerySet["DiseaseClassification"]: ...
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def patient_diseases(self) -> models.QuerySet["PatientDisease"]: ...
|
|
39
45
|
|
|
40
46
|
def natural_key(self):
|
|
41
47
|
"""Returns the natural key (name) as a tuple."""
|
|
@@ -52,9 +58,7 @@ class Disease(models.Model):
|
|
|
52
58
|
Returns:
|
|
53
59
|
List[DiseaseClassification]: A list of related disease classification objects.
|
|
54
60
|
"""
|
|
55
|
-
classifications: List[DiseaseClassification] = [
|
|
56
|
-
_ for _ in self.disease_classifications.all()
|
|
57
|
-
]
|
|
61
|
+
classifications: List[DiseaseClassification] = [_ for _ in self.disease_classifications.all()]
|
|
58
62
|
return classifications
|
|
59
63
|
|
|
60
64
|
|
|
@@ -78,17 +82,18 @@ class DiseaseClassification(models.Model):
|
|
|
78
82
|
"""
|
|
79
83
|
Represents a classification system applicable to a specific disease (e.g., Forrest classification for ulcers).
|
|
80
84
|
"""
|
|
85
|
+
|
|
81
86
|
name = models.CharField(max_length=255, unique=True)
|
|
82
87
|
|
|
83
|
-
disease = models.ForeignKey(
|
|
84
|
-
Disease, on_delete=models.CASCADE, related_name="disease_classifications"
|
|
85
|
-
)
|
|
88
|
+
disease = models.ForeignKey(Disease, on_delete=models.CASCADE, related_name="disease_classifications")
|
|
86
89
|
|
|
87
90
|
objects = DiseaseClassificationManager()
|
|
88
91
|
|
|
89
92
|
if TYPE_CHECKING:
|
|
90
|
-
disease: "Disease"
|
|
91
|
-
|
|
93
|
+
disease: models.ForeignKey["Disease"]
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def disease_classification_choices(self) -> models.manager.RelatedManager["DiseaseClassificationChoice"]: ...
|
|
92
97
|
|
|
93
98
|
def natural_key(self):
|
|
94
99
|
"""Returns the natural key (name) as a tuple."""
|
|
@@ -105,9 +110,7 @@ class DiseaseClassification(models.Model):
|
|
|
105
110
|
Returns:
|
|
106
111
|
List[DiseaseClassificationChoice]: A list of related disease classification choices.
|
|
107
112
|
"""
|
|
108
|
-
choices: List[DiseaseClassificationChoice] = [
|
|
109
|
-
_ for _ in self.disease_classification_choices.all()
|
|
110
|
-
]
|
|
113
|
+
choices: List[DiseaseClassificationChoice] = [_ for _ in self.disease_classification_choices.all()]
|
|
111
114
|
return choices
|
|
112
115
|
|
|
113
116
|
|
|
@@ -133,6 +136,7 @@ class DiseaseClassificationChoice(models.Model):
|
|
|
133
136
|
"""
|
|
134
137
|
Represents a specific choice within a disease classification system (e.g., Forrest IIa).
|
|
135
138
|
"""
|
|
139
|
+
|
|
136
140
|
name = models.CharField(max_length=255, unique=True)
|
|
137
141
|
|
|
138
142
|
disease_classification = models.ForeignKey(
|
|
@@ -144,8 +148,10 @@ class DiseaseClassificationChoice(models.Model):
|
|
|
144
148
|
objects = DiseaseClassificationChoiceManager()
|
|
145
149
|
|
|
146
150
|
if TYPE_CHECKING:
|
|
147
|
-
disease_classification: "DiseaseClassification"
|
|
148
|
-
|
|
151
|
+
disease_classification: models.ForeignKey["DiseaseClassification"]
|
|
152
|
+
|
|
153
|
+
@property
|
|
154
|
+
def patient_diseases(self) -> models.manager.RelatedManager["PatientDisease"]: ...
|
|
149
155
|
|
|
150
156
|
def natural_key(self):
|
|
151
157
|
"""Returns the natural key (name) as a tuple."""
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, List
|
|
2
|
+
|
|
1
3
|
from django.db import models
|
|
2
|
-
from typing import List, TYPE_CHECKING
|
|
3
4
|
|
|
4
5
|
if TYPE_CHECKING:
|
|
5
6
|
from endoreg_db.models import PatientEvent
|
|
@@ -13,14 +14,14 @@ class EventManager(models.Manager):
|
|
|
13
14
|
def get_by_natural_key(self, name: str) -> "Event":
|
|
14
15
|
"""
|
|
15
16
|
Retrieves an Event instance using its natural key.
|
|
16
|
-
|
|
17
|
+
|
|
17
18
|
This method returns the event whose name matches the provided natural key.
|
|
18
|
-
It is primarily used to support Django's natural key serialization during
|
|
19
|
+
It is primarily used to support Django's natural key serialization during
|
|
19
20
|
data import/export and deserialization processes.
|
|
20
|
-
|
|
21
|
+
|
|
21
22
|
Args:
|
|
22
23
|
name: The unique event name serving as the natural key.
|
|
23
|
-
|
|
24
|
+
|
|
24
25
|
Returns:
|
|
25
26
|
The Event object corresponding to the given name.
|
|
26
27
|
"""
|
|
@@ -38,22 +39,19 @@ class Event(models.Model):
|
|
|
38
39
|
|
|
39
40
|
name = models.CharField(max_length=100, unique=True)
|
|
40
41
|
description = models.TextField(blank=True, null=True)
|
|
41
|
-
|
|
42
|
-
"EventClassification",
|
|
43
|
-
on_delete=models.CASCADE,
|
|
44
|
-
related_name="events",
|
|
45
|
-
null=True,
|
|
46
|
-
blank=True,
|
|
47
|
-
)
|
|
42
|
+
|
|
48
43
|
objects = EventManager()
|
|
49
44
|
|
|
50
45
|
if TYPE_CHECKING:
|
|
51
|
-
patient_events: models.
|
|
46
|
+
patient_events: models.ForeignKey["PatientEvent"]
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def event_classifications(self) -> models.QuerySet["EventClassification"]: ...
|
|
52
50
|
|
|
53
51
|
def natural_key(self):
|
|
54
52
|
"""
|
|
55
53
|
Returns a tuple representing the natural key for this instance.
|
|
56
|
-
|
|
54
|
+
|
|
57
55
|
The natural key consists of the instance's unique name.
|
|
58
56
|
"""
|
|
59
57
|
return (self.name,)
|
|
@@ -61,7 +59,7 @@ class Event(models.Model):
|
|
|
61
59
|
def __str__(self):
|
|
62
60
|
"""
|
|
63
61
|
Return a string representation of the instance's name.
|
|
64
|
-
|
|
62
|
+
|
|
65
63
|
This method converts the 'name' attribute to a string, providing a human-readable
|
|
66
64
|
representation of the model instance.
|
|
67
65
|
"""
|
|
@@ -85,6 +83,18 @@ class EventClassification(models.Model):
|
|
|
85
83
|
|
|
86
84
|
objects = EventClassificationManager()
|
|
87
85
|
|
|
86
|
+
event = models.ForeignKey(
|
|
87
|
+
Event,
|
|
88
|
+
on_delete=models.CASCADE,
|
|
89
|
+
related_name="event_classifications",
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
if TYPE_CHECKING:
|
|
93
|
+
event: models.ForeignKey["Event"]
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def event_classification_choices(self) -> models.QuerySet["EventClassificationChoice"]: ...
|
|
97
|
+
|
|
88
98
|
def natural_key(self):
|
|
89
99
|
"""Returns the natural key (name) as a tuple."""
|
|
90
100
|
return (self.name,)
|
|
@@ -95,9 +105,7 @@ class EventClassification(models.Model):
|
|
|
95
105
|
|
|
96
106
|
def get_choices(self) -> List["EventClassificationChoice"]:
|
|
97
107
|
"""Retrieves all choices associated with this classification."""
|
|
98
|
-
choices: List[EventClassificationChoice] = [
|
|
99
|
-
_ for _ in self.event_classification_choices.all()
|
|
100
|
-
]
|
|
108
|
+
choices: List[EventClassificationChoice] = [_ for _ in self.event_classification_choices.all()]
|
|
101
109
|
return choices
|
|
102
110
|
|
|
103
111
|
|
|
@@ -128,6 +136,11 @@ class EventClassificationChoice(models.Model):
|
|
|
128
136
|
|
|
129
137
|
objects = EventClassificationChoiceManager()
|
|
130
138
|
|
|
139
|
+
@property
|
|
140
|
+
def event(self):
|
|
141
|
+
"""Returns the associated Event instance."""
|
|
142
|
+
return self.event_classification.event
|
|
143
|
+
|
|
131
144
|
def natural_key(self):
|
|
132
145
|
"""Returns the natural key (name) as a tuple."""
|
|
133
146
|
return (self.name,)
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
from .examination import Examination, ExaminationRequirementSet
|
|
2
|
-
from .
|
|
2
|
+
from .examination_indication import ExaminationIndication, ExaminationIndicationClassification, ExaminationIndicationClassificationChoice
|
|
3
3
|
from .examination_time import ExaminationTime
|
|
4
4
|
from .examination_time_type import ExaminationTimeType
|
|
5
|
-
from .
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
from .examination_type import ExaminationType
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"Examination",
|
|
9
|
+
"ExaminationRequirementSet",
|
|
10
|
+
"ExaminationType",
|
|
11
|
+
"ExaminationTime",
|
|
12
|
+
"ExaminationTimeType",
|
|
13
|
+
"ExaminationIndication",
|
|
14
|
+
"ExaminationIndicationClassification",
|
|
15
|
+
"ExaminationIndicationClassificationChoice",
|
|
16
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, List, cast
|
|
2
|
+
|
|
1
3
|
from django.db import models
|
|
2
|
-
from typing import List
|
|
3
|
-
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
5
|
if TYPE_CHECKING:
|
|
6
6
|
from endoreg_db.models import Finding
|
|
@@ -28,24 +28,43 @@ class Examination(models.Model):
|
|
|
28
28
|
name = models.CharField(max_length=100, unique=True)
|
|
29
29
|
examination_types = models.ManyToManyField("ExaminationType", blank=True)
|
|
30
30
|
description = models.TextField(blank=True, null=True)
|
|
31
|
+
indications = models.ManyToManyField(
|
|
32
|
+
"ExaminationIndication",
|
|
33
|
+
related_name="examinations",
|
|
34
|
+
blank=True,
|
|
35
|
+
)
|
|
36
|
+
examination_times = models.ManyToManyField(
|
|
37
|
+
"ExaminationTime",
|
|
38
|
+
related_name="examinations",
|
|
39
|
+
blank=True,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
findings = models.ManyToManyField(
|
|
43
|
+
"Finding",
|
|
44
|
+
blank=True,
|
|
45
|
+
related_name="examinations",
|
|
46
|
+
)
|
|
47
|
+
information_sources = models.ManyToManyField(
|
|
48
|
+
"InformationSource",
|
|
49
|
+
related_name="examinations",
|
|
50
|
+
blank=True,
|
|
51
|
+
)
|
|
31
52
|
|
|
32
53
|
objects = ExaminationManager()
|
|
33
54
|
|
|
34
55
|
if TYPE_CHECKING:
|
|
35
|
-
from endoreg_db.models import ExaminationIndication, Finding, FindingClassification
|
|
36
|
-
|
|
37
|
-
indications
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
# # Requirement sets associated with the examination.
|
|
42
|
-
# requirement_sets = models.ManyToManyField(
|
|
43
|
-
# "RequirementSet",
|
|
44
|
-
# through="ExaminationRequirementSet",
|
|
45
|
-
# related_name="examinations",
|
|
46
|
-
# blank=True,
|
|
47
|
-
# )
|
|
56
|
+
from endoreg_db.models import ExaminationIndication, ExaminationTime, Finding, FindingClassification, InformationSource
|
|
57
|
+
|
|
58
|
+
indications = cast("models.manager.RelatedManager[ExaminationIndication]", indications)
|
|
59
|
+
examination_times = cast("models.manager.RelatedManager[ExaminationTime]", examination_times)
|
|
60
|
+
findings = cast("models.manager.RelatedManager[Finding]", findings)
|
|
61
|
+
information_sources = cast("models.manager.RelatedManager[InformationSource]", information_sources)
|
|
48
62
|
|
|
63
|
+
@property
|
|
64
|
+
def finding_classifications(self) -> "models.manager.RelatedManager[FindingClassification]": ...
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def exam_reqset_links(self) -> "models.manager.RelatedManager[ExaminationRequirementSet]": ...
|
|
49
68
|
|
|
50
69
|
@property
|
|
51
70
|
def links(self) -> "RequirementLinks":
|
|
@@ -61,7 +80,7 @@ class Examination(models.Model):
|
|
|
61
80
|
examinations=[self],
|
|
62
81
|
findings=list(self.findings.all()),
|
|
63
82
|
finding_classifications=list(self.finding_classifications.all()),
|
|
64
|
-
examination_indications=list(self.indications.all())
|
|
83
|
+
examination_indications=list(self.indications.all()),
|
|
65
84
|
)
|
|
66
85
|
|
|
67
86
|
def __str__(self) -> str:
|
|
@@ -108,12 +127,13 @@ class ExaminationRequirementSetManager(models.Manager):
|
|
|
108
127
|
def get_by_natural_key(self, name: str) -> "ExaminationRequirementSet":
|
|
109
128
|
return self.get(name=name)
|
|
110
129
|
|
|
111
|
-
|
|
130
|
+
|
|
112
131
|
class ExaminationRequirementSet(models.Model):
|
|
113
132
|
"""
|
|
114
133
|
Through table for Examination ↔ RequirementSet link.
|
|
115
134
|
Lets you store per-link metadata (order, default, etc.)
|
|
116
135
|
"""
|
|
136
|
+
|
|
117
137
|
examinations = models.ManyToManyField(
|
|
118
138
|
"Examination",
|
|
119
139
|
related_name="exam_reqset_links",
|
|
@@ -126,7 +146,7 @@ class ExaminationRequirementSet(models.Model):
|
|
|
126
146
|
# )
|
|
127
147
|
# Optional metadata
|
|
128
148
|
enabled_by_default = models.BooleanField(default=False)
|
|
129
|
-
|
|
149
|
+
|
|
130
150
|
name = models.CharField(max_length=100, unique=True)
|
|
131
151
|
|
|
132
152
|
objects = ExaminationRequirementSetManager()
|
|
@@ -136,7 +156,7 @@ class ExaminationRequirementSet(models.Model):
|
|
|
136
156
|
|
|
137
157
|
# def __str__(self) -> str:
|
|
138
158
|
# return f"{self.examination} ↔ {self.requirement_set} (prio={self.priority})"
|
|
139
|
-
|
|
159
|
+
|
|
140
160
|
def natural_key(self) -> tuple:
|
|
141
161
|
"""
|
|
142
162
|
Returns the natural key for the ExaminationRequirementSet.
|
|
@@ -145,4 +165,3 @@ class ExaminationRequirementSet(models.Model):
|
|
|
145
165
|
tuple: The natural key consisting of the name.
|
|
146
166
|
"""
|
|
147
167
|
return (self.name,)
|
|
148
|
-
|