endoreg-db 0.8.9.32__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/__init__.py +0 -0
- endoreg_db/_version.py +34 -0
- endoreg_db/admin.py +97 -0
- endoreg_db/api/serializers/finding_descriptions.py +0 -0
- endoreg_db/api/views/finding_descriptions.py +0 -0
- endoreg_db/api_urls.py +4 -0
- endoreg_db/apps.py +17 -0
- endoreg_db/assets/dummy_model.ckpt +1 -0
- endoreg_db/authz/auth.py +78 -0
- endoreg_db/authz/backends.py +168 -0
- endoreg_db/authz/management/commands/list_routes.py +20 -0
- endoreg_db/authz/middleware.py +84 -0
- endoreg_db/authz/permissions.py +138 -0
- endoreg_db/authz/policy.py +224 -0
- endoreg_db/authz/settings.py +64 -0
- endoreg_db/authz/views_auth.py +70 -0
- endoreg_db/codemods/readme.md +88 -0
- endoreg_db/codemods/rename_datetime_fields.py +99 -0
- endoreg_db/config/__init__.py +0 -0
- endoreg_db/config/env.py +106 -0
- endoreg_db/config/settings/__init__.py +6 -0
- endoreg_db/config/settings/base.py +148 -0
- endoreg_db/config/settings/case_gen.py +32 -0
- endoreg_db/config/settings/dev.py +108 -0
- endoreg_db/config/settings/keycloak.py +177 -0
- endoreg_db/config/settings/prod.py +66 -0
- endoreg_db/config/settings/test.py +72 -0
- endoreg_db/data/__init__.py +135 -0
- endoreg_db/data/ai_model/data.yaml +7 -0
- endoreg_db/data/ai_model_label/label/data.yaml +88 -0
- endoreg_db/data/ai_model_label/label/polyp_classification.yaml +52 -0
- endoreg_db/data/ai_model_label/label-set/data.yaml +40 -0
- endoreg_db/data/ai_model_label/label-set/polyp_classifications.yaml +25 -0
- endoreg_db/data/ai_model_label/label-type/data.yaml +7 -0
- endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +27 -0
- endoreg_db/data/ai_model_type/data.yaml +7 -0
- endoreg_db/data/ai_model_video_segmentation_label/base_segmentation.yaml +176 -0
- endoreg_db/data/ai_model_video_segmentation_labelset/data.yaml +20 -0
- endoreg_db/data/case_template/rule/00_patient_lab_sample_add_default_value.yaml +167 -0
- endoreg_db/data/case_template/rule/01_patient-set-age.yaml +8 -0
- endoreg_db/data/case_template/rule/01_patient-set-gender.yaml +9 -0
- endoreg_db/data/case_template/rule/11_create_patient_lab_sample.yaml +23 -0
- endoreg_db/data/case_template/rule/12_create-patient_medication-anticoagulation.yaml +19 -0
- endoreg_db/data/case_template/rule/13_create-patient_medication_schedule-anticoagulation.yaml +19 -0
- endoreg_db/data/case_template/rule/19_create_patient.yaml +17 -0
- endoreg_db/data/case_template/rule_type/base_types.yaml +35 -0
- endoreg_db/data/case_template/rule_value/.init +0 -0
- endoreg_db/data/case_template/rule_value_type/base_types.yaml +59 -0
- endoreg_db/data/case_template/template/base.yaml +8 -0
- endoreg_db/data/case_template/template_type/pre_endoscopy.yaml +3 -0
- endoreg_db/data/case_template/tmp/_rule_value +13 -0
- endoreg_db/data/case_template/tmp/rule/01_atrial_fibrillation.yaml +21 -0
- endoreg_db/data/case_template/tmp/rule/02_create_object.yaml +10 -0
- endoreg_db/data/case_template/tmp/template/atrial_fibrillation_low_risk.yaml +7 -0
- endoreg_db/data/center/data.yaml +99 -0
- endoreg_db/data/center_resource/green_endoscopy_dashboard_CenterResource.yaml +144 -0
- endoreg_db/data/center_shift/ukw.yaml +9 -0
- endoreg_db/data/center_waste/green_endoscopy_dashboard_CenterWaste.yaml +48 -0
- endoreg_db/data/contraindication/bleeding.yaml +11 -0
- endoreg_db/data/db_summary.csv +58 -0
- endoreg_db/data/db_summary.xlsx +0 -0
- endoreg_db/data/disease/cardiovascular.yaml +37 -0
- endoreg_db/data/disease/hepatology.yaml +5 -0
- endoreg_db/data/disease/misc.yaml +5 -0
- endoreg_db/data/disease/renal.yaml +5 -0
- endoreg_db/data/disease_classification/chronic_kidney_disease.yaml +6 -0
- endoreg_db/data/disease_classification/coronary_vessel_disease.yaml +6 -0
- endoreg_db/data/disease_classification_choice/chronic_kidney_disease.yaml +41 -0
- endoreg_db/data/disease_classification_choice/coronary_vessel_disease.yaml +20 -0
- endoreg_db/data/distribution/date/patient.yaml +7 -0
- endoreg_db/data/distribution/multiple_categorical/.init +0 -0
- endoreg_db/data/distribution/numeric/data.yaml +14 -0
- endoreg_db/data/distribution/single_categorical/patient.yaml +7 -0
- endoreg_db/data/emission_factor/green_endoscopy_dashboard_EmissionFactor.yaml +132 -0
- endoreg_db/data/endoscope/data.yaml +93 -0
- endoreg_db/data/endoscope_type/data.yaml +11 -0
- endoreg_db/data/endoscopy_processor/data.yaml +50 -0
- endoreg_db/data/event/cardiology.yaml +15 -0
- endoreg_db/data/event/neurology.yaml +14 -0
- endoreg_db/data/event/surgery.yaml +13 -0
- endoreg_db/data/event/thrombembolism.yaml +20 -0
- 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 +172 -0
- endoreg_db/data/examination/time/data.yaml +48 -0
- endoreg_db/data/examination/time-type/data.yaml +5 -0
- endoreg_db/data/examination/type/data.yaml +17 -0
- endoreg_db/data/examination_indication/endoscopy.yaml +359 -0
- endoreg_db/data/examination_indication_classification/endoscopy.yaml +90 -0
- endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +97 -0
- endoreg_db/data/examination_requirement_set/colonoscopy.yaml +15 -0
- 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/00_generic.yaml +15 -0
- endoreg_db/data/finding_classification_choice/00_generic_baseline.yaml +23 -0
- endoreg_db/data/finding_classification_choice/00_generic_complication.yaml +15 -0
- endoreg_db/data/finding_classification_choice/00_generic_histology.yaml +21 -0
- endoreg_db/data/finding_classification_choice/00_generic_lesion.yaml +158 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_bowel_preparation.yaml +49 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_generic.yaml +19 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_histology.yaml +20 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_location.yaml +248 -0
- 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/02_colonoscopy_polyp_morphology.yaml +75 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_size.yaml +27 -0
- endoreg_db/data/finding_classification_type/00_generic.yaml +53 -0
- 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_intervention_type/endoscopy.yaml +15 -0
- endoreg_db/data/finding_type/data.yaml +39 -0
- endoreg_db/data/gender/data.yaml +42 -0
- endoreg_db/data/information_source/annotation.yaml +6 -0
- endoreg_db/data/information_source/data.yaml +30 -0
- endoreg_db/data/information_source/endoscopy_guidelines.yaml +7 -0
- endoreg_db/data/information_source/medication.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/cardiac_enzymes.yaml +37 -0
- endoreg_db/data/lab_value/coagulation.yaml +54 -0
- endoreg_db/data/lab_value/electrolytes.yaml +228 -0
- endoreg_db/data/lab_value/gastrointestinal_function.yaml +133 -0
- endoreg_db/data/lab_value/hematology.yaml +184 -0
- endoreg_db/data/lab_value/hormones.yaml +59 -0
- endoreg_db/data/lab_value/lipids.yaml +53 -0
- endoreg_db/data/lab_value/misc.yaml +76 -0
- endoreg_db/data/lab_value/renal_function.yaml +12 -0
- endoreg_db/data/log_type/data.yaml +57 -0
- endoreg_db/data/lx_client_tag/base.yaml +54 -0
- endoreg_db/data/lx_client_type/base.yaml +30 -0
- endoreg_db/data/lx_permission/base.yaml +24 -0
- endoreg_db/data/lx_permission/endoreg.yaml +52 -0
- endoreg_db/data/material/material.yaml +91 -0
- endoreg_db/data/medication/anticoagulation.yaml +65 -0
- endoreg_db/data/medication/tah.yaml +70 -0
- endoreg_db/data/medication_indication/anticoagulation.yaml +115 -0
- endoreg_db/data/medication_indication_type/data.yaml +11 -0
- endoreg_db/data/medication_indication_type/thrombembolism.yaml +41 -0
- endoreg_db/data/medication_intake_time/base.yaml +31 -0
- endoreg_db/data/medication_schedule/apixaban.yaml +95 -0
- endoreg_db/data/medication_schedule/ass.yaml +12 -0
- endoreg_db/data/medication_schedule/enoxaparin.yaml +26 -0
- endoreg_db/data/names_first/first_names.yaml +54 -0
- endoreg_db/data/names_last/last_names.yaml +51 -0
- endoreg_db/data/network_device/data.yaml +59 -0
- endoreg_db/data/network_device_type/data.yaml +12 -0
- endoreg_db/data/organ/data.yaml +29 -0
- endoreg_db/data/patient_lab_sample_type/generic.yaml +6 -0
- endoreg_db/data/pdf_type/data.yaml +46 -0
- endoreg_db/data/product/green_endoscopy_dashboard_Product.yaml +66 -0
- endoreg_db/data/product_group/green_endoscopy_dashboard_ProductGroup.yaml +33 -0
- endoreg_db/data/product_material/green_endoscopy_dashboard_ProductMaterial.yaml +308 -0
- endoreg_db/data/product_weight/green_endoscopy_dashboard_ProductWeight.yaml +88 -0
- endoreg_db/data/profession/data.yaml +70 -0
- 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/reference_product/green_endoscopy_dashboard_ReferenceProduct.yaml +55 -0
- endoreg_db/data/report_reader_flag/rkh-histology-generic.yaml +10 -0
- endoreg_db/data/report_reader_flag/ukw-examination-generic.yaml +30 -0
- endoreg_db/data/report_reader_flag/ukw-histology-generic.yaml +24 -0
- 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/colonoscopy_baseline_austria.yaml +45 -0
- endoreg_db/data/requirement/old/coloreg_colon_polyp.yaml +49 -0
- endoreg_db/data/requirement/old/disease_cardiovascular.yaml +79 -0
- endoreg_db/data/requirement/old/disease_classification_choice_cardiovascular.yaml +41 -0
- endoreg_db/data/requirement/old/disease_hepatology.yaml +12 -0
- endoreg_db/data/requirement/old/disease_misc.yaml +12 -0
- endoreg_db/data/requirement/old/disease_renal.yaml +96 -0
- endoreg_db/data/requirement/old/endoscopy_bleeding_risk.yaml +59 -0
- endoreg_db/data/requirement/old/event_cardiology.yaml +251 -0
- endoreg_db/data/requirement/old/event_requirements.yaml +145 -0
- endoreg_db/data/requirement/old/finding_colon_polyp.yaml +50 -0
- endoreg_db/data/requirement/old/gender.yaml +0 -0
- endoreg_db/data/requirement/old/lab_value.yaml +441 -0
- endoreg_db/data/requirement/old/medication.yaml +93 -0
- endoreg_db/data/requirement_operator/_old/age.yaml +13 -0
- endoreg_db/data/requirement_operator/_old/lab_operators.yaml +129 -0
- endoreg_db/data/requirement_operator/_old/model_operators.yaml +96 -0
- endoreg_db/data/requirement_operator/new_operators.yaml +36 -0
- endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +65 -0
- endoreg_db/data/requirement_set/01_laboratory.yaml +13 -0
- endoreg_db/data/requirement_set/02_endoscopy_bleeding_risk.yaml +46 -0
- endoreg_db/data/requirement_set/90_coloreg.yaml +190 -0
- endoreg_db/data/requirement_set/_old_ +109 -0
- endoreg_db/data/requirement_set/colonoscopy_austria_screening.yaml +57 -0
- endoreg_db/data/requirement_set_type/data.yaml +41 -0
- endoreg_db/data/requirement_type/requirement_types.yaml +165 -0
- endoreg_db/data/resource/green_endoscopy_dashboard_Resource.yaml +15 -0
- endoreg_db/data/risk/bleeding.yaml +26 -0
- endoreg_db/data/risk/thrombosis.yaml +37 -0
- endoreg_db/data/risk_type/data.yaml +27 -0
- endoreg_db/data/setup_config.yaml +38 -0
- endoreg_db/data/shift/endoscopy.yaml +21 -0
- endoreg_db/data/shift/m2.yaml +0 -0
- endoreg_db/data/shift_type/base.yaml +35 -0
- endoreg_db/data/tag/requirement_set_tags.yaml +32 -0
- endoreg_db/data/tmp/chronic_kidney_disease.yaml +0 -0
- endoreg_db/data/tmp/congestive_heart_failure.yaml +0 -0
- endoreg_db/data/transport_route/green_endoscopy_dashboard_TransportRoute.yaml +12 -0
- endoreg_db/data/unit/concentration.yaml +115 -0
- endoreg_db/data/unit/data.yaml +17 -0
- endoreg_db/data/unit/length.yaml +31 -0
- endoreg_db/data/unit/misc.yaml +20 -0
- endoreg_db/data/unit/rate.yaml +6 -0
- endoreg_db/data/unit/time.yaml +48 -0
- endoreg_db/data/unit/volume.yaml +35 -0
- endoreg_db/data/unit/weight.yaml +38 -0
- endoreg_db/data/waste/data.yaml +12 -0
- endoreg_db/exceptions.py +24 -0
- endoreg_db/export/frames/export.py +6 -0
- endoreg_db/export/frames/export_frames_with_labels.py +616 -0
- endoreg_db/factories/__init__.py +0 -0
- endoreg_db/forms/__init__.py +4 -0
- endoreg_db/forms/examination_form.py +12 -0
- endoreg_db/forms/patient_finding_intervention_form.py +40 -0
- endoreg_db/forms/patient_form.py +23 -0
- endoreg_db/forms/questionnaires/__init__.py +1 -0
- endoreg_db/forms/questionnaires/tto_questionnaire.py +23 -0
- endoreg_db/forms/settings/__init__.py +11 -0
- endoreg_db/forms/unit.py +7 -0
- endoreg_db/helpers/__init__.py +0 -0
- endoreg_db/helpers/count_db.py +48 -0
- endoreg_db/helpers/data_loader.py +280 -0
- endoreg_db/helpers/default_objects.py +414 -0
- endoreg_db/helpers/download_segmentation_model.py +32 -0
- endoreg_db/helpers/interact.py +1 -0
- endoreg_db/helpers/test_video_helper.py +127 -0
- 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 +83 -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 +42 -0
- endoreg_db/import_files/context/validate_directories.py +57 -0
- endoreg_db/import_files/file_storage/__init__.py +15 -0
- endoreg_db/import_files/file_storage/create_report_file.py +99 -0
- endoreg_db/import_files/file_storage/create_video_file.py +104 -0
- endoreg_db/import_files/file_storage/sensitive_meta_storage.py +42 -0
- endoreg_db/import_files/file_storage/state_management.py +463 -0
- endoreg_db/import_files/file_storage/storage.py +42 -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 +99 -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/pseudonymization/__init__.py +0 -0
- endoreg_db/import_files/pseudonymization/fake.py +52 -0
- endoreg_db/import_files/pseudonymization/k_anonymity.py +181 -0
- endoreg_db/import_files/pseudonymization/k_pseudonymity.py +139 -0
- endoreg_db/import_files/pseudonymization/pseudonymize.py +0 -0
- endoreg_db/import_files/report_import_service.py +147 -0
- endoreg_db/import_files/video_import_service.py +154 -0
- endoreg_db/logger_conf.py +156 -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 +132 -0
- endoreg_db/management/commands/create_model_meta_from_huggingface.py +177 -0
- endoreg_db/management/commands/create_multilabel_model_meta.py +419 -0
- endoreg_db/management/commands/export_frame_annot.py +196 -0
- endoreg_db/management/commands/fix_missing_patient_data.py +206 -0
- endoreg_db/management/commands/fix_video_paths.py +186 -0
- endoreg_db/management/commands/import_report.py +361 -0
- endoreg_db/management/commands/list_routes.py +20 -0
- endoreg_db/management/commands/load_ai_model_data.py +83 -0
- endoreg_db/management/commands/load_ai_model_label_data.py +60 -0
- endoreg_db/management/commands/load_base_db_data.py +63 -0
- endoreg_db/management/commands/load_center_data.py +68 -0
- endoreg_db/management/commands/load_contraindication_data.py +39 -0
- endoreg_db/management/commands/load_disease_classification_choices_data.py +38 -0
- endoreg_db/management/commands/load_disease_classification_data.py +38 -0
- endoreg_db/management/commands/load_disease_data.py +59 -0
- endoreg_db/management/commands/load_distribution_data.py +63 -0
- endoreg_db/management/commands/load_endoscope_data.py +58 -0
- endoreg_db/management/commands/load_event_data.py +39 -0
- endoreg_db/management/commands/load_examination_data.py +78 -0
- endoreg_db/management/commands/load_examination_indication_data.py +85 -0
- endoreg_db/management/commands/load_finding_data.py +115 -0
- endoreg_db/management/commands/load_gender_data.py +37 -0
- endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +142 -0
- endoreg_db/management/commands/load_information_source.py +46 -0
- endoreg_db/management/commands/load_lab_value_data.py +52 -0
- endoreg_db/management/commands/load_legacy_data.py +303 -0
- endoreg_db/management/commands/load_medication_data.py +104 -0
- endoreg_db/management/commands/load_name_data.py +36 -0
- endoreg_db/management/commands/load_organ_data.py +39 -0
- endoreg_db/management/commands/load_pdf_type_data.py +58 -0
- endoreg_db/management/commands/load_profession_data.py +40 -0
- endoreg_db/management/commands/load_qualification_data.py +56 -0
- endoreg_db/management/commands/load_report_reader_flag_data.py +40 -0
- endoreg_db/management/commands/load_requirement_data.py +207 -0
- endoreg_db/management/commands/load_requirement_set_tags.py +95 -0
- endoreg_db/management/commands/load_risk_data.py +57 -0
- endoreg_db/management/commands/load_shift_data.py +57 -0
- endoreg_db/management/commands/load_tag_data.py +54 -0
- endoreg_db/management/commands/load_unit_data.py +40 -0
- endoreg_db/management/commands/load_user_groups.py +26 -0
- endoreg_db/management/commands/model_input.py +169 -0
- endoreg_db/management/commands/register_ai_model.py +70 -0
- endoreg_db/management/commands/setup_endoreg_db.py +459 -0
- endoreg_db/management/commands/start_filewatcher.py +115 -0
- endoreg_db/management/commands/storage_management.py +622 -0
- endoreg_db/management/commands/summarize_db_content.py +280 -0
- endoreg_db/management/commands/train_image_multilabel_model.py +144 -0
- endoreg_db/management/commands/validate_video_files.py +189 -0
- endoreg_db/management/commands/video_validation.py +20 -0
- endoreg_db/mermaid/Overall_flow_patient_finding_intervention.md +10 -0
- endoreg_db/mermaid/anonymized_image_annotation.md +20 -0
- endoreg_db/mermaid/binary_classification_annotation.md +50 -0
- endoreg_db/mermaid/classification.md +8 -0
- endoreg_db/mermaid/examination.md +8 -0
- endoreg_db/mermaid/findings.md +7 -0
- endoreg_db/mermaid/image_classification.md +28 -0
- endoreg_db/mermaid/interventions.md +8 -0
- endoreg_db/mermaid/morphology.md +8 -0
- endoreg_db/mermaid/patient_creation.md +14 -0
- endoreg_db/mermaid/video_segmentation_annotation.md +17 -0
- endoreg_db/migrations/0001_initial.py +1953 -0
- endoreg_db/migrations/__init__.py +0 -0
- endoreg_db/models/__init__.py +322 -0
- endoreg_db/models/administration/__init__.py +95 -0
- endoreg_db/models/administration/ai/__init__.py +9 -0
- endoreg_db/models/administration/ai/active_model.py +35 -0
- endoreg_db/models/administration/ai/ai_model.py +180 -0
- endoreg_db/models/administration/ai/model_type.py +42 -0
- endoreg_db/models/administration/case/__init__.py +5 -0
- endoreg_db/models/administration/case/case.py +114 -0
- endoreg_db/models/administration/case/case_template/__init__.py +3 -0
- endoreg_db/models/administration/case/case_template/case_template.py +3 -0
- endoreg_db/models/administration/case/case_template/case_template_rule.py +3 -0
- endoreg_db/models/administration/case/case_template/case_template_rule_value.py +3 -0
- endoreg_db/models/administration/case/case_template/case_template_type.py +3 -0
- endoreg_db/models/administration/center/__init__.py +13 -0
- endoreg_db/models/administration/center/center.py +85 -0
- endoreg_db/models/administration/center/center_product.py +67 -0
- endoreg_db/models/administration/center/center_resource.py +69 -0
- endoreg_db/models/administration/center/center_shift.py +94 -0
- endoreg_db/models/administration/center/center_waste.py +42 -0
- endoreg_db/models/administration/person/__init__.py +26 -0
- endoreg_db/models/administration/person/employee/__init__.py +3 -0
- endoreg_db/models/administration/person/employee/employee.py +40 -0
- endoreg_db/models/administration/person/employee/employee_qualification.py +44 -0
- endoreg_db/models/administration/person/employee/employee_type.py +50 -0
- endoreg_db/models/administration/person/examiner/__init__.py +4 -0
- endoreg_db/models/administration/person/examiner/examiner.py +64 -0
- endoreg_db/models/administration/person/names/__init__.py +0 -0
- endoreg_db/models/administration/person/names/first_name.py +20 -0
- endoreg_db/models/administration/person/names/last_name.py +20 -0
- endoreg_db/models/administration/person/patient/__init__.py +7 -0
- endoreg_db/models/administration/person/patient/patient.py +488 -0
- endoreg_db/models/administration/person/patient/patient_external_id.py +36 -0
- endoreg_db/models/administration/person/person.py +35 -0
- endoreg_db/models/administration/person/profession/__init__.py +28 -0
- endoreg_db/models/administration/person/user/__init__.py +5 -0
- endoreg_db/models/administration/person/user/portal_user_information.py +41 -0
- endoreg_db/models/administration/product/__init__.py +15 -0
- endoreg_db/models/administration/product/product.py +106 -0
- endoreg_db/models/administration/product/product_group.py +41 -0
- endoreg_db/models/administration/product/product_material.py +60 -0
- endoreg_db/models/administration/product/product_weight.py +51 -0
- endoreg_db/models/administration/product/reference_product.py +147 -0
- endoreg_db/models/administration/qualification/__init__.py +7 -0
- endoreg_db/models/administration/qualification/qualification.py +43 -0
- endoreg_db/models/administration/qualification/qualification_type.py +39 -0
- endoreg_db/models/administration/shift/__init__.py +9 -0
- endoreg_db/models/administration/shift/scheduled_days.py +72 -0
- endoreg_db/models/administration/shift/shift.py +57 -0
- endoreg_db/models/administration/shift/shift_type.py +108 -0
- endoreg_db/models/aidataset/__init__.py +5 -0
- endoreg_db/models/aidataset/aidataset.py +193 -0
- endoreg_db/models/label/__init__.py +23 -0
- endoreg_db/models/label/annotation/__init__.py +12 -0
- endoreg_db/models/label/annotation/image_classification.py +85 -0
- endoreg_db/models/label/annotation/video_segmentation_annotation.py +61 -0
- endoreg_db/models/label/label.py +91 -0
- endoreg_db/models/label/label_set.py +68 -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 +42 -0
- endoreg_db/models/label/label_video_segment/label_video_segment.py +611 -0
- endoreg_db/models/label/video_segmentation_label.py +35 -0
- endoreg_db/models/label/video_segmentation_labelset.py +28 -0
- endoreg_db/models/media/__init__.py +23 -0
- endoreg_db/models/media/frame/__init__.py +3 -0
- endoreg_db/models/media/frame/frame.py +137 -0
- endoreg_db/models/media/pdf/__init__.py +12 -0
- endoreg_db/models/media/pdf/raw_pdf.py +764 -0
- endoreg_db/models/media/pdf/report_file.py +162 -0
- endoreg_db/models/media/pdf/report_reader/__init__.py +7 -0
- endoreg_db/models/media/pdf/report_reader/report_reader_config.py +85 -0
- endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +46 -0
- endoreg_db/models/media/video/__init__.py +9 -0
- endoreg_db/models/media/video/create_from_file.py +402 -0
- endoreg_db/models/media/video/pipe_1.py +258 -0
- endoreg_db/models/media/video/pipe_2.py +129 -0
- endoreg_db/models/media/video/video_file.py +907 -0
- endoreg_db/models/media/video/video_file_ai.py +828 -0
- endoreg_db/models/media/video/video_file_anonymize.py +524 -0
- endoreg_db/models/media/video/video_file_frames/__init__.py +49 -0
- endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +25 -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 +126 -0
- endoreg_db/models/media/video/video_file_frames/_extract_frames.py +233 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame.py +36 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +13 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +24 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +40 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +44 -0
- endoreg_db/models/media/video/video_file_frames/_get_frames.py +30 -0
- endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +205 -0
- endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +228 -0
- endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +107 -0
- endoreg_db/models/media/video/video_file_io.py +272 -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 +58 -0
- endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +62 -0
- endoreg_db/models/media/video/video_file_meta/get_fps.py +183 -0
- endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +198 -0
- endoreg_db/models/media/video/video_file_meta/text_meta.py +178 -0
- endoreg_db/models/media/video/video_file_meta/video_meta.py +105 -0
- endoreg_db/models/media/video/video_file_segments.py +317 -0
- endoreg_db/models/media/video/video_metadata.py +67 -0
- endoreg_db/models/media/video/video_processing.py +192 -0
- endoreg_db/models/medical/__init__.py +136 -0
- endoreg_db/models/medical/contraindication/README.md +1 -0
- endoreg_db/models/medical/contraindication/__init__.py +29 -0
- endoreg_db/models/medical/disease.py +174 -0
- endoreg_db/models/medical/event.py +154 -0
- endoreg_db/models/medical/examination/__init__.py +20 -0
- endoreg_db/models/medical/examination/examination.py +183 -0
- endoreg_db/models/medical/examination/examination_indication.py +229 -0
- endoreg_db/models/medical/examination/examination_time.py +68 -0
- endoreg_db/models/medical/examination/examination_time_type.py +44 -0
- endoreg_db/models/medical/examination/examination_type.py +47 -0
- endoreg_db/models/medical/finding/__init__.py +20 -0
- endoreg_db/models/medical/finding/finding.py +113 -0
- endoreg_db/models/medical/finding/finding_classification.py +131 -0
- endoreg_db/models/medical/finding/finding_intervention.py +68 -0
- endoreg_db/models/medical/finding/finding_type.py +38 -0
- endoreg_db/models/medical/hardware/__init__.py +8 -0
- endoreg_db/models/medical/hardware/endoscope.py +77 -0
- endoreg_db/models/medical/hardware/endoscopy_processor.py +182 -0
- endoreg_db/models/medical/laboratory/__init__.py +5 -0
- endoreg_db/models/medical/laboratory/lab_value.py +490 -0
- endoreg_db/models/medical/medication/__init__.py +23 -0
- endoreg_db/models/medical/medication/medication.py +45 -0
- endoreg_db/models/medical/medication/medication_indication.py +78 -0
- endoreg_db/models/medical/medication/medication_indication_type.py +58 -0
- endoreg_db/models/medical/medication/medication_intake_time.py +58 -0
- endoreg_db/models/medical/medication/medication_schedule.py +58 -0
- endoreg_db/models/medical/organ/__init__.py +38 -0
- endoreg_db/models/medical/patient/__init__.py +48 -0
- endoreg_db/models/medical/patient/medication_examples.py +56 -0
- endoreg_db/models/medical/patient/patient_disease.py +72 -0
- endoreg_db/models/medical/patient/patient_event.py +80 -0
- endoreg_db/models/medical/patient/patient_examination.py +280 -0
- endoreg_db/models/medical/patient/patient_examination_indication.py +57 -0
- endoreg_db/models/medical/patient/patient_finding.py +416 -0
- endoreg_db/models/medical/patient/patient_finding_classification.py +231 -0
- endoreg_db/models/medical/patient/patient_finding_intervention.py +37 -0
- endoreg_db/models/medical/patient/patient_lab_sample.py +157 -0
- endoreg_db/models/medical/patient/patient_lab_value.py +247 -0
- endoreg_db/models/medical/patient/patient_medication.py +111 -0
- endoreg_db/models/medical/patient/patient_medication_schedule.py +152 -0
- endoreg_db/models/medical/risk/__init__.py +7 -0
- endoreg_db/models/medical/risk/risk.py +73 -0
- endoreg_db/models/medical/risk/risk_type.py +54 -0
- endoreg_db/models/metadata/__init__.py +19 -0
- endoreg_db/models/metadata/model_meta.py +266 -0
- endoreg_db/models/metadata/model_meta_logic.py +485 -0
- endoreg_db/models/metadata/pdf_meta.py +96 -0
- endoreg_db/models/metadata/sensitive_meta.py +345 -0
- endoreg_db/models/metadata/sensitive_meta_logic.py +1161 -0
- endoreg_db/models/metadata/video_meta.py +459 -0
- endoreg_db/models/metadata/video_prediction_logic.py +232 -0
- endoreg_db/models/metadata/video_prediction_meta.py +319 -0
- endoreg_db/models/operation_log.py +63 -0
- endoreg_db/models/other/__init__.py +40 -0
- endoreg_db/models/other/distribution/__init__.py +46 -0
- endoreg_db/models/other/distribution/base_value_distribution.py +22 -0
- endoreg_db/models/other/distribution/date_value_distribution.py +163 -0
- endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +50 -0
- endoreg_db/models/other/distribution/numeric_value_distribution.py +211 -0
- endoreg_db/models/other/distribution/single_categorical_value_distribution.py +23 -0
- endoreg_db/models/other/emission/__init__.py +5 -0
- endoreg_db/models/other/emission/emission_factor.py +110 -0
- endoreg_db/models/other/gender.py +32 -0
- endoreg_db/models/other/information_source.py +190 -0
- endoreg_db/models/other/material.py +34 -0
- endoreg_db/models/other/resource.py +24 -0
- endoreg_db/models/other/tag.py +32 -0
- endoreg_db/models/other/transport_route.py +40 -0
- endoreg_db/models/other/unit.py +40 -0
- endoreg_db/models/other/waste.py +28 -0
- endoreg_db/models/report/__init__.py +0 -0
- endoreg_db/models/report/images.py +0 -0
- endoreg_db/models/report/report.py +5 -0
- endoreg_db/models/requirement/__init__.py +11 -0
- endoreg_db/models/requirement/requirement.py +792 -0
- endoreg_db/models/requirement/requirement_error.py +84 -0
- endoreg_db/models/requirement/requirement_evaluation/__init__.py +6 -0
- endoreg_db/models/requirement/requirement_evaluation/evaluate_with_dependencies.py +268 -0
- endoreg_db/models/requirement/requirement_evaluation/get_values.py +40 -0
- endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +6 -0
- endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +137 -0
- endoreg_db/models/requirement/requirement_operator.py +187 -0
- endoreg_db/models/requirement/requirement_set.py +327 -0
- endoreg_db/models/state/__init__.py +13 -0
- endoreg_db/models/state/abstract.py +11 -0
- endoreg_db/models/state/anonymization.py +30 -0
- endoreg_db/models/state/audit_ledger.py +155 -0
- endoreg_db/models/state/label_video_segment.py +31 -0
- endoreg_db/models/state/processing_history/__init__.py +3 -0
- endoreg_db/models/state/processing_history/processing_history.py +136 -0
- endoreg_db/models/state/raw_pdf.py +219 -0
- endoreg_db/models/state/sensitive_meta.py +50 -0
- endoreg_db/models/state/video.py +251 -0
- endoreg_db/models/upload_job.py +100 -0
- endoreg_db/models/utils.py +138 -0
- endoreg_db/queries/__init__.py +3 -0
- endoreg_db/queries/annotations/__init__.py +1 -0
- endoreg_db/queries/annotations/legacy.py +169 -0
- endoreg_db/queries/sanity/__init_.py +0 -0
- endoreg_db/root_urls.py +27 -0
- endoreg_db/schemas/__init__.py +0 -0
- endoreg_db/schemas/examination_evaluation.py +30 -0
- endoreg_db/serializers/Frames_NICE_and_PARIS_classifications.py +861 -0
- endoreg_db/serializers/__init__.py +104 -0
- endoreg_db/serializers/administration/__init__.py +13 -0
- endoreg_db/serializers/administration/ai/__init__.py +9 -0
- endoreg_db/serializers/administration/ai/active_model.py +12 -0
- endoreg_db/serializers/administration/ai/ai_model.py +20 -0
- endoreg_db/serializers/administration/ai/model_type.py +12 -0
- endoreg_db/serializers/administration/center.py +14 -0
- endoreg_db/serializers/administration/gender.py +11 -0
- endoreg_db/serializers/anonymization.py +77 -0
- endoreg_db/serializers/evaluation/examination_evaluation.py +0 -0
- endoreg_db/serializers/examination/__init__.py +10 -0
- endoreg_db/serializers/examination/base.py +45 -0
- endoreg_db/serializers/examination/dropdown.py +20 -0
- endoreg_db/serializers/examination_serializer.py +9 -0
- endoreg_db/serializers/finding/__init__.py +5 -0
- endoreg_db/serializers/finding/finding.py +61 -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 +11 -0
- endoreg_db/serializers/label_video_segment/__init__.py +9 -0
- endoreg_db/serializers/label_video_segment/image_classification_annotation.py +62 -0
- endoreg_db/serializers/label_video_segment/label/__init__.py +6 -0
- endoreg_db/serializers/label_video_segment/label/label.py +15 -0
- endoreg_db/serializers/label_video_segment/label_video_segment.py +427 -0
- endoreg_db/serializers/meta/__init__.py +13 -0
- endoreg_db/serializers/meta/sensitive_meta_detail.py +122 -0
- endoreg_db/serializers/meta/sensitive_meta_update.py +153 -0
- endoreg_db/serializers/meta/sensitive_meta_verification.py +62 -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 +72 -0
- endoreg_db/serializers/misc/sensitive_patient_data.py +144 -0
- endoreg_db/serializers/misc/stats.py +35 -0
- endoreg_db/serializers/misc/translatable_field_mix_in.py +44 -0
- endoreg_db/serializers/misc/upload_job.py +74 -0
- endoreg_db/serializers/patient/__init__.py +12 -0
- endoreg_db/serializers/patient/patient.py +103 -0
- endoreg_db/serializers/patient/patient_dropdown.py +35 -0
- endoreg_db/serializers/patient_examination/__init__.py +7 -0
- endoreg_db/serializers/patient_examination/patient_examination.py +168 -0
- endoreg_db/serializers/patient_finding/__init__.py +15 -0
- endoreg_db/serializers/patient_finding/patient_finding.py +32 -0
- endoreg_db/serializers/patient_finding/patient_finding_classification.py +47 -0
- endoreg_db/serializers/patient_finding/patient_finding_detail.py +62 -0
- endoreg_db/serializers/patient_finding/patient_finding_intervention.py +28 -0
- endoreg_db/serializers/patient_finding/patient_finding_list.py +40 -0
- endoreg_db/serializers/patient_finding/patient_finding_write.py +135 -0
- endoreg_db/serializers/pdf/__init__.py +3 -0
- endoreg_db/serializers/pdf/anony_text_validation.py +101 -0
- endoreg_db/serializers/requirements/requirement_schema.py +20 -0
- endoreg_db/serializers/requirements/requirement_sets.py +99 -0
- endoreg_db/serializers/sensitive_meta_serializer.py +301 -0
- endoreg_db/serializers/video/__init__.py +7 -0
- endoreg_db/serializers/video/video_file.py +283 -0
- endoreg_db/serializers/video/video_file_brief.py +14 -0
- endoreg_db/serializers/video/video_file_detail.py +96 -0
- endoreg_db/serializers/video/video_file_list.py +100 -0
- endoreg_db/serializers/video/video_processing_history.py +172 -0
- endoreg_db/serializers/video_examination.py +198 -0
- endoreg_db/services/__init__.py +5 -0
- endoreg_db/services/anonymization.py +274 -0
- endoreg_db/services/examination_evaluation.py +172 -0
- endoreg_db/services/finding_description_service.py +0 -0
- endoreg_db/services/lookup_service.py +424 -0
- endoreg_db/services/lookup_store.py +266 -0
- endoreg_db/services/model_meta_from_hf.py +76 -0
- endoreg_db/services/pdf_import.py +0 -0
- endoreg_db/services/polling_coordinator.py +319 -0
- endoreg_db/services/pseudonym_service.py +94 -0
- endoreg_db/services/report_import.py +13 -0
- endoreg_db/services/segment_sync.py +171 -0
- endoreg_db/services/video_import.py +9 -0
- endoreg_db/templates/admin/patient_finding_intervention.html +253 -0
- endoreg_db/templates/admin/start_examination.html +12 -0
- endoreg_db/templates/timeline.html +176 -0
- endoreg_db/urls/__init__.py +56 -0
- endoreg_db/urls/ai.py +14 -0
- endoreg_db/urls/anonymization.py +78 -0
- endoreg_db/urls/auth.py +16 -0
- endoreg_db/urls/classification.py +34 -0
- endoreg_db/urls/examination.py +63 -0
- endoreg_db/urls/media.py +251 -0
- endoreg_db/urls/patient.py +23 -0
- endoreg_db/urls/requirements.py +15 -0
- endoreg_db/urls/root_urls.py +28 -0
- endoreg_db/urls/stats.py +54 -0
- endoreg_db/urls/upload.py +12 -0
- endoreg_db/urls.py +9 -0
- endoreg_db/utils/__init__.py +97 -0
- endoreg_db/utils/ai/__init__.py +9 -0
- endoreg_db/utils/ai/data_loader_for_model_input.py +262 -0
- endoreg_db/utils/ai/data_loader_for_model_training.py +262 -0
- endoreg_db/utils/ai/get.py +6 -0
- endoreg_db/utils/ai/inference_dataset.py +51 -0
- endoreg_db/utils/ai/model_training/config.py +117 -0
- endoreg_db/utils/ai/model_training/dataset.py +74 -0
- endoreg_db/utils/ai/model_training/losses.py +68 -0
- endoreg_db/utils/ai/model_training/metrics.py +78 -0
- endoreg_db/utils/ai/model_training/model_backbones.py +155 -0
- endoreg_db/utils/ai/model_training/model_gastronet_resnet.py +118 -0
- endoreg_db/utils/ai/model_training/trainer_gastronet_multilabel.py +771 -0
- endoreg_db/utils/ai/multilabel_classification_net.py +270 -0
- endoreg_db/utils/ai/postprocess.py +63 -0
- endoreg_db/utils/ai/predict.py +293 -0
- endoreg_db/utils/ai/preprocess.py +76 -0
- endoreg_db/utils/calc_duration_seconds.py +24 -0
- endoreg_db/utils/case_generator/__init__.py +3 -0
- endoreg_db/utils/case_generator/lab_sample_factory.py +32 -0
- endoreg_db/utils/check_video_files.py +175 -0
- endoreg_db/utils/cropping.py +30 -0
- endoreg_db/utils/dataloader.py +285 -0
- endoreg_db/utils/dates.py +59 -0
- endoreg_db/utils/defaults/set_default_center.py +33 -0
- endoreg_db/utils/env.py +37 -0
- endoreg_db/utils/extract_specific_frames.py +87 -0
- endoreg_db/utils/file_operations.py +70 -0
- endoreg_db/utils/fix_video_path_direct.py +157 -0
- endoreg_db/utils/frame_anonymization_utils.py +463 -0
- endoreg_db/utils/hashs.py +138 -0
- endoreg_db/utils/links/__init__.py +0 -0
- endoreg_db/utils/links/requirement_link.py +237 -0
- endoreg_db/utils/mime_types.py +0 -0
- endoreg_db/utils/names.py +82 -0
- endoreg_db/utils/ocr.py +195 -0
- endoreg_db/utils/operation_log.py +87 -0
- endoreg_db/utils/parse_and_generate_yaml.py +45 -0
- endoreg_db/utils/paths.py +159 -0
- endoreg_db/utils/permissions.py +160 -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 +144 -0
- endoreg_db/utils/product/__init__.py +0 -0
- endoreg_db/utils/product/sum_emissions.py +22 -0
- endoreg_db/utils/product/sum_weights.py +20 -0
- endoreg_db/utils/pydantic_models/__init__.py +5 -0
- endoreg_db/utils/pydantic_models/db_config.py +57 -0
- endoreg_db/utils/requirement_helpers.py +0 -0
- endoreg_db/utils/requirement_operator_logic/__init__.py +0 -0
- endoreg_db/utils/requirement_operator_logic/_old/lab_value_operators.py +678 -0
- endoreg_db/utils/requirement_operator_logic/_old/model_evaluators.py +842 -0
- endoreg_db/utils/requirement_operator_logic/new_operator_logic.py +114 -0
- endoreg_db/utils/setup_config.py +196 -0
- endoreg_db/utils/storage.py +117 -0
- endoreg_db/utils/translation.py +31 -0
- endoreg_db/utils/uuid.py +5 -0
- endoreg_db/utils/validate_endo_roi.py +33 -0
- endoreg_db/utils/validate_subcategory_dict.py +93 -0
- endoreg_db/utils/validate_video_detailed.py +415 -0
- endoreg_db/utils/video/__init__.py +30 -0
- endoreg_db/utils/video/extract_frames.py +100 -0
- endoreg_db/utils/video/ffmpeg_wrapper.py +996 -0
- endoreg_db/utils/video/names.py +47 -0
- endoreg_db/utils/video/streaming_processor.py +386 -0
- endoreg_db/utils/video/video_splitter.py +105 -0
- endoreg_db/versioning.md +79 -0
- endoreg_db/views/Frames_NICE_and_PARIS_classifications_views.py +247 -0
- endoreg_db/views/__init__.py +157 -0
- endoreg_db/views/anonymization/__init__.py +31 -0
- endoreg_db/views/anonymization/media_management.py +486 -0
- endoreg_db/views/anonymization/overview.py +307 -0
- endoreg_db/views/anonymization/validate.py +310 -0
- endoreg_db/views/auth/__init__.py +13 -0
- endoreg_db/views/auth/keycloak.py +146 -0
- endoreg_db/views/examination/__init__.py +30 -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 +62 -0
- endoreg_db/views/examination/get_finding_classifications.py +38 -0
- endoreg_db/views/examination/get_findings.py +39 -0
- endoreg_db/views/examination/get_instruments.py +19 -0
- endoreg_db/views/examination/get_interventions.py +14 -0
- endoreg_db/views/finding/__init__.py +9 -0
- endoreg_db/views/finding/finding.py +116 -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 +41 -0
- endoreg_db/views/finding_classification/get_classification_choices.py +54 -0
- endoreg_db/views/media/__init__.py +32 -0
- endoreg_db/views/media/pdf_media.py +411 -0
- endoreg_db/views/media/sensitive_metadata.py +372 -0
- endoreg_db/views/media/video_media.py +275 -0
- endoreg_db/views/meta/__init__.py +7 -0
- endoreg_db/views/meta/sensitive_meta_list.py +102 -0
- endoreg_db/views/meta/sensitive_meta_verification.py +74 -0
- endoreg_db/views/misc/__init__.py +29 -0
- endoreg_db/views/misc/center.py +14 -0
- endoreg_db/views/misc/csrf.py +8 -0
- endoreg_db/views/misc/gender.py +15 -0
- endoreg_db/views/misc/stats.py +255 -0
- endoreg_db/views/misc/upload_views.py +241 -0
- endoreg_db/views/patient/__init__.py +3 -0
- endoreg_db/views/patient/patient.py +253 -0
- endoreg_db/views/patient_examination/__init__.py +11 -0
- endoreg_db/views/patient_examination/patient_examination.py +141 -0
- endoreg_db/views/patient_examination/patient_examination_create.py +58 -0
- endoreg_db/views/patient_examination/patient_examination_detail.py +63 -0
- endoreg_db/views/patient_examination/patient_examination_list.py +72 -0
- endoreg_db/views/patient_examination/video.py +228 -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 +71 -0
- endoreg_db/views/patient_finding/patient_finding_optimized.py +291 -0
- endoreg_db/views/patient_finding_classification/__init__.py +5 -0
- endoreg_db/views/patient_finding_classification/pfc_create.py +75 -0
- endoreg_db/views/report/__init__.py +7 -0
- endoreg_db/views/report/reimport.py +177 -0
- endoreg_db/views/report/report_stream.py +191 -0
- endoreg_db/views/requirement/__init__.py +11 -0
- endoreg_db/views/requirement/evaluate.py +278 -0
- endoreg_db/views/requirement/lookup.py +380 -0
- endoreg_db/views/requirement/lookup_store.py +183 -0
- endoreg_db/views/requirement/requirement_utils.py +87 -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 +266 -0
- endoreg_db/views/video/__init__.py +49 -0
- endoreg_db/views/video/ai/__init__.py +8 -0
- endoreg_db/views/video/ai/label.py +159 -0
- endoreg_db/views/video/correction.py +529 -0
- endoreg_db/views/video/reimport.py +230 -0
- endoreg_db/views/video/segments_crud.py +709 -0
- endoreg_db/views/video/video_apply_mask.py +49 -0
- endoreg_db/views/video/video_correction.py +22 -0
- endoreg_db/views/video/video_download_processed.py +58 -0
- endoreg_db/views/video/video_examination_viewset.py +242 -0
- endoreg_db/views/video/video_metadata.py +101 -0
- endoreg_db/views/video/video_processing_history.py +25 -0
- endoreg_db/views/video/video_remove_frames.py +49 -0
- endoreg_db/views/video/video_stream.py +334 -0
- endoreg_db-0.8.9.32.dist-info/METADATA +404 -0
- endoreg_db-0.8.9.32.dist-info/RECORD +787 -0
- endoreg_db-0.8.9.32.dist-info/WHEEL +4 -0
- endoreg_db-0.8.9.32.dist-info/licenses/LICENSE +674 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from django.conf import settings
|
|
4
|
+
from rest_framework import serializers
|
|
5
|
+
|
|
6
|
+
from ...models import RawPdfFile
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class RawPdfAnonyTextSerializer(serializers.ModelSerializer):
|
|
10
|
+
"""
|
|
11
|
+
Serializer to fetch report metadata along with `anonymized_text` from `RawPdfFile`.
|
|
12
|
+
Ensures Vue.js can process JSON efficiently.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
pdf_url = serializers.SerializerMethodField()
|
|
16
|
+
full_pdf_path = serializers.SerializerMethodField()
|
|
17
|
+
file = serializers.SerializerMethodField()
|
|
18
|
+
|
|
19
|
+
class Meta:
|
|
20
|
+
model = RawPdfFile
|
|
21
|
+
fields = [
|
|
22
|
+
"id",
|
|
23
|
+
"file",
|
|
24
|
+
"pdf_url",
|
|
25
|
+
"full_pdf_path",
|
|
26
|
+
"sensitive_meta_id",
|
|
27
|
+
"anonymized_text",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
@staticmethod
|
|
31
|
+
def get_next_pdf(last_id=None):
|
|
32
|
+
"""
|
|
33
|
+
Retrieves the first available report if `last_id` is NOT provided.
|
|
34
|
+
Otherwise, fetches the next available report where `id > last_id`.
|
|
35
|
+
"""
|
|
36
|
+
query_filter = {} if last_id is None else {"id__gt": int(last_id)}
|
|
37
|
+
pdf_entry = RawPdfFile.objects.filter(**query_filter).order_by("id").first()
|
|
38
|
+
return pdf_entry
|
|
39
|
+
|
|
40
|
+
def get_pdf_url(self, obj):
|
|
41
|
+
"""
|
|
42
|
+
Returns the absolute URL for accessing the anonymized text report endpoint for the given object.
|
|
43
|
+
|
|
44
|
+
If the request context or file is missing, returns None.
|
|
45
|
+
"""
|
|
46
|
+
request = self.context.get("request")
|
|
47
|
+
return (
|
|
48
|
+
request.build_absolute_uri(f"/pdf/anony_text/?id={obj.id}")
|
|
49
|
+
if request and obj.file
|
|
50
|
+
else None
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
def get_file(self, obj):
|
|
54
|
+
"""
|
|
55
|
+
Retrieves the relative file path of the report from the model instance.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
The relative file path as a string, or None if no file is associated.
|
|
59
|
+
"""
|
|
60
|
+
return str(obj.file.name).strip() if obj.file else None
|
|
61
|
+
|
|
62
|
+
def get_full_pdf_path(self, obj):
|
|
63
|
+
"""
|
|
64
|
+
Constructs the full absolute file path using `settings.MEDIA_ROOT`.
|
|
65
|
+
"""
|
|
66
|
+
if not obj.file:
|
|
67
|
+
return None
|
|
68
|
+
pdf_relative_path = str(obj.file.name)
|
|
69
|
+
full_path = Path(settings.MEDIA_ROOT) / pdf_relative_path
|
|
70
|
+
return str(full_path) if full_path.exists() else None
|
|
71
|
+
|
|
72
|
+
def validate_anonymized_text(self, value):
|
|
73
|
+
"""
|
|
74
|
+
Validates that the anonymized text is non-empty and does not exceed 5000 characters.
|
|
75
|
+
|
|
76
|
+
Raises:
|
|
77
|
+
serializers.ValidationError: If the text is empty or exceeds the length limit.
|
|
78
|
+
"""
|
|
79
|
+
if not value.strip():
|
|
80
|
+
raise serializers.ValidationError("Anonymized text cannot be empty.")
|
|
81
|
+
# FIXME move this to a settings variable @Hamzaukw @maxhild
|
|
82
|
+
if len(value) > 5000: # Arbitrary limit to prevent excessively long text
|
|
83
|
+
raise serializers.ValidationError(
|
|
84
|
+
"Anonymized text exceeds the maximum length of 5000 characters."
|
|
85
|
+
)
|
|
86
|
+
return value
|
|
87
|
+
|
|
88
|
+
def update(self, instance, validated_data):
|
|
89
|
+
"""
|
|
90
|
+
Update the `anonymized_text` field of a RawPdfFile instance with validated data.
|
|
91
|
+
|
|
92
|
+
Only the `anonymized_text` field is modified; all other fields remain unchanged.
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
The updated RawPdfFile instance.
|
|
96
|
+
"""
|
|
97
|
+
instance.anonymized_text = validated_data.get(
|
|
98
|
+
"anonymized_text", instance.anonymized_text
|
|
99
|
+
)
|
|
100
|
+
instance.save()
|
|
101
|
+
return instance
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
from typing import List
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class RequirementSchema(BaseModel):
|
|
6
|
+
id: int
|
|
7
|
+
name: str
|
|
8
|
+
description: str
|
|
9
|
+
satisfied: bool
|
|
10
|
+
message: str
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class RequirementSetSchema(BaseModel):
|
|
14
|
+
id: int
|
|
15
|
+
name: str
|
|
16
|
+
description: str
|
|
17
|
+
is_satisfied: bool
|
|
18
|
+
requirements: List[RequirementSchema]
|
|
19
|
+
linked_sets: List["RequirementSetSchema"]
|
|
20
|
+
messages: List[str]
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
from rest_framework import serializers
|
|
2
|
+
|
|
3
|
+
from endoreg_db.models.requirement.requirement_set import RequirementSet
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class RequirementSetSerializer(serializers.ModelSerializer):
|
|
7
|
+
"""
|
|
8
|
+
Serializer for RequirementSet model with optional tag field.
|
|
9
|
+
|
|
10
|
+
This serializer provides a flexible representation of requirement sets,
|
|
11
|
+
including role-based tags for filtering (e.g., "Gastroenterologist", "Student").
|
|
12
|
+
|
|
13
|
+
Fields:
|
|
14
|
+
id: Primary key
|
|
15
|
+
name: Display name of the requirement set
|
|
16
|
+
description: Optional description text
|
|
17
|
+
requirement_set_type: Type classification
|
|
18
|
+
tags: List of tag names (optional, read-only)
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
tags = serializers.SlugRelatedField(
|
|
22
|
+
many=True, read_only=True, slug_field="name", required=False
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
requirement_set_type = serializers.CharField(
|
|
26
|
+
source="requirement_set_type.name", read_only=True, allow_null=True
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
class Meta:
|
|
30
|
+
model = RequirementSet
|
|
31
|
+
fields = ["id", "name", "description", "requirement_set_type", "tags"]
|
|
32
|
+
|
|
33
|
+
def to_representation(self, instance):
|
|
34
|
+
"""
|
|
35
|
+
Customize representation to exclude tags field if empty or not prefetched.
|
|
36
|
+
|
|
37
|
+
This prevents N+1 query issues and keeps the response clean when tags
|
|
38
|
+
aren't needed or weren't prefetched in the queryset.
|
|
39
|
+
"""
|
|
40
|
+
representation = super().to_representation(instance)
|
|
41
|
+
|
|
42
|
+
# Only include tags if they exist and were prefetched
|
|
43
|
+
if not representation.get("tags"):
|
|
44
|
+
representation.pop("tags", None)
|
|
45
|
+
|
|
46
|
+
return representation
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def requirement_set_to_dict(requirement_set: RequirementSet) -> dict:
|
|
50
|
+
"""
|
|
51
|
+
Convert a RequirementSet instance to a dictionary representation.
|
|
52
|
+
|
|
53
|
+
This function performs additional queries to fetch related data including
|
|
54
|
+
requirements and linked sets. Use RequirementSetSerializer for simpler
|
|
55
|
+
representations without the overhead of additional queries.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
requirement_set: The RequirementSet instance to convert.
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
Dictionary representation of the RequirementSet with full nested details:
|
|
62
|
+
- id, name, description: Basic metadata
|
|
63
|
+
- requirements: List of requirement dictionaries
|
|
64
|
+
- links: List of linked requirement set data
|
|
65
|
+
- tags: List of tag names (if any exist)
|
|
66
|
+
"""
|
|
67
|
+
# Fetch the requirement set with all related data to avoid N+1 queries
|
|
68
|
+
requirement_set_full = (
|
|
69
|
+
RequirementSet.objects.select_related("requirement_set_type")
|
|
70
|
+
.prefetch_related("requirements", "links_to_sets", "tags")
|
|
71
|
+
.get(pk=requirement_set.pk)
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Get linked requirement sets
|
|
75
|
+
linked_sets = requirement_set_full.links_to_sets.all()
|
|
76
|
+
|
|
77
|
+
result = {
|
|
78
|
+
"id": requirement_set_full.pk,
|
|
79
|
+
"name": requirement_set_full.name,
|
|
80
|
+
"description": requirement_set_full.description or "",
|
|
81
|
+
"requirement_set_type": requirement_set_full.requirement_set_type.name
|
|
82
|
+
if requirement_set_full.requirement_set_type
|
|
83
|
+
else None,
|
|
84
|
+
"requirements": [
|
|
85
|
+
{"id": req.pk, "name": req.name, "description": req.description or ""}
|
|
86
|
+
for req in requirement_set_full.requirements.all()
|
|
87
|
+
],
|
|
88
|
+
"linked_sets": [
|
|
89
|
+
{"id": link.pk, "name": link.name, "description": link.description or ""}
|
|
90
|
+
for link in linked_sets
|
|
91
|
+
],
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# Add tags if they exist
|
|
95
|
+
tags = list(requirement_set_full.tags.values_list("name", flat=True))
|
|
96
|
+
if tags:
|
|
97
|
+
result["tags"] = tags
|
|
98
|
+
|
|
99
|
+
return result
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
from rest_framework import serializers
|
|
2
|
+
from django.db import transaction
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
from ..models import SensitiveMeta, Center, Gender
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SensitiveMetaDetailSerializer(serializers.ModelSerializer):
|
|
11
|
+
"""
|
|
12
|
+
Serializer for displaying SensitiveMeta details with verification state.
|
|
13
|
+
Includes all relevant fields for annotation and verification.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
# State verification fields
|
|
17
|
+
is_verified = serializers.SerializerMethodField()
|
|
18
|
+
dob_verified = serializers.SerializerMethodField()
|
|
19
|
+
names_verified = serializers.SerializerMethodField()
|
|
20
|
+
|
|
21
|
+
# Related fields for better display
|
|
22
|
+
center_name = serializers.CharField(source="center.name", read_only=True)
|
|
23
|
+
patient_gender_name = serializers.CharField(
|
|
24
|
+
source="patient_gender.name", read_only=True
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# Examiner information
|
|
28
|
+
examiners_display = serializers.SerializerMethodField()
|
|
29
|
+
|
|
30
|
+
# Formatted dates for display
|
|
31
|
+
patient_dob_display = serializers.SerializerMethodField()
|
|
32
|
+
examination_date_display = serializers.SerializerMethodField()
|
|
33
|
+
|
|
34
|
+
# Hash displays (last 8 characters for security)
|
|
35
|
+
patient_hash_display = serializers.SerializerMethodField()
|
|
36
|
+
examination_hash_display = serializers.SerializerMethodField()
|
|
37
|
+
|
|
38
|
+
class Meta:
|
|
39
|
+
model = SensitiveMeta
|
|
40
|
+
fields = [
|
|
41
|
+
"id",
|
|
42
|
+
"patient_first_name",
|
|
43
|
+
"patient_last_name",
|
|
44
|
+
"patient_dob",
|
|
45
|
+
"patient_dob_display",
|
|
46
|
+
"examination_date",
|
|
47
|
+
"examination_date_display",
|
|
48
|
+
"center_name",
|
|
49
|
+
"patient_gender_name",
|
|
50
|
+
"endoscope_type",
|
|
51
|
+
"endoscope_sn",
|
|
52
|
+
"patient_hash_display",
|
|
53
|
+
"examination_hash_display",
|
|
54
|
+
"examiners_display",
|
|
55
|
+
"is_verified",
|
|
56
|
+
"dob_verified",
|
|
57
|
+
"names_verified",
|
|
58
|
+
]
|
|
59
|
+
read_only_fields = [
|
|
60
|
+
"id",
|
|
61
|
+
"patient_hash_display",
|
|
62
|
+
"examination_hash_display",
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
def get_is_verified(self, obj):
|
|
66
|
+
"""Get overall verification status."""
|
|
67
|
+
try:
|
|
68
|
+
return obj.is_verified
|
|
69
|
+
except AttributeError:
|
|
70
|
+
return False
|
|
71
|
+
except Exception as e:
|
|
72
|
+
logger.exception(
|
|
73
|
+
f"Unexpected error in get_is_verified for SensitiveMeta {getattr(obj, 'pk', None)}: {e}"
|
|
74
|
+
)
|
|
75
|
+
raise
|
|
76
|
+
|
|
77
|
+
def get_dob_verified(self, obj):
|
|
78
|
+
"""Get DOB verification status."""
|
|
79
|
+
try:
|
|
80
|
+
return obj.state.dob_verified
|
|
81
|
+
except Exception:
|
|
82
|
+
return False
|
|
83
|
+
|
|
84
|
+
def get_names_verified(self, obj):
|
|
85
|
+
"""Get names verification status."""
|
|
86
|
+
try:
|
|
87
|
+
return obj.state.names_verified
|
|
88
|
+
except Exception:
|
|
89
|
+
return False
|
|
90
|
+
|
|
91
|
+
def get_examiners_display(self, obj):
|
|
92
|
+
"""Get formatted examiner names."""
|
|
93
|
+
try:
|
|
94
|
+
if obj.pk:
|
|
95
|
+
examiners = obj.examiners.all()
|
|
96
|
+
return [f"{e.first_name} {e.last_name}" for e in examiners]
|
|
97
|
+
return []
|
|
98
|
+
except Exception as e:
|
|
99
|
+
logger.warning(f"Error getting examiners for SensitiveMeta {obj.pk}: {e}")
|
|
100
|
+
return []
|
|
101
|
+
|
|
102
|
+
def get_patient_dob_display(self, obj):
|
|
103
|
+
"""Get formatted DOB for display."""
|
|
104
|
+
if obj.patient_dob:
|
|
105
|
+
return obj.patient_dob.strftime("%Y-%m-%d")
|
|
106
|
+
return None
|
|
107
|
+
|
|
108
|
+
def get_examination_date_display(self, obj):
|
|
109
|
+
"""Get formatted examination date for display."""
|
|
110
|
+
if obj.examination_date:
|
|
111
|
+
return obj.examination_date.strftime("%Y-%m-%d")
|
|
112
|
+
return None
|
|
113
|
+
|
|
114
|
+
def get_patient_hash_display(self, obj):
|
|
115
|
+
"""Get truncated patient hash for display."""
|
|
116
|
+
if obj.patient_hash:
|
|
117
|
+
return f"...{obj.patient_hash[-8:]}"
|
|
118
|
+
return None
|
|
119
|
+
|
|
120
|
+
def get_examination_hash_display(self, obj):
|
|
121
|
+
"""Get truncated examination hash for display."""
|
|
122
|
+
if obj.examination_hash:
|
|
123
|
+
return f"...{obj.examination_hash[-8:]}"
|
|
124
|
+
return None
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class SensitiveMetaUpdateSerializer(serializers.ModelSerializer):
|
|
128
|
+
"""
|
|
129
|
+
Serializer for updating SensitiveMeta fields including verification state.
|
|
130
|
+
Handles partial updates and state management.
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
# Verification state fields
|
|
134
|
+
dob_verified = serializers.BooleanField(required=False)
|
|
135
|
+
names_verified = serializers.BooleanField(required=False)
|
|
136
|
+
|
|
137
|
+
# Center can be updated by name
|
|
138
|
+
center_name = serializers.CharField(write_only=True, required=False)
|
|
139
|
+
|
|
140
|
+
# Gender can be updated by name
|
|
141
|
+
patient_gender_name = serializers.CharField(write_only=True, required=False)
|
|
142
|
+
|
|
143
|
+
class Meta:
|
|
144
|
+
model = SensitiveMeta
|
|
145
|
+
fields = [
|
|
146
|
+
"patient_first_name",
|
|
147
|
+
"patient_last_name",
|
|
148
|
+
"patient_dob",
|
|
149
|
+
"examination_date",
|
|
150
|
+
"center_name",
|
|
151
|
+
"patient_gender_name",
|
|
152
|
+
"endoscope_type",
|
|
153
|
+
"endoscope_sn",
|
|
154
|
+
"examiner_first_name",
|
|
155
|
+
"examiner_last_name",
|
|
156
|
+
"dob_verified",
|
|
157
|
+
"names_verified",
|
|
158
|
+
]
|
|
159
|
+
|
|
160
|
+
def validate_center_name(self, value):
|
|
161
|
+
"""Validate center exists and return the instance."""
|
|
162
|
+
if value:
|
|
163
|
+
try:
|
|
164
|
+
# Return the instance to avoid double query in update()
|
|
165
|
+
return Center.objects.get_by_natural_key(value)
|
|
166
|
+
except Center.DoesNotExist:
|
|
167
|
+
raise serializers.ValidationError(f"Center '{value}' does not exist.")
|
|
168
|
+
return value
|
|
169
|
+
|
|
170
|
+
def validate_patient_gender_name(self, value):
|
|
171
|
+
"""Validate gender exists and return the instance."""
|
|
172
|
+
if value:
|
|
173
|
+
try:
|
|
174
|
+
# Return the instance to avoid double query in update()
|
|
175
|
+
return Gender.objects.get(name=value)
|
|
176
|
+
except Gender.DoesNotExist:
|
|
177
|
+
raise serializers.ValidationError(f"Gender '{value}' does not exist.")
|
|
178
|
+
return value
|
|
179
|
+
|
|
180
|
+
def validate(self, data):
|
|
181
|
+
"""Custom validation for the entire data set."""
|
|
182
|
+
# Guard against None values before calling strip()
|
|
183
|
+
first_name = data.get("patient_first_name")
|
|
184
|
+
if first_name is not None and not first_name.strip():
|
|
185
|
+
raise serializers.ValidationError(
|
|
186
|
+
{"patient_first_name": "First name cannot be empty."}
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
last_name = data.get("patient_last_name")
|
|
190
|
+
if last_name is not None and not last_name.strip():
|
|
191
|
+
raise serializers.ValidationError(
|
|
192
|
+
{"patient_last_name": "Last name cannot be empty."}
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
return data
|
|
196
|
+
|
|
197
|
+
@transaction.atomic
|
|
198
|
+
def update(self, instance, validated_data):
|
|
199
|
+
"""
|
|
200
|
+
Update SensitiveMeta instance and its related state.
|
|
201
|
+
Handles both model fields and verification state.
|
|
202
|
+
"""
|
|
203
|
+
# Extract verification state data
|
|
204
|
+
dob_verified = validated_data.pop("dob_verified", None)
|
|
205
|
+
names_verified = validated_data.pop("names_verified", None)
|
|
206
|
+
|
|
207
|
+
# -- center -------------------------------------------------
|
|
208
|
+
center = validated_data.pop("center_name", None)
|
|
209
|
+
if isinstance(center, Center): # returned by validate_center_name
|
|
210
|
+
instance.center = center
|
|
211
|
+
|
|
212
|
+
# -- gender -------------------------------------------------
|
|
213
|
+
gender = validated_data.pop("patient_gender_name", None)
|
|
214
|
+
if isinstance(gender, Gender): # returned by validate_patient_gender_name
|
|
215
|
+
instance.patient_gender = gender
|
|
216
|
+
|
|
217
|
+
# -- ordinary fields ---------------------------------------
|
|
218
|
+
if validated_data:
|
|
219
|
+
instance.update_from_dict(validated_data) # should NOT call save()
|
|
220
|
+
|
|
221
|
+
# -- verification state ------------------------------------
|
|
222
|
+
if dob_verified is not None or names_verified is not None:
|
|
223
|
+
state = instance.get_or_create_state()
|
|
224
|
+
if dob_verified is not None:
|
|
225
|
+
state.dob_verified = dob_verified
|
|
226
|
+
logger.info(
|
|
227
|
+
f"Updated DOB verification for SensitiveMeta {instance.pk}: {dob_verified}"
|
|
228
|
+
)
|
|
229
|
+
if names_verified is not None:
|
|
230
|
+
state.names_verified = names_verified
|
|
231
|
+
logger.info(
|
|
232
|
+
f"Updated names verification for SensitiveMeta {instance.pk}: {names_verified}"
|
|
233
|
+
)
|
|
234
|
+
state.save()
|
|
235
|
+
|
|
236
|
+
# -- finally persist the model itself ----------------------
|
|
237
|
+
instance.save()
|
|
238
|
+
return instance
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
class SensitiveMetaVerificationSerializer(serializers.Serializer):
|
|
242
|
+
"""
|
|
243
|
+
Simple serializer for bulk verification state updates.
|
|
244
|
+
Used when only updating verification flags.
|
|
245
|
+
"""
|
|
246
|
+
|
|
247
|
+
sensitive_meta_id = serializers.IntegerField()
|
|
248
|
+
dob_verified = serializers.BooleanField(required=False)
|
|
249
|
+
names_verified = serializers.BooleanField(required=False)
|
|
250
|
+
|
|
251
|
+
def validate_sensitive_meta_id(self, value):
|
|
252
|
+
"""Ensure SensitiveMeta exists."""
|
|
253
|
+
try:
|
|
254
|
+
SensitiveMeta.objects.get(id=value)
|
|
255
|
+
return value
|
|
256
|
+
except SensitiveMeta.DoesNotExist:
|
|
257
|
+
raise serializers.ValidationError(
|
|
258
|
+
f"SensitiveMeta with ID {value} does not exist."
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
@transaction.atomic
|
|
262
|
+
def save(self):
|
|
263
|
+
"""Update verification state for the specified SensitiveMeta with proper locking."""
|
|
264
|
+
sensitive_meta_id = self.validated_data["sensitive_meta_id"]
|
|
265
|
+
dob_verified = self.validated_data.get("dob_verified")
|
|
266
|
+
names_verified = self.validated_data.get("names_verified")
|
|
267
|
+
|
|
268
|
+
try:
|
|
269
|
+
# Use select_for_update for strong consistency in concurrent environments
|
|
270
|
+
sensitive_meta = SensitiveMeta.objects.select_for_update().get(
|
|
271
|
+
id=sensitive_meta_id
|
|
272
|
+
)
|
|
273
|
+
state = sensitive_meta.get_or_create_state()
|
|
274
|
+
|
|
275
|
+
if dob_verified is not None:
|
|
276
|
+
state.dob_verified = dob_verified
|
|
277
|
+
|
|
278
|
+
if names_verified is not None:
|
|
279
|
+
state.names_verified = names_verified
|
|
280
|
+
|
|
281
|
+
state.save()
|
|
282
|
+
|
|
283
|
+
# Only log the ID to avoid potential PII leakage
|
|
284
|
+
logger.info(
|
|
285
|
+
f"Updated verification state for SensitiveMeta ID {sensitive_meta_id}"
|
|
286
|
+
)
|
|
287
|
+
return state
|
|
288
|
+
|
|
289
|
+
except SensitiveMeta.DoesNotExist:
|
|
290
|
+
logger.error(
|
|
291
|
+
f"SensitiveMeta ID {sensitive_meta_id} not found during verification update"
|
|
292
|
+
)
|
|
293
|
+
raise serializers.ValidationError(
|
|
294
|
+
f"SensitiveMeta with ID {sensitive_meta_id} does not exist."
|
|
295
|
+
)
|
|
296
|
+
except Exception as e:
|
|
297
|
+
# Log the exception class but not the full details to avoid PII leakage
|
|
298
|
+
logger.error(
|
|
299
|
+
f"Error updating verification state for ID {sensitive_meta_id}: {type(e).__name__}"
|
|
300
|
+
)
|
|
301
|
+
raise serializers.ValidationError("Failed to update verification state.")
|