endoreg-db 0.6.4__py3-none-any.whl → 0.8.2__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/admin.py +26 -26
- endoreg_db/api_urls.py +4 -0
- endoreg_db/apps.py +12 -0
- endoreg_db/assets/dummy_model.ckpt +1 -0
- endoreg_db/codemods/readme.md +88 -0
- endoreg_db/codemods/rename_datetime_fields.py +92 -0
- endoreg_db/config/env.py +101 -0
- endoreg_db/data/__init__.py +12 -0
- endoreg_db/data/ai_model/data.yaml +1 -1
- endoreg_db/data/ai_model_label/label/polyp_classification.yaml +52 -0
- endoreg_db/data/ai_model_label/label-set/data.yaml +20 -1
- endoreg_db/data/ai_model_label/label-set/polyp_classifications.yaml +25 -0
- endoreg_db/data/center/data.yaml +13 -12
- endoreg_db/data/center_shift/ukw.yaml +9 -0
- endoreg_db/data/db_summary.csv +58 -0
- endoreg_db/data/db_summary.xlsx +0 -0
- endoreg_db/data/disease/misc.yaml +1 -2
- endoreg_db/data/endoscopy_processor/data.yaml +3 -0
- endoreg_db/data/event/cardiology.yaml +0 -13
- endoreg_db/data/examination/examinations/data.yaml +14 -9
- endoreg_db/data/examination_indication/endoscopy.yaml +30 -30
- endoreg_db/data/examination_indication_classification/endoscopy.yaml +11 -11
- endoreg_db/data/examination_requirement_set/colonoscopy.yaml +15 -0
- endoreg_db/data/finding/anatomy_colon.yaml +128 -0
- endoreg_db/data/finding/colonoscopy.yaml +40 -0
- endoreg_db/data/finding/colonoscopy_bowel_prep.yaml +56 -0
- endoreg_db/data/finding/complication.yaml +16 -0
- endoreg_db/data/finding/data.yaml +3 -46
- endoreg_db/data/finding/examination_setting.yaml +16 -0
- endoreg_db/data/finding/medication_related.yaml +18 -0
- endoreg_db/data/finding/outcome.yaml +12 -0
- endoreg_db/data/finding_classification/colonoscopy_bowel_preparation.yaml +95 -0
- endoreg_db/data/finding_classification/colonoscopy_jnet.yaml +22 -0
- endoreg_db/data/finding_classification/colonoscopy_kudo.yaml +25 -0
- endoreg_db/data/finding_classification/colonoscopy_lesion_circularity.yaml +20 -0
- endoreg_db/data/finding_classification/colonoscopy_lesion_planarity.yaml +24 -0
- endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +68 -0
- endoreg_db/data/finding_classification/colonoscopy_lesion_surface.yaml +20 -0
- endoreg_db/data/finding_classification/colonoscopy_location.yaml +80 -0
- endoreg_db/data/finding_classification/colonoscopy_lst.yaml +21 -0
- endoreg_db/data/finding_classification/colonoscopy_nice.yaml +20 -0
- endoreg_db/data/finding_classification/colonoscopy_paris.yaml +26 -0
- endoreg_db/data/finding_classification/colonoscopy_sano.yaml +22 -0
- endoreg_db/data/finding_classification/colonoscopy_summary.yaml +53 -0
- endoreg_db/data/finding_classification/complication_generic.yaml +25 -0
- endoreg_db/data/finding_classification/examination_setting_generic.yaml +40 -0
- endoreg_db/data/finding_classification/histology_colo.yaml +51 -0
- endoreg_db/data/finding_classification/intervention_required.yaml +26 -0
- endoreg_db/data/finding_classification/medication_related.yaml +23 -0
- endoreg_db/data/finding_classification/visualized.yaml +33 -0
- endoreg_db/data/finding_classification_choice/bowel_preparation.yaml +78 -0
- endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_circularity_default.yaml +0 -2
- endoreg_db/data/finding_classification_choice/colon_lesion_jnet.yaml +15 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_kudo.yaml +23 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_lst.yaml +15 -0
- endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_nice.yaml +4 -7
- endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_paris.yaml +0 -8
- endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_planarity_default.yaml +6 -13
- endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +14 -0
- endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_surface_intact_default.yaml +3 -6
- endoreg_db/data/{finding_location_classification_choice/colonoscopy.yaml → finding_classification_choice/colonoscopy_location.yaml} +11 -22
- endoreg_db/data/finding_classification_choice/colonoscopy_not_complete_reason.yaml +19 -0
- endoreg_db/data/finding_classification_choice/colonoscopy_size.yaml +82 -0
- endoreg_db/data/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +15 -0
- endoreg_db/data/finding_classification_choice/complication_generic_types.yaml +15 -0
- endoreg_db/data/finding_classification_choice/examination_setting_generic_types.yaml +15 -0
- endoreg_db/data/finding_classification_choice/histology.yaml +24 -0
- endoreg_db/data/finding_classification_choice/histology_polyp.yaml +20 -0
- endoreg_db/data/finding_classification_choice/outcome.yaml +19 -0
- endoreg_db/data/finding_classification_choice/yes_no_na.yaml +11 -0
- endoreg_db/data/finding_classification_type/colonoscopy_basic.yaml +48 -0
- endoreg_db/data/finding_intervention/endoscopy_colonoscopy.yaml +8 -3
- endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +6 -6
- endoreg_db/data/finding_type/data.yaml +23 -10
- endoreg_db/data/gender/data.yaml +8 -1
- endoreg_db/data/information_source/annotation.yaml +6 -0
- endoreg_db/data/information_source/prediction.yaml +7 -0
- endoreg_db/data/information_source_type/data.yaml +8 -0
- endoreg_db/data/lab_value/misc.yaml +43 -0
- endoreg_db/data/medication/anticoagulation.yaml +5 -5
- endoreg_db/data/medication/tah.yaml +5 -5
- endoreg_db/data/medication_intake_time/base.yaml +4 -4
- endoreg_db/data/names_first/first_names.yaml +3 -0
- endoreg_db/data/pdf_type/data.yaml +26 -2
- endoreg_db/data/qualification/endoscopy.yaml +36 -0
- endoreg_db/data/qualification/m2.yaml +39 -0
- endoreg_db/data/qualification/outpatient_clinic.yaml +35 -0
- endoreg_db/data/qualification/sonography.yaml +36 -0
- endoreg_db/data/qualification_type/base.yaml +29 -0
- endoreg_db/data/report_reader_flag/rkh-histology-generic.yaml +10 -0
- endoreg_db/data/report_reader_flag/ukw-histology-generic.yaml +5 -0
- endoreg_db/data/requirement/age.yaml +26 -0
- endoreg_db/data/requirement/colonoscopy_baseline_austria.yaml +45 -0
- endoreg_db/data/requirement/disease_cardiovascular.yaml +6 -6
- endoreg_db/data/requirement/disease_classification_choice_cardiovascular.yaml +9 -6
- endoreg_db/data/requirement/disease_hepatology.yaml +1 -1
- endoreg_db/data/requirement/disease_misc.yaml +3 -3
- endoreg_db/data/requirement/disease_renal.yaml +18 -2
- endoreg_db/data/requirement/{colonoscopy_indications.yaml → endoscopy_bleeding_risk.yaml} +6 -3
- endoreg_db/data/requirement/event_cardiology.yaml +17 -17
- endoreg_db/data/requirement/event_requirements.yaml +145 -0
- endoreg_db/data/requirement/finding_colon_polyp.yaml +50 -0
- endoreg_db/data/requirement/gender.yaml +25 -0
- endoreg_db/data/requirement/lab_value.yaml +352 -31
- endoreg_db/data/requirement/medication.yaml +93 -0
- endoreg_db/data/requirement_operator/age.yaml +13 -0
- endoreg_db/data/requirement_operator/lab_operators.yaml +36 -35
- endoreg_db/data/requirement_operator/model_operators.yaml +13 -7
- endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +48 -0
- endoreg_db/data/requirement_set/colonoscopy_austria_screening.yaml +57 -0
- endoreg_db/data/requirement_set/endoscopy_bleeding_risk.yaml +42 -2
- endoreg_db/data/requirement_type/requirement_types.yaml +82 -0
- endoreg_db/data/shift/endoscopy.yaml +21 -0
- endoreg_db/data/shift_type/base.yaml +35 -0
- endoreg_db/data/tag/requirement_set_tags.yaml +11 -0
- endoreg_db/data/unit/concentration.yaml +23 -0
- endoreg_db/exceptions.py +19 -0
- endoreg_db/forms/patient_finding_intervention_form.py +4 -5
- endoreg_db/forms/patient_form.py +7 -6
- endoreg_db/forms/questionnaires/__init__.py +1 -1
- endoreg_db/forms/questionnaires/tto_questionnaire.py +19 -19
- endoreg_db/helpers/count_db.py +45 -0
- endoreg_db/helpers/data_loader.py +208 -0
- endoreg_db/helpers/default_objects.py +359 -0
- endoreg_db/helpers/download_segmentation_model.py +31 -0
- endoreg_db/helpers/interact.py +6 -0
- endoreg_db/helpers/test_video_helper.py +119 -0
- endoreg_db/logger_conf.py +140 -0
- endoreg_db/management/__init__.py +1 -0
- endoreg_db/management/commands/__init__.py +1 -0
- endoreg_db/management/commands/anonymize_video.py +0 -0
- endoreg_db/management/commands/check_auth.py +125 -0
- endoreg_db/management/commands/create_multilabel_model_meta.py +214 -0
- endoreg_db/management/commands/fix_missing_patient_data.py +172 -0
- endoreg_db/management/commands/fix_video_paths.py +165 -0
- endoreg_db/management/commands/import_fallback_video.py +203 -0
- endoreg_db/management/commands/import_report.py +298 -0
- endoreg_db/management/commands/import_video.py +422 -0
- endoreg_db/management/commands/import_video_with_classification.py +367 -0
- endoreg_db/management/commands/init_default_ai_model.py +112 -0
- endoreg_db/management/commands/load_ai_model_data.py +2 -7
- endoreg_db/management/commands/load_base_db_data.py +1 -0
- endoreg_db/management/commands/load_endoscope_data.py +2 -2
- endoreg_db/management/commands/load_examination_indication_data.py +2 -3
- endoreg_db/management/commands/load_finding_data.py +49 -92
- endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +0 -1
- endoreg_db/management/commands/load_information_source.py +13 -7
- endoreg_db/management/commands/load_name_data.py +37 -0
- endoreg_db/management/commands/load_qualification_data.py +59 -0
- endoreg_db/management/commands/load_requirement_data.py +30 -6
- endoreg_db/management/commands/load_shift_data.py +60 -0
- endoreg_db/management/commands/load_tag_data.py +57 -0
- endoreg_db/management/commands/register_ai_model.py +1 -1
- endoreg_db/management/commands/start_filewatcher.py +106 -0
- endoreg_db/management/commands/storage_management.py +548 -0
- endoreg_db/management/commands/summarize_db_content.py +189 -0
- endoreg_db/management/commands/validate_video.py +204 -0
- endoreg_db/management/commands/validate_video_files.py +161 -0
- endoreg_db/management/commands/video_validation.py +22 -0
- endoreg_db/migrations/0001_initial.py +625 -813
- endoreg_db/migrations/0002_add_video_correction_models.py +52 -0
- endoreg_db/models/__init__.py +270 -307
- endoreg_db/models/administration/__init__.py +116 -0
- endoreg_db/models/{ai_model → administration/ai}/__init__.py +6 -1
- endoreg_db/models/administration/ai/active_model.py +35 -0
- endoreg_db/models/administration/ai/ai_model.py +156 -0
- endoreg_db/models/{ai_model → administration/ai}/model_type.py +6 -1
- endoreg_db/models/administration/case/__init__.py +19 -0
- endoreg_db/models/administration/case/case.py +114 -0
- endoreg_db/models/{case_template → administration/case/case_template}/case_template.py +3 -3
- endoreg_db/models/{case_template → administration/case/case_template}/case_template_rule.py +3 -10
- endoreg_db/models/{case_template → administration/case/case_template}/case_template_rule_value.py +2 -4
- endoreg_db/models/{case_template → administration/case/case_template}/case_template_type.py +1 -3
- endoreg_db/models/{center → administration/center}/__init__.py +3 -1
- endoreg_db/models/administration/center/center.py +61 -0
- endoreg_db/models/administration/center/center_product.py +64 -0
- endoreg_db/models/{center → administration/center}/center_resource.py +19 -3
- endoreg_db/models/administration/center/center_shift.py +88 -0
- endoreg_db/models/administration/center/center_waste.py +30 -0
- endoreg_db/models/administration/permissions/__init__.py +44 -0
- endoreg_db/models/administration/person/__init__.py +24 -0
- endoreg_db/models/administration/person/employee/__init__.py +3 -0
- endoreg_db/models/administration/person/employee/employee.py +35 -0
- endoreg_db/models/administration/person/employee/employee_qualification.py +39 -0
- endoreg_db/models/administration/person/employee/employee_type.py +42 -0
- endoreg_db/models/administration/person/examiner/__init__.py +4 -0
- endoreg_db/models/administration/person/examiner/examiner.py +54 -0
- endoreg_db/models/administration/person/names/__init__.py +0 -0
- endoreg_db/models/{persons → administration/person/names}/first_name.py +1 -1
- endoreg_db/models/{persons → administration/person/names}/last_name.py +2 -3
- endoreg_db/models/administration/person/patient/__init__.py +5 -0
- endoreg_db/models/administration/person/patient/patient.py +460 -0
- endoreg_db/models/administration/person/profession/__init__.py +24 -0
- endoreg_db/models/administration/person/user/__init__.py +5 -0
- endoreg_db/models/administration/person/user/portal_user_information.py +37 -0
- endoreg_db/models/administration/product/product.py +97 -0
- endoreg_db/models/administration/product/product_group.py +39 -0
- endoreg_db/models/administration/product/product_material.py +54 -0
- endoreg_db/models/{product → administration/product}/product_weight.py +9 -0
- endoreg_db/models/{product → administration/product}/reference_product.py +26 -11
- endoreg_db/models/administration/qualification/__init__.py +7 -0
- endoreg_db/models/administration/qualification/qualification.py +37 -0
- endoreg_db/models/administration/qualification/qualification_type.py +35 -0
- endoreg_db/models/administration/shift/__init__.py +9 -0
- endoreg_db/models/administration/shift/scheduled_days.py +69 -0
- endoreg_db/models/administration/shift/shift.py +51 -0
- endoreg_db/models/administration/shift/shift_type.py +108 -0
- endoreg_db/models/label/__init__.py +24 -1
- endoreg_db/models/label/annotation/__init__.py +12 -0
- endoreg_db/models/label/annotation/image_classification.py +84 -0
- endoreg_db/models/label/annotation/video_segmentation_annotation.py +66 -0
- endoreg_db/models/label/label.py +45 -74
- endoreg_db/models/label/label_set.py +53 -0
- endoreg_db/models/label/label_type.py +29 -0
- endoreg_db/models/label/label_video_segment/__init__.py +3 -0
- endoreg_db/models/label/label_video_segment/_create_from_video.py +41 -0
- endoreg_db/models/label/label_video_segment/label_video_segment.py +511 -0
- endoreg_db/models/label/video_segmentation_label.py +31 -0
- endoreg_db/models/{annotation → label}/video_segmentation_labelset.py +7 -0
- endoreg_db/models/media/__init__.py +14 -0
- endoreg_db/models/media/frame/__init__.py +3 -0
- endoreg_db/models/media/frame/frame.py +111 -0
- endoreg_db/models/media/pdf/__init__.py +11 -0
- endoreg_db/models/media/pdf/raw_pdf.py +608 -0
- endoreg_db/models/media/pdf/report_file.py +162 -0
- endoreg_db/models/media/pdf/report_reader/report_reader_config.py +77 -0
- endoreg_db/models/media/video/__init__.py +4 -0
- endoreg_db/models/media/video/create_from_file.py +336 -0
- endoreg_db/models/media/video/pipe_1.py +207 -0
- endoreg_db/models/media/video/pipe_2.py +105 -0
- endoreg_db/models/media/video/refactor_plan.md +0 -0
- endoreg_db/models/media/video/video_file.py +680 -0
- endoreg_db/models/media/video/video_file_ai.py +443 -0
- endoreg_db/models/media/video/video_file_anonymize.py +348 -0
- endoreg_db/models/media/video/video_file_frames/__init__.py +47 -0
- endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +22 -0
- endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +23 -0
- endoreg_db/models/media/video/video_file_frames/_delete_frames.py +104 -0
- endoreg_db/models/media/video/video_file_frames/_extract_frames.py +174 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame.py +28 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +27 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +20 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +27 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +34 -0
- endoreg_db/models/media/video/video_file_frames/_get_frames.py +27 -0
- endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +129 -0
- endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +129 -0
- endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +65 -0
- endoreg_db/models/media/video/video_file_frames.py +0 -0
- endoreg_db/models/media/video/video_file_io.py +166 -0
- endoreg_db/models/media/video/video_file_meta/__init__.py +22 -0
- endoreg_db/models/media/video/video_file_meta/get_crop_template.py +45 -0
- endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +39 -0
- endoreg_db/models/media/video/video_file_meta/get_fps.py +147 -0
- endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +143 -0
- endoreg_db/models/media/video/video_file_meta/text_meta.py +134 -0
- endoreg_db/models/media/video/video_file_meta/video_meta.py +70 -0
- endoreg_db/models/media/video/video_file_meta.py +11 -0
- endoreg_db/models/media/video/video_file_segments.py +209 -0
- endoreg_db/models/medical/__init__.py +146 -0
- endoreg_db/models/{contraindication → medical/contraindication}/__init__.py +1 -5
- endoreg_db/models/{disease.py → medical/disease.py} +60 -52
- endoreg_db/models/{event.py → medical/event.py} +31 -54
- endoreg_db/models/{examination → medical/examination}/__init__.py +1 -1
- endoreg_db/models/medical/examination/examination.py +148 -0
- endoreg_db/models/{examination → medical/examination}/examination_indication.py +64 -35
- endoreg_db/models/{examination → medical/examination}/examination_time.py +0 -4
- endoreg_db/models/{examination → medical/examination}/examination_time_type.py +1 -8
- endoreg_db/models/{examination → medical/examination}/examination_type.py +1 -7
- endoreg_db/models/medical/finding/__init__.py +18 -0
- endoreg_db/models/medical/finding/finding.py +96 -0
- endoreg_db/models/medical/finding/finding_classification.py +142 -0
- endoreg_db/models/{finding → medical/finding}/finding_intervention.py +2 -10
- endoreg_db/models/medical/finding/finding_type.py +35 -0
- endoreg_db/models/medical/hardware/__init__.py +8 -0
- endoreg_db/models/{hardware → medical/hardware}/endoscope.py +28 -23
- endoreg_db/models/medical/laboratory/__init__.py +5 -0
- endoreg_db/models/medical/laboratory/lab_value.py +419 -0
- endoreg_db/models/{medication → medical/medication}/medication.py +1 -3
- endoreg_db/models/{medication → medical/medication}/medication_indication_type.py +8 -3
- endoreg_db/models/{medication → medical/medication}/medication_intake_time.py +21 -3
- endoreg_db/models/{medication → medical/medication}/medication_schedule.py +13 -5
- endoreg_db/models/{organ → medical/organ}/__init__.py +3 -6
- endoreg_db/models/medical/patient/__init__.py +56 -0
- endoreg_db/models/medical/patient/medication_examples.py +38 -0
- endoreg_db/models/medical/patient/patient_disease.py +63 -0
- endoreg_db/models/medical/patient/patient_event.py +75 -0
- endoreg_db/models/medical/patient/patient_examination.py +249 -0
- endoreg_db/models/{persons → medical}/patient/patient_examination_indication.py +21 -9
- endoreg_db/models/medical/patient/patient_finding.py +357 -0
- endoreg_db/models/medical/patient/patient_finding_classification.py +207 -0
- endoreg_db/models/{patient → medical/patient}/patient_finding_intervention.py +15 -1
- endoreg_db/models/medical/patient/patient_lab_sample.py +148 -0
- endoreg_db/models/{persons → medical}/patient/patient_lab_value.py +40 -15
- endoreg_db/models/medical/patient/patient_medication.py +104 -0
- endoreg_db/models/medical/patient/patient_medication_schedule.py +136 -0
- endoreg_db/models/{risk → medical/risk}/risk_type.py +0 -4
- endoreg_db/models/{data_file/metadata → metadata}/__init__.py +6 -0
- endoreg_db/models/metadata/frame_ocr_result.py +0 -0
- endoreg_db/models/metadata/model_meta.py +193 -0
- endoreg_db/models/metadata/model_meta_logic.py +236 -0
- endoreg_db/models/{data_file/metadata → metadata}/pdf_meta.py +28 -13
- endoreg_db/models/metadata/sensitive_meta.py +288 -0
- endoreg_db/models/metadata/sensitive_meta_logic.py +643 -0
- endoreg_db/models/metadata/video_meta.py +332 -0
- endoreg_db/models/metadata/video_prediction_logic.py +190 -0
- endoreg_db/models/metadata/video_prediction_meta.py +270 -0
- endoreg_db/models/other/__init__.py +17 -0
- endoreg_db/models/other/distribution/date_value_distribution.py +0 -2
- endoreg_db/models/other/distribution/numeric_value_distribution.py +30 -2
- endoreg_db/models/{emission → other/emission}/emission_factor.py +15 -6
- endoreg_db/models/{persons → other}/gender.py +8 -3
- endoreg_db/models/other/information_source.py +159 -0
- endoreg_db/models/other/material.py +10 -2
- endoreg_db/models/other/resource.py +6 -2
- endoreg_db/models/other/tag.py +27 -0
- endoreg_db/models/other/transport_route.py +13 -2
- endoreg_db/models/{unit.py → other/unit.py} +16 -6
- endoreg_db/models/other/waste.py +10 -3
- endoreg_db/models/requirement/requirement.py +556 -114
- endoreg_db/models/requirement/requirement_evaluation/__init__.py +4 -132
- endoreg_db/models/requirement/requirement_evaluation/get_values.py +40 -0
- endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +9 -0
- endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +80 -87
- endoreg_db/models/requirement/requirement_operator.py +132 -14
- endoreg_db/models/requirement/requirement_set.py +181 -21
- endoreg_db/models/rule/__init__.py +13 -0
- endoreg_db/models/{rules → rule}/rule.py +6 -3
- endoreg_db/models/{rules → rule}/rule_attribute_dtype.py +0 -2
- endoreg_db/models/{rules → rule}/rule_type.py +0 -2
- endoreg_db/models/{rules → rule}/ruleset.py +0 -2
- endoreg_db/models/state/__init__.py +12 -0
- endoreg_db/models/state/abstract.py +11 -0
- endoreg_db/models/state/audit_ledger.py +150 -0
- endoreg_db/models/state/label_video_segment.py +22 -0
- endoreg_db/models/state/raw_pdf.py +187 -0
- endoreg_db/models/state/sensitive_meta.py +46 -0
- endoreg_db/models/state/video.py +232 -0
- endoreg_db/models/upload_job.py +99 -0
- endoreg_db/models/utils.py +135 -0
- endoreg_db/models/video_metadata.py +66 -0
- endoreg_db/models/video_processing.py +153 -0
- endoreg_db/renames.yml +8 -0
- endoreg_db/root_urls.py +9 -0
- endoreg_db/schemas/__init__.py +0 -0
- endoreg_db/schemas/examination_evaluation.py +27 -0
- endoreg_db/serializers/Frames_NICE_and_PARIS_classifications.py +775 -0
- endoreg_db/serializers/__init__.py +147 -10
- endoreg_db/serializers/{raw_pdf_meta_validation.py → _old/raw_pdf_meta_validation.py} +3 -3
- endoreg_db/serializers/{raw_video_meta_validation.py → _old/raw_video_meta_validation.py} +18 -14
- endoreg_db/serializers/_old/video.py +71 -0
- endoreg_db/serializers/administration/__init__.py +14 -0
- endoreg_db/serializers/administration/ai/__init__.py +10 -0
- endoreg_db/serializers/administration/ai/active_model.py +10 -0
- endoreg_db/serializers/administration/ai/ai_model.py +18 -0
- endoreg_db/serializers/administration/ai/model_type.py +10 -0
- endoreg_db/serializers/administration/center.py +9 -0
- endoreg_db/serializers/administration/gender.py +9 -0
- endoreg_db/serializers/anonymization.py +69 -0
- endoreg_db/serializers/evaluation/examination_evaluation.py +1 -0
- endoreg_db/serializers/examination/__init__.py +10 -0
- endoreg_db/serializers/examination/base.py +46 -0
- endoreg_db/serializers/examination/dropdown.py +21 -0
- endoreg_db/serializers/examination_serializer.py +12 -0
- endoreg_db/serializers/finding/__init__.py +5 -0
- endoreg_db/serializers/finding/finding.py +54 -0
- endoreg_db/serializers/finding_classification/__init__.py +7 -0
- endoreg_db/serializers/finding_classification/choice.py +19 -0
- endoreg_db/serializers/finding_classification/classification.py +13 -0
- endoreg_db/serializers/label/__init__.py +7 -0
- endoreg_db/serializers/label/image_classification_annotation.py +62 -0
- endoreg_db/serializers/label/label.py +15 -0
- endoreg_db/serializers/label_video_segment/__init__.py +7 -0
- endoreg_db/serializers/label_video_segment/_lvs_create.py +149 -0
- endoreg_db/serializers/label_video_segment/_lvs_update.py +138 -0
- endoreg_db/serializers/label_video_segment/_lvs_validate.py +149 -0
- endoreg_db/serializers/label_video_segment/label_video_segment.py +344 -0
- endoreg_db/serializers/label_video_segment/label_video_segment_annotation.py +99 -0
- endoreg_db/serializers/label_video_segment/label_video_segment_update.py +163 -0
- endoreg_db/serializers/meta/__init__.py +19 -0
- endoreg_db/serializers/meta/pdf_file_meta_extraction.py +115 -0
- endoreg_db/serializers/meta/report_meta.py +53 -0
- endoreg_db/serializers/meta/sensitive_meta_detail.py +162 -0
- endoreg_db/serializers/meta/sensitive_meta_update.py +148 -0
- endoreg_db/serializers/meta/sensitive_meta_verification.py +59 -0
- endoreg_db/serializers/meta/video_meta.py +39 -0
- endoreg_db/serializers/misc/__init__.py +14 -0
- endoreg_db/serializers/misc/file_overview.py +152 -0
- endoreg_db/serializers/misc/stats.py +33 -0
- endoreg_db/serializers/misc/translatable_field_mix_in.py +44 -0
- endoreg_db/serializers/misc/upload_job.py +71 -0
- endoreg_db/serializers/misc/vop_patient_data.py +120 -0
- endoreg_db/serializers/patient/__init__.py +11 -0
- endoreg_db/serializers/patient/patient.py +86 -0
- endoreg_db/serializers/patient/patient_dropdown.py +27 -0
- endoreg_db/serializers/patient_examination/__init__.py +7 -0
- endoreg_db/serializers/patient_examination/patient_examination.py +141 -0
- endoreg_db/serializers/patient_finding/__init__.py +15 -0
- endoreg_db/serializers/patient_finding/patient_finding.py +31 -0
- endoreg_db/serializers/patient_finding/patient_finding_classification.py +39 -0
- endoreg_db/serializers/patient_finding/patient_finding_detail.py +53 -0
- endoreg_db/serializers/patient_finding/patient_finding_intervention.py +26 -0
- endoreg_db/serializers/patient_finding/patient_finding_list.py +41 -0
- endoreg_db/serializers/patient_finding/patient_finding_write.py +126 -0
- endoreg_db/serializers/pdf/__init__.py +5 -0
- endoreg_db/serializers/pdf/anony_text_validation.py +85 -0
- endoreg_db/serializers/report/__init__.py +9 -0
- endoreg_db/serializers/report/mixins.py +45 -0
- endoreg_db/serializers/report/report.py +105 -0
- endoreg_db/serializers/report/report_list.py +22 -0
- endoreg_db/serializers/report/secure_file_url.py +26 -0
- endoreg_db/serializers/requirements/requirement_schema.py +25 -0
- endoreg_db/serializers/requirements/requirement_sets.py +29 -0
- endoreg_db/serializers/sensitive_meta_serializer.py +282 -0
- endoreg_db/serializers/video/__init__.py +7 -0
- endoreg_db/serializers/video/segmentation.py +263 -0
- endoreg_db/serializers/video/video_file_brief.py +10 -0
- endoreg_db/serializers/video/video_file_detail.py +83 -0
- endoreg_db/serializers/video/video_file_list.py +67 -0
- endoreg_db/serializers/video/video_metadata.py +105 -0
- endoreg_db/serializers/video/video_processing_history.py +153 -0
- endoreg_db/services/__init__.py +5 -0
- endoreg_db/services/anonymization.py +223 -0
- endoreg_db/services/examination_evaluation.py +149 -0
- endoreg_db/services/finding_description_service.py +0 -0
- endoreg_db/services/lookup_service.py +241 -0
- endoreg_db/services/lookup_store.py +122 -0
- endoreg_db/services/ollama_api_docs.py +1528 -0
- endoreg_db/services/pdf_import.py +963 -0
- endoreg_db/services/polling_coordinator.py +288 -0
- endoreg_db/services/pseudonym_service.py +89 -0
- endoreg_db/services/requirements_object.py +147 -0
- endoreg_db/services/segment_sync.py +155 -0
- endoreg_db/services/storage_aware_video_processor.py +344 -0
- endoreg_db/services/video_import.py +1118 -0
- endoreg_db/tasks/upload_tasks.py +207 -0
- endoreg_db/tasks/video_ingest.py +157 -0
- endoreg_db/tasks/video_processing_tasks.py +327 -0
- endoreg_db/urls/__init__.py +70 -0
- endoreg_db/urls/anonymization.py +32 -0
- endoreg_db/urls/auth.py +16 -0
- endoreg_db/urls/classification.py +39 -0
- endoreg_db/urls/examination.py +54 -0
- endoreg_db/urls/files.py +6 -0
- endoreg_db/urls/label_video_segment_validate.py +33 -0
- endoreg_db/urls/label_video_segments.py +44 -0
- endoreg_db/urls/media.py +229 -0
- endoreg_db/urls/patient.py +19 -0
- endoreg_db/urls/report.py +48 -0
- endoreg_db/urls/requirements.py +13 -0
- endoreg_db/urls/stats.py +46 -0
- endoreg_db/urls/upload.py +20 -0
- endoreg_db/urls/video.py +61 -0
- endoreg_db/urls.py +6 -283
- endoreg_db/utils/__init__.py +66 -57
- endoreg_db/utils/ai/__init__.py +9 -0
- endoreg_db/{models/ai_model/utils.py → utils/ai/get.py} +1 -4
- endoreg_db/{models/ai_model/lightning → utils/ai}/inference_dataset.py +0 -1
- endoreg_db/{models/ai_model/lightning → utils/ai}/multilabel_classification_net.py +14 -10
- endoreg_db/{models/ai_model/lightning → utils/ai}/postprocess.py +15 -5
- endoreg_db/utils/ai/predict.py +291 -0
- endoreg_db/{models/ai_model/lightning → utils/ai}/preprocess.py +1 -1
- endoreg_db/utils/calc_duration_seconds.py +24 -0
- endoreg_db/utils/case_generator/__init__.py +0 -0
- endoreg_db/utils/check_video_files.py +148 -0
- endoreg_db/utils/dataloader.py +50 -12
- endoreg_db/utils/dates.py +21 -0
- endoreg_db/utils/env.py +33 -0
- endoreg_db/utils/extract_specific_frames.py +72 -0
- endoreg_db/utils/file_operations.py +29 -1
- endoreg_db/utils/fix_video_path_direct.py +141 -0
- endoreg_db/utils/frame_anonymization_utils.py +463 -0
- endoreg_db/utils/links/__init__.py +0 -0
- endoreg_db/utils/links/requirement_link.py +193 -0
- endoreg_db/utils/mime_types.py +0 -0
- endoreg_db/utils/names.py +2 -0
- endoreg_db/utils/paths.py +100 -82
- endoreg_db/utils/permissions.py +143 -0
- endoreg_db/utils/pipelines/Readme.md +235 -0
- endoreg_db/utils/pipelines/__init__.py +0 -0
- endoreg_db/utils/pipelines/process_video_dir.py +120 -0
- endoreg_db/utils/product/__init__.py +0 -0
- endoreg_db/utils/product/sum_emissions.py +20 -0
- endoreg_db/utils/product/sum_weights.py +18 -0
- endoreg_db/utils/pydantic_models/db_config.py +1 -1
- endoreg_db/utils/requirement_helpers.py +0 -0
- endoreg_db/utils/requirement_operator_logic/__init__.py +0 -0
- endoreg_db/utils/requirement_operator_logic/lab_value_operators.py +578 -0
- endoreg_db/utils/requirement_operator_logic/model_evaluators.py +368 -0
- endoreg_db/utils/translation.py +27 -0
- endoreg_db/utils/validate_video_detailed.py +357 -0
- endoreg_db/utils/video/__init__.py +19 -6
- endoreg_db/utils/video/extract_frames.py +37 -70
- endoreg_db/utils/video/ffmpeg_wrapper.py +772 -0
- endoreg_db/utils/video/names.py +42 -0
- endoreg_db/utils/video/streaming_processor.py +312 -0
- endoreg_db/utils/video/video_splitter.py +94 -0
- endoreg_db/views/Frames_NICE_and_PARIS_classifications_views.py +238 -0
- endoreg_db/views/__init__.py +282 -2
- endoreg_db/views/anonymization/__init__.py +27 -0
- endoreg_db/views/anonymization/media_management.py +454 -0
- endoreg_db/views/anonymization/overview.py +216 -0
- endoreg_db/views/anonymization/validate.py +66 -0
- endoreg_db/views/auth/__init__.py +13 -0
- endoreg_db/views/{views.py → auth/keycloak.py} +19 -13
- endoreg_db/views/examination/__init__.py +33 -0
- endoreg_db/views/examination/examination.py +37 -0
- endoreg_db/views/examination/examination_manifest_cache.py +26 -0
- endoreg_db/views/examination/get_finding_classification_choices.py +59 -0
- endoreg_db/views/examination/get_finding_classifications.py +36 -0
- endoreg_db/views/examination/get_findings.py +41 -0
- endoreg_db/views/examination/get_instruments.py +18 -0
- endoreg_db/views/examination/get_interventions.py +14 -0
- endoreg_db/views/finding/__init__.py +9 -0
- endoreg_db/views/finding/finding.py +112 -0
- endoreg_db/views/finding/get_classifications.py +14 -0
- endoreg_db/views/finding/get_interventions.py +17 -0
- endoreg_db/views/finding_classification/__init__.py +13 -0
- endoreg_db/views/finding_classification/base.py +0 -0
- endoreg_db/views/finding_classification/finding_classification.py +42 -0
- endoreg_db/views/finding_classification/get_classification_choices.py +55 -0
- endoreg_db/views/label/__init__.py +5 -0
- endoreg_db/views/label/label.py +15 -0
- endoreg_db/views/label_video_segment/__init__.py +16 -0
- endoreg_db/views/label_video_segment/create_lvs_from_annotation.py +44 -0
- endoreg_db/views/label_video_segment/get_lvs_by_name_and_video.py +50 -0
- endoreg_db/views/label_video_segment/label_video_segment.py +77 -0
- endoreg_db/views/label_video_segment/label_video_segment_by_label.py +174 -0
- endoreg_db/views/label_video_segment/label_video_segment_detail.py +73 -0
- endoreg_db/views/label_video_segment/update_lvs_from_annotation.py +46 -0
- endoreg_db/views/label_video_segment/validate.py +226 -0
- endoreg_db/views/media/__init__.py +45 -0
- endoreg_db/views/media/pdf_media.py +386 -0
- endoreg_db/views/media/segments.py +71 -0
- endoreg_db/views/media/sensitive_metadata.py +314 -0
- endoreg_db/views/media/video_media.py +272 -0
- endoreg_db/views/media/video_segments.py +596 -0
- endoreg_db/views/meta/__init__.py +15 -0
- endoreg_db/views/meta/available_files_list.py +146 -0
- endoreg_db/views/meta/report_meta.py +53 -0
- endoreg_db/views/meta/sensitive_meta_detail.py +148 -0
- endoreg_db/views/meta/sensitive_meta_list.py +104 -0
- endoreg_db/views/meta/sensitive_meta_verification.py +71 -0
- endoreg_db/views/misc/__init__.py +63 -0
- endoreg_db/views/misc/center.py +13 -0
- endoreg_db/views/misc/gender.py +14 -0
- endoreg_db/views/misc/secure_file_serving_view.py +80 -0
- endoreg_db/views/misc/secure_file_url_view.py +84 -0
- endoreg_db/views/misc/secure_url_validate.py +79 -0
- endoreg_db/views/misc/stats.py +220 -0
- endoreg_db/views/misc/translation.py +182 -0
- endoreg_db/views/misc/upload_views.py +240 -0
- endoreg_db/views/patient/__init__.py +5 -0
- endoreg_db/views/patient/patient.py +210 -0
- endoreg_db/views/patient_examination/DEPRECATED_video_backup.py +164 -0
- endoreg_db/views/patient_examination/__init__.py +11 -0
- endoreg_db/views/patient_examination/patient_examination.py +140 -0
- endoreg_db/views/patient_examination/patient_examination_create.py +63 -0
- endoreg_db/views/patient_examination/patient_examination_detail.py +66 -0
- endoreg_db/views/patient_examination/patient_examination_list.py +68 -0
- endoreg_db/views/patient_examination/video.py +194 -0
- endoreg_db/views/patient_finding/__init__.py +7 -0
- endoreg_db/views/patient_finding/base.py +0 -0
- endoreg_db/views/patient_finding/patient_finding.py +64 -0
- endoreg_db/views/patient_finding/patient_finding_optimized.py +259 -0
- endoreg_db/views/patient_finding_classification/__init__.py +5 -0
- endoreg_db/views/patient_finding_classification/pfc_create.py +67 -0
- endoreg_db/views/patient_finding_location/__init__.py +5 -0
- endoreg_db/views/patient_finding_location/pfl_create.py +70 -0
- endoreg_db/views/patient_finding_morphology/__init__.py +5 -0
- endoreg_db/views/patient_finding_morphology/pfm_create.py +70 -0
- endoreg_db/views/pdf/__init__.py +11 -0
- endoreg_db/views/pdf/pdf_media.py +239 -0
- endoreg_db/views/pdf/pdf_stream_views.py +127 -0
- endoreg_db/views/pdf/reimport.py +161 -0
- endoreg_db/views/report/__init__.py +9 -0
- endoreg_db/views/report/report_list.py +112 -0
- endoreg_db/views/report/report_with_secure_url.py +28 -0
- endoreg_db/views/report/start_examination.py +7 -0
- endoreg_db/views/requirement/__init__.py +10 -0
- endoreg_db/views/requirement/evaluate.py +279 -0
- endoreg_db/views/requirement/lookup.py +483 -0
- endoreg_db/views/requirement/lookup_store.py +252 -0
- endoreg_db/views/requirement_lookup/lookup.py +0 -0
- endoreg_db/views/requirement_lookup/lookup_store.py +0 -0
- endoreg_db/views/stats/__init__.py +13 -0
- endoreg_db/views/stats/stats_views.py +229 -0
- endoreg_db/views/video/__init__.py +64 -0
- endoreg_db/views/video/correction.py +672 -0
- endoreg_db/views/video/reimport.py +195 -0
- endoreg_db/views/video/segmentation.py +274 -0
- endoreg_db/views/video/task_status.py +49 -0
- endoreg_db/views/{views_for_timeline.py → video/timeline.py} +3 -3
- endoreg_db/views/video/video_analyze.py +52 -0
- endoreg_db/views/video/video_apply_mask.py +48 -0
- endoreg_db/views/video/video_correction.py +21 -0
- endoreg_db/views/video/video_download_processed.py +58 -0
- endoreg_db/views/video/video_examination_viewset.py +329 -0
- endoreg_db/views/video/video_media.py +158 -0
- endoreg_db/views/video/video_meta.py +29 -0
- endoreg_db/views/video/video_processing_history.py +24 -0
- endoreg_db/views/video/video_remove_frames.py +48 -0
- endoreg_db/views/video/video_reprocess.py +40 -0
- endoreg_db/views/video/video_stream.py +306 -0
- endoreg_db-0.8.2.dist-info/METADATA +384 -0
- endoreg_db-0.8.2.dist-info/RECORD +790 -0
- endoreg_db/data/agl_service/data.yaml +0 -19
- endoreg_db/data/finding_location_classification/colonoscopy.yaml +0 -46
- endoreg_db/data/finding_morphology_classification/colonoscopy.yaml +0 -48
- endoreg_db/data/finding_morphology_classification_choice/colonoscopy_size.yaml +0 -57
- endoreg_db/management/commands/_load_model_template.py +0 -41
- endoreg_db/management/commands/delete_all.py +0 -18
- endoreg_db/management/commands/fetch_legacy_image_dataset.py +0 -32
- endoreg_db/management/commands/fix_auth_permission.py +0 -20
- endoreg_db/management/commands/load_active_model_data.py +0 -45
- endoreg_db/management/commands/load_g_play_data.py +0 -113
- endoreg_db/management/commands/load_logging_data.py +0 -39
- endoreg_db/management/commands/load_lx_data.py +0 -64
- endoreg_db/management/commands/load_medication_indication_data.py +0 -63
- endoreg_db/management/commands/load_medication_indication_type_data.py +0 -41
- endoreg_db/management/commands/load_medication_intake_time_data.py +0 -41
- endoreg_db/management/commands/load_medication_schedule_data.py +0 -55
- endoreg_db/management/commands/load_network_data.py +0 -57
- endoreg_db/migrations/0002_alter_frame_image_alter_rawframe_image.py +0 -23
- endoreg_db/migrations/0003_alter_frame_image_alter_rawframe_image.py +0 -23
- endoreg_db/migrations/0004_alter_rawvideofile_file_alter_video_file.py +0 -25
- endoreg_db/migrations/0005_rawvideofile_frame_count_and_more.py +0 -33
- endoreg_db/migrations/0006_frame_extracted_rawframe_extracted.py +0 -23
- endoreg_db/migrations/0007_rename_pseudo_patient_video_patient_and_more.py +0 -24
- endoreg_db/migrations/0008_remove_reportfile_patient_examination_and_more.py +0 -48
- endoreg_db/migrations/0009_requirementoperator_requirementsettype_and_more.py +0 -154
- endoreg_db/models/ai_model/active_model.py +0 -9
- endoreg_db/models/ai_model/ai_model.py +0 -90
- endoreg_db/models/ai_model/lightning/__init__.py +0 -3
- endoreg_db/models/ai_model/lightning/predict.py +0 -172
- endoreg_db/models/ai_model/lightning/prediction_visualizer.py +0 -55
- endoreg_db/models/ai_model/lightning/run_visualizer.py +0 -21
- endoreg_db/models/ai_model/model_meta.py +0 -240
- endoreg_db/models/annotation/__init__.py +0 -32
- endoreg_db/models/annotation/anonymized_image_annotation.py +0 -115
- endoreg_db/models/annotation/binary_classification_annotation_task.py +0 -117
- endoreg_db/models/annotation/image_classification.py +0 -86
- endoreg_db/models/annotation/video_segmentation_annotation.py +0 -52
- endoreg_db/models/case/__init__.py +0 -1
- endoreg_db/models/case/case.py +0 -34
- endoreg_db/models/center/center.py +0 -51
- endoreg_db/models/center/center_product.py +0 -33
- endoreg_db/models/center/center_waste.py +0 -16
- endoreg_db/models/data_file/__init__.py +0 -39
- endoreg_db/models/data_file/base_classes/__init__.py +0 -7
- endoreg_db/models/data_file/base_classes/abstract_frame.py +0 -98
- endoreg_db/models/data_file/base_classes/abstract_pdf.py +0 -127
- endoreg_db/models/data_file/base_classes/abstract_video.py +0 -806
- endoreg_db/models/data_file/base_classes/frame_helpers.py +0 -17
- endoreg_db/models/data_file/base_classes/prepare_bulk_frames.py +0 -19
- endoreg_db/models/data_file/base_classes/utils.py +0 -58
- endoreg_db/models/data_file/frame.py +0 -29
- endoreg_db/models/data_file/import_classes/__init__.py +0 -18
- endoreg_db/models/data_file/import_classes/processing_functions/__init__.py +0 -35
- endoreg_db/models/data_file/import_classes/processing_functions/pdf.py +0 -28
- endoreg_db/models/data_file/import_classes/processing_functions/video.py +0 -260
- endoreg_db/models/data_file/import_classes/raw_pdf.py +0 -254
- endoreg_db/models/data_file/import_classes/raw_video.py +0 -290
- endoreg_db/models/data_file/metadata/sensitive_meta.py +0 -290
- endoreg_db/models/data_file/metadata/video_meta.py +0 -199
- endoreg_db/models/data_file/report_file.py +0 -56
- endoreg_db/models/data_file/video/__init__.py +0 -11
- endoreg_db/models/data_file/video/import_meta.py +0 -25
- endoreg_db/models/data_file/video/video.py +0 -196
- endoreg_db/models/data_file/video_segment.py +0 -214
- endoreg_db/models/examination/examination.py +0 -67
- endoreg_db/models/finding/__init__.py +0 -11
- endoreg_db/models/finding/finding.py +0 -75
- endoreg_db/models/finding/finding_location_classification.py +0 -94
- endoreg_db/models/finding/finding_morphology_classification.py +0 -89
- endoreg_db/models/finding/finding_type.py +0 -22
- endoreg_db/models/hardware/__init__.py +0 -2
- endoreg_db/models/information_source.py +0 -65
- endoreg_db/models/laboratory/__init__.py +0 -1
- endoreg_db/models/laboratory/lab_value.py +0 -162
- endoreg_db/models/logging/__init__.py +0 -11
- endoreg_db/models/logging/agl_service.py +0 -19
- endoreg_db/models/logging/base.py +0 -22
- endoreg_db/models/logging/log_type.py +0 -23
- endoreg_db/models/logging/network_device.py +0 -27
- endoreg_db/models/lx/__init__.py +0 -4
- endoreg_db/models/lx/client.py +0 -57
- endoreg_db/models/lx/identity.py +0 -34
- endoreg_db/models/lx/permission.py +0 -18
- endoreg_db/models/lx/user.py +0 -16
- endoreg_db/models/network/__init__.py +0 -9
- endoreg_db/models/network/agl_service.py +0 -38
- endoreg_db/models/network/network_device.py +0 -58
- endoreg_db/models/network/network_device_type.py +0 -23
- endoreg_db/models/other/distribution.py +0 -5
- endoreg_db/models/patient/__init__.py +0 -24
- endoreg_db/models/patient/patient_examination.py +0 -182
- endoreg_db/models/patient/patient_finding.py +0 -143
- endoreg_db/models/patient/patient_finding_location.py +0 -120
- endoreg_db/models/patient/patient_finding_morphology.py +0 -166
- endoreg_db/models/permissions/__init__.py +0 -44
- endoreg_db/models/persons/__init__.py +0 -34
- endoreg_db/models/persons/examiner/__init__.py +0 -2
- endoreg_db/models/persons/examiner/examiner.py +0 -60
- endoreg_db/models/persons/examiner/examiner_type.py +0 -2
- endoreg_db/models/persons/patient/__init__.py +0 -8
- endoreg_db/models/persons/patient/patient.py +0 -389
- endoreg_db/models/persons/patient/patient_disease.py +0 -22
- endoreg_db/models/persons/patient/patient_event.py +0 -52
- endoreg_db/models/persons/patient/patient_lab_sample.py +0 -108
- endoreg_db/models/persons/patient/patient_medication.py +0 -59
- endoreg_db/models/persons/patient/patient_medication_schedule.py +0 -88
- endoreg_db/models/persons/portal_user_information.py +0 -27
- endoreg_db/models/prediction/__init__.py +0 -8
- endoreg_db/models/prediction/image_classification.py +0 -51
- endoreg_db/models/prediction/video_prediction_meta.py +0 -306
- endoreg_db/models/product/product.py +0 -110
- endoreg_db/models/product/product_group.py +0 -27
- endoreg_db/models/product/product_material.py +0 -28
- endoreg_db/models/questionnaires/__init__.py +0 -114
- endoreg_db/models/quiz/__init__.py +0 -9
- endoreg_db/models/quiz/quiz_answer.py +0 -41
- endoreg_db/models/quiz/quiz_question.py +0 -54
- endoreg_db/models/report_reader/report_reader_config.py +0 -53
- endoreg_db/models/rules/__init__.py +0 -5
- endoreg_db/queries/get/__init__.py +0 -6
- endoreg_db/queries/get/center.py +0 -42
- endoreg_db/queries/get/model.py +0 -13
- endoreg_db/queries/get/patient.py +0 -14
- endoreg_db/queries/get/patient_examination.py +0 -20
- endoreg_db/queries/get/report_file.py +0 -33
- endoreg_db/queries/get/video.py +0 -31
- endoreg_db/serializers/ai_model.py +0 -19
- endoreg_db/serializers/annotation.py +0 -14
- endoreg_db/serializers/center.py +0 -11
- endoreg_db/serializers/examination.py +0 -33
- endoreg_db/serializers/frame.py +0 -9
- endoreg_db/serializers/hardware.py +0 -21
- endoreg_db/serializers/label.py +0 -22
- endoreg_db/serializers/patient.py +0 -33
- endoreg_db/serializers/prediction.py +0 -10
- endoreg_db/serializers/raw_pdf_anony_text_validation.py +0 -137
- endoreg_db/serializers/report_file.py +0 -7
- endoreg_db/serializers/video.py +0 -20
- endoreg_db/serializers/video_segmentation.py +0 -574
- endoreg_db/tests.py +0 -3
- endoreg_db/utils/legacy_ocr.py +0 -201
- endoreg_db/utils/video/transcode_videofile.py +0 -111
- endoreg_db/views/patient_views.py +0 -90
- endoreg_db/views/raw_pdf_anony_text_validation_views.py +0 -95
- endoreg_db/views/raw_pdf_meta_validation_views.py +0 -111
- endoreg_db/views/raw_video_meta_validation_views.py +0 -148
- endoreg_db/views/report_views.py +0 -96
- endoreg_db/views/video_segmentation_views.py +0 -166
- endoreg_db-0.6.4.dist-info/METADATA +0 -161
- endoreg_db-0.6.4.dist-info/RECORD +0 -470
- /endoreg_db/{case_generator/__init__.py → api/serializers/finding_descriptions.py} +0 -0
- /endoreg_db/{queries/get/annotation.py → api/views/finding_descriptions.py} +0 -0
- /endoreg_db/{queries/get/prediction.py → data/shift/m2.yaml} +0 -0
- /endoreg_db/{queries/get/video_import_meta.py → factories/__init__.py} +0 -0
- /endoreg_db/{queries/get/video_prediction_meta.py → helpers/__init__.py} +0 -0
- /endoreg_db/models/{case_template → administration/case/case_template}/__init__.py +0 -0
- /endoreg_db/models/{persons → administration/person}/person.py +0 -0
- /endoreg_db/models/{product → administration/product}/__init__.py +0 -0
- /endoreg_db/models/{report_reader → media/pdf/report_reader}/__init__.py +0 -0
- /endoreg_db/models/{report_reader → media/pdf/report_reader}/report_reader_flag.py +0 -0
- /endoreg_db/models/{hardware → medical/hardware}/endoscopy_processor.py +0 -0
- /endoreg_db/models/{medication → medical/medication}/__init__.py +0 -0
- /endoreg_db/models/{medication → medical/medication}/medication_indication.py +0 -0
- /endoreg_db/models/{risk → medical/risk}/__init__.py +0 -0
- /endoreg_db/models/{risk → medical/risk}/risk.py +0 -0
- /endoreg_db/models/{emission → other/emission}/__init__.py +0 -0
- /endoreg_db/models/{rules → rule}/rule_applicator.py +0 -0
- /endoreg_db/{case_generator → utils/case_generator}/case_generator.py +0 -0
- /endoreg_db/{case_generator → utils/case_generator}/lab_sample_factory.py +0 -0
- /endoreg_db/{case_generator → utils/case_generator}/utils.py +0 -0
- /endoreg_db/views/{csrf.py → misc/csrf.py} +0 -0
- {endoreg_db-0.6.4.dist-info → endoreg_db-0.8.2.dist-info}/WHEEL +0 -0
- {endoreg_db-0.6.4.dist-info → endoreg_db-0.8.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
from django.db import models
|
|
2
|
-
from typing import TYPE_CHECKING
|
|
2
|
+
from typing import TYPE_CHECKING, List
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
REQUIREMENT_SET_TYPE_FUNCTION_LOOKUP = {
|
|
6
|
+
"all": all,
|
|
7
|
+
"any": any,
|
|
8
|
+
"none": lambda x: not any(x), # Custom function for 'none'
|
|
9
|
+
"exactly_1": lambda x: sum(1 for item in x if item) == 1,
|
|
10
|
+
"at_least_1": lambda x: sum(1 for item in x if item) >= 1, # Equivalent to any(x)
|
|
11
|
+
"at_most_1": lambda x: sum(1 for item in x if item) <= 1,
|
|
12
|
+
}
|
|
13
|
+
|
|
5
14
|
class RequirementSetTypeManager(models.Manager):
|
|
6
15
|
"""
|
|
7
16
|
Manager for RequirementSetType with custom query methods.
|
|
@@ -26,13 +35,9 @@ class RequirementSetType(models.Model):
|
|
|
26
35
|
|
|
27
36
|
Attributes:
|
|
28
37
|
name (str): The name of the requirement set type.
|
|
29
|
-
name_de (str): The German name of the requirement set type.
|
|
30
|
-
name_en (str): The English name of the requirement set type.
|
|
31
38
|
"""
|
|
32
39
|
|
|
33
40
|
name = models.CharField(max_length=100, unique=True)
|
|
34
|
-
name_de = models.CharField(max_length=100, blank=True, null=True)
|
|
35
|
-
name_en = models.CharField(max_length=100, blank=True, null=True)
|
|
36
41
|
description = models.TextField(blank=True, null=True)
|
|
37
42
|
|
|
38
43
|
objects = RequirementSetTypeManager()
|
|
@@ -72,46 +77,58 @@ class RequirementSet(models.Model):
|
|
|
72
77
|
|
|
73
78
|
Attributes:
|
|
74
79
|
name (str): The name of the requirement set.
|
|
75
|
-
name_de (str): The German name of the requirement set.
|
|
76
|
-
name_en (str): The English name of the requirement set.
|
|
77
80
|
description (str): A description of the requirement set.
|
|
78
81
|
"""
|
|
79
82
|
|
|
80
83
|
name = models.CharField(max_length=100, unique=True)
|
|
81
|
-
name_de = models.CharField(max_length=100, blank=True, null=True)
|
|
82
|
-
name_en = models.CharField(max_length=100, blank=True, null=True)
|
|
83
84
|
description = models.TextField(blank=True, null=True)
|
|
84
|
-
requirements = models.ManyToManyField(
|
|
85
|
+
requirements = models.ManyToManyField( # type: ignore[assignment]
|
|
85
86
|
"Requirement",
|
|
86
87
|
blank=True,
|
|
87
88
|
related_name="requirement_sets",
|
|
88
89
|
)
|
|
89
|
-
links_to_sets = models.ManyToManyField(
|
|
90
|
+
links_to_sets = models.ManyToManyField( # type: ignore[assignment]
|
|
90
91
|
"RequirementSet",
|
|
91
92
|
blank=True,
|
|
92
93
|
related_name="links_from_sets",
|
|
93
94
|
)
|
|
94
|
-
requirement_set_type = models.ForeignKey(
|
|
95
|
+
requirement_set_type = models.ForeignKey( # type: ignore[assignment]
|
|
95
96
|
"RequirementSetType",
|
|
96
97
|
on_delete=models.CASCADE,
|
|
97
98
|
related_name="requirement_sets",
|
|
98
99
|
blank=True,
|
|
99
100
|
null=True,
|
|
100
101
|
)
|
|
101
|
-
information_sources = models.ManyToManyField(
|
|
102
|
+
information_sources = models.ManyToManyField( # type: ignore[assignment]
|
|
102
103
|
"InformationSource",
|
|
103
104
|
related_name="requirement_sets",
|
|
104
105
|
blank=True,
|
|
105
106
|
)
|
|
107
|
+
|
|
108
|
+
reqset_exam_links = models.ManyToManyField( # type: ignore[assignment]
|
|
109
|
+
"ExaminationRequirementSet",
|
|
110
|
+
related_name="requirement_set",
|
|
111
|
+
blank=True,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
tags = models.ManyToManyField( # type: ignore[assignment]
|
|
115
|
+
"Tag",
|
|
116
|
+
related_name="requirement_sets",
|
|
117
|
+
blank=True,
|
|
118
|
+
)
|
|
119
|
+
|
|
106
120
|
objects = RequirementSetManager()
|
|
107
121
|
|
|
108
122
|
if TYPE_CHECKING:
|
|
109
|
-
from endoreg_db.models import Requirement, InformationSource
|
|
123
|
+
from endoreg_db.models import Tag, Requirement, InformationSource
|
|
124
|
+
from typing import Optional
|
|
110
125
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
126
|
+
tags: "models.ManyToManyField[Tag]"
|
|
127
|
+
requirements: "models.Manager[Requirement]"
|
|
128
|
+
information_sources: "models.Manager[InformationSource]"
|
|
129
|
+
requirement_set_type: Optional[RequirementSetType]
|
|
130
|
+
links_to_sets: "models.Manager[RequirementSet]"
|
|
131
|
+
links_from_sets: "models.Manager[RequirementSet]"
|
|
115
132
|
|
|
116
133
|
def natural_key(self):
|
|
117
134
|
"""Return the natural key as a tuple containing the instance's name."""
|
|
@@ -119,9 +136,152 @@ class RequirementSet(models.Model):
|
|
|
119
136
|
|
|
120
137
|
def __str__(self):
|
|
121
138
|
"""
|
|
122
|
-
|
|
139
|
+
Returns the name of the requirement set as its string representation.
|
|
140
|
+
"""
|
|
141
|
+
return str(self.name)
|
|
142
|
+
|
|
143
|
+
def evaluate_requirements(self, input_object, mode="loose") -> List[bool]:
|
|
144
|
+
"""
|
|
145
|
+
Evaluates all requirements in the set against the provided input object.
|
|
146
|
+
|
|
147
|
+
Intelligently selects the appropriate input data for each requirement based on its expected model types.
|
|
148
|
+
For example, if a requirement expects PatientFinding but receives a PatientExamination,
|
|
149
|
+
it will use the examination's patient_findings instead.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
input_object: The object to be evaluated by each requirement.
|
|
153
|
+
mode: Optional evaluation mode passed to each requirement (default is "loose").
|
|
123
154
|
|
|
124
155
|
Returns:
|
|
125
|
-
|
|
156
|
+
A list of boolean values indicating whether each requirement is satisfied.
|
|
126
157
|
"""
|
|
127
|
-
|
|
158
|
+
results = []
|
|
159
|
+
for requirement in self.requirements.all():
|
|
160
|
+
# Get the appropriate input for this specific requirement
|
|
161
|
+
evaluation_input = self._get_evaluation_input_for_requirement(requirement, input_object)
|
|
162
|
+
result = requirement.evaluate(evaluation_input, mode=mode)
|
|
163
|
+
results.append(result)
|
|
164
|
+
return results
|
|
165
|
+
|
|
166
|
+
def _get_evaluation_input_for_requirement(self, requirement, input_object):
|
|
167
|
+
"""
|
|
168
|
+
Determines the appropriate input object for evaluating a specific requirement.
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
requirement: The requirement to be evaluated
|
|
172
|
+
input_object: The original input object
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
The most appropriate input object for the requirement evaluation
|
|
176
|
+
"""
|
|
177
|
+
expected_models = requirement.expected_models
|
|
178
|
+
|
|
179
|
+
# If the input object is already one of the expected models, use it directly
|
|
180
|
+
for expected_model in expected_models:
|
|
181
|
+
if isinstance(input_object, expected_model):
|
|
182
|
+
return input_object
|
|
183
|
+
|
|
184
|
+
# Import here to avoid circular imports
|
|
185
|
+
from endoreg_db.models.medical.patient.patient_examination import PatientExamination
|
|
186
|
+
from endoreg_db.models.medical.patient.patient_finding import PatientFinding
|
|
187
|
+
|
|
188
|
+
# Handle PatientExamination -> PatientFinding conversion
|
|
189
|
+
if isinstance(input_object, PatientExamination):
|
|
190
|
+
# If requirement expects PatientFinding, return the examination's findings
|
|
191
|
+
if PatientFinding in expected_models:
|
|
192
|
+
return input_object.patient_findings.all()
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
# Handle other model conversions as needed in the future
|
|
196
|
+
# For now, return the original input object as fallback
|
|
197
|
+
return input_object
|
|
198
|
+
|
|
199
|
+
def evaluate_requirement_sets(self, input_object) -> List[bool]:
|
|
200
|
+
"""
|
|
201
|
+
Evaluates all linked requirement sets against the provided input object.
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
A list of boolean values indicating whether each linked requirement set is satisfied.
|
|
205
|
+
"""
|
|
206
|
+
results = []
|
|
207
|
+
linked_sets = self.all_linked_sets
|
|
208
|
+
if not linked_sets:
|
|
209
|
+
return results
|
|
210
|
+
for linked_set in linked_sets:
|
|
211
|
+
result = linked_set.evaluate(input_object)
|
|
212
|
+
results.append(result)
|
|
213
|
+
return results
|
|
214
|
+
|
|
215
|
+
@property
|
|
216
|
+
def eval_function(self):
|
|
217
|
+
"""
|
|
218
|
+
Returns the evaluation function associated with this requirement set's type.
|
|
219
|
+
|
|
220
|
+
If the requirement set type is defined and matches a known type, returns the corresponding function from REQUIREMENT_SET_TYPE_FUNCTION_LOOKUP. Returns None if no matching function is found.
|
|
221
|
+
"""
|
|
222
|
+
if self.requirement_set_type and self.requirement_set_type.name in REQUIREMENT_SET_TYPE_FUNCTION_LOOKUP:
|
|
223
|
+
return REQUIREMENT_SET_TYPE_FUNCTION_LOOKUP[self.requirement_set_type.name]
|
|
224
|
+
return None
|
|
225
|
+
|
|
226
|
+
def evaluate(self, input_object):
|
|
227
|
+
"""
|
|
228
|
+
Evaluates whether the input object satisfies this requirement set.
|
|
229
|
+
|
|
230
|
+
Combines the evaluation results of all direct requirements and linked requirement sets, then applies the set's evaluation function (such as all, any, none, etc.) to determine if the input object meets the overall criteria.
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
input_object: The object to be evaluated against the requirements and linked sets.
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
True if the input object satisfies the requirement set according to its evaluation logic; otherwise, False.
|
|
237
|
+
"""
|
|
238
|
+
evaluate_r_results = self.evaluate_requirements(input_object)
|
|
239
|
+
evaluate_rs_results = self.evaluate_requirement_sets(input_object)
|
|
240
|
+
|
|
241
|
+
results = evaluate_r_results + evaluate_rs_results
|
|
242
|
+
|
|
243
|
+
eval_result = self.eval_function(results) if self.eval_function else all(results)
|
|
244
|
+
|
|
245
|
+
return eval_result
|
|
246
|
+
|
|
247
|
+
@property
|
|
248
|
+
def all_linked_sets(self):
|
|
249
|
+
"""
|
|
250
|
+
Returns all linked requirement sets, including those linked to the current set and those linked to any of its linked sets.
|
|
251
|
+
|
|
252
|
+
Uses recursive traversal with cycle detection to safely handle circular relationships.
|
|
253
|
+
Eliminates duplicates by tracking visited sets.
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
List[RequirementSet]: A list of all linked requirement sets.
|
|
257
|
+
"""
|
|
258
|
+
visited = set()
|
|
259
|
+
result:List["RequirementSet"] = []
|
|
260
|
+
|
|
261
|
+
def _collect_linked_sets(requirement_set:"RequirementSet"):
|
|
262
|
+
"""
|
|
263
|
+
Recursively collect linked sets while avoiding cycles and duplicates.
|
|
264
|
+
|
|
265
|
+
Args:
|
|
266
|
+
requirement_set: The RequirementSet to process
|
|
267
|
+
"""
|
|
268
|
+
# Use the primary key to track visited sets (avoids issues with object comparison)
|
|
269
|
+
if requirement_set.pk in visited:
|
|
270
|
+
return
|
|
271
|
+
|
|
272
|
+
visited.add(requirement_set.pk)
|
|
273
|
+
|
|
274
|
+
# Process all directly linked sets
|
|
275
|
+
for linked_set in requirement_set.links_to_sets.all():
|
|
276
|
+
if linked_set.pk not in visited:
|
|
277
|
+
result.append(linked_set)
|
|
278
|
+
# Recursively process the linked set's links
|
|
279
|
+
_collect_linked_sets(linked_set)
|
|
280
|
+
|
|
281
|
+
# Start the recursive collection from this instance
|
|
282
|
+
_collect_linked_sets(self)
|
|
283
|
+
|
|
284
|
+
return result
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from .rule_type import RuleType
|
|
2
|
+
from .rule import Rule
|
|
3
|
+
from .ruleset import Ruleset
|
|
4
|
+
from .rule_attribute_dtype import RuleAttributeDType
|
|
5
|
+
from .rule_applicator import RuleApplicator
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"RuleType",
|
|
9
|
+
"Rule",
|
|
10
|
+
"Ruleset",
|
|
11
|
+
"RuleAttributeDType",
|
|
12
|
+
"RuleApplicator",
|
|
13
|
+
]
|
|
@@ -6,8 +6,6 @@ class RuleManager(models.Manager):
|
|
|
6
6
|
|
|
7
7
|
class Rule(models.Model):
|
|
8
8
|
name = models.CharField(max_length=255, unique=True)
|
|
9
|
-
name_de = models.CharField(max_length=255, blank=True, null=True)
|
|
10
|
-
name_en = models.CharField(max_length=255, blank=True, null=True)
|
|
11
9
|
description = models.TextField(blank=True, null=True)
|
|
12
10
|
attribute_key = models.CharField(max_length=255)
|
|
13
11
|
rule_type = models.ForeignKey("RuleType", on_delete=models.CASCADE)
|
|
@@ -20,5 +18,10 @@ class Rule(models.Model):
|
|
|
20
18
|
verbose_name_plural = 'Rules'
|
|
21
19
|
|
|
22
20
|
def natural_key(self):
|
|
21
|
+
"""
|
|
22
|
+
Return a tuple representing the natural key for this Rule instance.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
tuple: A one-element tuple containing the Rule's unique name.
|
|
26
|
+
"""
|
|
23
27
|
return (self.name,)
|
|
24
|
-
|
|
@@ -7,8 +7,6 @@ class RuleAttributeDtypeManager(models.Manager):
|
|
|
7
7
|
|
|
8
8
|
class RuleAttributeDType(models.Model):
|
|
9
9
|
name = models.CharField(max_length=255, unique=True)
|
|
10
|
-
name_de = models.CharField(max_length=255, blank=True, null=True)
|
|
11
|
-
name_en = models.CharField(max_length=255, blank=True, null=True)
|
|
12
10
|
|
|
13
11
|
objects = RuleAttributeDtypeManager()
|
|
14
12
|
|
|
@@ -6,8 +6,6 @@ class RuleTypeManager(models.Manager):
|
|
|
6
6
|
|
|
7
7
|
class RuleType(models.Model):
|
|
8
8
|
name = models.CharField(max_length=255, unique=True)
|
|
9
|
-
name_de = models.CharField(max_length=255, blank=True, null=True)
|
|
10
|
-
name_en = models.CharField(max_length=255, blank=True, null=True)
|
|
11
9
|
|
|
12
10
|
objects = RuleTypeManager()
|
|
13
11
|
|
|
@@ -6,8 +6,6 @@ class RulesetManager(models.Manager):
|
|
|
6
6
|
|
|
7
7
|
class Ruleset(models.Model):
|
|
8
8
|
name = models.CharField(max_length=255, unique=True)
|
|
9
|
-
name_de = models.CharField(max_length=255, blank=True, null=True)
|
|
10
|
-
name_en = models.CharField(max_length=255, blank=True, null=True)
|
|
11
9
|
rules = models.ManyToManyField('Rule')
|
|
12
10
|
|
|
13
11
|
objects = RulesetManager()
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from .sensitive_meta import SensitiveMetaState
|
|
2
|
+
from .video import VideoState, AnonymizationStatus
|
|
3
|
+
from .label_video_segment import LabelVideoSegmentState
|
|
4
|
+
from .raw_pdf import RawPdfState
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"SensitiveMetaState",
|
|
8
|
+
"VideoState",
|
|
9
|
+
"LabelVideoSegmentState",
|
|
10
|
+
"AnonymizationStatus",
|
|
11
|
+
"RawPdfState",
|
|
12
|
+
]
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# stats/models.py
|
|
2
|
+
import hashlib, json, uuid
|
|
3
|
+
from django.db import models
|
|
4
|
+
from django.utils import timezone
|
|
5
|
+
from django.conf import settings
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
AuditLedger Model
|
|
10
|
+
|
|
11
|
+
AuditLedger is a model that tracks changes to other models in the database.
|
|
12
|
+
It stores a hash of the previous state, the current state, and the action taken.
|
|
13
|
+
This allows for a complete audit trail of changes made to the database.
|
|
14
|
+
The model includes fields for the timestamp, user who made the change, object type,
|
|
15
|
+
object primary key, action taken, and the data associated with the change.
|
|
16
|
+
The save method computes the hash of the current state and the previous state
|
|
17
|
+
before saving the record to the database.
|
|
18
|
+
The hash is computed using SHA-256 and includes the timestamp, user ID,
|
|
19
|
+
object type, object primary key, action taken, and the data associated with the change.
|
|
20
|
+
The hash is stored in the database to ensure data integrity and to allow for
|
|
21
|
+
verification of the data.
|
|
22
|
+
The model also includes a method to retrieve the last hash from the database
|
|
23
|
+
to ensure that the current hash is always based on the most recent state of the database.
|
|
24
|
+
The model is designed to be immutable, meaning that once a record is created,
|
|
25
|
+
it cannot be modified. This ensures that the audit trail is complete and accurate.
|
|
26
|
+
|
|
27
|
+
Raises:
|
|
28
|
+
RuntimeError: _description_
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
_type_: _description_
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class AuditLedger(models.Model):
|
|
36
|
+
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
37
|
+
ts = models.DateTimeField(default=timezone.now, editable=False)
|
|
38
|
+
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)
|
|
39
|
+
object_type = models.CharField(max_length=80) # e.g. 'VideoFile'
|
|
40
|
+
object_pk = models.CharField(max_length=40) # UUID or int
|
|
41
|
+
action = models.CharField(max_length=40) # 'created' | 'validated' | …
|
|
42
|
+
data = models.JSONField() # snapshot / diff / metadata
|
|
43
|
+
prev_hash = models.CharField(max_length=64, editable=False)
|
|
44
|
+
hash = models.CharField(max_length=64, editable=False)
|
|
45
|
+
|
|
46
|
+
class Meta:
|
|
47
|
+
ordering = ['ts']
|
|
48
|
+
indexes = [models.Index(fields=['object_type', 'object_pk'])]
|
|
49
|
+
|
|
50
|
+
# ------------------------------------------------------
|
|
51
|
+
def save(self, *args, **kw):
|
|
52
|
+
"""
|
|
53
|
+
Saves a new immutable audit record, computing and linking cryptographic hashes.
|
|
54
|
+
|
|
55
|
+
Raises:
|
|
56
|
+
RuntimeError: If an attempt is made to modify an existing audit record.
|
|
57
|
+
"""
|
|
58
|
+
if self._state.adding: # only on INSERT
|
|
59
|
+
self.prev_hash = self._last_hash()
|
|
60
|
+
self.hash = self._compute_hash()
|
|
61
|
+
else:
|
|
62
|
+
raise RuntimeError("AuditLedger rows are immutable")
|
|
63
|
+
super().save(*args, **kw)
|
|
64
|
+
|
|
65
|
+
# ------------------------------------------------------
|
|
66
|
+
def _last_hash(self) -> str:
|
|
67
|
+
"""
|
|
68
|
+
Retrieves the hash of the most recent audit record.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
The SHA-256 hash of the latest `AuditLedger` entry by timestamp, or a string of 64 zeros if no records exist.
|
|
72
|
+
"""
|
|
73
|
+
last = AuditLedger.objects.order_by('-ts').first()
|
|
74
|
+
return last.hash if last else '0' * 64
|
|
75
|
+
|
|
76
|
+
def _compute_hash(self) -> str:
|
|
77
|
+
"""
|
|
78
|
+
Computes the SHA-256 hash of the current audit record's data.
|
|
79
|
+
|
|
80
|
+
The hash is generated from a JSON-serialized payload containing the timestamp, user ID, object type and primary key, action, associated data, and the previous record's hash. This ensures the integrity and immutability of the audit trail.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
The hexadecimal SHA-256 hash string representing the current audit record.
|
|
84
|
+
"""
|
|
85
|
+
payload = {
|
|
86
|
+
'ts': self.ts.isoformat(),
|
|
87
|
+
'uid': str(self.user_id),
|
|
88
|
+
'obj': f'{self.object_type}:{self.object_pk}',
|
|
89
|
+
'act': self.action,
|
|
90
|
+
'data': self.data,
|
|
91
|
+
'prev': self.prev_hash,
|
|
92
|
+
}
|
|
93
|
+
return hashlib.sha256(json.dumps(payload, sort_keys=True).encode()).hexdigest()
|
|
94
|
+
|
|
95
|
+
def log_validation(user, instance, action: str, extra=None):
|
|
96
|
+
"""
|
|
97
|
+
Creates an audit record for a validation action performed by a user on a specific model instance.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
user: The user performing the action.
|
|
101
|
+
instance: The model instance being validated.
|
|
102
|
+
action: The action performed (e.g., 'validated').
|
|
103
|
+
extra: Optional additional data to include in the audit record.
|
|
104
|
+
"""
|
|
105
|
+
AuditLedger.objects.create(
|
|
106
|
+
user=user,
|
|
107
|
+
object_type=instance.__class__.__name__,
|
|
108
|
+
object_pk=str(instance.pk),
|
|
109
|
+
action=action,
|
|
110
|
+
data=extra or {},
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
def _distinct(object_type: str, action: str):
|
|
114
|
+
"""
|
|
115
|
+
Returns the number of distinct objects of a given type that have a specific audit action recorded.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
object_type: The type of object to filter by (e.g., 'VideoFile').
|
|
119
|
+
action: The audit action to filter by (e.g., 'validated').
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
The count of unique object primary keys matching the specified type and action.
|
|
123
|
+
"""
|
|
124
|
+
return (
|
|
125
|
+
AuditLedger.objects
|
|
126
|
+
.filter(object_type=object_type, action=action)
|
|
127
|
+
.values('object_pk')
|
|
128
|
+
.distinct()
|
|
129
|
+
.count()
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
def collect_counters():
|
|
133
|
+
"""
|
|
134
|
+
Aggregates and returns summary statistics for audit actions and object types.
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
dict: A dictionary containing counts of distinct cases, videos, annotations,
|
|
138
|
+
anonymizations, images, and breakdowns of video statuses based on audit records.
|
|
139
|
+
"""
|
|
140
|
+
return {
|
|
141
|
+
"totalCases": AuditLedger._distinct("VideoFile", "created"),
|
|
142
|
+
"totalVideos": AuditLedger._distinct("VideoFile", "created"),
|
|
143
|
+
"totalAnnotations": AuditLedger.objects.filter(action="annotation_added").count(),
|
|
144
|
+
"totalAnonymizations": AuditLedger._distinct("VideoFile", "anonymized"),
|
|
145
|
+
"totalImages": AuditLedger._distinct("Image", "created"),
|
|
146
|
+
# video breakdown
|
|
147
|
+
"videosCompleted": AuditLedger._distinct("VideoFile", "validated"),
|
|
148
|
+
"videosAnonym": AuditLedger._distinct("VideoFile", "anonymized"),
|
|
149
|
+
# add more as needed …
|
|
150
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
from .abstract import AbstractState
|
|
3
|
+
|
|
4
|
+
class LabelVideoSegmentState(AbstractState):
|
|
5
|
+
"""State for label video segment data."""
|
|
6
|
+
|
|
7
|
+
prediction = models.BooleanField(default=False)
|
|
8
|
+
annotation = models.BooleanField(default=False)
|
|
9
|
+
frames_extracted = models.BooleanField(default=False)
|
|
10
|
+
is_validated = models.BooleanField(default=False)
|
|
11
|
+
|
|
12
|
+
origin = models.OneToOneField(
|
|
13
|
+
"LabelVideoSegment",
|
|
14
|
+
on_delete=models.CASCADE,
|
|
15
|
+
related_name="state",
|
|
16
|
+
null=True,
|
|
17
|
+
blank=True,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
class Meta:
|
|
21
|
+
verbose_name = "Label Video Segment State"
|
|
22
|
+
verbose_name_plural = "Label Video Segment States"
|