Skip to content

Commit

Permalink
fix(qualtrics): Removed unecessary resource validation that was inadv…
Browse files Browse the repository at this point in the history
…ertently changing return value; added type hints for methods
  • Loading branch information
b32147 committed Jul 17, 2024
1 parent ad0f0cd commit 71ec972
Showing 1 changed file with 31 additions and 21 deletions.
52 changes: 31 additions & 21 deletions ppmutils/qualtrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from fhirclient.models.patient import Patient

from ppmutils.fhir import FHIR
from ppmutils.ppm import PPM

import logging

Expand All @@ -21,7 +22,7 @@ class ConversionError(Exception):
pass

@classmethod
def is_survey_export(cls, survey):
def is_survey_export(cls, survey: dict) -> bool:
"""
Inspects a survey export object and confirms that's what it is.
Qualtrics surveys can be described by three separate formats:
Expand All @@ -36,7 +37,7 @@ def is_survey_export(cls, survey):
return survey.get("SurveyElements") is not None

@classmethod
def is_survey_definition(cls, survey):
def is_survey_definition(cls, survey: dict) -> bool:
"""
Inspects a survey definition object and confirms that's what it is.
Qualtrics surveys can be described by three separate formats:
Expand All @@ -51,7 +52,7 @@ def is_survey_definition(cls, survey):
return survey.get("SurveyOptions") is not None and survey.get("Questions") is not None

@classmethod
def is_survey_object(cls, survey):
def is_survey_object(cls, survey: dict) -> bool:
"""
Inspects a survey object and confirms that's what it is.
Qualtrics surveys can be described by three separate formats:
Expand All @@ -66,7 +67,7 @@ def is_survey_object(cls, survey):
return survey.get("name") is not None and survey.get("questions") is not None

@classmethod
def get_survey_response_metadata(cls, response):
def get_survey_response_metadata(cls, response: dict) -> dict:
"""
Given a Qualtrics survey response object from the API, this returns
a dictionary of metadata for the response relating to the study
Expand Down Expand Up @@ -96,7 +97,7 @@ def get_survey_response_metadata(cls, response):
return metadata

@classmethod
def questionnaire(cls, survey, survey_id, questionnaire_id=None):
def questionnaire(cls, survey: dict, survey_id: str, questionnaire_id: str = None) -> dict:
"""
Accepts a Qualtrics survey definition (QSF) and creates a FHIR
Questionnaire resource from it. Does not support all of Qualtrics
Expand All @@ -109,6 +110,8 @@ def questionnaire(cls, survey, survey_id, questionnaire_id=None):
:type survey_id: str
:param questionnaire_id: The ID to assign to the Questionnaire, defaults to None
:type questionnaire_id: str, optional
:returns: The Questionnaire resource as a dict
:rtype: dict
"""
try:
# Extract the items
Expand Down Expand Up @@ -182,7 +185,7 @@ def questionnaire(cls, survey, survey_id, questionnaire_id=None):
raise Qualtrics.ConversionError

@classmethod
def questionnaire_item_generator(cls, survey_id, survey):
def questionnaire_item_generator(cls, survey_id: str, survey: dict) -> collections.Iterator[dict]:
"""
Returns a generator of QuestionnaireItem resources
to be added to the Questionnaire. This will determine
Expand All @@ -195,7 +198,7 @@ def questionnaire_item_generator(cls, survey_id, survey):
:type survey: dict
:raises Exception: Raises exception if block is an unhandled type
:return: The FHIR QuestionnaireItem generator
:rtype: generator
:rtype: Iterator[dict]
"""
# Flow sets order of blocks, blocks set order of questions
flows = [
Expand Down Expand Up @@ -245,7 +248,7 @@ def questionnaire_item_generator(cls, survey_id, survey):
yield item

@classmethod
def questionnaire_group(cls, survey_id, survey, block_id, block):
def questionnaire_group(cls, survey_id: str, survey: dict, block_id: str, block: dict) -> dict:
"""
Returns a FHIR resource for a QuestionnaireItem parsed from
a block of Qualtrics survey's questions. This should be used
Expand Down Expand Up @@ -302,7 +305,7 @@ def questionnaire_group(cls, survey_id, survey, block_id, block):
raise e

@classmethod
def _qid_to_linkid(cls, qid):
def _qid_to_linkid(cls, qid: str) -> str:
"""
This is a utility method to convert a Qualtrics QID question ID
to a FHIR Questionnaire/QuestionnaireResponse Link ID.
Expand All @@ -315,7 +318,7 @@ def _qid_to_linkid(cls, qid):
return f'question-{qid.replace("QID", "").replace("S", "-")}'

@classmethod
def questionnaire_item(cls, survey_id, survey, question_id, question):
def questionnaire_item(cls, survey_id: str, survey: dict, question_id: str, question: dict) -> dict:
"""
Returns a FHIR resource for a QuestionnaireItem parsed from
the Qualtrics survey's question
Expand Down Expand Up @@ -615,8 +618,16 @@ def questionnaire_item(cls, survey_id, survey, question_id, question):

@classmethod
def questionnaire_response(
cls, study, ppm_id, questionnaire_id, survey_id, response_id, survey_definition=None, survey=None, response=None
):
cls,
study: PPM.Study | str,
ppm_id: str,
questionnaire_id: str,
survey_id: str,
response_id: str,
survey_definition: dict = None,
survey: dict = None,
response: dict = None,
) -> dict:
"""
Returns QuestionnaireResponse resource for a survey taken through
Qualtrics. This method requires that Qualtrics question names are
Expand Down Expand Up @@ -701,7 +712,9 @@ def questionnaire_response(
return data

@classmethod
def questionnaire_response_item_generator(cls, survey_definition, survey, response, blocks):
def questionnaire_response_item_generator(
cls, survey_definition: dict, survey: dict, response: dict, blocks: dict
) -> collections.Iterator[dict]:
"""
Accepts the survey, response objects as well as the list of blocks add their
respective questions and yields a set of QuestionnareResponseItem
Expand All @@ -717,7 +730,7 @@ def questionnaire_response_item_generator(cls, survey_definition, survey, respon
:type blocks: dict
:raises Exception: Raises exception if value is an unhandled type
:returns A generator of QuestionnaireResponseItem resources
:rtype generator
:rtype Iterator[dict]
"""
question_id = None
for block_id, question_ids in blocks.items():
Expand Down Expand Up @@ -814,15 +827,15 @@ def questionnaire_response_item_generator(cls, survey_definition, survey, respon
raise e

@classmethod
def survey_response_is_required(cls, survey_definition, survey, response, key):
def survey_response_is_required(cls, survey_definition: dict, survey: dict, response: dict, key: str) -> bool:
"""
Returns whether a response to the question is required or not according
to the Qualtrics survey object. This inspects not only properties of
the question but also ensures it's enabled via conditional logic. If
not enabled, will not be returned as required.
:param survey_definition: The Qualtrics survey definition object
:type survey_definition: dict, defaults to None
:type survey_definition: dict
:param survey: The Qualtrics survey object
:type survey: object
:param response: The response object
Expand Down Expand Up @@ -967,7 +980,7 @@ def survey_response_is_required(cls, survey_definition, survey, response, key):
return True

@classmethod
def get_survey_response_values(cls, survey, response, qid):
def get_survey_response_values(cls, survey: dict, response: dict, qid: str) -> list | None:
"""
This method parses a survey response and returns the value of the
response for the given question, if any at all.
Expand Down Expand Up @@ -1234,7 +1247,7 @@ def questionnaire_response_item(cls, survey, response, key, loop=None):
return {"linkId": link_id, "answer": FHIR.Resources.questionnaire_response_answer(answer)}

@classmethod
def questionnaire_transaction(cls, questionnaire, questionnaire_id=None):
def questionnaire_transaction(cls, questionnaire: dict, questionnaire_id: str = None) -> dict | None:
"""
Accepts a Questionnaire object and builds the transaction to be used
to perform the needed operation in FHIR. Operations can be POST or PUT,
Expand Down Expand Up @@ -1262,9 +1275,6 @@ def questionnaire_transaction(cls, questionnaire, questionnaire_id=None):
logger.debug(f"PPM/Qualtrics: Questionnaire already exists for survey version {version}")
return None

# Use the FHIR client lib to validate our resource.
questionnaire = Questionnaire(questionnaire)

return FHIR.fhir_create(
resource_type="Questionnaire",
resource=questionnaire,
Expand Down

0 comments on commit 71ec972

Please sign in to comment.