qmenta-client 1.1.dev1326__py3-none-any.whl → 1.1.dev1337__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.
qmenta/client/Project.py CHANGED
@@ -200,14 +200,45 @@ def wrap_search_criteria(search_criteria={}):
200
200
  return modality, tags, file_metadata
201
201
 
202
202
 
203
+ def convert_qc_value_to_qcstatus(value):
204
+ """
205
+ Convert input string to QCStatus class.
206
+
207
+ Parameters
208
+ ----------
209
+ value : str
210
+ Value to convert.
211
+
212
+ Returns
213
+ -------
214
+ QCStatus or Bool
215
+ QCStatus.PASS, QCStatus.FAIL or QCStatus.UNDETERMINED
216
+ False if the Value cannot be convered.
217
+ """
218
+ logger = logging.getLogger(logger_name)
219
+ if value == "pass":
220
+ return QCStatus.PASS
221
+ elif value == "fail":
222
+ return QCStatus.FAIL
223
+ elif value == "":
224
+ return QCStatus.UNDERTERMINED
225
+ else:
226
+ logger.error(f"The input value '{value}' cannot be converted "
227
+ f"to class QCStatus.")
228
+ return False
229
+
230
+
203
231
  class QCStatus(Enum):
204
232
  """
205
233
  Enum with the following options:
206
- FAIL, PASS
234
+ FAIL, PASS, UNDERTERMINED
235
+ that are the possible options for the QA/QC status of both
236
+ analysis and session.
207
237
  """
208
238
 
209
239
  PASS = "pass"
210
240
  FAIL = "fail"
241
+ UNDERTERMINED = ""
211
242
 
212
243
 
213
244
  class Project:
@@ -1841,7 +1872,8 @@ class Project:
1841
1872
  modalities.append(modality)
1842
1873
  return modalities
1843
1874
 
1844
- def set_qc_status(self, analysis_id, status=QCStatus.PASS, comments=""):
1875
+ def set_qc_status_analysis(self, analysis_id,
1876
+ status=QCStatus.UNDERTERMINED, comments=""):
1845
1877
  """
1846
1878
  Changes the analysis QC status.
1847
1879
 
@@ -1850,85 +1882,257 @@ class Project:
1850
1882
  analysis_id : int
1851
1883
  Analysis ID number
1852
1884
  status : QCStatus
1853
- QCStatus.PASS or QCStatus.FAIL
1885
+ QCStatus.PASS, QCStatus.FAIL or QCStatus.UNDETERMINED
1854
1886
  comments : str, optional
1855
- Additional comments explaining why the QC status has been
1856
- set to pass or fail.
1887
+ Additional comments explaining why the reasoning of setting the
1888
+ QC status to such state.
1889
+
1890
+ Returns
1891
+ -------
1892
+ bool
1893
+ True if the QC status was correctly changed, False otherwise.
1857
1894
  """
1895
+
1858
1896
  logger = logging.getLogger(__name__)
1859
1897
  logger.info(f"Setting QC status to {status}: {comments}")
1860
1898
 
1861
- platform.parse_response(
1862
- platform.post(
1863
- auth=self._account.auth,
1864
- endpoint="projectset_manager/set_qa_status",
1865
- data={"item_ids": analysis_id, "status": status.value, "comments": comments, "entity": "analysis"},
1899
+ if not isinstance(status, QCStatus):
1900
+ raise ValueError("Status should be type 'QCStatus'.")
1901
+
1902
+ try:
1903
+ analysis_id = str(int(analysis_id))
1904
+ except ValueError:
1905
+ raise ValueError(f"analysis_id: '{analysis_id}' not valid. " f"Must be convertible to int.")
1906
+
1907
+ try:
1908
+ platform.parse_response(
1909
+ platform.post(
1910
+ auth=self._account.auth,
1911
+ endpoint="projectset_manager/set_qa_status",
1912
+ data={"item_ids": analysis_id, "status": status.value,
1913
+ "comments": str(comments), "entity": "analysis"},
1914
+ )
1866
1915
  )
1867
- )
1916
+ except Exception:
1917
+ logger.error(f"It was not possible to change the QC status of"
1918
+ f"Analysis ID: {analysis_id}")
1919
+ return False
1920
+ return True
1868
1921
 
1869
- def get_qc_status(self, patient_secret_name=None, ssid=None, analysis_id=None):
1922
+ def set_qc_status_subject(self, patient_id,
1923
+ status=QCStatus.UNDERTERMINED, comments=""):
1870
1924
  """
1871
- Gets the session QC status of a session. If the analysis_id is
1872
- specified, it returns the QC of the
1873
- analysis instead.
1925
+ Changes the QC status of a Patient ID (equivalent to a
1926
+ Subject ID/Session ID).
1927
+
1928
+ Parameters
1929
+ ----------
1930
+ patient_id : int
1931
+ Patient ID number of the session.
1932
+ status : QCStatus
1933
+ QCStatus.PASS, QCStatus.FAIL or QCStatus.UNDETERMINED
1934
+ comments : str, optional
1935
+ Additional comments explaining why the reasoning of setting the
1936
+ QC status to such state.
1874
1937
 
1938
+ Returns
1939
+ -------
1940
+ bool
1941
+ True if the QC status was correctly changed, False otherwise.
1875
1942
  """
1876
- if patient_secret_name and ssid:
1943
+ logger = logging.getLogger(__name__)
1944
+ logger.info(f"Setting QC status to {status}: {comments}")
1945
+
1946
+ if not isinstance(status, QCStatus):
1947
+ raise ValueError("Status should be type 'QCStatus'.")
1948
+
1949
+ try:
1950
+ patient_id = str(int(patient_id))
1951
+ except ValueError:
1952
+ raise ValueError(f"'patient_id': '{patient_id}' not valid. " f"Must be convertible to int.")
1953
+
1954
+ try:
1955
+ platform.parse_response(
1956
+ platform.post(
1957
+ auth=self._account.auth,
1958
+ endpoint="projectset_manager/set_qa_status",
1959
+ data={"item_ids": patient_id, "status": status.value,
1960
+ "comments": str(comments), "entity": "patients"},
1961
+ )
1962
+ )
1963
+ except Exception:
1964
+ logger.error(f"It was not possible to change the QC status of"
1965
+ f"Patient ID: {patient_id}")
1966
+ return False
1967
+ return True
1968
+
1969
+ def get_qc_status_analysis(self, analysis_id):
1970
+ """
1971
+ Gets the QC status of an anlaysis provided its Analysis ID.
1972
+
1973
+ Parameters
1974
+ ----------
1975
+ analysis_id : int
1976
+ Analysis ID number
1977
+
1978
+ Returns
1979
+ -------
1980
+ status : QCStatus or False
1981
+ QCStatus.PASS, QCStatus.FAIL or QCStatus.UNDETERMINED
1982
+ False if the status cannot be extracted.
1983
+ comments : str or False
1984
+ Comments defined in the QC Status.
1985
+ False if the comments cannot be extracted.
1986
+ """
1987
+ try:
1988
+ search_criteria = {"id": analysis_id}
1989
+ to_return = self.list_analysis(search_criteria)
1990
+ return convert_qc_value_to_qcstatus(to_return[0]["qa_status"]), to_return[0]["qa_comments"]
1991
+ except IndexError:
1992
+ # Handle the case where no matching analysis is found
1993
+ logging.error(f"No analysis was found with such Analysis ID: '{analysis_id}'.")
1994
+ return False, False
1995
+ except Exception:
1996
+ # Handle other potential exceptions
1997
+ logging.error(f"It was not possible to extract the QC status"
1998
+ f"from Analysis ID: {analysis_id}")
1999
+ return False, False
2000
+
2001
+ def get_qc_status_subject(self, patient_id=None, subject_name=None,
2002
+ ssid=None):
2003
+ """
2004
+ Gets the session QC status via the patient ID or the Subject ID
2005
+ and the Session ID.
2006
+
2007
+ Parameters
2008
+ ----------
2009
+ patient_id : int
2010
+ Patient ID number of the session
2011
+ subject_name : string
2012
+ Subject ID of the session
2013
+ ssid : string
2014
+ Session ID
2015
+
2016
+ Returns
2017
+ -------
2018
+ status : QCStatus or False
2019
+ QCStatus.PASS, QCStatus.FAIL or QCStatus.UNDETERMINED
2020
+ False if the status cannot be extracted.
2021
+ comments : str or False
2022
+ Comments defined in the QC Status.
2023
+ False if the comments cannot be extracted.
2024
+ """
2025
+
2026
+ if patient_id:
2027
+ try:
2028
+ patient_id = int(patient_id)
2029
+ except ValueError:
2030
+ raise ValueError(f"patient_id '{patient_id}' should be an "
2031
+ f"integer.")
2032
+ sessions = self.get_subjects_metadata(search_criteria={})
2033
+ session = [session for session in sessions if int(session["_id"]) == patient_id]
2034
+ if len(session) < 1:
2035
+ logging.error(f"No session was found with Patient ID: "
2036
+ f"'{patient_id}'.")
2037
+ return False, False
2038
+ return convert_qc_value_to_qcstatus(session[0]["qa_status"]), session[0]["qa_comments"]
2039
+ elif subject_name and ssid:
1877
2040
  session = self.get_subjects_metadata(
1878
2041
  search_criteria={
1879
- "pars_patient_secret_name": f"string;" f"{patient_secret_name}",
2042
+ "pars_patient_secret_name": f"string;{subject_name}",
1880
2043
  "pars_ssid": f"integer;eq|{ssid}",
1881
2044
  }
1882
2045
  )
1883
- to_return = session["qa_status"], session["qa_comments"]
1884
- elif analysis_id:
1885
- try:
1886
- to_return = [
1887
- analysis["qa_data"] for analysis in self.list_analysis() if analysis["_id"] == analysis_id
1888
- ][0]
1889
- to_return = to_return["qa_status"], to_return["qa_comments"]
1890
- except IndexError:
1891
- # Handle the case where no matching analysis is found
1892
- to_return = None
1893
- except Exception as e:
1894
- # Handle other potential exceptions
1895
- print(f"An error occurred: {e}")
1896
- to_return = None
2046
+ if len(session) < 1:
2047
+ logging.error(f"No session was found with Subject ID: "
2048
+ f"'{subject_name}' and Session ID: '{ssid}'.")
2049
+ return False, False
2050
+ return convert_qc_value_to_qcstatus(session[0]["qa_status"]), session[0]["qa_comments"]
1897
2051
  else:
1898
- raise Exception(f"Must specify {patient_secret_name} and {ssid} or {analysis_id}.")
1899
- return to_return
2052
+ raise ValueError("Either 'patient_id' or 'subject_name' and 'ssid'"
2053
+ " must not be empty.")
1900
2054
 
1901
- def set_project_qa_rules(self, rules_file_path, guidance_text=""):
2055
+ def set_project_pa_rules(self, rules_file_path, guidance_text=""):
1902
2056
  """
1903
- Logs in to the Qmenta platform, retrieves the project ID based on the project name,
1904
- and updates the project's QA rules using the provided rules file.
2057
+ Updates the active project's protocol adherence rules using the
2058
+ provided rules file.
1905
2059
 
1906
- Args:
1907
- rules_file_path (str): The file path to the JSON file containing the QA rules.
1908
- guidance_text (str): Description of the rules. Only visible for Platform admins.
2060
+ Parameters
2061
+ ----------
2062
+ rules_file_path : str
2063
+ The file path to the JSON file containing the protocol
2064
+ adherence rules.
2065
+ guidance_text : str
2066
+ Description of the protocol adherence rules.
1909
2067
 
1910
- Returns:
1911
- bool: True if the rules were set successfully, False otherwise.
2068
+ Returns
2069
+ -------
2070
+ bool: True if the protocol adherence rules were set successfully,
2071
+ False otherwise.
1912
2072
  """
2073
+ logger = logging.getLogger(logger_name)
1913
2074
  # Read the rules from the JSON file
1914
2075
  try:
1915
2076
  with open(rules_file_path, "r") as fr:
1916
2077
  rules = json.load(fr)
1917
2078
  except FileNotFoundError:
1918
- print(f"ERROR: Rules file '{rules_file_path}' not found.")
2079
+ logger.error(f"Pprotocol adherence rule file '{rules_file_path}' "
2080
+ f"not found.")
1919
2081
  return False
1920
2082
 
1921
2083
  # Update the project's QA rules
1922
- res = platform.post(
2084
+ res = platform.parse_response(platform.post(
1923
2085
  auth=self._account.auth,
1924
2086
  endpoint="projectset_manager/set_session_qa_requirements",
1925
2087
  data={"project_id": self._project_id, "rules": json.dumps(rules), "guidance_text": guidance_text},
1926
- )
2088
+ ))
1927
2089
 
1928
- if res.json().get("success") == 1:
1929
- print("Rules set up successfully!")
1930
- return True
1931
- else:
1932
- print("ERROR setting the rules")
1933
- print(res.json())
2090
+ if not res.get("success") == 1:
2091
+ logger.error("There was an error setting up the protocol "
2092
+ "adherence rules.")
2093
+ logger.error(platform.parse_response(res))
2094
+ return False
2095
+
2096
+ return True
2097
+
2098
+ def get_project_pa_rules(self, rules_file_path):
2099
+ """
2100
+ Retrive the active project's protocol adherence rules
2101
+
2102
+ Parameters
2103
+ ----------
2104
+ rules_file_path : str
2105
+ The file path to the JSON file to store the protocol adherence
2106
+ rules.
2107
+
2108
+ Returns
2109
+ -------
2110
+ guidance_text : str
2111
+ Description of the protocol adherence rules,
2112
+ False if extraction of the protocol adhernece rules is not
2113
+ possible.
2114
+ """
2115
+ logger = logging.getLogger(logger_name)
2116
+
2117
+ # Update the project's QA rules
2118
+ res = platform.parse_response(platform.post(
2119
+ auth=self._account.auth,
2120
+ endpoint="projectset_manager/get_session_qa_requirements",
2121
+ data={"project_id": self._project_id},
2122
+ ))
2123
+
2124
+ if "rules" not in res:
2125
+ logger.error(f"There was an error extracting the protocol "
2126
+ f"adherence rules from {self._project_name}.")
2127
+ logger.error(platform.parse_response(res))
2128
+ return False
2129
+
2130
+ try:
2131
+ with open(rules_file_path, "w") as fr:
2132
+ json.dump(res["rules"], fr, indent=4)
2133
+ except FileNotFoundError:
2134
+ logger.error(f"Protocol adherence rules could not be exported"
2135
+ f"to file: '{rules_file_path}'.")
1934
2136
  return False
2137
+
2138
+ return res["guidance_text"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: qmenta-client
3
- Version: 1.1.dev1326
3
+ Version: 1.1.dev1337
4
4
  Summary: Python client lib to interact with the QMENTA platform.
5
5
  Author: QMENTA
6
6
  Author-email: dev@qmenta.com
@@ -1,10 +1,10 @@
1
1
  qmenta/__init__.py,sha256=jv2YF__bseklT3OWEzlqJ5qE24c4aWd5F4r0TTjOrWQ,65
2
2
  qmenta/client/Account.py,sha256=MEljEy9cmg2uP2FG1d3TZAgfj66EE2_3PQAZ9rvpCXY,9647
3
3
  qmenta/client/File.py,sha256=ZgvSqejIosUt4uoX7opUnPnp5XGEaJNMRwFC0mQVB8k,5344
4
- qmenta/client/Project.py,sha256=T_IoH_CpyFg0IaaXeQW_x1xH76n8FsX_2v0qWJo7Yuk,68063
4
+ qmenta/client/Project.py,sha256=XzolIEPQzUWPelWtv67fiYvLGXp7bLRfH2-Ckvgl8Ao,75153
5
5
  qmenta/client/Subject.py,sha256=lhxxVdQ6d-GNoQC8mrJwa4L1f44nJc4PcJtDspmKN7I,8756
6
6
  qmenta/client/__init__.py,sha256=AjTojBhZeW5nl0i605KS8S1Gl5tPNc1hdzD47BGNfoI,147
7
7
  qmenta/client/utils.py,sha256=5DK2T_HQprrCwLS0Ycm2CjseaYmAUKaJkJvYoW-Rqzc,2479
8
- qmenta_client-1.1.dev1326.dist-info/METADATA,sha256=h6qd-k47PLto2IDPKURSwiuRhRyfFA3bZ8a0-IRbGrE,672
9
- qmenta_client-1.1.dev1326.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
10
- qmenta_client-1.1.dev1326.dist-info/RECORD,,
8
+ qmenta_client-1.1.dev1337.dist-info/METADATA,sha256=Epl4svIqv_lvXPjjfBh5zAU02b5i_sq1z-ZptA0c58o,672
9
+ qmenta_client-1.1.dev1337.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
10
+ qmenta_client-1.1.dev1337.dist-info/RECORD,,