From 72aedf245c6d2d27b82b1b08a33838dd10d4e1ed Mon Sep 17 00:00:00 2001 From: SimonKonar Date: Sun, 27 Oct 2024 11:24:27 +0100 Subject: [PATCH 1/4] refactor --- src/MIABIS_on_FHIR/__init__.py | 13 ++++ src/MIABIS_on_FHIR/biobank.py | 20 +++--- src/MIABIS_on_FHIR/collection.py | 15 +++-- src/MIABIS_on_FHIR/collection_organization.py | 21 +++---- src/MIABIS_on_FHIR/condition.py | 8 +-- src/MIABIS_on_FHIR/diagnosis_report.py | 7 +-- src/MIABIS_on_FHIR/network.py | 6 +- src/MIABIS_on_FHIR/network_organization.py | 10 +-- src/MIABIS_on_FHIR/observation.py | 10 ++- src/MIABIS_on_FHIR/sample.py | 10 +-- src/MIABIS_on_FHIR/sample_donor.py | 8 +-- src/{ => MIABIS_on_FHIR/util}/config.py | 0 .../util/{_constants.py => constants.py} | 0 .../{_parsing_util.py => parsing_util.py} | 2 +- src/MIABIS_on_FHIR/util/{_util.py => util.py} | 0 src/__init__.py | 0 .../NonExistentResourceException.py | 0 src/blaze_client/__init__.py | 2 + src/{client => blaze_client}/blaze_client.py | 63 +++++++++++++++---- src/client/__init__.py | 0 test/service/test_blaze_client.py | 4 +- 21 files changed, 124 insertions(+), 75 deletions(-) rename src/{ => MIABIS_on_FHIR/util}/config.py (100%) rename src/MIABIS_on_FHIR/util/{_constants.py => constants.py} (100%) rename src/MIABIS_on_FHIR/util/{_parsing_util.py => parsing_util.py} (91%) rename src/MIABIS_on_FHIR/util/{_util.py => util.py} (100%) delete mode 100644 src/__init__.py rename src/{client => blaze_client}/NonExistentResourceException.py (100%) create mode 100644 src/blaze_client/__init__.py rename src/{client => blaze_client}/blaze_client.py (95%) delete mode 100644 src/client/__init__.py diff --git a/src/MIABIS_on_FHIR/__init__.py b/src/MIABIS_on_FHIR/__init__.py index e69de29..079d857 100644 --- a/src/MIABIS_on_FHIR/__init__.py +++ b/src/MIABIS_on_FHIR/__init__.py @@ -0,0 +1,13 @@ +from .biobank import Biobank +from .collection import Collection +from .collection_organization import CollectionOrganization +from .condition import Condition +from .diagnosis_report import DiagnosisReport +from .gender import Gender +from .incorrect_json_format import IncorrectJsonFormatException +from .network import Network +from .network_organization import NetworkOrganization +from .observation import Observation +from .sample import Sample +from .sample_donor import SampleDonor +from .storage_temperature import StorageTemperature diff --git a/src/MIABIS_on_FHIR/biobank.py b/src/MIABIS_on_FHIR/biobank.py index 45cc5d3..bb85eb4 100644 --- a/src/MIABIS_on_FHIR/biobank.py +++ b/src/MIABIS_on_FHIR/biobank.py @@ -3,14 +3,14 @@ from fhirclient.models.meta import Meta from fhirclient.models.organization import Organization -from src.MIABIS_on_FHIR.util._constants import BIOBANK_BIOPROCESSING_AND_ANALYTICAL_CAPABILITIES, \ +from src.MIABIS_on_FHIR.incorrect_json_format import IncorrectJsonFormatException +from src.MIABIS_on_FHIR.util.config import FHIRConfig +from src.MIABIS_on_FHIR.util.constants import BIOBANK_BIOPROCESSING_AND_ANALYTICAL_CAPABILITIES, \ BIOBANK_INFRASTRUCTURAL_CAPABILITIES, \ BIOBANK_ORGANISATIONAL_CAPABILITIES, DEFINITION_BASE_URL -from src.MIABIS_on_FHIR.util._parsing_util import get_nested_value, parse_contact -from src.MIABIS_on_FHIR.util._util import create_fhir_identifier, create_contact, create_country_of_residence, \ +from src.MIABIS_on_FHIR.util.parsing_util import get_nested_value, parse_contact +from src.MIABIS_on_FHIR.util.util import create_fhir_identifier, create_contact, create_country_of_residence, \ create_codeable_concept_extension, create_string_extension -from src.MIABIS_on_FHIR.incorrect_json_format import IncorrectJsonFormatException -from src.config import FHIRConfig class Biobank: @@ -30,14 +30,14 @@ def __init__(self, identifier: str, name: str, alias: str, country: str, contact :param contact_surname: surname of the contact person :param contact_email: email of the contact person :param infrastructural_capabilities: The technical infrastructural capabilities that - the biobank can offer to the clients. Available values in the _constants.py file + the biobank can offer to the clients. Available values in the constants.py file :param organisational_capabilities: The organisational capabilities and services that - the biobank can provide to support clients. Available values in the _constants.py file + the biobank can provide to support clients. Available values in the constants.py file :param bioprocessing_and_analysis_capabilities: The bioprocessing and analytical services - that the biobank can offer to the clients. Available values in the _constants.py file + that the biobank can offer to the clients. Available values in the constants.py file :param quality__management_standards: The standards that the biobank is certified or accredited for. :param juristic_person: The legal entity that is responsible for the biobank. - Available values in the _constants.py file + Available values in the constants.py file """ self.identifier = identifier self.name = name @@ -316,7 +316,7 @@ def to_fhir(self) -> Organization: self.juristic_person)) if self.description is not None: extensions.append(create_string_extension( - FHIRConfig.get_extension_url("biobank","description"), + FHIRConfig.get_extension_url("biobank", "description"), self.description)) if extensions: fhir_organization.extension = extensions diff --git a/src/MIABIS_on_FHIR/collection.py b/src/MIABIS_on_FHIR/collection.py index d516df7..c674ed7 100644 --- a/src/MIABIS_on_FHIR/collection.py +++ b/src/MIABIS_on_FHIR/collection.py @@ -9,16 +9,15 @@ from fhirclient.models.quantity import Quantity from fhirclient.models.range import Range -from src.MIABIS_on_FHIR.util._constants import COLLECTION_INCLUSION_CRITERIA, COLLECTION_MATERIAL_TYPE_CODES, \ - DEFINITION_BASE_URL -from src.MIABIS_on_FHIR.util._parsing_util import get_nested_value, parse_reference_id -from src.MIABIS_on_FHIR.util._util import create_fhir_identifier, create_integer_extension, \ - create_codeable_concept_extension, \ - create_codeable_concept from src.MIABIS_on_FHIR.gender import Gender from src.MIABIS_on_FHIR.incorrect_json_format import IncorrectJsonFormatException from src.MIABIS_on_FHIR.storage_temperature import StorageTemperature -from src.config import FHIRConfig +from src.MIABIS_on_FHIR.util.config import FHIRConfig +from src.MIABIS_on_FHIR.util.constants import COLLECTION_INCLUSION_CRITERIA, COLLECTION_MATERIAL_TYPE_CODES +from src.MIABIS_on_FHIR.util.parsing_util import get_nested_value, parse_reference_id +from src.MIABIS_on_FHIR.util.util import create_fhir_identifier, create_integer_extension, \ + create_codeable_concept_extension, \ + create_codeable_concept class Collection: @@ -40,7 +39,7 @@ def __init__(self, identifier: str, name: str, managing_collection_org_id: str, :param storage_temperatures: List of storage temperatures of the samples in the collection. :param material_types: List of material types of the samples in the collection. :param diagnoses: List of diagnoses of the subjects in the collection. - Available values in the _constants.py file + Available values in the constants.py file :param number_of_subjects: Number of subjects in the collection. :param inclusion_criteria: Inclusion criteria for the subjects in the collection. :param sample_ids: List of sample identifiers belonging to the collection. diff --git a/src/MIABIS_on_FHIR/collection_organization.py b/src/MIABIS_on_FHIR/collection_organization.py index f5c438a..df7df5d 100644 --- a/src/MIABIS_on_FHIR/collection_organization.py +++ b/src/MIABIS_on_FHIR/collection_organization.py @@ -6,14 +6,13 @@ from fhirclient.models.meta import Meta from fhirclient.models.organization import Organization -from src.MIABIS_on_FHIR.util._constants import COLLECTION_DESIGN, COLLECTION_SAMPLE_COLLECTION_SETTING, \ +from src.MIABIS_on_FHIR.incorrect_json_format import IncorrectJsonFormatException +from src.MIABIS_on_FHIR.util.config import FHIRConfig +from src.MIABIS_on_FHIR.util.constants import COLLECTION_DESIGN, COLLECTION_SAMPLE_COLLECTION_SETTING, \ COLLECTION_SAMPLE_SOURCE, COLLECTION_DATASET_TYPE, COLLECTION_USE_AND_ACCESS_CONDITIONS -from src.MIABIS_on_FHIR.util._parsing_util import get_nested_value, parse_contact, parse_reference_id -from src.MIABIS_on_FHIR.util._util import create_country_of_residence, create_contact, \ - create_codeable_concept_extension, \ +from src.MIABIS_on_FHIR.util.parsing_util import get_nested_value, parse_contact, parse_reference_id +from src.MIABIS_on_FHIR.util.util import create_country_of_residence, create_contact, create_codeable_concept_extension, \ create_string_extension, create_fhir_identifier -from src.MIABIS_on_FHIR.incorrect_json_format import IncorrectJsonFormatException -from src.config import FHIRConfig class CollectionOrganization: @@ -43,12 +42,12 @@ def __init__(self, identifier: str, name: str, managing_biobank_id: str, :param alias: Alias of the collection. :param url: URL of the collection. :param description: Description of the collection. - :param dataset_type: Type of the dataset. Available values in the _constants.py file - :param sample_source: Source of the samples. Available values in the _constants.py file - :param sample_collection_setting: Setting of the sample collection. Available values in the _constants.py file - :param collection_design: Design of the collection. Available values in the _constants.py file + :param dataset_type: Type of the dataset. Available values in the constants.py file + :param sample_source: Source of the samples. Available values in the constants.py file + :param sample_collection_setting: Setting of the sample collection. Available values in the constants.py file + :param collection_design: Design of the collection. Available values in the constants.py file :param use_and_access_conditions: Conditions for use and access of the collection. - Available values in the _constants.py file + Available values in the constants.py file :param publications: Publications related to the collection. """ diff --git a/src/MIABIS_on_FHIR/condition.py b/src/MIABIS_on_FHIR/condition.py index 2633e28..45b2917 100644 --- a/src/MIABIS_on_FHIR/condition.py +++ b/src/MIABIS_on_FHIR/condition.py @@ -1,4 +1,5 @@ from typing import Self + import fhirclient.models.condition as fhir_condition import simple_icd_10 as icd10 from fhirclient.models.codeableconcept import CodeableConcept @@ -6,11 +7,10 @@ from fhirclient.models.fhirreference import FHIRReference from fhirclient.models.meta import Meta -from src.MIABIS_on_FHIR.util._constants import DEFINITION_BASE_URL -from src.MIABIS_on_FHIR.util._parsing_util import get_nested_value, parse_reference_id from src.MIABIS_on_FHIR.incorrect_json_format import IncorrectJsonFormatException -from src.MIABIS_on_FHIR.util._util import create_fhir_identifier -from src.config import FHIRConfig +from src.MIABIS_on_FHIR.util.config import FHIRConfig +from src.MIABIS_on_FHIR.util.parsing_util import get_nested_value, parse_reference_id +from src.MIABIS_on_FHIR.util.util import create_fhir_identifier class Condition: diff --git a/src/MIABIS_on_FHIR/diagnosis_report.py b/src/MIABIS_on_FHIR/diagnosis_report.py index f825cb3..1729879 100644 --- a/src/MIABIS_on_FHIR/diagnosis_report.py +++ b/src/MIABIS_on_FHIR/diagnosis_report.py @@ -6,11 +6,10 @@ from fhirclient.models.fhirreference import FHIRReference from fhirclient.models.meta import Meta -from src.MIABIS_on_FHIR.util._constants import DEFINITION_BASE_URL -from src.MIABIS_on_FHIR.util._parsing_util import get_nested_value, parse_reference_id -from src.MIABIS_on_FHIR.util._util import create_fhir_identifier from src.MIABIS_on_FHIR.incorrect_json_format import IncorrectJsonFormatException -from src.config import FHIRConfig +from src.MIABIS_on_FHIR.util.config import FHIRConfig +from src.MIABIS_on_FHIR.util.parsing_util import get_nested_value, parse_reference_id +from src.MIABIS_on_FHIR.util.util import create_fhir_identifier class DiagnosisReport: diff --git a/src/MIABIS_on_FHIR/network.py b/src/MIABIS_on_FHIR/network.py index 4bc1328..8ebf950 100644 --- a/src/MIABIS_on_FHIR/network.py +++ b/src/MIABIS_on_FHIR/network.py @@ -5,10 +5,10 @@ from fhirclient.models.group import Group from fhirclient.models.meta import Meta -from src.MIABIS_on_FHIR.util._parsing_util import get_nested_value, parse_reference_id -from src.MIABIS_on_FHIR.util._util import create_fhir_identifier from src.MIABIS_on_FHIR.incorrect_json_format import IncorrectJsonFormatException -from src.config import FHIRConfig +from src.MIABIS_on_FHIR.util.config import FHIRConfig +from src.MIABIS_on_FHIR.util.parsing_util import get_nested_value, parse_reference_id +from src.MIABIS_on_FHIR.util.util import create_fhir_identifier class Network: diff --git a/src/MIABIS_on_FHIR/network_organization.py b/src/MIABIS_on_FHIR/network_organization.py index 9128bce..cda8f3e 100644 --- a/src/MIABIS_on_FHIR/network_organization.py +++ b/src/MIABIS_on_FHIR/network_organization.py @@ -4,12 +4,12 @@ from fhirclient.models.meta import Meta from fhirclient.models.organization import Organization -from src.MIABIS_on_FHIR.util._constants import NETWORK_COMMON_COLLAB_TOPICS, DEFINITION_BASE_URL -from src.MIABIS_on_FHIR.util._parsing_util import get_nested_value, parse_contact, parse_reference_id -from src.MIABIS_on_FHIR.util._util import create_fhir_identifier, create_contact, create_country_of_residence, \ - create_codeable_concept_extension, create_string_extension from src.MIABIS_on_FHIR.incorrect_json_format import IncorrectJsonFormatException -from src.config import FHIRConfig +from src.MIABIS_on_FHIR.util.config import FHIRConfig +from src.MIABIS_on_FHIR.util.constants import NETWORK_COMMON_COLLAB_TOPICS +from src.MIABIS_on_FHIR.util.parsing_util import get_nested_value, parse_contact, parse_reference_id +from src.MIABIS_on_FHIR.util.util import create_fhir_identifier, create_contact, create_country_of_residence, \ + create_codeable_concept_extension, create_string_extension class NetworkOrganization: diff --git a/src/MIABIS_on_FHIR/observation.py b/src/MIABIS_on_FHIR/observation.py index 26bd551..91ca094 100644 --- a/src/MIABIS_on_FHIR/observation.py +++ b/src/MIABIS_on_FHIR/observation.py @@ -1,22 +1,20 @@ from datetime import datetime -from dateutil import parser as date_parser from typing import Self import fhirclient.models.observation as fhir_observation import simple_icd_10 as icd10 +from dateutil import parser as date_parser from dateutil.parser import ParserError from fhirclient.models.codeableconcept import CodeableConcept from fhirclient.models.coding import Coding -from fhirclient.models.fhirdate import FHIRDate from fhirclient.models.fhirdatetime import FHIRDateTime from fhirclient.models.fhirreference import FHIRReference from fhirclient.models.meta import Meta -from src.MIABIS_on_FHIR.util._constants import DEFINITION_BASE_URL -from src.MIABIS_on_FHIR.util._parsing_util import get_nested_value, parse_reference_id -from src.MIABIS_on_FHIR.util._util import create_fhir_identifier from src.MIABIS_on_FHIR.incorrect_json_format import IncorrectJsonFormatException -from src.config import FHIRConfig +from src.MIABIS_on_FHIR.util.config import FHIRConfig +from src.MIABIS_on_FHIR.util.parsing_util import get_nested_value, parse_reference_id +from src.MIABIS_on_FHIR.util.util import create_fhir_identifier class Observation: diff --git a/src/MIABIS_on_FHIR/sample.py b/src/MIABIS_on_FHIR/sample.py index 3c66a3e..4d0d588 100644 --- a/src/MIABIS_on_FHIR/sample.py +++ b/src/MIABIS_on_FHIR/sample.py @@ -9,13 +9,13 @@ from fhirclient.models.meta import Meta from fhirclient.models.specimen import Specimen, SpecimenCollection, SpecimenProcessing -from src.MIABIS_on_FHIR.util._constants import DETAILED_MATERIAL_TYPE_CODES, DEFINITION_BASE_URL -from src.MIABIS_on_FHIR.util._parsing_util import get_nested_value, parse_reference_id -from src.MIABIS_on_FHIR.util._util import create_fhir_identifier, create_codeable_concept, \ - create_codeable_concept_extension from src.MIABIS_on_FHIR.incorrect_json_format import IncorrectJsonFormatException from src.MIABIS_on_FHIR.storage_temperature import StorageTemperature -from src.config import FHIRConfig +from src.MIABIS_on_FHIR.util.config import FHIRConfig +from src.MIABIS_on_FHIR.util.constants import DETAILED_MATERIAL_TYPE_CODES +from src.MIABIS_on_FHIR.util.parsing_util import get_nested_value, parse_reference_id +from src.MIABIS_on_FHIR.util.util import create_fhir_identifier, create_codeable_concept, \ + create_codeable_concept_extension class Sample: diff --git a/src/MIABIS_on_FHIR/sample_donor.py b/src/MIABIS_on_FHIR/sample_donor.py index 51352bc..eb1d10c 100644 --- a/src/MIABIS_on_FHIR/sample_donor.py +++ b/src/MIABIS_on_FHIR/sample_donor.py @@ -6,12 +6,12 @@ from fhirclient.models.meta import Meta from fhirclient.models.patient import Patient -from src.MIABIS_on_FHIR.util._constants import DONOR_DATASET_TYPE, DEFINITION_BASE_URL -from src.MIABIS_on_FHIR.util._parsing_util import get_nested_value -from src.MIABIS_on_FHIR.util._util import create_fhir_identifier, create_codeable_concept_extension from src.MIABIS_on_FHIR.gender import Gender from src.MIABIS_on_FHIR.incorrect_json_format import IncorrectJsonFormatException -from src.config import FHIRConfig +from src.MIABIS_on_FHIR.util.config import FHIRConfig +from src.MIABIS_on_FHIR.util.constants import DONOR_DATASET_TYPE +from src.MIABIS_on_FHIR.util.parsing_util import get_nested_value +from src.MIABIS_on_FHIR.util.util import create_fhir_identifier, create_codeable_concept_extension class SampleDonor: diff --git a/src/config.py b/src/MIABIS_on_FHIR/util/config.py similarity index 100% rename from src/config.py rename to src/MIABIS_on_FHIR/util/config.py diff --git a/src/MIABIS_on_FHIR/util/_constants.py b/src/MIABIS_on_FHIR/util/constants.py similarity index 100% rename from src/MIABIS_on_FHIR/util/_constants.py rename to src/MIABIS_on_FHIR/util/constants.py diff --git a/src/MIABIS_on_FHIR/util/_parsing_util.py b/src/MIABIS_on_FHIR/util/parsing_util.py similarity index 91% rename from src/MIABIS_on_FHIR/util/_parsing_util.py rename to src/MIABIS_on_FHIR/util/parsing_util.py index 0fc6069..e5adb9f 100644 --- a/src/MIABIS_on_FHIR/util/_parsing_util.py +++ b/src/MIABIS_on_FHIR/util/parsing_util.py @@ -1,7 +1,7 @@ from dateutil import parser as date_parser from datetime import date -from src.MIABIS_on_FHIR.util._constants import DETAILED_MATERIAL_TYPE_TO_COLLECTION_MATERIAL_TYPE_MAP +from src.MIABIS_on_FHIR.util.constants import DETAILED_MATERIAL_TYPE_TO_COLLECTION_MATERIAL_TYPE_MAP def get_nested_value(data: dict, keys: list): diff --git a/src/MIABIS_on_FHIR/util/_util.py b/src/MIABIS_on_FHIR/util/util.py similarity index 100% rename from src/MIABIS_on_FHIR/util/_util.py rename to src/MIABIS_on_FHIR/util/util.py diff --git a/src/__init__.py b/src/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/client/NonExistentResourceException.py b/src/blaze_client/NonExistentResourceException.py similarity index 100% rename from src/client/NonExistentResourceException.py rename to src/blaze_client/NonExistentResourceException.py diff --git a/src/blaze_client/__init__.py b/src/blaze_client/__init__.py new file mode 100644 index 0000000..0283a24 --- /dev/null +++ b/src/blaze_client/__init__.py @@ -0,0 +1,2 @@ +from .blaze_client import BlazeClient +from .NonExistentResourceException import NonExistentResourceException \ No newline at end of file diff --git a/src/client/blaze_client.py b/src/blaze_client/blaze_client.py similarity index 95% rename from src/client/blaze_client.py rename to src/blaze_client/blaze_client.py index e249bd3..6029884 100644 --- a/src/client/blaze_client.py +++ b/src/blaze_client/blaze_client.py @@ -13,14 +13,11 @@ from src.MIABIS_on_FHIR.observation import Observation from src.MIABIS_on_FHIR.sample import Sample from src.MIABIS_on_FHIR.sample_donor import SampleDonor -from src.MIABIS_on_FHIR.util._parsing_util import get_nested_value, parse_reference_id, \ +from src.MIABIS_on_FHIR.util.parsing_util import get_nested_value, parse_reference_id, \ get_material_type_from_detailed_material_type -from src.client.NonExistentResourceException import NonExistentResourceException +from src.blaze_client.NonExistentResourceException import NonExistentResourceException -# TODO add update collection, update network -# TODO update methods- if there is no fhir_id (even when using the get_fhir_id method), throw an ValueException (or a custom one) - class BlazeClient: """Class for handling communication with a blaze server, be it for CRUD operations, creating objects from json, etc.""" @@ -107,7 +104,8 @@ def get_identifier_by_fhir_id(self, resource_type: str, resource_fhir_id: str) - def get_observation_fhir_ids_belonging_to_sample(self, sample_fhir_id: str) -> list[str]: """get all observations linked to a specific sample :param sample_fhir_id: fhir id of a sample for which the observations should be retrieved - :return list of fhir ids linked to a specific sample""" + :return list of fhir ids linked to a specific sample + :raises HTTPError: if the request to blaze fails""" response = self._session.get(f"{self._blaze_url}/Observation?specimen={sample_fhir_id}") self.__raise_for_status_extract_diagnostics_message(response) observations_fhir_ids = [] @@ -123,7 +121,8 @@ def get_observation_fhir_ids_belonging_to_sample(self, sample_fhir_id: str) -> l def get_diagnosis_report_fhir_id_belonging_to_sample(self, sample_fhir_id: str) -> str | None: """get diagnosis report which belongs to a specific sample :param sample_fhir_id: fhir id of sample that this diagnosis report belongs to - :return fhir id of the diagnosis report""" + :return fhir id of the diagnosis report + :raises HTTPError: if the request to blaze fails""" response = self._session.get(f"{self._blaze_url}/DiagnosticReport?specimen={sample_fhir_id}") self.__raise_for_status_extract_diagnostics_message(response) diagnosis_report_json = response.json() @@ -132,7 +131,8 @@ def get_diagnosis_report_fhir_id_belonging_to_sample(self, sample_fhir_id: str) def get_diagnosis_report_fhir_ids_belonging_to_patient(self, donor_fhir_id: str) -> list[str]: """get diagnosis reports fhir ids, which belong to a specific donor :param donor_fhir_id: fhir id of donor that these diagnosis reports belong to - :return list of diagnosis fhir ids belonging to a specified donor """ + :return list of diagnosis fhir ids belonging to a specified donor + :raises HTTPError: if the request to blaze fails""" diagnosis_report_fhir_ids = [] response = self._session.get(f"{self._blaze_url}/DiagnosticReport?subject={donor_fhir_id}") self.__raise_for_status_extract_diagnostics_message(response) @@ -150,6 +150,7 @@ def update_fhir_resource(self, resource_type: str, resource_fhir_id: str, resour :param resource_fhir_id: the fhir id of the resource :param resource_json: the json representation of the resource :return: True if the resource was updated successfully + :raises NonExistentResourceException: if the resource cannot be found :raises HTTPError: if the request to blaze fails """ response = self._session.put(f"{self._blaze_url}/{resource_type}/{resource_fhir_id}", json=resource_json) @@ -161,6 +162,7 @@ def upload_donor(self, donor: SampleDonor) -> str: :param donor: the donor to upload :raises HTTPError: if the request to blaze fails :return: the fhir id of the uploaded donor + :raises HTTPError: if the request to blaze fails """ response = self._session.post(f"{self._blaze_url}/Patient", json=donor.to_fhir().as_json()) self.__raise_for_status_extract_diagnostics_message(response) @@ -171,6 +173,7 @@ def upload_sample(self, sample: Sample) -> str: :param sample: the sample to upload :raises HTTPError: if the request to blaze fails :return: the fhir id of the uploaded sample + :raises HTTPError: if the request to blaze fails """ donor_fhir_id = sample.subject_fhir_id or self.get_fhir_id("Patient", sample.donor_identifier) if donor_fhir_id is None: @@ -229,8 +232,8 @@ def upload_diagnosis_report(self, diagnosis_report: DiagnosisReport) -> str: def upload_condition(self, condition: Condition) -> str: """Upload a condition to blaze. :param condition: the condition to upload - :param diagnosis_reports_fhir_ids: the fhir ids of the diagnosis reports in the condition :raises HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found :return: the fhir id of the uploaded condition """ donor_fhir_id = condition.patient_fhir_id or self.get_fhir_id("Patient", condition.patient_identifier) @@ -262,6 +265,7 @@ def upload_collection_organization(self, collection_org: CollectionOrganization) Upload a collection organization resource to a blaze :param collection_org: collection organization resource to upload :raises: HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found :return: the fhir id of the uploaded collection organization""" managing_biobank_fhir_id = collection_org.managing_biobank_fhir_id or \ @@ -280,6 +284,7 @@ def upload_collection(self, collection: Collection) -> str: Upload a collection resource to blaze. :param collection: collection resource to upload :raises: HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found :return: the fhir id of the uploaded collection """ @@ -311,6 +316,7 @@ def upload_network_organization(self, network_org: NetworkOrganization) -> str: Upload a network organization resource to blaze. :param network_org: network organization resource to upload :raises: HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found :return: the fhir id of uploaded network organization """ managing_biobank_fhir_id = network_org.managing_biobank_fhir_id \ @@ -328,7 +334,7 @@ def upload_network(self, network: Network) -> str: """ Upload a network resource to blaze. :param network: network resource to upload - :param managing_network_org_fhir_id: fhir id of the network_org that is linked to this network resource + :raises NonExistentResourceException: if the resource cannot be found :raises: HTTPError: if the request to blaze fails :return: the fhir id of uploaded network """ @@ -371,6 +377,8 @@ def upload_network(self, network: Network) -> str: def build_donor_from_json(self, donor_fhir_id: str) -> SampleDonor: """Build Donor Object from json representation :param donor_fhir_id: FHIR ID of the Patient resource + :raises HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found :return SampleDonor Object""" if not self.is_resource_present_in_blaze("Patient", donor_fhir_id): raise NonExistentResourceException(f"Patient with fhir id {donor_fhir_id} is not present in blaze store") @@ -381,6 +389,8 @@ def build_donor_from_json(self, donor_fhir_id: str) -> SampleDonor: def build_sample_from_json(self, sample_fhir_id: str) -> Sample: """Build Sample Object from json representation :param sample_fhir_id: FHIR ID of the Specimen resource + :raises HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found :return Sample Object""" if not self.is_resource_present_in_blaze("Specimen", sample_fhir_id): raise NonExistentResourceException(f"Sample with FHIR ID {sample_fhir_id} is not present in blaze store") @@ -393,6 +403,8 @@ def build_sample_from_json(self, sample_fhir_id: str) -> Sample: def build_observation_from_json(self, observation_fhir_id: str) -> Observation: """Build Observation Object from json representation :param observation_fhir_id: FHIR ID of the Observation resource + :raises HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found :return Observation Object""" if not self.is_resource_present_in_blaze("Observation", observation_fhir_id): raise NonExistentResourceException( @@ -408,6 +420,8 @@ def build_observation_from_json(self, observation_fhir_id: str) -> Observation: def build_diagnosis_report_from_json(self, diagnosis_report_fhir_id: str) -> DiagnosisReport: """Build DiagnosisReport object from json representation :param diagnosis_report_fhir_id: FHIR ID of the DiagnosticReport resource + :raises HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found :return DiagnosisReport Object""" if not self.is_resource_present_in_blaze("DiagnosticReport", diagnosis_report_fhir_id): raise NonExistentResourceException( @@ -437,6 +451,8 @@ def build_diagnosis_report_from_json(self, diagnosis_report_fhir_id: str) -> Dia def build_condition_from_json(self, condition_fhir_id: str) -> Condition: """Build Condition object from json representation :param condition_fhir_id: FHIR ID of the Condition resource + :raises HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found :return Condition Object""" if not self.is_resource_present_in_blaze("Condition", condition_fhir_id): raise NonExistentResourceException( @@ -453,6 +469,7 @@ def build_collection_from_json(self, collection_fhir_id: str) -> Collection: :param collection_fhir_id: FHIR ID of the Collection resource :return: Collection object :raises HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found """ if not self.is_resource_present_in_blaze("Group", collection_fhir_id): raise NonExistentResourceException( @@ -473,6 +490,8 @@ def build_collection_from_json(self, collection_fhir_id: str) -> Collection: def build_collection_organization_from_json(self, collection_organization_fhir_id: str) -> CollectionOrganization: """Build a CollectionOrganization object from a json representation :param collection_organization_fhir_id: FHIR ID of the collection resource + :raises HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found :return CollectionOrganization Object""" if not self.is_resource_present_in_blaze("Organization", collection_organization_fhir_id): raise NonExistentResourceException( @@ -486,6 +505,8 @@ def build_collection_organization_from_json(self, collection_organization_fhir_i def build_network_from_json(self, network_fhir_id: str) -> Network: """Build a Network object form a json representation :param network_fhir_id: FHIR ID of the network resource + :raises HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found :return Network Object""" if not self.is_resource_present_in_blaze("Group", network_fhir_id): raise NonExistentResourceException(f"Network with FHIR ID {network_fhir_id} is not present in blaze store") @@ -505,6 +526,8 @@ def build_network_from_json(self, network_fhir_id: str) -> Network: def build_network_org_from_json(self, network_org_fhir_id: str) -> NetworkOrganization: """Build a NetworkOrganization object from a json representation :param network_org_fhir_id: FHIR ID of the network organization resource + :raises HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found :return NetworkOrganisation object""" if not self.is_resource_present_in_blaze("Organization", network_org_fhir_id): raise NonExistentResourceException( @@ -518,6 +541,8 @@ def build_network_org_from_json(self, network_org_fhir_id: str) -> NetworkOrgani def build_biobank_from_json(self, biobank_fhir_id: str) -> Biobank: """Build a Biobank object from a json representation :param biobank_fhir_id: FHIR ID of the biobank resource + :raises HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found :return Biobank object""" if not self.is_resource_present_in_blaze("Organization", biobank_fhir_id): raise NonExistentResourceException(f"Biobank with FHIR ID {biobank_fhir_id} is not present in blaze store") @@ -526,7 +551,12 @@ def build_biobank_from_json(self, biobank_fhir_id: str) -> Biobank: return biobank def add_diagnosis_reports_to_condition(self, condition_fhir_id: str, diagnosis_report_fhir_ids: list[str]) -> bool: - """add new diagnosis to already present condition in the blaze store""" + """add new diagnosis to already present condition in the blaze store + :param condition_fhir_id: FHIR ID of the condition + :param diagnosis_report_fhir_ids: FHIR IDs of the diagnosis reports + :raises HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found + :returns: True if the diagnosis reports were added successfully, false otherwise""" condition = self.build_condition_from_json(condition_fhir_id) for diagnosis_report_fhir_id in diagnosis_report_fhir_ids: if diagnosis_report_fhir_id not in condition.diagnosis_report_fhir_ids: @@ -560,6 +590,8 @@ def add_already_present_samples_to_existing_collection(self, sample_fhir_ids: li """Add samples already present in blaze to the collection :param sample_fhir_ids: FHIR IDs of samples to add to collection :param collection_fhir_id: FHIR ID of collection + :raises HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found :return: Bool indicating outcome of this operation""" collection = self.build_collection_from_json(collection_fhir_id) samples = [self.build_sample_from_json(sample_fhir_id) for sample_fhir_id in sample_fhir_ids] @@ -576,6 +608,8 @@ def update_collection_values(self, collection_fhir_id) -> bool: """Removes samples FHIR IDs that are not present in the blaze store from collection,and recalculates characteristics: :param collection_fhir_id: FHIR ID of collection + :raises HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found :return: Bool indicating if the collection was updated or not""" collection = self.build_collection_from_json(collection_fhir_id) sample_fhir_ids = collection.sample_fhir_ids @@ -600,6 +634,7 @@ def __update_collection_characteristics_from_samples(self, samples: list[Sample] :param collection_fhir_id: the fhir id of the collection :return: updated collection object :raises HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found """ already_present_samples = [self.build_sample_from_json(sample_fhir_id) for sample_fhir_id in collection.sample_fhir_ids] @@ -641,7 +676,9 @@ def __update_collection_characteristics_from_samples(self, samples: list[Sample] def get_observation_fhir_ids_belonging_to_diagnosis_report(self, diagnosis_report_fhir_id: str) -> list[str]: """Get observation FHIR IDs belonging to a diagnosis report - :param diagnosis_report_fhir_id: FHIR ID of diagnosis report""" + :param diagnosis_report_fhir_id: FHIR ID of diagnosis report + :raises HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found""" diagnosis_report = self.build_diagnosis_report_from_json(diagnosis_report_fhir_id) if diagnosis_report.observations_fhir_identifiers is None: return [] @@ -650,6 +687,8 @@ def get_observation_fhir_ids_belonging_to_diagnosis_report(self, diagnosis_repor def __get_diagnoses_of_sample(self, sample_fhir_id: str) -> list[str]: """Get all diagnoses that are linked to a sample :param sample_fhir_id: FHIR ID of sample + :raises HTTPError: if the request to blaze fails + :raises NonExistentResourceException: if the resource cannot be found :return: List of diagnoses codes""" diagnoses = [] observation_fhir_ids = self.get_observation_fhir_ids_belonging_to_sample(sample_fhir_id) diff --git a/src/client/__init__.py b/src/client/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/test/service/test_blaze_client.py b/test/service/test_blaze_client.py index 89c1159..27d8818 100644 --- a/test/service/test_blaze_client.py +++ b/test/service/test_blaze_client.py @@ -17,8 +17,8 @@ from src.MIABIS_on_FHIR.sample import Sample from src.MIABIS_on_FHIR.sample_donor import SampleDonor from src.MIABIS_on_FHIR.storage_temperature import StorageTemperature -from src.client.NonExistentResourceException import NonExistentResourceException -from src.client.blaze_client import BlazeClient +from src.blaze_client.NonExistentResourceException import NonExistentResourceException +from src.blaze_client.blaze_client import BlazeClient class TestBlazeService(unittest.TestCase): From 68132205fe8217b0a4acf6a2fdea768e4e022d94 Mon Sep 17 00:00:00 2001 From: SimonKonar Date: Tue, 29 Oct 2024 14:09:20 +0100 Subject: [PATCH 2/4] update README --- README.md | 48 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f0ab08f..1e7d375 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +## Introduction + MIABIS is focused on standardizing the data elements used to describe biobanks, research on samples, and related data. The goal of MIABIS is to enhance interoperability among biobanks that share valuable data and samples. MIABIS Core 2.0, introduced in 2016, established general attributes at an aggregated/metadata level for describing biobanks, sample @@ -10,8 +12,28 @@ The foundation for this FHIR profile (all the attributes defined by MIABIS) is a The MIABIS on FHIR profile full specification along with the guide is available on the [simplifier platform](https://simplifier.net/miabis). -This Python package provides a set of classes that can be used to create, read, and validate MIABIS on FHIR resources, as well as to convert them to and from JSON format. -This package aims to allow developers to easily work with MIABIS on FHIR resources in Python, while ensuring that the resources are compliant with the MIABIS on FHIR profile. +## Modules + +### 1. `MIABIS_on_FHIR` +The `MIABIS_on_FHIR` module includes a set of classes to help developers: +- **Create** MIABIS on FHIR resources. +- **Read** and **validate** these resources. +- **Convert** resources to and from JSON format. + +This module ensures compliance with the MIABIS on FHIR profile, allowing developers to handle MIABIS resources confidently and efficiently in Python. + +### 2. `blaze_client` +The `blaze_client` module simplifies communication with the [Samply.blaze](https://github.com/samply/blaze) FHIR storage server. Samply.blaze is a FHIR-compliant database designed for managing and storing FHIR resources. This module provides: +- **Streamlined communication** with Samply.blaze, abstracting away the need for direct JSON response handling. +- **BlazeClient** methods that simplify operations with the server, focusing on ease of use and minimizing boilerplate code. + +## Key Features +- **Compliance**: Ensures MIABIS on FHIR resources meet the profile standards. +- **Ease of Use**: Abstracts complex JSON interactions for a streamlined experience. +- **Blaze Integration**: Seamless integration with Samply.blaze for FHIR resource management. + +This package is ideal for developers looking to work with MIABIS on FHIR resources and interact with FHIR storage servers using Python. + ## Installation ```bash @@ -24,10 +46,24 @@ Here is how you can create a MIABIS on FHIR sample resource: from src.MIABIS_on_FHIR import Sample from src.MIABIS_on_FHIR import StorageTemperature -sample = Sample("sampleId", "donorId", "Blood", storage_temperature=StorageTemperature.TEMPERATURE_GN, +sample = Sample("sampleId", "donorId", "Urine", storage_temperature=StorageTemperature.TEMPERATURE_ROOM, use_restrictions="No restrictions") -# Convert the MoFSample object to a FHIR resource +# Convert the Sample object to a FHIR resource sample_resource = sample.to_fhir("donorId") # Convert the FHIR resource to a JSON string -sample_json = sample_resource.to_json() -``` \ No newline at end of file +sample_json = sample_resource.as_json() +``` + +Here is an example on how to communicate with blaze server via the BlazeClient: + +```python +import datetime +from src.MIABIS_on_FHIR import Gender +from src.blaze_client import BlazeClient +from src.MIABIS_on_FHIR import SampleDonor + +client = BlazeClient("example_url","username","password") + +donor = SampleDonor("donorId", Gender.MALE, birth_date=datetime.datetime(year=2000,month=12,day=12)) +donor_fhir_id = client.upload_donor(donor) +``` From bd8543380a197573818f96bbf6adc119498e5e2e Mon Sep 17 00:00:00 2001 From: SimonKonar Date: Tue, 29 Oct 2024 14:09:57 +0100 Subject: [PATCH 3/4] feat: add functionality for searching samples based on --- src/blaze_client/blaze_client.py | 86 ++++++++++++++++++++++++++++--- test/service/test_blaze_client.py | 22 ++++++++ 2 files changed, 102 insertions(+), 6 deletions(-) diff --git a/src/blaze_client/blaze_client.py b/src/blaze_client/blaze_client.py index 6029884..0935243 100644 --- a/src/blaze_client/blaze_client.py +++ b/src/blaze_client/blaze_client.py @@ -674,6 +674,29 @@ def __update_collection_characteristics_from_samples(self, samples: list[Sample] collection.number_of_subjects += count_of_new_subjects return collection + def get_collection_fhir_id_by_sample_fhir_identifier(self, sample_fhir_id: str) -> str | None: + """Get Collection FHIR id which contains provided sample FHIR ID, if there is one + :param sample_fhir_id: FHIR ID of the sample + :return: collection FHIR id if there is collection which contains this sample, None otherwise""" + return self.__get_group_fhir_id_by_resource_fhir_identifier(sample_fhir_id) + + def get_network_fhir_id_by_member_fhir_identifier(self, member_fhir_id: str) -> str | None: + """Get Network FHIR id which contains provided member FHIR ID (either collection resource of biobank resource), + if there is one + :param member_fhir_id: FHIR ID of the member of network + :return: network FHIR id if there is network which contains this member, None otherwise""" + return self.__get_group_fhir_id_by_resource_fhir_identifier(member_fhir_id) + + def __get_group_fhir_id_by_resource_fhir_identifier(self, resource_fhir_id: str) -> str | None: + """Get Group FHIR id which contains provided FHIR_ID or resource, if there is one + :param resource_fhir_id: FHIR ID of the resource + :return: Group resource FHIR ID if there is group which + contains reference to resource_fhir_id, none otherwise""" + response = self._session.get(f"{self._blaze_url}/Group?groupMember={resource_fhir_id}") + self.__raise_for_status_extract_diagnostics_message(response) + response_json = response.json() + return get_nested_value(response_json, ["entry", 0, "resource", "id"]) + def get_observation_fhir_ids_belonging_to_diagnosis_report(self, diagnosis_report_fhir_id: str) -> list[str]: """Get observation FHIR IDs belonging to a diagnosis report :param diagnosis_report_fhir_id: FHIR ID of diagnosis report @@ -737,6 +760,7 @@ def delete_donor(self, donor_fhir_id: str, part_of_bundle: bool = False) -> list patient_entry = self.__create_delete_bundle_entry("Patient", donor_fhir_id) entries.append(patient_entry) sample_fhir_ids = self.__get_all_sample_fhir_ids_belonging_to_patient(donor_fhir_id) + delete_from_collection = self.__delete_sample_references_from_collections(sample_fhir_ids) condition_fhir_id = self.__get_condition_fhir_id_by_donor_identifier(donor_fhir_id) for sample_fhir_id in sample_fhir_ids: sample_entries = self.delete_sample(sample_fhir_id, True, True) @@ -751,6 +775,33 @@ def delete_donor(self, donor_fhir_id: str, part_of_bundle: bool = False) -> list self.__raise_for_status_extract_diagnostics_message(response) return response.status_code == 200 or response.status_code == 204 + def __delete_sample_references_from_collections(self, sample_fhir_ids: list[str]) -> bool: + """ + :param sample_fhir_ids: + :return: + """ + entries = [] + collection_sample_fhir_ids_map = {} + for sample_fhir_id in sample_fhir_ids: + collection_fhir_id = self.get_collection_fhir_id_by_sample_fhir_identifier(sample_fhir_id) + if collection_fhir_id is None: + continue + if collection_fhir_id not in collection_sample_fhir_ids_map: + + collection_sample_fhir_ids_map[collection_fhir_id] = set() + collection_sample_fhir_ids_map[collection_fhir_id].add(sample_fhir_id) + else: + collection_sample_fhir_ids_map[collection_fhir_id].add(sample_fhir_id) + for collection_fhir_id, sample_fhir_ids_set in collection_sample_fhir_ids_map.items(): + updated_collection = self.__delete_samples_from_collection(collection_fhir_id, list(sample_fhir_ids_set)) + entries.append(self.__create_bundle_entry_for_updating_collection(updated_collection)) + if entries is None: + return True + bundle = self.__create_bundle(entries) + response = self._session.post(f"{self._blaze_url}", json=bundle.as_json()) + self.__raise_for_status_extract_diagnostics_message(response) + return 200 <= response.status_code < 300 + def delete_condition(self, condition_fhir_id: str, part_of_bundle: bool = False) -> list[BundleEntry] | bool: """Delete a condition from blaze. :param condition_fhir_id: the fhir id of the condition to delete @@ -792,6 +843,8 @@ def delete_sample(self, sample_fhir_id: str, part_of_bundle: bool = False, f"sample is not present in the blaze store.") specimen_entry = self.__create_delete_bundle_entry("Specimen", sample_fhir_id) entries.append(specimen_entry) + if not part_of_deleting_patient: + self.__delete_sample_references_from_collections([sample_fhir_id]) observations_linked_to_sample_fhir_ids = self.get_observation_fhir_ids_belonging_to_sample(sample_fhir_id) set_observations_linked_to_sample = set(observations_linked_to_sample_fhir_ids) diagnosis_reports_fhir_ids = self.__get_diagnosis_reports_fhir_id_by_sample_identifier(sample_fhir_id) @@ -902,6 +955,15 @@ def __delete_collection_reference_from_network(self, network_fhir_id: str, colle update_network_fhir = network.add_fhir_id_to_network(network.to_fhir()) return self.update_fhir_resource("Group", network_fhir_id, update_network_fhir.as_json()) + def __delete_samples_from_collection(self, collection_fhir_id: str, sample_fhir_ids: list[str]) -> Collection: + collection = self.build_collection_from_json(collection_fhir_id) + sample_fhir_ids_set = set(collection.sample_fhir_ids) + for sample_fhir_id in sample_fhir_ids: + if sample_fhir_id in sample_fhir_ids_set: + sample_fhir_ids_set.remove(sample_fhir_id) + collection._sample_fhir_ids = list(sample_fhir_ids_set) + return collection + def delete_collection_organization(self, collection_organization_fhir_id: str, part_of_bundle: bool = False) \ -> list[BundleEntry] | bool: """delete collection organization from blaze store. WARNING: deleting collection organization @@ -921,9 +983,10 @@ def delete_collection_organization(self, collection_organization_fhir_id: str, p f"{self._blaze_url}/Group?managing-entity={collection_organization_fhir_id}") response_json = collection_response.json() if response_json["total"] != 0: - collection_fhir_id = get_nested_value(response_json, ["entry", 0, "resource", "id"]) - collection_entries = self.delete_collection(collection_fhir_id, True) - entries.extend(collection_entries) + for entry in response_json["entry"]: + collection_fhir_id = get_nested_value(entry, ["resource", "id"]) + collection_entries = self.delete_collection(collection_fhir_id, True) + entries.extend(collection_entries) if part_of_bundle: return entries bundle = self.__create_bundle(entries) @@ -970,9 +1033,10 @@ def delete_network_organization(self, network_organization_fhir_id: str, part_of f"{self._blaze_url}/Group?managing-entity={network_organization_fhir_id}") response_json = network_response.json() if response_json["total"] != 0: - network_fhir_id = get_nested_value(response_json, ["entry", 0, "resource", "id"]) - network_entries = self.delete_network(network_fhir_id, True) - entries.extend(network_entries) + for entry in response_json["entry"]: + network_fhir_id = get_nested_value(entry, ["resource", "id"]) + network_entries = self.delete_network(network_fhir_id, True) + entries.extend(network_entries) if part_of_bundle: return entries bundle = self.__create_bundle(entries) @@ -1141,3 +1205,13 @@ def __create_delete_bundle_entry(resource_type: str, resource_fhir_id: str) -> B entry.request.method = "DELETE" entry.request.url = f"{resource_type}/{resource_fhir_id}" return entry + + @staticmethod + def __create_bundle_entry_for_updating_collection(collection: Collection) -> BundleEntry: + collection_fhir = collection.add_fhir_id_to_collection(collection.to_fhir()) + collection_entry = BundleEntry() + collection_entry.resource = collection_fhir + collection_entry.request = BundleEntryRequest() + collection_entry.request.method = "PUT" + collection_entry.request.url = f"Group/{collection.collection_fhir_id}" + return collection_entry diff --git a/test/service/test_blaze_client.py b/test/service/test_blaze_client.py index 27d8818..80aad04 100644 --- a/test/service/test_blaze_client.py +++ b/test/service/test_blaze_client.py @@ -3,6 +3,8 @@ import pytest as pytest import requests.exceptions +from fhirclient.models.bundle import Bundle, BundleEntry, BundleEntryRequest +from fhirclient.models.patient import Patient from requests.exceptions import HTTPError from src.MIABIS_on_FHIR.biobank import Biobank @@ -660,8 +662,10 @@ def test_add_existing_sample_to_collection(self): self.blaze_service.upload_observation(self.example_observations[1]) self.blaze_service.upload_diagnosis_report(self.example_diagnosis_reports[0]) self.blaze_service.upload_biobank(self.example_biobank) + self.blaze_service.upload_network_organization(self.example_network_org) self.blaze_service.upload_collection_organization(self.example_collection_org) collection_fhir_id = self.blaze_service.upload_collection(self.example_collection) + self.blaze_service.upload_network(self.example_network) # sample_fhir_id = self.blaze_service.get_fhir_id("Specimen", "sampleId") # sample_json = self.blaze_service.get_fhir_resource_as_json("Specimen", sample_fhir_id) # sample = Sample.from_json(sample_json, "donorId") @@ -750,3 +754,21 @@ def test_update_collection_values_after_deleting_sample(self): self.assertIn(self.example_observations[0].icd10_code, updated_collection.diagnoses) self.assertNotIn(new_observation.icd10_code, updated_collection.diagnoses) + + def test_delete_sample_present_in_collection(self): + self.blaze_service.upload_donor(self.example_donor) + sample_fhir_id1 = self.blaze_service.upload_sample(self.example_samples[0]) + self.blaze_service.upload_observation(self.example_observations[0]) + self.blaze_service.upload_diagnosis_report(self.example_diagnosis_reports[0]) + self.blaze_service.upload_biobank(self.example_biobank) + self.blaze_service.upload_collection_organization(self.example_collection_org) + collection_fhir_id = self.blaze_service.upload_collection(self.example_collection) + # sample_fhir_id = self.blaze_service.get_fhir_id("Specimen", "sampleId") + # sample_json = self.blaze_service.get_fhir_resource_as_json("Specimen", sample_fhir_id) + # sample = Sample.from_json(sample_json, "donorId") + updated = self.blaze_service.add_already_present_samples_to_existing_collection( + [sample_fhir_id1], collection_fhir_id) + self.assertTrue(updated) + deleted = self.blaze_service.delete_sample(sample_fhir_id1) + self.assertTrue(deleted) + From 9f7899eb0bd807a700095cbb2a0434dd79a2374a Mon Sep 17 00:00:00 2001 From: SimonKonar Date: Tue, 29 Oct 2024 14:10:46 +0100 Subject: [PATCH 4/4] update pyproject.toml --- pyproject.toml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 430a07a..88b4a90 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "MIABIS_on_FHIR" -version = "1.0.0" +version = "1.1.1dev01" description = "Library containing classes for easier handling of data according to the MIABIS on FHIR profile" readme = "README.md" authors = [{"name" = "Simon Konar", "email" = "simon.konar@gmail.com"}] @@ -16,13 +16,21 @@ classifiers = [ keywords = ["MIABIS", "FHIR", "model" , "profile", "data", "handling"] dependencies = [ "simple-icd-10 >= 2.0.0", - "fhirclient >= 4.2.1" + "fhirclient >= 4.2.1", + "requests >= 2.32", + "python-dateutil >= 2.9.0" + ] requires-python = ">=3.11" [project.optional-dependencies] - test=["requests >= 2.32.0"] + test=["pytest >= 8.3.0"] + +[tool.setuptools] +package-dir = { "" = "src" } [tool.setuptools.packages.find] +where = ["src"] +include = ["MIABIS_on_FHIR*", "blaze_client*"] exclude =["test*"] \ No newline at end of file