endoreg-db 0.6.3__py3-none-any.whl → 0.8.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of endoreg-db might be problematic. Click here for more details.
- endoreg_db/admin.py +26 -26
- endoreg_db/api_urls.py +4 -0
- endoreg_db/apps.py +12 -0
- endoreg_db/assets/dummy_model.ckpt +1 -0
- endoreg_db/codemods/readme.md +88 -0
- endoreg_db/codemods/rename_datetime_fields.py +92 -0
- endoreg_db/config/env.py +101 -0
- endoreg_db/data/__init__.py +26 -0
- endoreg_db/data/ai_model/data.yaml +1 -1
- endoreg_db/data/ai_model_label/label/polyp_classification.yaml +52 -0
- endoreg_db/data/ai_model_label/label-set/data.yaml +20 -1
- endoreg_db/data/ai_model_label/label-set/polyp_classifications.yaml +25 -0
- endoreg_db/data/center/data.yaml +13 -12
- endoreg_db/data/center_shift/ukw.yaml +9 -0
- endoreg_db/data/db_summary.csv +58 -0
- endoreg_db/data/db_summary.xlsx +0 -0
- endoreg_db/data/disease/misc.yaml +1 -2
- endoreg_db/data/disease_classification/chronic_kidney_disease.yaml +2 -2
- endoreg_db/data/disease_classification_choice/chronic_kidney_disease.yaml +6 -6
- endoreg_db/data/endoscopy_processor/data.yaml +3 -0
- endoreg_db/data/event/cardiology.yaml +0 -13
- endoreg_db/data/examination/examinations/data.yaml +34 -28
- endoreg_db/data/examination/type/data.yaml +12 -0
- endoreg_db/data/examination_indication/endoscopy.yaml +418 -2
- endoreg_db/data/examination_indication_classification/endoscopy.yaml +157 -5
- endoreg_db/data/examination_requirement_set/colonoscopy.yaml +15 -0
- endoreg_db/data/finding/anatomy_colon.yaml +128 -0
- endoreg_db/data/finding/colonoscopy.yaml +40 -0
- endoreg_db/data/finding/colonoscopy_bowel_prep.yaml +56 -0
- endoreg_db/data/finding/complication.yaml +16 -0
- endoreg_db/data/finding/data.yaml +8 -44
- endoreg_db/data/finding/examination_setting.yaml +16 -0
- endoreg_db/data/finding/medication_related.yaml +18 -0
- endoreg_db/data/finding/outcome.yaml +12 -0
- endoreg_db/data/finding_classification/colonoscopy_bowel_preparation.yaml +95 -0
- endoreg_db/data/finding_classification/colonoscopy_jnet.yaml +22 -0
- endoreg_db/data/finding_classification/colonoscopy_kudo.yaml +25 -0
- endoreg_db/data/finding_classification/colonoscopy_lesion_circularity.yaml +20 -0
- endoreg_db/data/finding_classification/colonoscopy_lesion_planarity.yaml +24 -0
- endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +68 -0
- endoreg_db/data/finding_classification/colonoscopy_lesion_surface.yaml +20 -0
- endoreg_db/data/finding_classification/colonoscopy_location.yaml +80 -0
- endoreg_db/data/finding_classification/colonoscopy_lst.yaml +21 -0
- endoreg_db/data/finding_classification/colonoscopy_nice.yaml +20 -0
- endoreg_db/data/finding_classification/colonoscopy_paris.yaml +26 -0
- endoreg_db/data/finding_classification/colonoscopy_sano.yaml +22 -0
- endoreg_db/data/finding_classification/colonoscopy_summary.yaml +53 -0
- endoreg_db/data/finding_classification/complication_generic.yaml +25 -0
- endoreg_db/data/finding_classification/examination_setting_generic.yaml +40 -0
- endoreg_db/data/finding_classification/histology_colo.yaml +51 -0
- endoreg_db/data/finding_classification/intervention_required.yaml +26 -0
- endoreg_db/data/finding_classification/medication_related.yaml +23 -0
- endoreg_db/data/finding_classification/visualized.yaml +33 -0
- endoreg_db/data/finding_classification_choice/bowel_preparation.yaml +78 -0
- endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_circularity_default.yaml +0 -2
- endoreg_db/data/finding_classification_choice/colon_lesion_jnet.yaml +15 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_kudo.yaml +23 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_lst.yaml +15 -0
- endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_nice.yaml +4 -7
- endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_paris.yaml +0 -8
- endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_planarity_default.yaml +6 -13
- endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +14 -0
- endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_surface_intact_default.yaml +3 -6
- endoreg_db/data/{finding_location_classification_choice/colonoscopy.yaml → finding_classification_choice/colonoscopy_location.yaml} +11 -22
- endoreg_db/data/finding_classification_choice/colonoscopy_not_complete_reason.yaml +19 -0
- endoreg_db/data/finding_classification_choice/colonoscopy_size.yaml +82 -0
- endoreg_db/data/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +15 -0
- endoreg_db/data/finding_classification_choice/complication_generic_types.yaml +15 -0
- endoreg_db/data/finding_classification_choice/examination_setting_generic_types.yaml +15 -0
- endoreg_db/data/finding_classification_choice/histology.yaml +24 -0
- endoreg_db/data/finding_classification_choice/histology_polyp.yaml +20 -0
- endoreg_db/data/finding_classification_choice/outcome.yaml +19 -0
- endoreg_db/data/finding_classification_choice/yes_no_na.yaml +11 -0
- endoreg_db/data/finding_classification_type/colonoscopy_basic.yaml +48 -0
- endoreg_db/data/finding_intervention/endoscopy.yaml +26 -121
- endoreg_db/data/finding_intervention/endoscopy_colonoscopy.yaml +168 -0
- endoreg_db/data/finding_intervention/endoscopy_egd.yaml +128 -0
- endoreg_db/data/finding_intervention/endoscopy_ercp.yaml +32 -0
- endoreg_db/data/finding_intervention/endoscopy_eus_lower.yaml +9 -0
- endoreg_db/data/finding_intervention/endoscopy_eus_upper.yaml +36 -0
- endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +6 -6
- endoreg_db/data/finding_type/data.yaml +23 -10
- endoreg_db/data/gender/data.yaml +8 -1
- endoreg_db/data/information_source/annotation.yaml +6 -0
- endoreg_db/data/information_source/endoscopy_guidelines.yaml +7 -0
- endoreg_db/data/information_source/prediction.yaml +7 -0
- endoreg_db/data/information_source_type/data.yaml +8 -0
- endoreg_db/data/lab_value/misc.yaml +43 -0
- endoreg_db/data/medication/anticoagulation.yaml +5 -5
- endoreg_db/data/medication/tah.yaml +5 -5
- endoreg_db/data/medication_indication/anticoagulation.yaml +4 -4
- endoreg_db/data/medication_intake_time/base.yaml +4 -4
- endoreg_db/data/names_first/first_names.yaml +3 -0
- endoreg_db/data/pdf_type/data.yaml +27 -10
- endoreg_db/data/qualification/endoscopy.yaml +36 -0
- endoreg_db/data/qualification/m2.yaml +39 -0
- endoreg_db/data/qualification/outpatient_clinic.yaml +35 -0
- endoreg_db/data/qualification/sonography.yaml +36 -0
- endoreg_db/data/qualification_type/base.yaml +29 -0
- endoreg_db/data/report_reader_flag/rkh-histology-generic.yaml +10 -0
- endoreg_db/data/report_reader_flag/ukw-histology-generic.yaml +5 -0
- endoreg_db/data/requirement/age.yaml +26 -0
- endoreg_db/data/requirement/colonoscopy_baseline_austria.yaml +45 -0
- endoreg_db/data/requirement/disease_cardiovascular.yaml +79 -0
- endoreg_db/data/requirement/disease_classification_choice_cardiovascular.yaml +41 -0
- endoreg_db/data/requirement/disease_hepatology.yaml +12 -0
- endoreg_db/data/requirement/disease_misc.yaml +12 -0
- endoreg_db/data/requirement/disease_renal.yaml +96 -0
- endoreg_db/data/requirement/endoscopy_bleeding_risk.yaml +59 -0
- endoreg_db/data/requirement/event_cardiology.yaml +251 -0
- endoreg_db/data/requirement/event_requirements.yaml +145 -0
- endoreg_db/data/requirement/finding_colon_polyp.yaml +50 -0
- endoreg_db/data/requirement/gender.yaml +25 -0
- endoreg_db/data/requirement/lab_value.yaml +441 -0
- endoreg_db/data/requirement/medication.yaml +93 -0
- endoreg_db/data/requirement_operator/age.yaml +13 -0
- endoreg_db/data/requirement_operator/lab_operators.yaml +129 -0
- endoreg_db/data/requirement_operator/model_operators.yaml +96 -0
- endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +48 -0
- endoreg_db/data/requirement_set/colonoscopy_austria_screening.yaml +57 -0
- endoreg_db/data/requirement_set/endoscopy_bleeding_risk.yaml +52 -0
- endoreg_db/data/requirement_set_type/data.yaml +20 -0
- endoreg_db/data/requirement_type/requirement_types.yaml +165 -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/shift/endoscopy.yaml +21 -0
- endoreg_db/data/shift_type/base.yaml +35 -0
- endoreg_db/data/tag/requirement_set_tags.yaml +11 -0
- endoreg_db/data/unit/concentration.yaml +23 -0
- endoreg_db/data/unit/time.yaml +36 -1
- endoreg_db/exceptions.py +19 -0
- endoreg_db/forms/patient_finding_intervention_form.py +4 -5
- endoreg_db/forms/patient_form.py +7 -6
- endoreg_db/forms/questionnaires/__init__.py +1 -1
- endoreg_db/forms/questionnaires/tto_questionnaire.py +19 -19
- endoreg_db/helpers/count_db.py +45 -0
- endoreg_db/helpers/data_loader.py +208 -0
- endoreg_db/helpers/default_objects.py +359 -0
- endoreg_db/helpers/interact.py +6 -0
- endoreg_db/helpers/test_video_helper.py +119 -0
- endoreg_db/logger_conf.py +140 -0
- endoreg_db/management/__init__.py +1 -0
- endoreg_db/management/commands/__init__.py +1 -0
- endoreg_db/management/commands/anonymize_video.py +0 -0
- endoreg_db/management/commands/check_auth.py +125 -0
- endoreg_db/management/commands/create_multilabel_model_meta.py +214 -0
- endoreg_db/management/commands/fix_missing_patient_data.py +172 -0
- endoreg_db/management/commands/fix_video_paths.py +165 -0
- endoreg_db/management/commands/import_fallback_video.py +203 -0
- endoreg_db/management/commands/import_report.py +298 -0
- endoreg_db/management/commands/import_video.py +422 -0
- endoreg_db/management/commands/import_video_with_classification.py +367 -0
- endoreg_db/management/commands/init_default_ai_model.py +112 -0
- endoreg_db/management/commands/load_ai_model_data.py +2 -7
- endoreg_db/management/commands/load_base_db_data.py +15 -1
- endoreg_db/management/commands/load_center_data.py +46 -21
- endoreg_db/management/commands/load_endoscope_data.py +2 -2
- endoreg_db/management/commands/load_examination_indication_data.py +49 -28
- endoreg_db/management/commands/load_finding_data.py +49 -92
- endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +0 -1
- endoreg_db/management/commands/load_information_source.py +13 -7
- endoreg_db/management/commands/load_qualification_data.py +59 -0
- endoreg_db/management/commands/load_requirement_data.py +180 -0
- endoreg_db/management/commands/load_risk_data.py +56 -0
- endoreg_db/management/commands/load_shift_data.py +60 -0
- endoreg_db/management/commands/load_tag_data.py +57 -0
- endoreg_db/management/commands/register_ai_model.py +1 -1
- endoreg_db/management/commands/start_filewatcher.py +106 -0
- endoreg_db/management/commands/storage_management.py +548 -0
- endoreg_db/management/commands/summarize_db_content.py +189 -0
- endoreg_db/management/commands/validate_video.py +204 -0
- endoreg_db/management/commands/validate_video_files.py +161 -0
- endoreg_db/management/commands/video_validation.py +22 -0
- endoreg_db/migrations/0001_initial.py +625 -813
- endoreg_db/migrations/0002_add_video_correction_models.py +52 -0
- endoreg_db/models/__init__.py +274 -291
- endoreg_db/models/administration/__init__.py +116 -0
- endoreg_db/models/{ai_model → administration/ai}/__init__.py +6 -1
- endoreg_db/models/administration/ai/active_model.py +35 -0
- endoreg_db/models/administration/ai/ai_model.py +156 -0
- endoreg_db/models/{ai_model → administration/ai}/model_type.py +6 -1
- endoreg_db/models/administration/case/__init__.py +19 -0
- endoreg_db/models/administration/case/case.py +114 -0
- endoreg_db/models/{case_template → administration/case/case_template}/case_template.py +3 -3
- endoreg_db/models/{case_template → administration/case/case_template}/case_template_rule.py +3 -10
- endoreg_db/models/{case_template → administration/case/case_template}/case_template_rule_value.py +2 -4
- endoreg_db/models/{case_template → administration/case/case_template}/case_template_type.py +1 -3
- endoreg_db/models/{center → administration/center}/__init__.py +3 -1
- endoreg_db/models/administration/center/center.py +61 -0
- endoreg_db/models/administration/center/center_product.py +64 -0
- endoreg_db/models/{center → administration/center}/center_resource.py +19 -3
- endoreg_db/models/administration/center/center_shift.py +88 -0
- endoreg_db/models/administration/center/center_waste.py +30 -0
- endoreg_db/models/administration/permissions/__init__.py +44 -0
- endoreg_db/models/administration/person/__init__.py +24 -0
- endoreg_db/models/administration/person/employee/__init__.py +3 -0
- endoreg_db/models/administration/person/employee/employee.py +35 -0
- endoreg_db/models/administration/person/employee/employee_qualification.py +39 -0
- endoreg_db/models/administration/person/employee/employee_type.py +42 -0
- endoreg_db/models/administration/person/examiner/__init__.py +4 -0
- endoreg_db/models/administration/person/examiner/examiner.py +54 -0
- endoreg_db/models/administration/person/names/__init__.py +0 -0
- endoreg_db/models/{persons → administration/person/names}/first_name.py +1 -1
- endoreg_db/models/{persons → administration/person/names}/last_name.py +2 -3
- endoreg_db/models/administration/person/patient/__init__.py +5 -0
- endoreg_db/models/administration/person/patient/patient.py +460 -0
- endoreg_db/models/administration/person/profession/__init__.py +24 -0
- endoreg_db/models/administration/person/user/__init__.py +5 -0
- endoreg_db/models/administration/person/user/portal_user_information.py +37 -0
- endoreg_db/models/administration/product/product.py +97 -0
- endoreg_db/models/administration/product/product_group.py +39 -0
- endoreg_db/models/administration/product/product_material.py +54 -0
- endoreg_db/models/{product → administration/product}/product_weight.py +9 -0
- endoreg_db/models/{product → administration/product}/reference_product.py +26 -11
- endoreg_db/models/administration/qualification/__init__.py +7 -0
- endoreg_db/models/administration/qualification/qualification.py +37 -0
- endoreg_db/models/administration/qualification/qualification_type.py +35 -0
- endoreg_db/models/administration/shift/__init__.py +9 -0
- endoreg_db/models/administration/shift/scheduled_days.py +69 -0
- endoreg_db/models/administration/shift/shift.py +51 -0
- endoreg_db/models/administration/shift/shift_type.py +108 -0
- endoreg_db/models/label/__init__.py +24 -1
- endoreg_db/models/label/annotation/__init__.py +12 -0
- endoreg_db/models/label/annotation/image_classification.py +84 -0
- endoreg_db/models/label/annotation/video_segmentation_annotation.py +66 -0
- endoreg_db/models/label/label.py +45 -74
- endoreg_db/models/label/label_set.py +53 -0
- endoreg_db/models/label/label_type.py +29 -0
- endoreg_db/models/label/label_video_segment/__init__.py +3 -0
- endoreg_db/models/label/label_video_segment/_create_from_video.py +41 -0
- endoreg_db/models/label/label_video_segment/label_video_segment.py +511 -0
- endoreg_db/models/label/video_segmentation_label.py +31 -0
- endoreg_db/models/{annotation → label}/video_segmentation_labelset.py +7 -0
- endoreg_db/models/media/__init__.py +14 -0
- endoreg_db/models/media/frame/__init__.py +3 -0
- endoreg_db/models/media/frame/frame.py +111 -0
- endoreg_db/models/media/pdf/__init__.py +11 -0
- endoreg_db/models/media/pdf/raw_pdf.py +608 -0
- endoreg_db/models/media/pdf/report_file.py +162 -0
- endoreg_db/models/media/pdf/report_reader/report_reader_config.py +77 -0
- endoreg_db/models/media/video/__init__.py +4 -0
- endoreg_db/models/media/video/create_from_file.py +336 -0
- endoreg_db/models/media/video/pipe_1.py +195 -0
- endoreg_db/models/media/video/pipe_2.py +105 -0
- endoreg_db/models/media/video/refactor_plan.md +0 -0
- endoreg_db/models/media/video/video_file.py +680 -0
- endoreg_db/models/media/video/video_file_ai.py +443 -0
- endoreg_db/models/media/video/video_file_anonymize.py +348 -0
- endoreg_db/models/media/video/video_file_frames/__init__.py +47 -0
- endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +22 -0
- endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +23 -0
- endoreg_db/models/media/video/video_file_frames/_delete_frames.py +104 -0
- endoreg_db/models/media/video/video_file_frames/_extract_frames.py +174 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame.py +28 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +27 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +20 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +27 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +34 -0
- endoreg_db/models/media/video/video_file_frames/_get_frames.py +27 -0
- endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +129 -0
- endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +129 -0
- endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +65 -0
- endoreg_db/models/media/video/video_file_frames.py +0 -0
- endoreg_db/models/media/video/video_file_io.py +166 -0
- endoreg_db/models/media/video/video_file_meta/__init__.py +22 -0
- endoreg_db/models/media/video/video_file_meta/get_crop_template.py +45 -0
- endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +39 -0
- endoreg_db/models/media/video/video_file_meta/get_fps.py +147 -0
- endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +143 -0
- endoreg_db/models/media/video/video_file_meta/text_meta.py +134 -0
- endoreg_db/models/media/video/video_file_meta/video_meta.py +70 -0
- endoreg_db/models/media/video/video_file_meta.py +11 -0
- endoreg_db/models/media/video/video_file_segments.py +209 -0
- endoreg_db/models/medical/__init__.py +146 -0
- endoreg_db/models/{contraindication → medical/contraindication}/__init__.py +1 -5
- endoreg_db/models/medical/disease.py +156 -0
- endoreg_db/models/medical/event.py +137 -0
- endoreg_db/models/{examination → medical/examination}/__init__.py +1 -1
- endoreg_db/models/medical/examination/examination.py +148 -0
- endoreg_db/models/medical/examination/examination_indication.py +278 -0
- endoreg_db/models/{examination → medical/examination}/examination_time.py +0 -4
- endoreg_db/models/{examination → medical/examination}/examination_time_type.py +1 -8
- endoreg_db/models/{examination → medical/examination}/examination_type.py +18 -10
- endoreg_db/models/medical/finding/__init__.py +18 -0
- endoreg_db/models/medical/finding/finding.py +96 -0
- endoreg_db/models/medical/finding/finding_classification.py +142 -0
- endoreg_db/models/{finding → medical/finding}/finding_intervention.py +2 -10
- endoreg_db/models/medical/finding/finding_type.py +35 -0
- endoreg_db/models/medical/hardware/__init__.py +8 -0
- endoreg_db/models/{hardware → medical/hardware}/endoscope.py +28 -23
- endoreg_db/models/medical/laboratory/__init__.py +5 -0
- endoreg_db/models/medical/laboratory/lab_value.py +419 -0
- endoreg_db/models/{medication → medical/medication}/medication.py +1 -3
- endoreg_db/models/{medication → medical/medication}/medication_indication_type.py +8 -3
- endoreg_db/models/{medication → medical/medication}/medication_intake_time.py +21 -3
- endoreg_db/models/{medication → medical/medication}/medication_schedule.py +13 -5
- endoreg_db/models/{organ → medical/organ}/__init__.py +3 -6
- endoreg_db/models/medical/patient/__init__.py +56 -0
- endoreg_db/models/medical/patient/medication_examples.py +38 -0
- endoreg_db/models/medical/patient/patient_disease.py +63 -0
- endoreg_db/models/medical/patient/patient_event.py +75 -0
- endoreg_db/models/medical/patient/patient_examination.py +249 -0
- endoreg_db/models/{persons → medical}/patient/patient_examination_indication.py +21 -9
- endoreg_db/models/medical/patient/patient_finding.py +357 -0
- endoreg_db/models/medical/patient/patient_finding_classification.py +207 -0
- endoreg_db/models/{patient → medical/patient}/patient_finding_intervention.py +15 -1
- endoreg_db/models/medical/patient/patient_lab_sample.py +148 -0
- endoreg_db/models/{persons → medical}/patient/patient_lab_value.py +40 -15
- endoreg_db/models/medical/patient/patient_medication.py +104 -0
- endoreg_db/models/medical/patient/patient_medication_schedule.py +136 -0
- endoreg_db/models/medical/risk/__init__.py +7 -0
- endoreg_db/models/medical/risk/risk.py +72 -0
- endoreg_db/models/medical/risk/risk_type.py +51 -0
- endoreg_db/models/{data_file/metadata → metadata}/__init__.py +6 -0
- endoreg_db/models/metadata/frame_ocr_result.py +0 -0
- endoreg_db/models/metadata/model_meta.py +193 -0
- endoreg_db/models/metadata/model_meta_logic.py +236 -0
- endoreg_db/models/{data_file/metadata → metadata}/pdf_meta.py +28 -13
- endoreg_db/models/metadata/sensitive_meta.py +288 -0
- endoreg_db/models/metadata/sensitive_meta_logic.py +643 -0
- endoreg_db/models/metadata/video_meta.py +332 -0
- endoreg_db/models/metadata/video_prediction_logic.py +190 -0
- endoreg_db/models/metadata/video_prediction_meta.py +270 -0
- endoreg_db/models/other/__init__.py +17 -0
- endoreg_db/models/other/distribution/date_value_distribution.py +0 -2
- endoreg_db/models/other/distribution/numeric_value_distribution.py +30 -2
- endoreg_db/models/{emission → other/emission}/emission_factor.py +15 -6
- endoreg_db/models/{persons → other}/gender.py +8 -3
- endoreg_db/models/other/information_source.py +159 -0
- endoreg_db/models/other/material.py +10 -2
- endoreg_db/models/other/resource.py +6 -2
- endoreg_db/models/other/tag.py +27 -0
- endoreg_db/models/other/transport_route.py +13 -2
- endoreg_db/models/{unit.py → other/unit.py} +16 -6
- endoreg_db/models/other/waste.py +10 -3
- endoreg_db/models/requirement/__init__.py +11 -0
- endoreg_db/models/requirement/requirement.py +767 -0
- endoreg_db/models/requirement/requirement_evaluation/__init__.py +6 -0
- endoreg_db/models/requirement/requirement_evaluation/get_values.py +40 -0
- endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +9 -0
- endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +95 -0
- endoreg_db/models/requirement/requirement_operator.py +176 -0
- endoreg_db/models/requirement/requirement_set.py +287 -0
- endoreg_db/models/rule/__init__.py +13 -0
- endoreg_db/models/{rules → rule}/rule.py +6 -3
- endoreg_db/models/{rules → rule}/rule_attribute_dtype.py +0 -2
- endoreg_db/models/{rules → rule}/rule_type.py +0 -2
- endoreg_db/models/{rules → rule}/ruleset.py +0 -2
- endoreg_db/models/state/__init__.py +12 -0
- endoreg_db/models/state/abstract.py +11 -0
- endoreg_db/models/state/audit_ledger.py +150 -0
- endoreg_db/models/state/label_video_segment.py +22 -0
- endoreg_db/models/state/raw_pdf.py +187 -0
- endoreg_db/models/state/sensitive_meta.py +46 -0
- endoreg_db/models/state/video.py +232 -0
- endoreg_db/models/upload_job.py +99 -0
- endoreg_db/models/utils.py +135 -0
- endoreg_db/models/video_metadata.py +66 -0
- endoreg_db/models/video_processing.py +153 -0
- endoreg_db/renames.yml +8 -0
- endoreg_db/root_urls.py +9 -0
- endoreg_db/schemas/__init__.py +0 -0
- endoreg_db/schemas/examination_evaluation.py +27 -0
- endoreg_db/serializers/Frames_NICE_and_PARIS_classifications.py +775 -0
- endoreg_db/serializers/__init__.py +147 -10
- endoreg_db/serializers/{raw_pdf_meta_validation.py → _old/raw_pdf_meta_validation.py} +3 -3
- endoreg_db/serializers/{raw_video_meta_validation.py → _old/raw_video_meta_validation.py} +18 -14
- endoreg_db/serializers/_old/video.py +71 -0
- endoreg_db/serializers/administration/__init__.py +14 -0
- endoreg_db/serializers/administration/ai/__init__.py +10 -0
- endoreg_db/serializers/administration/ai/active_model.py +10 -0
- endoreg_db/serializers/administration/ai/ai_model.py +18 -0
- endoreg_db/serializers/administration/ai/model_type.py +10 -0
- endoreg_db/serializers/administration/center.py +9 -0
- endoreg_db/serializers/administration/gender.py +9 -0
- endoreg_db/serializers/anonymization.py +66 -0
- endoreg_db/serializers/evaluation/examination_evaluation.py +1 -0
- endoreg_db/serializers/examination/__init__.py +10 -0
- endoreg_db/serializers/examination/base.py +46 -0
- endoreg_db/serializers/examination/dropdown.py +21 -0
- endoreg_db/serializers/examination_serializer.py +12 -0
- endoreg_db/serializers/finding/__init__.py +5 -0
- endoreg_db/serializers/finding/finding.py +54 -0
- endoreg_db/serializers/finding_classification/__init__.py +7 -0
- endoreg_db/serializers/finding_classification/choice.py +19 -0
- endoreg_db/serializers/finding_classification/classification.py +13 -0
- endoreg_db/serializers/label/__init__.py +7 -0
- endoreg_db/serializers/label/image_classification_annotation.py +62 -0
- endoreg_db/serializers/label/label.py +15 -0
- endoreg_db/serializers/label_video_segment/__init__.py +7 -0
- endoreg_db/serializers/label_video_segment/_lvs_create.py +149 -0
- endoreg_db/serializers/label_video_segment/_lvs_update.py +138 -0
- endoreg_db/serializers/label_video_segment/_lvs_validate.py +149 -0
- endoreg_db/serializers/label_video_segment/label_video_segment.py +344 -0
- endoreg_db/serializers/label_video_segment/label_video_segment_annotation.py +99 -0
- endoreg_db/serializers/label_video_segment/label_video_segment_update.py +163 -0
- endoreg_db/serializers/meta/__init__.py +19 -0
- endoreg_db/serializers/meta/pdf_file_meta_extraction.py +115 -0
- endoreg_db/serializers/meta/report_meta.py +53 -0
- endoreg_db/serializers/meta/sensitive_meta_detail.py +162 -0
- endoreg_db/serializers/meta/sensitive_meta_update.py +148 -0
- endoreg_db/serializers/meta/sensitive_meta_verification.py +59 -0
- endoreg_db/serializers/meta/video_meta.py +39 -0
- endoreg_db/serializers/misc/__init__.py +14 -0
- endoreg_db/serializers/misc/file_overview.py +152 -0
- endoreg_db/serializers/misc/stats.py +33 -0
- endoreg_db/serializers/misc/translatable_field_mix_in.py +44 -0
- endoreg_db/serializers/misc/upload_job.py +71 -0
- endoreg_db/serializers/misc/vop_patient_data.py +120 -0
- endoreg_db/serializers/patient/__init__.py +11 -0
- endoreg_db/serializers/patient/patient.py +86 -0
- endoreg_db/serializers/patient/patient_dropdown.py +27 -0
- endoreg_db/serializers/patient_examination/__init__.py +7 -0
- endoreg_db/serializers/patient_examination/patient_examination.py +141 -0
- endoreg_db/serializers/patient_finding/__init__.py +15 -0
- endoreg_db/serializers/patient_finding/patient_finding.py +31 -0
- endoreg_db/serializers/patient_finding/patient_finding_classification.py +39 -0
- endoreg_db/serializers/patient_finding/patient_finding_detail.py +53 -0
- endoreg_db/serializers/patient_finding/patient_finding_intervention.py +26 -0
- endoreg_db/serializers/patient_finding/patient_finding_list.py +41 -0
- endoreg_db/serializers/patient_finding/patient_finding_write.py +126 -0
- endoreg_db/serializers/pdf/__init__.py +5 -0
- endoreg_db/serializers/pdf/anony_text_validation.py +85 -0
- endoreg_db/serializers/report/__init__.py +9 -0
- endoreg_db/serializers/report/mixins.py +45 -0
- endoreg_db/serializers/report/report.py +105 -0
- endoreg_db/serializers/report/report_list.py +22 -0
- endoreg_db/serializers/report/secure_file_url.py +26 -0
- endoreg_db/serializers/requirements/requirement_schema.py +25 -0
- endoreg_db/serializers/requirements/requirement_sets.py +29 -0
- endoreg_db/serializers/sensitive_meta_serializer.py +282 -0
- endoreg_db/serializers/video/__init__.py +7 -0
- endoreg_db/serializers/video/segmentation.py +263 -0
- endoreg_db/serializers/video/video_file_brief.py +10 -0
- endoreg_db/serializers/video/video_file_detail.py +83 -0
- endoreg_db/serializers/video/video_file_list.py +67 -0
- endoreg_db/serializers/video/video_metadata.py +105 -0
- endoreg_db/serializers/video/video_processing_history.py +153 -0
- endoreg_db/services/__init__.py +5 -0
- endoreg_db/services/anonymization.py +223 -0
- endoreg_db/services/examination_evaluation.py +149 -0
- endoreg_db/services/finding_description_service.py +0 -0
- endoreg_db/services/lookup_service.py +241 -0
- endoreg_db/services/lookup_store.py +122 -0
- endoreg_db/services/ollama_api_docs.py +1528 -0
- endoreg_db/services/pdf_import.py +993 -0
- endoreg_db/services/polling_coordinator.py +288 -0
- endoreg_db/services/pseudonym_service.py +89 -0
- endoreg_db/services/requirements_object.py +147 -0
- endoreg_db/services/segment_sync.py +155 -0
- endoreg_db/services/storage_aware_video_processor.py +344 -0
- endoreg_db/services/video_import.py +915 -0
- endoreg_db/tasks/upload_tasks.py +207 -0
- endoreg_db/tasks/video_ingest.py +157 -0
- endoreg_db/tasks/video_processing_tasks.py +327 -0
- endoreg_db/urls/__init__.py +72 -0
- endoreg_db/urls/anonymization.py +32 -0
- endoreg_db/urls/auth.py +16 -0
- endoreg_db/urls/classification.py +39 -0
- endoreg_db/urls/examination.py +54 -0
- endoreg_db/urls/files.py +6 -0
- endoreg_db/urls/label_video_segment_validate.py +33 -0
- endoreg_db/urls/label_video_segments.py +44 -0
- endoreg_db/urls/media.py +32 -0
- endoreg_db/urls/patient.py +19 -0
- endoreg_db/urls/pdf.py +0 -0
- endoreg_db/urls/report.py +78 -0
- endoreg_db/urls/requirements.py +13 -0
- endoreg_db/urls/sensitive_meta.py +36 -0
- endoreg_db/urls/stats.py +46 -0
- endoreg_db/urls/upload.py +20 -0
- endoreg_db/urls/video.py +119 -0
- endoreg_db/urls.py +6 -269
- endoreg_db/utils/__init__.py +68 -16
- endoreg_db/utils/ai/__init__.py +9 -0
- endoreg_db/{models/ai_model/utils.py → utils/ai/get.py} +1 -4
- endoreg_db/{models/ai_model/lightning → utils/ai}/inference_dataset.py +0 -1
- endoreg_db/{models/ai_model/lightning → utils/ai}/multilabel_classification_net.py +14 -10
- endoreg_db/{models/ai_model/lightning → utils/ai}/postprocess.py +15 -5
- endoreg_db/utils/ai/predict.py +291 -0
- endoreg_db/{models/ai_model/lightning → utils/ai}/preprocess.py +1 -1
- endoreg_db/utils/calc_duration_seconds.py +24 -0
- endoreg_db/utils/case_generator/__init__.py +0 -0
- endoreg_db/utils/check_video_files.py +148 -0
- endoreg_db/utils/dataloader.py +88 -31
- endoreg_db/utils/dates.py +21 -0
- endoreg_db/utils/env.py +33 -0
- endoreg_db/utils/extract_specific_frames.py +72 -0
- endoreg_db/utils/file_operations.py +29 -1
- endoreg_db/utils/fix_video_path_direct.py +141 -0
- endoreg_db/utils/frame_anonymization_utils.py +463 -0
- endoreg_db/utils/hashs.py +1 -0
- endoreg_db/utils/links/__init__.py +0 -0
- endoreg_db/utils/links/requirement_link.py +193 -0
- endoreg_db/utils/mime_types.py +0 -0
- endoreg_db/utils/names.py +2 -0
- endoreg_db/utils/paths.py +104 -0
- endoreg_db/utils/permissions.py +143 -0
- endoreg_db/utils/pipelines/Readme.md +235 -0
- endoreg_db/utils/pipelines/__init__.py +0 -0
- endoreg_db/utils/pipelines/process_video_dir.py +120 -0
- endoreg_db/utils/product/__init__.py +0 -0
- endoreg_db/utils/product/sum_emissions.py +20 -0
- endoreg_db/utils/product/sum_weights.py +18 -0
- endoreg_db/utils/pydantic_models/db_config.py +1 -1
- endoreg_db/utils/requirement_helpers.py +0 -0
- endoreg_db/utils/requirement_operator_logic/__init__.py +0 -0
- endoreg_db/utils/requirement_operator_logic/lab_value_operators.py +578 -0
- endoreg_db/utils/requirement_operator_logic/model_evaluators.py +368 -0
- endoreg_db/utils/translation.py +27 -0
- endoreg_db/utils/validate_video_detailed.py +357 -0
- endoreg_db/utils/video/__init__.py +19 -6
- endoreg_db/utils/video/extract_frames.py +37 -70
- endoreg_db/utils/video/ffmpeg_wrapper.py +772 -0
- endoreg_db/utils/video/names.py +42 -0
- endoreg_db/utils/video/streaming_processor.py +312 -0
- endoreg_db/utils/video/video_splitter.py +94 -0
- endoreg_db/views/Frames_NICE_and_PARIS_classifications_views.py +238 -0
- endoreg_db/views/__init__.py +282 -2
- endoreg_db/views/anonymization/__init__.py +27 -0
- endoreg_db/views/anonymization/media_management.py +454 -0
- endoreg_db/views/anonymization/overview.py +216 -0
- endoreg_db/views/anonymization/validate.py +63 -0
- endoreg_db/views/auth/__init__.py +13 -0
- endoreg_db/views/auth/keycloak.py +113 -0
- endoreg_db/views/examination/__init__.py +33 -0
- endoreg_db/views/examination/examination.py +37 -0
- endoreg_db/views/examination/examination_manifest_cache.py +26 -0
- endoreg_db/views/examination/get_finding_classification_choices.py +59 -0
- endoreg_db/views/examination/get_finding_classifications.py +36 -0
- endoreg_db/views/examination/get_findings.py +41 -0
- endoreg_db/views/examination/get_instruments.py +18 -0
- endoreg_db/views/examination/get_interventions.py +14 -0
- endoreg_db/views/finding/__init__.py +9 -0
- endoreg_db/views/finding/finding.py +112 -0
- endoreg_db/views/finding/get_classifications.py +14 -0
- endoreg_db/views/finding/get_interventions.py +17 -0
- endoreg_db/views/finding_classification/__init__.py +13 -0
- endoreg_db/views/finding_classification/base.py +0 -0
- endoreg_db/views/finding_classification/finding_classification.py +42 -0
- endoreg_db/views/finding_classification/get_classification_choices.py +55 -0
- endoreg_db/views/label/__init__.py +5 -0
- endoreg_db/views/label/label.py +15 -0
- endoreg_db/views/label_video_segment/__init__.py +16 -0
- endoreg_db/views/label_video_segment/create_lvs_from_annotation.py +44 -0
- endoreg_db/views/label_video_segment/get_lvs_by_name_and_video.py +50 -0
- endoreg_db/views/label_video_segment/label_video_segment.py +77 -0
- endoreg_db/views/label_video_segment/label_video_segment_by_label.py +174 -0
- endoreg_db/views/label_video_segment/label_video_segment_detail.py +73 -0
- endoreg_db/views/label_video_segment/update_lvs_from_annotation.py +46 -0
- endoreg_db/views/label_video_segment/validate.py +226 -0
- endoreg_db/views/media/__init__.py +9 -0
- endoreg_db/views/media/pdf_media.py +386 -0
- endoreg_db/views/media/video_media.py +272 -0
- endoreg_db/views/meta/__init__.py +15 -0
- endoreg_db/views/meta/available_files_list.py +146 -0
- endoreg_db/views/meta/report_meta.py +53 -0
- endoreg_db/views/meta/sensitive_meta_detail.py +148 -0
- endoreg_db/views/meta/sensitive_meta_list.py +104 -0
- endoreg_db/views/meta/sensitive_meta_verification.py +71 -0
- endoreg_db/views/misc/__init__.py +63 -0
- endoreg_db/views/misc/center.py +13 -0
- endoreg_db/views/misc/gender.py +14 -0
- endoreg_db/views/misc/secure_file_serving_view.py +80 -0
- endoreg_db/views/misc/secure_file_url_view.py +84 -0
- endoreg_db/views/misc/secure_url_validate.py +79 -0
- endoreg_db/views/misc/stats.py +220 -0
- endoreg_db/views/misc/translation.py +182 -0
- endoreg_db/views/misc/upload_views.py +240 -0
- endoreg_db/views/patient/__init__.py +5 -0
- endoreg_db/views/patient/patient.py +210 -0
- endoreg_db/views/patient_examination/DEPRECATED_video_backup.py +164 -0
- endoreg_db/views/patient_examination/__init__.py +11 -0
- endoreg_db/views/patient_examination/patient_examination.py +140 -0
- endoreg_db/views/patient_examination/patient_examination_create.py +63 -0
- endoreg_db/views/patient_examination/patient_examination_detail.py +66 -0
- endoreg_db/views/patient_examination/patient_examination_list.py +68 -0
- endoreg_db/views/patient_examination/video.py +194 -0
- endoreg_db/views/patient_finding/__init__.py +7 -0
- endoreg_db/views/patient_finding/base.py +0 -0
- endoreg_db/views/patient_finding/patient_finding.py +64 -0
- endoreg_db/views/patient_finding/patient_finding_optimized.py +259 -0
- endoreg_db/views/patient_finding_classification/__init__.py +5 -0
- endoreg_db/views/patient_finding_classification/pfc_create.py +67 -0
- endoreg_db/views/patient_finding_location/__init__.py +5 -0
- endoreg_db/views/patient_finding_location/pfl_create.py +70 -0
- endoreg_db/views/patient_finding_morphology/__init__.py +5 -0
- endoreg_db/views/patient_finding_morphology/pfm_create.py +70 -0
- endoreg_db/views/pdf/__init__.py +11 -0
- endoreg_db/views/pdf/pdf_media.py +239 -0
- endoreg_db/views/pdf/pdf_stream_views.py +127 -0
- endoreg_db/views/pdf/reimport.py +151 -0
- endoreg_db/views/report/__init__.py +9 -0
- endoreg_db/views/report/report_list.py +112 -0
- endoreg_db/views/report/report_with_secure_url.py +28 -0
- endoreg_db/views/report/start_examination.py +7 -0
- endoreg_db/views/requirement/__init__.py +10 -0
- endoreg_db/views/requirement/evaluate.py +279 -0
- endoreg_db/views/requirement/lookup.py +483 -0
- endoreg_db/views/requirement/lookup_store.py +252 -0
- endoreg_db/views/requirement_lookup/lookup.py +0 -0
- endoreg_db/views/requirement_lookup/lookup_store.py +0 -0
- endoreg_db/views/stats/__init__.py +13 -0
- endoreg_db/views/stats/stats_views.py +229 -0
- endoreg_db/views/video/__init__.py +72 -0
- endoreg_db/views/video/correction.py +672 -0
- endoreg_db/views/video/media/__init__.py +23 -0
- endoreg_db/views/video/media/task_status.py +49 -0
- endoreg_db/views/video/media/video_analyze.py +52 -0
- endoreg_db/views/video/media/video_apply_mask.py +48 -0
- endoreg_db/views/video/media/video_correction.py +21 -0
- endoreg_db/views/video/media/video_download_processed.py +58 -0
- endoreg_db/views/video/media/video_media.py +158 -0
- endoreg_db/views/video/media/video_meta.py +29 -0
- endoreg_db/views/video/media/video_processing_history.py +24 -0
- endoreg_db/views/video/media/video_remove_frames.py +48 -0
- endoreg_db/views/video/media/video_reprocess.py +40 -0
- endoreg_db/views/video/reimport.py +192 -0
- endoreg_db/views/video/segmentation.py +274 -0
- endoreg_db/views/{views_for_timeline.py → video/timeline.py} +3 -3
- endoreg_db/views/video/video_examination_viewset.py +329 -0
- endoreg_db/views/video/video_stream.py +188 -0
- endoreg_db-0.8.1.dist-info/METADATA +384 -0
- endoreg_db-0.8.1.dist-info/RECORD +789 -0
- endoreg_db/data/agl_service/data.yaml +0 -19
- endoreg_db/data/finding_location_classification/colonoscopy.yaml +0 -46
- endoreg_db/data/finding_morphology_classification/colonoscopy.yaml +0 -48
- endoreg_db/data/finding_morphology_classification_choice/colonoscopy_size.yaml +0 -57
- endoreg_db/management/commands/_load_model_template.py +0 -41
- endoreg_db/management/commands/delete_all.py +0 -18
- endoreg_db/management/commands/fetch_legacy_image_dataset.py +0 -32
- endoreg_db/management/commands/fix_auth_permission.py +0 -20
- endoreg_db/management/commands/load_active_model_data.py +0 -45
- endoreg_db/management/commands/load_g_play_data.py +0 -113
- endoreg_db/management/commands/load_logging_data.py +0 -39
- endoreg_db/management/commands/load_lx_data.py +0 -64
- endoreg_db/management/commands/load_medication_indication_data.py +0 -63
- endoreg_db/management/commands/load_medication_indication_type_data.py +0 -41
- endoreg_db/management/commands/load_medication_intake_time_data.py +0 -41
- endoreg_db/management/commands/load_medication_schedule_data.py +0 -55
- endoreg_db/management/commands/load_network_data.py +0 -57
- endoreg_db/migrations/0002_alter_frame_image_alter_rawframe_image.py +0 -23
- endoreg_db/migrations/0003_alter_frame_image_alter_rawframe_image.py +0 -23
- endoreg_db/migrations/0004_alter_rawvideofile_file_alter_video_file.py +0 -25
- endoreg_db/migrations/0005_rawvideofile_frame_count_and_more.py +0 -33
- endoreg_db/migrations/0006_frame_extracted_rawframe_extracted.py +0 -23
- endoreg_db/migrations/0007_rename_pseudo_patient_video_patient_and_more.py +0 -24
- endoreg_db/migrations/0008_remove_reportfile_patient_examination_and_more.py +0 -48
- endoreg_db/models/ai_model/active_model.py +0 -9
- endoreg_db/models/ai_model/ai_model.py +0 -103
- endoreg_db/models/ai_model/lightning/__init__.py +0 -3
- endoreg_db/models/ai_model/lightning/predict.py +0 -172
- endoreg_db/models/ai_model/lightning/prediction_visualizer.py +0 -55
- endoreg_db/models/ai_model/lightning/run_visualizer.py +0 -21
- endoreg_db/models/ai_model/model_meta.py +0 -250
- endoreg_db/models/annotation/__init__.py +0 -32
- endoreg_db/models/annotation/anonymized_image_annotation.py +0 -115
- endoreg_db/models/annotation/binary_classification_annotation_task.py +0 -117
- endoreg_db/models/annotation/image_classification.py +0 -86
- endoreg_db/models/annotation/video_segmentation_annotation.py +0 -52
- endoreg_db/models/case/__init__.py +0 -1
- endoreg_db/models/case/case.py +0 -34
- endoreg_db/models/center/center.py +0 -51
- endoreg_db/models/center/center_product.py +0 -33
- endoreg_db/models/center/center_waste.py +0 -16
- endoreg_db/models/data_file/__init__.py +0 -39
- endoreg_db/models/data_file/base_classes/__init__.py +0 -7
- endoreg_db/models/data_file/base_classes/abstract_frame.py +0 -100
- endoreg_db/models/data_file/base_classes/abstract_pdf.py +0 -136
- endoreg_db/models/data_file/base_classes/abstract_video.py +0 -807
- endoreg_db/models/data_file/base_classes/frame_helpers.py +0 -17
- endoreg_db/models/data_file/base_classes/prepare_bulk_frames.py +0 -19
- endoreg_db/models/data_file/base_classes/utils.py +0 -80
- endoreg_db/models/data_file/frame.py +0 -29
- endoreg_db/models/data_file/import_classes/__init__.py +0 -18
- endoreg_db/models/data_file/import_classes/processing_functions/__init__.py +0 -35
- endoreg_db/models/data_file/import_classes/processing_functions/pdf.py +0 -28
- endoreg_db/models/data_file/import_classes/processing_functions/video.py +0 -260
- endoreg_db/models/data_file/import_classes/raw_pdf.py +0 -260
- endoreg_db/models/data_file/import_classes/raw_video.py +0 -288
- endoreg_db/models/data_file/metadata/sensitive_meta.py +0 -290
- endoreg_db/models/data_file/metadata/video_meta.py +0 -199
- endoreg_db/models/data_file/report_file.py +0 -56
- endoreg_db/models/data_file/video/__init__.py +0 -11
- endoreg_db/models/data_file/video/import_meta.py +0 -25
- endoreg_db/models/data_file/video/video.py +0 -196
- endoreg_db/models/data_file/video_segment.py +0 -214
- endoreg_db/models/disease.py +0 -79
- endoreg_db/models/event.py +0 -73
- endoreg_db/models/examination/examination.py +0 -67
- endoreg_db/models/examination/examination_indication.py +0 -170
- endoreg_db/models/finding/__init__.py +0 -11
- endoreg_db/models/finding/finding.py +0 -75
- endoreg_db/models/finding/finding_location_classification.py +0 -94
- endoreg_db/models/finding/finding_morphology_classification.py +0 -89
- endoreg_db/models/finding/finding_type.py +0 -22
- endoreg_db/models/hardware/__init__.py +0 -2
- endoreg_db/models/information_source.py +0 -29
- endoreg_db/models/laboratory/__init__.py +0 -1
- endoreg_db/models/laboratory/lab_value.py +0 -111
- endoreg_db/models/logging/__init__.py +0 -11
- endoreg_db/models/logging/agl_service.py +0 -19
- endoreg_db/models/logging/base.py +0 -22
- endoreg_db/models/logging/log_type.py +0 -23
- endoreg_db/models/logging/network_device.py +0 -27
- endoreg_db/models/lx/__init__.py +0 -4
- endoreg_db/models/lx/client.py +0 -57
- endoreg_db/models/lx/identity.py +0 -34
- endoreg_db/models/lx/permission.py +0 -18
- endoreg_db/models/lx/user.py +0 -16
- endoreg_db/models/network/__init__.py +0 -9
- endoreg_db/models/network/agl_service.py +0 -38
- endoreg_db/models/network/network_device.py +0 -58
- endoreg_db/models/network/network_device_type.py +0 -23
- endoreg_db/models/other/distribution.py +0 -5
- endoreg_db/models/patient/__init__.py +0 -24
- endoreg_db/models/patient/patient_examination.py +0 -182
- endoreg_db/models/patient/patient_finding.py +0 -143
- endoreg_db/models/patient/patient_finding_location.py +0 -120
- endoreg_db/models/patient/patient_finding_morphology.py +0 -166
- endoreg_db/models/permissions/__init__.py +0 -44
- endoreg_db/models/persons/__init__.py +0 -34
- endoreg_db/models/persons/examiner/__init__.py +0 -2
- endoreg_db/models/persons/examiner/examiner.py +0 -60
- endoreg_db/models/persons/examiner/examiner_type.py +0 -2
- endoreg_db/models/persons/patient/__init__.py +0 -8
- endoreg_db/models/persons/patient/patient.py +0 -389
- endoreg_db/models/persons/patient/patient_disease.py +0 -22
- endoreg_db/models/persons/patient/patient_event.py +0 -52
- endoreg_db/models/persons/patient/patient_lab_sample.py +0 -108
- endoreg_db/models/persons/patient/patient_medication.py +0 -59
- endoreg_db/models/persons/patient/patient_medication_schedule.py +0 -88
- endoreg_db/models/persons/portal_user_information.py +0 -27
- endoreg_db/models/prediction/__init__.py +0 -8
- endoreg_db/models/prediction/image_classification.py +0 -51
- endoreg_db/models/prediction/video_prediction_meta.py +0 -306
- endoreg_db/models/product/product.py +0 -110
- endoreg_db/models/product/product_group.py +0 -27
- endoreg_db/models/product/product_material.py +0 -28
- endoreg_db/models/questionnaires/__init__.py +0 -114
- endoreg_db/models/quiz/__init__.py +0 -9
- endoreg_db/models/quiz/quiz_answer.py +0 -41
- endoreg_db/models/quiz/quiz_question.py +0 -54
- endoreg_db/models/report_reader/report_reader_config.py +0 -53
- endoreg_db/models/rules/__init__.py +0 -5
- endoreg_db/queries/get/__init__.py +0 -6
- endoreg_db/queries/get/center.py +0 -42
- endoreg_db/queries/get/model.py +0 -13
- endoreg_db/queries/get/patient.py +0 -14
- endoreg_db/queries/get/patient_examination.py +0 -20
- endoreg_db/queries/get/report_file.py +0 -33
- endoreg_db/queries/get/video.py +0 -31
- endoreg_db/serializers/ai_model.py +0 -19
- endoreg_db/serializers/annotation.py +0 -14
- endoreg_db/serializers/center.py +0 -11
- endoreg_db/serializers/examination.py +0 -33
- endoreg_db/serializers/frame.py +0 -9
- endoreg_db/serializers/hardware.py +0 -21
- endoreg_db/serializers/label.py +0 -22
- endoreg_db/serializers/patient.py +0 -33
- endoreg_db/serializers/prediction.py +0 -10
- endoreg_db/serializers/raw_pdf_anony_text_validation.py +0 -137
- endoreg_db/serializers/report_file.py +0 -7
- endoreg_db/serializers/video.py +0 -20
- endoreg_db/serializers/video_segmentation.py +0 -587
- endoreg_db/tests.py +0 -3
- endoreg_db/utils/legacy_ocr.py +0 -201
- endoreg_db/utils/video/transcode_videofile.py +0 -111
- endoreg_db/views/patient_views.py +0 -90
- endoreg_db/views/raw_pdf_anony_text_validation_views.py +0 -95
- endoreg_db/views/raw_pdf_meta_validation_views.py +0 -111
- endoreg_db/views/raw_video_meta_validation_views.py +0 -148
- endoreg_db/views/report_views.py +0 -96
- endoreg_db/views/video_segmentation_views.py +0 -166
- endoreg_db-0.6.3.dist-info/METADATA +0 -161
- endoreg_db-0.6.3.dist-info/RECORD +0 -435
- /endoreg_db/{case_generator/__init__.py → api/serializers/finding_descriptions.py} +0 -0
- /endoreg_db/{queries/get/annotation.py → api/views/finding_descriptions.py} +0 -0
- /endoreg_db/{queries/get/prediction.py → data/shift/m2.yaml} +0 -0
- /endoreg_db/{queries/get/video_import_meta.py → factories/__init__.py} +0 -0
- /endoreg_db/{queries/get/video_prediction_meta.py → helpers/__init__.py} +0 -0
- /endoreg_db/models/{case_template → administration/case/case_template}/__init__.py +0 -0
- /endoreg_db/models/{persons → administration/person}/person.py +0 -0
- /endoreg_db/models/{product → administration/product}/__init__.py +0 -0
- /endoreg_db/models/{report_reader → media/pdf/report_reader}/__init__.py +0 -0
- /endoreg_db/models/{report_reader → media/pdf/report_reader}/report_reader_flag.py +0 -0
- /endoreg_db/models/{hardware → medical/hardware}/endoscopy_processor.py +0 -0
- /endoreg_db/models/{medication → medical/medication}/__init__.py +0 -0
- /endoreg_db/models/{medication → medical/medication}/medication_indication.py +0 -0
- /endoreg_db/models/{emission → other/emission}/__init__.py +0 -0
- /endoreg_db/models/{rules → rule}/rule_applicator.py +0 -0
- /endoreg_db/{case_generator → utils/case_generator}/case_generator.py +0 -0
- /endoreg_db/{case_generator → utils/case_generator}/lab_sample_factory.py +0 -0
- /endoreg_db/{case_generator → utils/case_generator}/utils.py +0 -0
- /endoreg_db/views/{csrf.py → misc/csrf.py} +0 -0
- {endoreg_db-0.6.3.dist-info → endoreg_db-0.8.1.dist-info}/WHEEL +0 -0
- {endoreg_db-0.6.3.dist-info → endoreg_db-0.8.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
from django.shortcuts import render
|
|
2
|
+
from django.contrib.admin.views.decorators import staff_member_required
|
|
3
|
+
from django.db import transaction
|
|
4
|
+
|
|
5
|
+
from rest_framework import viewsets, status, serializers
|
|
6
|
+
from rest_framework.response import Response
|
|
7
|
+
from rest_framework.decorators import action
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
from endoreg_db.models import Patient
|
|
11
|
+
from endoreg_db.serializers.patient import PatientSerializer
|
|
12
|
+
from endoreg_db.models.medical.patient.patient_examination import PatientExamination
|
|
13
|
+
|
|
14
|
+
@staff_member_required # Ensures only staff members can access the page
|
|
15
|
+
def start_examination(request):
|
|
16
|
+
return render(request, 'admin/start_examination.html') # Loads the simple HTML page
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
#TODO Review this view
|
|
20
|
+
class PatientViewSet(viewsets.ModelViewSet):
|
|
21
|
+
"""API endpoint for managing patients."""
|
|
22
|
+
queryset = Patient.objects.all()
|
|
23
|
+
serializer_class = PatientSerializer
|
|
24
|
+
#permission_classes = [IsAuthenticatedOrReadOnly]
|
|
25
|
+
|
|
26
|
+
def perform_create(self, serializer):
|
|
27
|
+
"""Erweiterte Validierung beim Erstellen eines Patienten"""
|
|
28
|
+
try:
|
|
29
|
+
# Zusätzliche Validierung falls nötig
|
|
30
|
+
patient = serializer.save()
|
|
31
|
+
return patient
|
|
32
|
+
except Exception as e:
|
|
33
|
+
raise serializers.ValidationError(f"Fehler beim Erstellen des Patienten: {str(e)}")
|
|
34
|
+
|
|
35
|
+
def update(self, request, *args, **kwargs):
|
|
36
|
+
"""Erweiterte Logik für das Aktualisieren von Patienten"""
|
|
37
|
+
try:
|
|
38
|
+
return super().update(request, *args, **kwargs)
|
|
39
|
+
except Exception as e:
|
|
40
|
+
return Response(
|
|
41
|
+
{"error": f"Fehler beim Aktualisieren des Patienten: {str(e)}"},
|
|
42
|
+
status=status.HTTP_400_BAD_REQUEST
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
def destroy(self, request, *args, **kwargs):
|
|
46
|
+
"""
|
|
47
|
+
Delete a patient with proper error handling and cascade protection.
|
|
48
|
+
"""
|
|
49
|
+
patient = self.get_object()
|
|
50
|
+
|
|
51
|
+
try:
|
|
52
|
+
with transaction.atomic():
|
|
53
|
+
# Check if patient has related examinations
|
|
54
|
+
examination_count = patient.patient_examinations.count() if hasattr(patient, 'patient_examinations') else 0
|
|
55
|
+
finding_count = 0
|
|
56
|
+
|
|
57
|
+
if examination_count > 0:
|
|
58
|
+
finding_count = sum(
|
|
59
|
+
exam.patient_findings.count() if hasattr(exam, 'patient_findings') else 0
|
|
60
|
+
for exam in patient.patient_examinations.all()
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
return Response({
|
|
64
|
+
'error': 'Patient cannot be deleted',
|
|
65
|
+
'reason': f'Patient has {examination_count} examination(s) and {finding_count} finding(s).',
|
|
66
|
+
'detail': 'Please remove all related examinations and findings before deleting the patient.'
|
|
67
|
+
}, status=status.HTTP_409_CONFLICT)
|
|
68
|
+
|
|
69
|
+
# Check if this is a real person (additional protection)
|
|
70
|
+
if hasattr(patient, 'is_real_person') and patient.is_real_person:
|
|
71
|
+
return Response({
|
|
72
|
+
'error': 'Cannot delete real patient',
|
|
73
|
+
'reason': 'This patient is marked as a real person.',
|
|
74
|
+
'detail': 'Real patient data cannot be deleted for data protection reasons.'
|
|
75
|
+
}, status=status.HTTP_403_FORBIDDEN)
|
|
76
|
+
|
|
77
|
+
# Perform the deletion
|
|
78
|
+
patient_name = f"{patient.first_name} {patient.last_name}"
|
|
79
|
+
patient.delete()
|
|
80
|
+
|
|
81
|
+
return Response({
|
|
82
|
+
'message': f'Patient "{patient_name}" has been successfully deleted.'
|
|
83
|
+
}, status=status.HTTP_200_OK)
|
|
84
|
+
|
|
85
|
+
except Exception as e:
|
|
86
|
+
return Response({
|
|
87
|
+
'error': 'Patient deletion failed',
|
|
88
|
+
'reason': 'Patient has protected related objects.',
|
|
89
|
+
'detail': str(e)
|
|
90
|
+
}, status=status.HTTP_409_CONFLICT)
|
|
91
|
+
except Exception as e:
|
|
92
|
+
return Response(
|
|
93
|
+
{"error": f"Fehler beim Löschen des Patienten: {str(e)}"},
|
|
94
|
+
status=status.HTTP_400_BAD_REQUEST
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
def check_pe_exist(self, request, pk=None):
|
|
98
|
+
"""Check if a patient examination exists.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
request (id): pk of the PatientExamination
|
|
102
|
+
pk (int, optional): _description_. Defaults to None.
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
_type_: _description_
|
|
106
|
+
"""
|
|
107
|
+
try:
|
|
108
|
+
PatientExamination.objects.get(pk=pk)
|
|
109
|
+
return Response({"exists": True}, status=status.HTTP_200_OK)
|
|
110
|
+
except PatientExamination.DoesNotExist:
|
|
111
|
+
return Response({"exists": False}, status=status.HTTP_404_NOT_FOUND)
|
|
112
|
+
|
|
113
|
+
@action(detail=True, methods=['get'])
|
|
114
|
+
def check_deletion_safety(self, request, pk=None):
|
|
115
|
+
"""
|
|
116
|
+
Check if a patient can be safely deleted.
|
|
117
|
+
Returns information about related objects.
|
|
118
|
+
"""
|
|
119
|
+
patient = self.get_object()
|
|
120
|
+
|
|
121
|
+
examination_count = patient.patient_examinations.count() if hasattr(patient, 'patient_examinations') else 0
|
|
122
|
+
examinations = patient.patient_examinations.all() if hasattr(patient, 'patient_examinations') else []
|
|
123
|
+
|
|
124
|
+
finding_count = sum(
|
|
125
|
+
exam.patient_findings.count() if hasattr(exam, 'patient_findings') else 0
|
|
126
|
+
for exam in examinations
|
|
127
|
+
)
|
|
128
|
+
video_count = sum(
|
|
129
|
+
1 for exam in examinations
|
|
130
|
+
if hasattr(exam, 'video') and exam.video
|
|
131
|
+
)
|
|
132
|
+
report_count = sum(
|
|
133
|
+
exam.raw_pdf_files.count() if hasattr(exam, 'raw_pdf_files') else 0
|
|
134
|
+
for exam in examinations
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
is_real_person = hasattr(patient, 'is_real_person') and patient.is_real_person
|
|
138
|
+
can_delete = examination_count == 0 and not is_real_person
|
|
139
|
+
|
|
140
|
+
warnings = []
|
|
141
|
+
if is_real_person:
|
|
142
|
+
warnings.append('This patient is marked as a real person')
|
|
143
|
+
if examination_count > 0:
|
|
144
|
+
warnings.append(f'Patient has {examination_count} examination(s)')
|
|
145
|
+
if finding_count > 0:
|
|
146
|
+
warnings.append(f'Patient has {finding_count} finding(s)')
|
|
147
|
+
|
|
148
|
+
return Response({
|
|
149
|
+
'can_delete': can_delete,
|
|
150
|
+
'is_real_person': is_real_person,
|
|
151
|
+
'related_objects': {
|
|
152
|
+
'examinations': examination_count,
|
|
153
|
+
'findings': finding_count,
|
|
154
|
+
'videos': video_count,
|
|
155
|
+
'reports': report_count
|
|
156
|
+
},
|
|
157
|
+
'warnings': warnings
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
@action(detail=False, methods=['get'])
|
|
161
|
+
def patient_count(self, request):
|
|
162
|
+
"""Gibt die Anzahl der Patienten zurück"""
|
|
163
|
+
count = Patient.objects.count()
|
|
164
|
+
return Response({"count": count})
|
|
165
|
+
|
|
166
|
+
@action(detail=True, methods=['post'], url_path='pseudonym')
|
|
167
|
+
def generate_pseudonym(self, request, pk=None):
|
|
168
|
+
"""
|
|
169
|
+
Generate a pseudonym hash for an existing patient.
|
|
170
|
+
|
|
171
|
+
This endpoint generates a deterministic hash based on the patient's
|
|
172
|
+
personal data (name, dob, center) using server-side logic without
|
|
173
|
+
exposing any secrets to the frontend.
|
|
174
|
+
"""
|
|
175
|
+
from endoreg_db.services.pseudonym_service import generate_patient_pseudonym, validate_patient_for_pseudonym
|
|
176
|
+
|
|
177
|
+
patient = self.get_object()
|
|
178
|
+
|
|
179
|
+
try:
|
|
180
|
+
# Validate that patient has required fields
|
|
181
|
+
missing_fields = validate_patient_for_pseudonym(patient)
|
|
182
|
+
if missing_fields:
|
|
183
|
+
return Response({
|
|
184
|
+
'error': 'Missing required fields for pseudonym generation',
|
|
185
|
+
'missing_fields': missing_fields,
|
|
186
|
+
'detail': f'Please provide: {", ".join(missing_fields)}'
|
|
187
|
+
}, status=status.HTTP_400_BAD_REQUEST)
|
|
188
|
+
|
|
189
|
+
# Generate the pseudonym
|
|
190
|
+
patient_hash, persisted = generate_patient_pseudonym(patient)
|
|
191
|
+
|
|
192
|
+
return Response({
|
|
193
|
+
'patient_id': patient.id,
|
|
194
|
+
'patient_hash': patient_hash,
|
|
195
|
+
'source': 'server',
|
|
196
|
+
'persisted': persisted,
|
|
197
|
+
'message': 'Pseudonym generated successfully'
|
|
198
|
+
}, status=status.HTTP_200_OK)
|
|
199
|
+
|
|
200
|
+
except ValueError as e:
|
|
201
|
+
return Response({
|
|
202
|
+
'error': 'Pseudonym generation failed',
|
|
203
|
+
'detail': str(e)
|
|
204
|
+
}, status=status.HTTP_400_BAD_REQUEST)
|
|
205
|
+
except Exception as e:
|
|
206
|
+
return Response({
|
|
207
|
+
'error': 'Internal server error during pseudonym generation',
|
|
208
|
+
'detail': str(e)
|
|
209
|
+
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
|
210
|
+
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# from rest_framework import viewsets, status
|
|
2
|
+
# from rest_framework.response import Response
|
|
3
|
+
# from django.shortcuts import get_object_or_404
|
|
4
|
+
# from endoreg_db.models import Examination, VideoFile, Finding, FindingClassification
|
|
5
|
+
# from django.db import transaction
|
|
6
|
+
# from django.utils import timezone
|
|
7
|
+
# import logging
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# class VideoExaminationViewSet(viewsets.ModelViewSet):
|
|
11
|
+
# """
|
|
12
|
+
# ViewSet for Video Examination CRUD operations
|
|
13
|
+
# Handles POST and PATCH for video examinations at timestamps
|
|
14
|
+
# """
|
|
15
|
+
# def get_queryset(self):
|
|
16
|
+
# return []
|
|
17
|
+
|
|
18
|
+
# def create(self, request, *args, **kwargs):
|
|
19
|
+
|
|
20
|
+
# logger = logging.getLogger(__name__)
|
|
21
|
+
# try:
|
|
22
|
+
# data = request.data
|
|
23
|
+
# required_fields = ['videoId', 'timestamp', 'examinationTypeId', 'findingId']
|
|
24
|
+
# for field in required_fields:
|
|
25
|
+
# if field not in data or data[field] is None:
|
|
26
|
+
# return Response({'error': f'Missing or null required field: {field}'}, status=status.HTTP_400_BAD_REQUEST)
|
|
27
|
+
# try:
|
|
28
|
+
# video_id = int(data['videoId'])
|
|
29
|
+
# timestamp = float(data['timestamp'])
|
|
30
|
+
# examination_type_id = int(data['examinationTypeId'])
|
|
31
|
+
# finding_id = int(data['findingId'])
|
|
32
|
+
# except (ValueError, TypeError) as e:
|
|
33
|
+
# return Response({'error': f'Invalid data type in request: {str(e)}'}, status=status.HTTP_400_BAD_REQUEST)
|
|
34
|
+
# if timestamp < 0:
|
|
35
|
+
# return Response({'error': 'Timestamp cannot be negative'}, status=status.HTTP_400_BAD_REQUEST)
|
|
36
|
+
# with transaction.atomic():
|
|
37
|
+
# try:
|
|
38
|
+
# video = VideoFile.objects.get(id=video_id)
|
|
39
|
+
# except VideoFile.DoesNotExist:
|
|
40
|
+
# return Response({'error': 'Video not found'}, status=status.HTTP_404_NOT_FOUND)
|
|
41
|
+
# try:
|
|
42
|
+
# examination = Examination.objects.get(id=examination_type_id)
|
|
43
|
+
# except Examination.DoesNotExist:
|
|
44
|
+
# return Response({'error': 'Examination type not found'}, status=status.HTTP_404_NOT_FOUND)
|
|
45
|
+
# try:
|
|
46
|
+
# finding = Finding.objects.get(id=finding_id)
|
|
47
|
+
# except Finding.DoesNotExist:
|
|
48
|
+
# return Response({'error': 'Finding not found'}, status=status.HTTP_404_NOT_FOUND)
|
|
49
|
+
# if data.get('locationClassificationId'):
|
|
50
|
+
# try:
|
|
51
|
+
# FindingClassification.objects.get(id=data['locationClassificationId'], classification_types__name__iexact="location")
|
|
52
|
+
# except FindingClassification.DoesNotExist:
|
|
53
|
+
# return Response({'error': 'Location classification not found'}, status=status.HTTP_404_NOT_FOUND)
|
|
54
|
+
# if data.get('morphologyClassificationId'):
|
|
55
|
+
# try:
|
|
56
|
+
# FindingClassification.objects.get(id=data['morphologyClassificationId'], classification_types__name__iexact="morphology")
|
|
57
|
+
# except FindingClassification.DoesNotExist:
|
|
58
|
+
# return Response({'error': 'Morphology classification not found'}, status=status.HTTP_404_NOT_FOUND)
|
|
59
|
+
# examination_data = {
|
|
60
|
+
# 'id': f"exam_{video.id}_{timestamp}_{examination.id}",
|
|
61
|
+
# 'video_id': video_id,
|
|
62
|
+
# 'timestamp': timestamp,
|
|
63
|
+
# 'examination_type': examination.name,
|
|
64
|
+
# 'finding': finding.name,
|
|
65
|
+
# 'location_classification': data.get('locationClassificationId'),
|
|
66
|
+
# 'location_choice': data.get('locationChoiceId'),
|
|
67
|
+
# 'morphology_classification': data.get('morphologyClassificationId'),
|
|
68
|
+
# 'morphology_choice': data.get('morphologyChoiceId'),
|
|
69
|
+
# 'interventions': data.get('interventionIds', []),
|
|
70
|
+
# 'notes': data.get('notes', ''),
|
|
71
|
+
# 'created_at': timezone.now().isoformat()
|
|
72
|
+
# }
|
|
73
|
+
# logger.info(f"Created video examination for video {video_id} at timestamp {timestamp}")
|
|
74
|
+
# return Response(examination_data, status=status.HTTP_201_CREATED)
|
|
75
|
+
# except Exception as e:
|
|
76
|
+
# logger.error(f"Unexpected error creating examination: {str(e)}")
|
|
77
|
+
# return Response({'error': 'Internal server error while creating examination'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
|
78
|
+
|
|
79
|
+
# def update(self, request, *args, **kwargs):
|
|
80
|
+
# logger = logging.getLogger(__name__)
|
|
81
|
+
# try:
|
|
82
|
+
# examination_id = kwargs.get('pk')
|
|
83
|
+
# if not examination_id:
|
|
84
|
+
# return Response({'error': 'Examination ID is required'}, status=status.HTTP_400_BAD_REQUEST)
|
|
85
|
+
# data = request.data
|
|
86
|
+
# if 'videoId' in data:
|
|
87
|
+
# try:
|
|
88
|
+
# data['videoId'] = int(data['videoId'])
|
|
89
|
+
# except (ValueError, TypeError):
|
|
90
|
+
# return Response({'error': 'Invalid videoId format'}, status=status.HTTP_400_BAD_REQUEST)
|
|
91
|
+
# if 'timestamp' in data:
|
|
92
|
+
# try:
|
|
93
|
+
# timestamp = float(data['timestamp'])
|
|
94
|
+
# if timestamp < 0:
|
|
95
|
+
# return Response({'error': 'Timestamp cannot be negative'}, status=status.HTTP_400_BAD_REQUEST)
|
|
96
|
+
# data['timestamp'] = timestamp
|
|
97
|
+
# except (ValueError, TypeError):
|
|
98
|
+
# return Response({'error': 'Invalid timestamp format'}, status=status.HTTP_400_BAD_REQUEST)
|
|
99
|
+
# with transaction.atomic():
|
|
100
|
+
# if 'videoId' in data:
|
|
101
|
+
# try:
|
|
102
|
+
# VideoFile.objects.get(id=data['videoId'])
|
|
103
|
+
# except VideoFile.DoesNotExist:
|
|
104
|
+
# return Response({'error': 'Video not found'}, status=status.HTTP_404_NOT_FOUND)
|
|
105
|
+
# if 'examinationTypeId' in data:
|
|
106
|
+
# try:
|
|
107
|
+
# examination_type_id = int(data['examinationTypeId'])
|
|
108
|
+
# Examination.objects.get(id=examination_type_id)
|
|
109
|
+
# except (ValueError, TypeError):
|
|
110
|
+
# return Response({'error': 'Invalid examination type ID format'}, status=status.HTTP_400_BAD_REQUEST)
|
|
111
|
+
# except Examination.DoesNotExist:
|
|
112
|
+
# return Response({'error': 'Examination type not found'}, status=status.HTTP_404_NOT_FOUND)
|
|
113
|
+
# if 'findingId' in data:
|
|
114
|
+
# try:
|
|
115
|
+
# finding_id = int(data['findingId'])
|
|
116
|
+
# Finding.objects.get(id=finding_id)
|
|
117
|
+
# except (ValueError, TypeError):
|
|
118
|
+
# return Response({'error': 'Invalid finding ID format'}, status=status.HTTP_400_BAD_REQUEST)
|
|
119
|
+
# except Finding.DoesNotExist:
|
|
120
|
+
# return Response({'error': 'Finding not found'}, status=status.HTTP_404_NOT_FOUND)
|
|
121
|
+
# examination_data = {
|
|
122
|
+
# 'id': examination_id,
|
|
123
|
+
# 'video_id': data.get('videoId'),
|
|
124
|
+
# 'timestamp': data.get('timestamp'),
|
|
125
|
+
# 'examination_type': data.get('examinationTypeId'),
|
|
126
|
+
# 'finding': data.get('findingId'),
|
|
127
|
+
# 'location_classification': data.get('locationClassificationId'),
|
|
128
|
+
# 'location_choice': data.get('locationChoiceId'),
|
|
129
|
+
# 'morphology_classification': data.get('morphologyClassificationId'),
|
|
130
|
+
# 'morphology_choice': data.get('morphologyChoiceId'),
|
|
131
|
+
# 'interventions': data.get('interventionIds', []),
|
|
132
|
+
# 'notes': data.get('notes', ''),
|
|
133
|
+
# 'updated_at': '2024-01-01T00:00:00Z'
|
|
134
|
+
# }
|
|
135
|
+
# logger.info(f"Updated video examination {examination_id}")
|
|
136
|
+
# return Response(examination_data, status=status.HTTP_200_OK)
|
|
137
|
+
# except Exception as e:
|
|
138
|
+
# logger.error(f"Unexpected error updating examination {examination_id}: {str(e)}")
|
|
139
|
+
# return Response({'error': 'Internal server error while updating examination'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
|
140
|
+
|
|
141
|
+
# def destroy(self, request, *args, **kwargs):
|
|
142
|
+
# logger = logging.getLogger(__name__)
|
|
143
|
+
# try:
|
|
144
|
+
# examination_id = kwargs.get('pk')
|
|
145
|
+
# if not examination_id:
|
|
146
|
+
# return Response({'error': 'Examination ID is required'}, status=status.HTTP_400_BAD_REQUEST)
|
|
147
|
+
# try:
|
|
148
|
+
# if not str(examination_id).strip():
|
|
149
|
+
# return Response({'error': 'Invalid examination ID format'}, status=status.HTTP_400_BAD_REQUEST)
|
|
150
|
+
# except (ValueError, TypeError):
|
|
151
|
+
# return Response({'error': 'Invalid examination ID format'}, status=status.HTTP_400_BAD_REQUEST)
|
|
152
|
+
# with transaction.atomic():
|
|
153
|
+
# logger.info(f"Deleted video examination {examination_id}")
|
|
154
|
+
# return Response({'message': f'Examination {examination_id} deleted successfully'}, status=status.HTTP_204_NO_CONTENT)
|
|
155
|
+
# except Exception as e:
|
|
156
|
+
# logger.error(f"Unexpected error deleting examination {examination_id}: {str(e)}")
|
|
157
|
+
# return Response({'error': 'Internal server error while deleting examination'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
|
158
|
+
|
|
159
|
+
# from rest_framework.decorators import api_view
|
|
160
|
+
# @api_view(["GET"])
|
|
161
|
+
# def get_examinations_for_video(request, video_id):
|
|
162
|
+
# _video = get_object_or_404(VideoFile, id=video_id)
|
|
163
|
+
# #TODO no functionality implemented yet
|
|
164
|
+
# return Response([])
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from .patient_examination_create import ExaminationCreateView
|
|
2
|
+
from .patient_examination_detail import PatientExaminationDetailView
|
|
3
|
+
from .patient_examination_list import PatientExaminationListView
|
|
4
|
+
from .patient_examination import PatientExaminationViewSet
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
'ExaminationCreateView',
|
|
8
|
+
'PatientExaminationDetailView',
|
|
9
|
+
'PatientExaminationListView',
|
|
10
|
+
'PatientExaminationViewSet'
|
|
11
|
+
]
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
from rest_framework import viewsets, status
|
|
2
|
+
from rest_framework.decorators import action
|
|
3
|
+
from rest_framework.response import Response
|
|
4
|
+
from endoreg_db.models import PatientExamination, Patient, Examination
|
|
5
|
+
from endoreg_db.serializers.patient.patient_dropdown import PatientDropdownSerializer
|
|
6
|
+
from endoreg_db.serializers.patient_examination import (
|
|
7
|
+
PatientExaminationSerializer,
|
|
8
|
+
)
|
|
9
|
+
from endoreg_db.serializers.examination import ExaminationDropdownSerializer
|
|
10
|
+
|
|
11
|
+
class PatientExaminationViewSet(viewsets.ModelViewSet):
|
|
12
|
+
"""
|
|
13
|
+
ViewSet für PatientExamination mit vollständiger CRUD-Unterstützung
|
|
14
|
+
"""
|
|
15
|
+
queryset = PatientExamination.objects.all().select_related('patient', 'examination')
|
|
16
|
+
serializer_class = PatientExaminationSerializer
|
|
17
|
+
|
|
18
|
+
def get_queryset(self):
|
|
19
|
+
"""Optimierte Abfrage mit besserer Performance"""
|
|
20
|
+
return PatientExamination.objects.select_related(
|
|
21
|
+
'patient', 'examination'
|
|
22
|
+
).prefetch_related(
|
|
23
|
+
'patient_findings', 'indications'
|
|
24
|
+
).order_by('-date_start', '-id')
|
|
25
|
+
|
|
26
|
+
def get_patient_examination_ids(self):
|
|
27
|
+
"""Hilfsmethode zum Abrufen mehrerer PatientExamination IDs"""
|
|
28
|
+
return PatientExamination.objects.filter(all=True).values_list('id', flat=True)
|
|
29
|
+
|
|
30
|
+
def get_patient_examination_by_id(self, pk):
|
|
31
|
+
"""Hilfsmethode zum Abrufen einer PatientExamination nach ID"""
|
|
32
|
+
if not PatientExamination.objects.filter(pk=pk).exists():
|
|
33
|
+
return None
|
|
34
|
+
else:
|
|
35
|
+
return PatientExamination.objects.select_related(
|
|
36
|
+
'patient', 'examination'
|
|
37
|
+
).get(pk=pk)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@action(detail=False, methods=['get'])
|
|
41
|
+
def patients_dropdown(self, request):
|
|
42
|
+
"""
|
|
43
|
+
Endpoint für Patient-Dropdown-Daten
|
|
44
|
+
GET /api/patient-examinations/patients_dropdown/
|
|
45
|
+
"""
|
|
46
|
+
patients = Patient.objects.all().order_by('first_name', 'last_name')
|
|
47
|
+
serializer = PatientDropdownSerializer(patients, many=True)
|
|
48
|
+
return Response(serializer.data)
|
|
49
|
+
|
|
50
|
+
@action(detail=False, methods=['get'])
|
|
51
|
+
def examinations_dropdown(self, request):
|
|
52
|
+
"""
|
|
53
|
+
Endpoint für Examination-Dropdown-Daten
|
|
54
|
+
GET /api/patient-examinations/examinations_dropdown/
|
|
55
|
+
"""
|
|
56
|
+
examinations = Examination.objects.all().order_by('name')
|
|
57
|
+
serializer = ExaminationDropdownSerializer(examinations, many=True)
|
|
58
|
+
return Response(serializer.data)
|
|
59
|
+
|
|
60
|
+
@action(detail=False, methods=['get'])
|
|
61
|
+
def recent(self, request):
|
|
62
|
+
"""
|
|
63
|
+
Endpoint für die letzten PatientExaminations
|
|
64
|
+
GET /api/patient-examinations/recent/
|
|
65
|
+
"""
|
|
66
|
+
limit = int(request.query_params.get('limit', 10))
|
|
67
|
+
recent_examinations = self.get_queryset()[:limit]
|
|
68
|
+
serializer = self.get_serializer(recent_examinations, many=True)
|
|
69
|
+
return Response(serializer.data)
|
|
70
|
+
|
|
71
|
+
@action(detail=True, methods=['get'])
|
|
72
|
+
def details(self, request, pk=None):
|
|
73
|
+
"""
|
|
74
|
+
Detaillierte Informationen über eine PatientExamination
|
|
75
|
+
GET /api/patient-examinations/{id}/details/
|
|
76
|
+
"""
|
|
77
|
+
examination = self.get_object()
|
|
78
|
+
data = {
|
|
79
|
+
'examination': PatientExaminationSerializer(examination).data,
|
|
80
|
+
'findings': examination.get_findings().count(),
|
|
81
|
+
'indications': examination.get_indications().count(),
|
|
82
|
+
'patient_age_at_examination': examination.get_patient_age_at_examination() if examination.date_start else None,
|
|
83
|
+
}
|
|
84
|
+
return Response(data)
|
|
85
|
+
|
|
86
|
+
def create(self, request, *args, **kwargs):
|
|
87
|
+
"""
|
|
88
|
+
Überschreibt die create-Methode für bessere Fehlerbehandlung
|
|
89
|
+
"""
|
|
90
|
+
serializer = self.get_serializer(data=request.data)
|
|
91
|
+
if serializer.is_valid():
|
|
92
|
+
try:
|
|
93
|
+
self.perform_create(serializer)
|
|
94
|
+
headers = self.get_success_headers(serializer.data)
|
|
95
|
+
return Response(
|
|
96
|
+
serializer.data,
|
|
97
|
+
status=status.HTTP_201_CREATED,
|
|
98
|
+
headers=headers
|
|
99
|
+
)
|
|
100
|
+
except Exception as e:
|
|
101
|
+
return Response(
|
|
102
|
+
{'error': f'Fehler beim Erstellen der Untersuchung: {str(e)}'},
|
|
103
|
+
status=status.HTTP_400_BAD_REQUEST
|
|
104
|
+
)
|
|
105
|
+
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
106
|
+
|
|
107
|
+
def update(self, request, *args, **kwargs):
|
|
108
|
+
"""
|
|
109
|
+
Überschreibt die update-Methode für bessere Fehlerbehandlung
|
|
110
|
+
"""
|
|
111
|
+
partial = kwargs.pop('partial', False)
|
|
112
|
+
instance = self.get_object()
|
|
113
|
+
serializer = self.get_serializer(instance, data=request.data, partial=partial)
|
|
114
|
+
|
|
115
|
+
if serializer.is_valid():
|
|
116
|
+
try:
|
|
117
|
+
self.perform_update(serializer)
|
|
118
|
+
return Response(serializer.data)
|
|
119
|
+
except Exception as e:
|
|
120
|
+
return Response(
|
|
121
|
+
{'error': f'Fehler beim Aktualisieren der Untersuchung: {str(e)}'},
|
|
122
|
+
status=status.HTTP_400_BAD_REQUEST
|
|
123
|
+
)
|
|
124
|
+
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
125
|
+
|
|
126
|
+
def get_findings_for_examination(self, request, pk=None):
|
|
127
|
+
"""
|
|
128
|
+
Endpoint to retrieve findings for a specific PatientExamination
|
|
129
|
+
GET /api/patient-examinations/{pk}/findings/
|
|
130
|
+
"""
|
|
131
|
+
examination = self.get_patient_examination_by_id(pk)
|
|
132
|
+
if not examination:
|
|
133
|
+
return Response(
|
|
134
|
+
{'error': 'PatientExamination nicht gefunden'},
|
|
135
|
+
status=status.HTTP_404_NOT_FOUND
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
findings = PatientExaminationSerializer.get_
|
|
139
|
+
finding_data = [{'id': f.id, 'name': str(f)} for f in findings]
|
|
140
|
+
return Response(finding_data)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from endoreg_db.serializers.patient_examination import PatientExaminationSerializer
|
|
2
|
+
|
|
3
|
+
from django.db import transaction
|
|
4
|
+
from rest_framework import generics, status
|
|
5
|
+
from rest_framework.response import Response
|
|
6
|
+
from endoreg_db.utils.permissions import EnvironmentAwarePermission
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
class ExaminationCreateView(generics.CreateAPIView):
|
|
12
|
+
"""
|
|
13
|
+
Create new PatientExamination instances.
|
|
14
|
+
POST /api/examinations/create/
|
|
15
|
+
|
|
16
|
+
Expected payload:
|
|
17
|
+
{
|
|
18
|
+
"patient": "patient_hash_string", # or patient_id integer
|
|
19
|
+
"examination": "examination_name", # examination name string
|
|
20
|
+
"date_start": "2024-01-15",
|
|
21
|
+
}
|
|
22
|
+
"""
|
|
23
|
+
serializer_class = PatientExaminationSerializer
|
|
24
|
+
permission_classes = [EnvironmentAwarePermission]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@transaction.atomic
|
|
28
|
+
def create(self, request, *args, **kwargs):
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
logger.info(f"Creating examination with data: {request.data}")
|
|
32
|
+
|
|
33
|
+
# Use the serializer for validation and creation
|
|
34
|
+
serializer = self.get_serializer(data=request.data)
|
|
35
|
+
|
|
36
|
+
if serializer.is_valid():
|
|
37
|
+
# The serializer handles patient lookup/creation in validate_patient
|
|
38
|
+
instance = serializer.save()
|
|
39
|
+
|
|
40
|
+
response_data = serializer.data
|
|
41
|
+
response_data['message'] = 'Examination created successfully'
|
|
42
|
+
|
|
43
|
+
logger.info(f"Examination created successfully with ID: {instance.id}")
|
|
44
|
+
return Response(response_data, status=status.HTTP_201_CREATED)
|
|
45
|
+
else:
|
|
46
|
+
logger.warning(f"Validation errors: {serializer.errors}")
|
|
47
|
+
return Response(
|
|
48
|
+
{
|
|
49
|
+
'error': 'Validation failed',
|
|
50
|
+
'details': serializer.errors
|
|
51
|
+
},
|
|
52
|
+
status=status.HTTP_400_BAD_REQUEST
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
except Exception as e:
|
|
56
|
+
logger.error(f"Error creating examination: {str(e)}")
|
|
57
|
+
return Response(
|
|
58
|
+
{
|
|
59
|
+
'error': 'Failed to create examination',
|
|
60
|
+
'message': str(e)
|
|
61
|
+
},
|
|
62
|
+
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
63
|
+
)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from endoreg_db.models import PatientExamination
|
|
2
|
+
from endoreg_db.serializers.patient_examination import PatientExaminationSerializer
|
|
3
|
+
|
|
4
|
+
from django.db import transaction
|
|
5
|
+
from rest_framework import generics, status
|
|
6
|
+
from rest_framework.response import Response
|
|
7
|
+
|
|
8
|
+
from endoreg_db.utils.permissions import DEBUG_PERMISSIONS
|
|
9
|
+
|
|
10
|
+
import logging
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
class PatientExaminationDetailView(generics.RetrieveUpdateAPIView):
|
|
14
|
+
"""
|
|
15
|
+
Retrieve and update PatientExamination instances.
|
|
16
|
+
GET /api/examinations/{id}/
|
|
17
|
+
PATCH /api/examinations/{id}/
|
|
18
|
+
"""
|
|
19
|
+
queryset = PatientExamination.objects.select_related('patient', 'examination')
|
|
20
|
+
serializer_class = PatientExaminationSerializer
|
|
21
|
+
permission_classes = DEBUG_PERMISSIONS
|
|
22
|
+
|
|
23
|
+
def get(self, request, *args, **kwargs):
|
|
24
|
+
try:
|
|
25
|
+
instance = self.get_object()
|
|
26
|
+
serializer = self.get_serializer(instance)
|
|
27
|
+
return Response(serializer.data)
|
|
28
|
+
except Exception as e:
|
|
29
|
+
logger.error(f"Error retrieving examination: {str(e)}")
|
|
30
|
+
return Response(
|
|
31
|
+
{'error': 'Failed to retrieve examination'},
|
|
32
|
+
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
@transaction.atomic
|
|
36
|
+
def patch(self, request, *args, **kwargs):
|
|
37
|
+
try:
|
|
38
|
+
instance = self.get_object()
|
|
39
|
+
serializer = self.get_serializer(instance, data=request.data, partial=True)
|
|
40
|
+
|
|
41
|
+
if serializer.is_valid():
|
|
42
|
+
updated_instance = serializer.save()
|
|
43
|
+
|
|
44
|
+
response_data = serializer.data
|
|
45
|
+
response_data['message'] = 'Examination updated successfully'
|
|
46
|
+
|
|
47
|
+
logger.info(f"Examination {instance.id} updated successfully")
|
|
48
|
+
return Response(response_data, status=status.HTTP_200_OK)
|
|
49
|
+
else:
|
|
50
|
+
return Response(
|
|
51
|
+
{
|
|
52
|
+
'error': 'Validation failed',
|
|
53
|
+
'details': serializer.errors
|
|
54
|
+
},
|
|
55
|
+
status=status.HTTP_400_BAD_REQUEST
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
except Exception as e:
|
|
59
|
+
logger.error(f"Error updating examination: {str(e)}")
|
|
60
|
+
return Response(
|
|
61
|
+
{
|
|
62
|
+
'error': 'Failed to update examination',
|
|
63
|
+
'message': str(e)
|
|
64
|
+
},
|
|
65
|
+
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
66
|
+
)
|