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,24 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
if TYPE_CHECKING:
|
|
4
|
+
from endoreg_db.models import VideoFile
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def _calc_duration_vf(obj: "VideoFile") -> float:
|
|
8
|
+
"""
|
|
9
|
+
Calculate duration of a VideoFile.
|
|
10
|
+
"""
|
|
11
|
+
if not obj.ffmpeg_meta:
|
|
12
|
+
raise ValueError("ffmpeg_meta is missing, cannot calculate duration.")
|
|
13
|
+
|
|
14
|
+
fps = obj.get_fps()
|
|
15
|
+
frame_count = obj.frame_count # TODO similar implementation as in get_fps
|
|
16
|
+
|
|
17
|
+
duration = frame_count / fps if fps > 0 else -1
|
|
18
|
+
if duration > 0:
|
|
19
|
+
return duration
|
|
20
|
+
else:
|
|
21
|
+
raise ValueError(
|
|
22
|
+
f"Invalid duration calculated for video {obj.video_hash}: {duration}. "
|
|
23
|
+
"Ensure the video file is valid and accessible."
|
|
24
|
+
)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from datetime import datetime, timezone
|
|
2
|
+
from endoreg_db.models import Patient, PatientLabSample, PatientLabSampleType
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class LabSampleFactory:
|
|
6
|
+
"""
|
|
7
|
+
Provides methods to generate lab samples.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
def __init__(self):
|
|
11
|
+
"""
|
|
12
|
+
Initializes the LabSampleFactory.
|
|
13
|
+
"""
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
def create_generic_lab_sample(self, patient: Patient):
|
|
17
|
+
"""
|
|
18
|
+
Generates a generic lab sample for a given patient.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
patient (Patient): The patient for whom the lab sample is generated.
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
PatientLabSample: The created lab sample instance.
|
|
25
|
+
"""
|
|
26
|
+
sample_type = PatientLabSampleType.objects.get(name="generic")
|
|
27
|
+
|
|
28
|
+
lab_sample = PatientLabSample.objects.create(
|
|
29
|
+
patient=patient, sample_type=sample_type, date=datetime.now(tz=timezone.utc)
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
return lab_sample
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Simple video file existence checker and path corrector for VideoFile records.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import argparse
|
|
7
|
+
import os
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
# Parse command-line arguments and environment variables for configuration
|
|
12
|
+
parser = argparse.ArgumentParser(
|
|
13
|
+
description="Simple video file existence checker and path corrector for VideoFile records."
|
|
14
|
+
)
|
|
15
|
+
parser.add_argument(
|
|
16
|
+
"--django-base",
|
|
17
|
+
type=str,
|
|
18
|
+
default=os.environ.get(
|
|
19
|
+
"ENDOREG_DJANGO_PROJECT_PATH",
|
|
20
|
+
str(Path(__file__).resolve().parent.parent.parent),
|
|
21
|
+
),
|
|
22
|
+
help="Path to the Django project base (default: env ENDOREG_DJANGO_PROJECT_PATH or project root)",
|
|
23
|
+
)
|
|
24
|
+
parser.add_argument(
|
|
25
|
+
"--django-settings",
|
|
26
|
+
type=str,
|
|
27
|
+
default=os.environ.get("DJANGO_SETTINGS_MODULE", "dev.dev_settings"),
|
|
28
|
+
help="Django settings module (default: env DJANGO_SETTINGS_MODULE or dev.dev_settings)",
|
|
29
|
+
)
|
|
30
|
+
parser.add_argument(
|
|
31
|
+
"--storage-dir",
|
|
32
|
+
type=str,
|
|
33
|
+
default=os.environ.get("ENDOREG_STORAGE_DIR", "./storage"),
|
|
34
|
+
help="Path to the storage directory (default: ./storage or $ENDOREG_STORAGE_DIR)",
|
|
35
|
+
)
|
|
36
|
+
args, unknown = parser.parse_known_args()
|
|
37
|
+
|
|
38
|
+
sys.path.insert(0, args.django_base)
|
|
39
|
+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", args.django_settings)
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
import django
|
|
43
|
+
|
|
44
|
+
django.setup()
|
|
45
|
+
from endoreg_db.models import VideoFile
|
|
46
|
+
|
|
47
|
+
DJANGO_AVAILABLE = True
|
|
48
|
+
except Exception as e:
|
|
49
|
+
print(f"Django not available: {e}")
|
|
50
|
+
DJANGO_AVAILABLE = False
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def find_video_files():
|
|
54
|
+
"""Find all video files in storage directory."""
|
|
55
|
+
storage_dir = Path(args.storage_dir)
|
|
56
|
+
video_files = []
|
|
57
|
+
|
|
58
|
+
for pattern in ["**/*.mp4", "**/*.avi", "**/*.mov", "**/*.mkv"]:
|
|
59
|
+
video_files.extend(storage_dir.glob(pattern))
|
|
60
|
+
|
|
61
|
+
return video_files
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def check_video_file_accessibility(file_path):
|
|
65
|
+
"""Check if a video file is accessible and valid."""
|
|
66
|
+
try:
|
|
67
|
+
if not file_path.exists():
|
|
68
|
+
return False, "File does not exist"
|
|
69
|
+
|
|
70
|
+
if file_path.stat().st_size == 0:
|
|
71
|
+
return False, "File is empty (0 bytes)"
|
|
72
|
+
|
|
73
|
+
if not os.access(file_path, os.R_OK):
|
|
74
|
+
return False, "File is not readable"
|
|
75
|
+
|
|
76
|
+
# Try to read first few bytes to check if it's actually a file
|
|
77
|
+
with open(file_path, "rb") as f:
|
|
78
|
+
header = f.read(8)
|
|
79
|
+
if len(header) < 8:
|
|
80
|
+
return False, "File too small or corrupted"
|
|
81
|
+
|
|
82
|
+
return True, f"OK - {file_path.stat().st_size / (1024 * 1024):.1f} MB"
|
|
83
|
+
|
|
84
|
+
except Exception as e:
|
|
85
|
+
return False, f"Error checking file: {e}"
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def main():
|
|
89
|
+
print("🔍 VIDEO FILE EXISTENCE CHECKER")
|
|
90
|
+
print("=" * 40)
|
|
91
|
+
|
|
92
|
+
# Find all video files
|
|
93
|
+
print("1. Scanning for video files...")
|
|
94
|
+
video_files = find_video_files()
|
|
95
|
+
print(f"Found {len(video_files)} video files in storage directory")
|
|
96
|
+
|
|
97
|
+
if not video_files:
|
|
98
|
+
print("❌ No video files found in storage directory!")
|
|
99
|
+
return
|
|
100
|
+
|
|
101
|
+
# Check each file
|
|
102
|
+
print("\n2. Checking file accessibility...")
|
|
103
|
+
accessible_files = []
|
|
104
|
+
|
|
105
|
+
for video_file in video_files[:10]: # Check first 10
|
|
106
|
+
accessible, message = check_video_file_accessibility(video_file)
|
|
107
|
+
status = "✅" if accessible else "❌"
|
|
108
|
+
print(f"{status} {video_file.name}: {message}")
|
|
109
|
+
|
|
110
|
+
if accessible:
|
|
111
|
+
accessible_files.append(video_file)
|
|
112
|
+
|
|
113
|
+
if not accessible_files:
|
|
114
|
+
print("\n❌ No accessible video files found!")
|
|
115
|
+
return
|
|
116
|
+
|
|
117
|
+
print(f"\n✅ Found {len(accessible_files)} accessible video files")
|
|
118
|
+
|
|
119
|
+
# If Django is available, check database records
|
|
120
|
+
if DJANGO_AVAILABLE:
|
|
121
|
+
print("\n3. Checking database records...")
|
|
122
|
+
try:
|
|
123
|
+
video_5 = VideoFile.objects.get(pk=5)
|
|
124
|
+
print("📋 Video ID 5 found in database:")
|
|
125
|
+
print(f" UUID: {video_5.video_hash}")
|
|
126
|
+
|
|
127
|
+
# Check different file path attributes
|
|
128
|
+
for attr in ["raw_file", "processed_file"]:
|
|
129
|
+
if hasattr(video_5, attr):
|
|
130
|
+
file_field = getattr(video_5, attr)
|
|
131
|
+
if file_field:
|
|
132
|
+
try:
|
|
133
|
+
file_path = Path(file_field.path)
|
|
134
|
+
accessible, message = check_video_file_accessibility(
|
|
135
|
+
file_path
|
|
136
|
+
)
|
|
137
|
+
status = "✅" if accessible else "❌"
|
|
138
|
+
print(f" {attr}: {status} {file_path} ({message})")
|
|
139
|
+
except Exception as e:
|
|
140
|
+
print(f" {attr}: ❌ Error accessing path: {e}")
|
|
141
|
+
else:
|
|
142
|
+
print(f" {attr}: ❌ No file set")
|
|
143
|
+
|
|
144
|
+
# Check if UUID matches any found files
|
|
145
|
+
uuid_str = str(video_5.video_hash)
|
|
146
|
+
matching_files = [f for f in accessible_files if uuid_str in str(f)]
|
|
147
|
+
|
|
148
|
+
if matching_files:
|
|
149
|
+
print(f"\n💡 Found matching files for UUID {uuid_str}:")
|
|
150
|
+
for match in matching_files:
|
|
151
|
+
accessible, message = check_video_file_accessibility(match)
|
|
152
|
+
print(f" ✅ {match} ({message})")
|
|
153
|
+
|
|
154
|
+
print("\n🔧 SOLUTION: Update VideoFile record to use:")
|
|
155
|
+
print(f" {matching_files[0]}")
|
|
156
|
+
print("\n🐍 Django command to fix:")
|
|
157
|
+
print(" video = VideoFile.objects.get(pk=5)")
|
|
158
|
+
print(
|
|
159
|
+
f" video.raw_file.name = '{matching_files[0].relative_to(Path(args.storage_dir))}'"
|
|
160
|
+
)
|
|
161
|
+
print(" video.save()")
|
|
162
|
+
else:
|
|
163
|
+
print(f"\n❌ No files found matching UUID {uuid_str}")
|
|
164
|
+
|
|
165
|
+
except Exception as e:
|
|
166
|
+
print(f"❌ Error checking database: {e}")
|
|
167
|
+
|
|
168
|
+
print("\n4. 🎯 QUICK TEST RECOMMENDATION:")
|
|
169
|
+
print(" Use this accessible file for testing:")
|
|
170
|
+
print(f" {accessible_files[0]}")
|
|
171
|
+
print(f" Size: {accessible_files[0].stat().st_size / (1024 * 1024):.1f} MB")
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
if __name__ == "__main__":
|
|
175
|
+
main()
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from PIL import Image
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def crop_and_insert(image: Image, x, y, h, w, bg_color=(255, 255, 255)):
|
|
5
|
+
"""
|
|
6
|
+
Crops a region from an inverted grayscale image and inserts it into a white image of the same size as the original.
|
|
7
|
+
|
|
8
|
+
Parameters:
|
|
9
|
+
- fp: File path or a file object of the original image.
|
|
10
|
+
- x, y: The top-left coordinates of the rectangle to be cropped.
|
|
11
|
+
- h, w: The height and width of the rectangle to be cropped.
|
|
12
|
+
|
|
13
|
+
Returns:
|
|
14
|
+
A PIL Image object containing the original image with the specified region replaced.
|
|
15
|
+
"""
|
|
16
|
+
# Load the original image
|
|
17
|
+
original_image = image
|
|
18
|
+
|
|
19
|
+
# Crop the specified region from the inverted image
|
|
20
|
+
crop_rectangle = (x, y, x + w, y + h)
|
|
21
|
+
cropped_content = original_image.crop(crop_rectangle)
|
|
22
|
+
|
|
23
|
+
# Create a new white image of the same size as the original image
|
|
24
|
+
white_background = Image.new("RGB", original_image.size, bg_color)
|
|
25
|
+
|
|
26
|
+
# Paste the cropped content onto the white image at the specified location
|
|
27
|
+
white_background.paste(cropped_content, (x, y))
|
|
28
|
+
|
|
29
|
+
# The final image can be displayed or saved as needed
|
|
30
|
+
return white_background
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from datetime import UTC, datetime
|
|
3
|
+
|
|
4
|
+
import yaml
|
|
5
|
+
from django.core.exceptions import ObjectDoesNotExist
|
|
6
|
+
from django.db import OperationalError, transaction
|
|
7
|
+
|
|
8
|
+
from endoreg_db.utils.paths import STORAGE_DIR
|
|
9
|
+
|
|
10
|
+
_WARNING_LOG_PATH = None
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _get_warning_log_path():
|
|
14
|
+
"""Return the path used for warning logs, creating it on first access."""
|
|
15
|
+
global _WARNING_LOG_PATH
|
|
16
|
+
if _WARNING_LOG_PATH is None:
|
|
17
|
+
log_dir = STORAGE_DIR / "logs"
|
|
18
|
+
log_dir.mkdir(parents=True, exist_ok=True)
|
|
19
|
+
timestamp = datetime.now(UTC).strftime("%Y%m%d-%H%M%S")
|
|
20
|
+
_WARNING_LOG_PATH = log_dir / f"dataloader_warnings_{timestamp}.log"
|
|
21
|
+
return _WARNING_LOG_PATH
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _record_warning(command, message, verbose, context):
|
|
25
|
+
"""Write a warning to stdout (when verbose) and append it to the log file."""
|
|
26
|
+
prefix = f"[{context}] " if context else ""
|
|
27
|
+
full_message = f"{prefix}{message}"
|
|
28
|
+
|
|
29
|
+
if verbose:
|
|
30
|
+
command.stdout.write(command.style.WARNING(full_message))
|
|
31
|
+
|
|
32
|
+
log_path = _get_warning_log_path()
|
|
33
|
+
with open(log_path, "a", encoding="utf-8") as log_file:
|
|
34
|
+
log_file.write(f"{datetime.now(UTC).isoformat()}Z {full_message}\n")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def load_model_data_from_yaml(command, model_name, metadata, verbose):
|
|
38
|
+
"""
|
|
39
|
+
Load model data from YAML files.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
command: Command object for stdout writing.
|
|
43
|
+
model_name: Name of the model being loaded.
|
|
44
|
+
metadata: Metadata including directory and foreign key information.
|
|
45
|
+
verbose: Boolean indicating whether to print verbose output.
|
|
46
|
+
"""
|
|
47
|
+
if verbose:
|
|
48
|
+
command.stdout.write(f"Start loading {model_name}")
|
|
49
|
+
|
|
50
|
+
warning_log_path = _get_warning_log_path()
|
|
51
|
+
if verbose:
|
|
52
|
+
command.stdout.write(f"Warning log file: {warning_log_path}")
|
|
53
|
+
model = metadata["model"]
|
|
54
|
+
dir_path = metadata["dir"]
|
|
55
|
+
foreign_keys = metadata["foreign_keys"]
|
|
56
|
+
foreign_key_models = metadata["foreign_key_models"]
|
|
57
|
+
validators = metadata.get("validators", [])
|
|
58
|
+
|
|
59
|
+
_files = [f for f in os.listdir(dir_path) if f.endswith(".yaml")]
|
|
60
|
+
# sort
|
|
61
|
+
_files.sort()
|
|
62
|
+
for file in _files:
|
|
63
|
+
with open(os.path.join(dir_path, file), "r", encoding="utf-8") as file:
|
|
64
|
+
yaml_data = yaml.safe_load(file)
|
|
65
|
+
|
|
66
|
+
load_data_with_foreign_keys(
|
|
67
|
+
command,
|
|
68
|
+
model,
|
|
69
|
+
yaml_data,
|
|
70
|
+
foreign_keys,
|
|
71
|
+
foreign_key_models,
|
|
72
|
+
validators,
|
|
73
|
+
verbose,
|
|
74
|
+
log_context=model_name or model.__name__,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def load_data_with_foreign_keys(
|
|
79
|
+
command,
|
|
80
|
+
model,
|
|
81
|
+
yaml_data,
|
|
82
|
+
foreign_keys,
|
|
83
|
+
foreign_key_models,
|
|
84
|
+
validators,
|
|
85
|
+
verbose,
|
|
86
|
+
log_context=None,
|
|
87
|
+
):
|
|
88
|
+
"""
|
|
89
|
+
Load YAML data into Django model instances with FK and M2M support.
|
|
90
|
+
|
|
91
|
+
Processes each YAML entry to create or update a model instance. For each entry, the
|
|
92
|
+
function extracts field data and uses the presence of a 'name' field to decide whether
|
|
93
|
+
to update an existing instance or create a new one. Foreign key fields listed in
|
|
94
|
+
foreign_keys are handled by retrieving related objects via natural keys. When a field
|
|
95
|
+
contains a list, it is treated as a many-to-many relationship and the corresponding
|
|
96
|
+
objects are set after the instance is saved. Missing or unresolved foreign keys trigger
|
|
97
|
+
warnings if verbose output is enabled.
|
|
98
|
+
|
|
99
|
+
Parameters:
|
|
100
|
+
model: The Django model class representing the data.
|
|
101
|
+
yaml_data: A list of dictionaries representing YAML entries.
|
|
102
|
+
foreign_keys: A list of foreign key field names to process from each entry.
|
|
103
|
+
foreign_key_models: The corresponding Django model classes for each foreign key.
|
|
104
|
+
validators: A sequence of callables invoked before persisting each entry. Each
|
|
105
|
+
validator receives a shallow copy of the entry's field dictionary along with
|
|
106
|
+
the original entry and model for context.
|
|
107
|
+
verbose: If True, prints detailed output and warnings during processing.
|
|
108
|
+
log_context: Label that identifies the source dataset inside the warning log.
|
|
109
|
+
"""
|
|
110
|
+
context_label = log_context or getattr(model, "__name__", "dataloader")
|
|
111
|
+
|
|
112
|
+
for entry in yaml_data:
|
|
113
|
+
raw_fields = entry.get("fields", {})
|
|
114
|
+
|
|
115
|
+
for validator in validators:
|
|
116
|
+
validator(dict(raw_fields), entry=entry, model=model)
|
|
117
|
+
|
|
118
|
+
fields = dict(raw_fields)
|
|
119
|
+
name = fields.pop("name", None)
|
|
120
|
+
|
|
121
|
+
if getattr(model, "_meta", None) and model._meta.model_name == "requirement":
|
|
122
|
+
requirement_types = fields.get("requirement_types", [])
|
|
123
|
+
|
|
124
|
+
if not requirement_types:
|
|
125
|
+
raise ValueError(
|
|
126
|
+
f"Requirement '{name}' must define at least one requirement_types entry."
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
####################
|
|
130
|
+
# TODO REMOVE AFTER TRANSLATION SUPPORT IS ADDED
|
|
131
|
+
SKIP_NAMES = [
|
|
132
|
+
"name_de", # German name, not used
|
|
133
|
+
"name_en", # English name, not used
|
|
134
|
+
"description_de", # German description
|
|
135
|
+
"description_en", # English description
|
|
136
|
+
]
|
|
137
|
+
|
|
138
|
+
# Remove fields that are not needed
|
|
139
|
+
for skip_name in SKIP_NAMES:
|
|
140
|
+
if skip_name in fields:
|
|
141
|
+
fields.pop(skip_name)
|
|
142
|
+
# ########################
|
|
143
|
+
|
|
144
|
+
m2m_relationships = {} # Store many-to-many relationships
|
|
145
|
+
# print(entry)
|
|
146
|
+
|
|
147
|
+
# Handle foreign keys and many-to-many relationships
|
|
148
|
+
for fk_field, fk_model in zip(foreign_keys, foreign_key_models):
|
|
149
|
+
# Skip fields that are not in the data
|
|
150
|
+
if fk_field not in fields:
|
|
151
|
+
continue
|
|
152
|
+
|
|
153
|
+
target_keys = fields.pop(fk_field, None)
|
|
154
|
+
|
|
155
|
+
# Ensure the foreign key exists
|
|
156
|
+
if target_keys is None:
|
|
157
|
+
_record_warning(
|
|
158
|
+
command,
|
|
159
|
+
f"Foreign key {fk_field} not found in fields",
|
|
160
|
+
verbose,
|
|
161
|
+
context_label,
|
|
162
|
+
)
|
|
163
|
+
continue # Skip if no foreign key provided
|
|
164
|
+
|
|
165
|
+
# Process many-to-many fields or foreign keys
|
|
166
|
+
if isinstance(target_keys, list): # Assume many-to-many relationship
|
|
167
|
+
related_objects = []
|
|
168
|
+
for key in target_keys:
|
|
169
|
+
try:
|
|
170
|
+
obj = fk_model.objects.get_by_natural_key(key)
|
|
171
|
+
except ObjectDoesNotExist:
|
|
172
|
+
_record_warning(
|
|
173
|
+
command,
|
|
174
|
+
f"{fk_model.__name__} with key {key} not found",
|
|
175
|
+
verbose,
|
|
176
|
+
context_label,
|
|
177
|
+
)
|
|
178
|
+
continue
|
|
179
|
+
related_objects.append(obj)
|
|
180
|
+
m2m_relationships[fk_field] = related_objects
|
|
181
|
+
else: # Single foreign key relationship
|
|
182
|
+
if model.__name__ == "ModelMeta" and fk_field == "labelset":
|
|
183
|
+
labelset_version = fields.pop("labelset_version", None)
|
|
184
|
+
|
|
185
|
+
if isinstance(target_keys, (tuple, list)):
|
|
186
|
+
labelset_name = target_keys[0] if target_keys else None
|
|
187
|
+
if len(target_keys) > 1 and labelset_version in (None, ""):
|
|
188
|
+
labelset_version = target_keys[1]
|
|
189
|
+
else:
|
|
190
|
+
labelset_name = target_keys
|
|
191
|
+
|
|
192
|
+
if not labelset_name:
|
|
193
|
+
_record_warning(
|
|
194
|
+
command,
|
|
195
|
+
"LabelSet name missing for ModelMeta entry",
|
|
196
|
+
verbose,
|
|
197
|
+
context_label,
|
|
198
|
+
)
|
|
199
|
+
continue
|
|
200
|
+
|
|
201
|
+
queryset = fk_model.objects.filter(name=labelset_name)
|
|
202
|
+
if labelset_version not in (None, "", -1):
|
|
203
|
+
try:
|
|
204
|
+
version_value = int(labelset_version)
|
|
205
|
+
except (TypeError, ValueError):
|
|
206
|
+
version_value = labelset_version
|
|
207
|
+
queryset = queryset.filter(version=version_value)
|
|
208
|
+
|
|
209
|
+
obj = queryset.order_by("-version").first()
|
|
210
|
+
if obj is None:
|
|
211
|
+
_record_warning(
|
|
212
|
+
command,
|
|
213
|
+
f"LabelSet '{labelset_name}' (version={labelset_version}) not found",
|
|
214
|
+
verbose,
|
|
215
|
+
context_label,
|
|
216
|
+
)
|
|
217
|
+
continue
|
|
218
|
+
fields[fk_field] = obj
|
|
219
|
+
else:
|
|
220
|
+
try:
|
|
221
|
+
obj = fk_model.objects.get_by_natural_key(target_keys)
|
|
222
|
+
except ObjectDoesNotExist:
|
|
223
|
+
_record_warning(
|
|
224
|
+
command,
|
|
225
|
+
f"{fk_model.__name__} with key {target_keys} not found",
|
|
226
|
+
verbose,
|
|
227
|
+
context_label,
|
|
228
|
+
)
|
|
229
|
+
continue
|
|
230
|
+
fields[fk_field] = obj
|
|
231
|
+
|
|
232
|
+
# Create or update the main object (avoid update_or_create to prevent SQLite locks)
|
|
233
|
+
version_value = fields.get("version")
|
|
234
|
+
|
|
235
|
+
def _save_instance():
|
|
236
|
+
if name is None:
|
|
237
|
+
# Try to find an existing object by all provided fields
|
|
238
|
+
obj = model.objects.filter(**fields).first()
|
|
239
|
+
if obj is None:
|
|
240
|
+
obj = model.objects.create(**fields)
|
|
241
|
+
created = True
|
|
242
|
+
else:
|
|
243
|
+
created = False
|
|
244
|
+
else:
|
|
245
|
+
lookup_kwargs = {"name": name}
|
|
246
|
+
if model.__name__ == "LabelSet" and version_value is not None:
|
|
247
|
+
lookup_kwargs["version"] = version_value
|
|
248
|
+
|
|
249
|
+
obj = model.objects.filter(**lookup_kwargs).first()
|
|
250
|
+
if obj is None:
|
|
251
|
+
obj = model.objects.create(name=name, **fields)
|
|
252
|
+
created = True
|
|
253
|
+
else:
|
|
254
|
+
# Update fields
|
|
255
|
+
for k, v in fields.items():
|
|
256
|
+
setattr(obj, k, v)
|
|
257
|
+
obj.save()
|
|
258
|
+
created = False
|
|
259
|
+
return obj, created
|
|
260
|
+
|
|
261
|
+
try:
|
|
262
|
+
# Attempt save inside a transaction for consistency
|
|
263
|
+
with transaction.atomic():
|
|
264
|
+
obj, created = _save_instance()
|
|
265
|
+
except OperationalError:
|
|
266
|
+
# Retry once on SQLite lock
|
|
267
|
+
obj, created = _save_instance()
|
|
268
|
+
|
|
269
|
+
if created and verbose:
|
|
270
|
+
command.stdout.write(
|
|
271
|
+
command.style.SUCCESS(f"Created {model.__name__} {name}")
|
|
272
|
+
)
|
|
273
|
+
elif verbose:
|
|
274
|
+
pass
|
|
275
|
+
|
|
276
|
+
# Set many-to-many relationships
|
|
277
|
+
for field_name, related_objs in m2m_relationships.items():
|
|
278
|
+
if related_objs: # Only set if there are objects to set
|
|
279
|
+
getattr(obj, field_name).set(related_objs)
|
|
280
|
+
if verbose:
|
|
281
|
+
command.stdout.write(
|
|
282
|
+
command.style.SUCCESS(
|
|
283
|
+
f"Set {len(related_objs)} {field_name} for {model.__name__} {name}"
|
|
284
|
+
)
|
|
285
|
+
)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from datetime import datetime, date, timedelta
|
|
2
|
+
from random import randint
|
|
3
|
+
from calendar import monthrange
|
|
4
|
+
from django.utils import timezone
|
|
5
|
+
|
|
6
|
+
# TODO replace used random_day_by_year function implementation when
|
|
7
|
+
# creating pseudo patients with new function "random date by age_at_date and examination_date"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def random_day_by_age_at_date(age_at_date: int, examination_date: date) -> date:
|
|
11
|
+
"""
|
|
12
|
+
Return a random birth day for a patient with the specified age at the specified examination date.
|
|
13
|
+
"""
|
|
14
|
+
examination_year = examination_date.year
|
|
15
|
+
latest_birthdate = examination_date.replace(year=examination_year - age_at_date)
|
|
16
|
+
valid_dates = [latest_birthdate - timedelta(days=i) for i in range(365)]
|
|
17
|
+
|
|
18
|
+
select = randint(0, len(valid_dates) - 1)
|
|
19
|
+
birth_date = valid_dates[select]
|
|
20
|
+
|
|
21
|
+
return birth_date
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def random_day_by_year(year: int) -> date:
|
|
25
|
+
"""
|
|
26
|
+
Return a random birth day within the specified year.
|
|
27
|
+
"""
|
|
28
|
+
month = randint(1, 12)
|
|
29
|
+
day = randint(1, monthrange(year, month)[1])
|
|
30
|
+
|
|
31
|
+
return date(year, month, day)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def random_day_by_month_year(month: int, year) -> date:
|
|
35
|
+
"""
|
|
36
|
+
Return a random birth day within the specified month and year.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
day = randint(1, monthrange(year, month)[1])
|
|
40
|
+
return date(year, month, day)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def ensure_aware_datetime(dt):
|
|
44
|
+
"""
|
|
45
|
+
Ensures a datetime object is timezone-aware.
|
|
46
|
+
If the datetime is naive (has no timezone info), the current timezone is applied.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
dt: A datetime object that may be naive
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
A timezone-aware datetime object
|
|
53
|
+
"""
|
|
54
|
+
if dt is None:
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
if isinstance(dt, datetime.datetime) and timezone.is_naive(dt):
|
|
58
|
+
return timezone.make_aware(dt)
|
|
59
|
+
return dt
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
|
|
3
|
+
# Start process with interactive pipes
|
|
4
|
+
proc = subprocess.Popen(
|
|
5
|
+
["python3", "-i"], # or your target program
|
|
6
|
+
stdin=subprocess.PIPE,
|
|
7
|
+
stdout=subprocess.PIPE,
|
|
8
|
+
stderr=subprocess.STDOUT,
|
|
9
|
+
text=True,
|
|
10
|
+
bufsize=1,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
proc.stdin.write("print('Trying to extract...')\n")
|
|
14
|
+
proc.stdin.flush()
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
subprocess.run(["python", "manage.py", "load_center_data"], check=True)
|
|
18
|
+
proc.stdout.write("print('found center')")
|
|
19
|
+
except subprocess.CalledProcessError:
|
|
20
|
+
proc.stdout.write(
|
|
21
|
+
"print('Didn't find center. Please add it to endoreg_db luxnix or via export DEFAULT_CENTER"
|
|
22
|
+
)
|
|
23
|
+
# """
|
|
24
|
+
# Future Implementation using dialogue
|
|
25
|
+
# """
|
|
26
|
+
# # Send commands as if from terminal
|
|
27
|
+
# proc.stdin.write("print('You dont have a default center set up yet. Please enter one here.')\n\nprint('Rule: use_this_format_and_connect_words_with_underscore')")
|
|
28
|
+
# proc.stdin.flush()
|
|
29
|
+
|
|
30
|
+
# # Read responses
|
|
31
|
+
# for _ in range(3):
|
|
32
|
+
# line = proc.stdout.readline()
|
|
33
|
+
# print("Selected >>", line.strip())
|
endoreg_db/utils/env.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
DEBUG = os.getenv("DEBUG", "false").lower() == "true"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def get_env_var(var_name: str, default: str = None) -> str | None:
|
|
7
|
+
"""
|
|
8
|
+
Get the value of an environment variable, with an optional default value.
|
|
9
|
+
If the environment variable is set, we need to remove flanking quotation marks and spaces.
|
|
10
|
+
if the environment variable is not set, we set it to the default value.
|
|
11
|
+
:param var_name: The name of the environment variable.
|
|
12
|
+
:param default: The default value to return if the environment variable is not set.
|
|
13
|
+
:return: The value of the environment variable or the default value.
|
|
14
|
+
"""
|
|
15
|
+
value = os.environ.get(var_name)
|
|
16
|
+
if value:
|
|
17
|
+
value = value.strip("\"'") # Strip both single and double quotes
|
|
18
|
+
if DEBUG:
|
|
19
|
+
print(f"Environment variable {var_name}: {value}")
|
|
20
|
+
return value
|
|
21
|
+
return default
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def set_env_var(var_name: str, value: str) -> None:
|
|
25
|
+
"""
|
|
26
|
+
Set the value of an environment variable.
|
|
27
|
+
:param var_name: The name of the environment variable.
|
|
28
|
+
:param value: The value to set.
|
|
29
|
+
"""
|
|
30
|
+
os.environ[var_name] = value
|
|
31
|
+
if DEBUG:
|
|
32
|
+
print(f"Set environment variable {var_name}: {value}")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
DJANGO_SETTINGS_MODULE = (
|
|
36
|
+
get_env_var("DJANGO_SETTINGS_MODULE") or "endoreg_db.settings_dev"
|
|
37
|
+
)
|