diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1157557..702c7ee 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,11 @@ repos: - repo: https://github.com/psf/black - rev: stable + rev: 22.3.0 hooks: - id: black language_version: python3 - repo: https://gitlab.com/pycqa/flake8 - rev: 3.7.9 + rev: 3.9.2 hooks: - id: flake8 additional_dependencies: @@ -13,10 +13,10 @@ repos: - flake8-black #- flake8-docstrings - repo: https://github.com/pre-commit/pre-commit-hooks.git - rev: master + rev: v4.3.0 hooks: - id: trailing-whitespace - id: mixed-line-ending - id: check-byte-order-marker - id: check-merge-conflict - - id: detect-aws-credentials \ No newline at end of file + - id: detect-aws-credentials diff --git a/ppmutils/fhir.py b/ppmutils/fhir.py index 24ee33c..eb0dde8 100644 --- a/ppmutils/fhir.py +++ b/ppmutils/fhir.py @@ -666,7 +666,7 @@ def get_created_resource_id(response, resource_type): # Check status if not response.ok: logger.error( - f"FHIR Error: Cannot get resource details from a failed response: " + "FHIR Error: Cannot get resource details from a failed response: " f"{response.status_code} : {response.content.decode()}" ) return None, None @@ -846,7 +846,7 @@ def create(study, patient, resource_type, resource, replace=False, query=None): # Check multiple if existing_resources and len(existing_resources) > 1: logger.error( - f"PPM/{patient}/{study}/FHIR: Multiple resources " f"found, cannot replace", + f"PPM/{patient}/{study}/FHIR: Multiple resources found, cannot replace", extra={ "study": study, "patient": patient, @@ -860,7 +860,7 @@ def create(study, patient, resource_type, resource, replace=False, query=None): elif existing_resources: resource_id = next(iter(existing_resources))["id"] logger.debug( - f"PPM/{patient}/{study}/FHIR: Will replace " f"{resource_type}/{resource_id}", + f"PPM/{patient}/{study}/FHIR: Will replace {resource_type}/{resource_id}", ) # Set the URL @@ -2044,7 +2044,7 @@ def query_participant(patient, questionnaires=None, flatten_return=False): :rtype: dict """ logger.warning('PPM/FHIR: Method "query_participant" is deprecated') - warnings.warn(f'PPM/FHIR: "query_participant" is deprecated, use "get_participant" instead', DeprecationWarning) + warnings.warn('PPM/FHIR: "query_participant" is deprecated, use "get_participant" instead', DeprecationWarning) return FHIR.get_participant(patient, questionnaires, flatten_return) @staticmethod @@ -2125,7 +2125,7 @@ def query_patient(patient, flatten_return=False): :rtype: dict """ logger.warning('PPM/FHIR: Method "query_patient" is deprecated') - warnings.warn(f'PPM/FHIR: "query_patient" is deprecated, use "get_patient" instead', DeprecationWarning) + warnings.warn('PPM/FHIR: "query_patient" is deprecated, use "get_patient" instead', DeprecationWarning) return FHIR.get_patient(patient, flatten_return) # TODO: This method is deprecated @@ -2141,7 +2141,7 @@ def get_composition(patient, flatten_return=False): """ logger.warning('PPM/FHIR: Method "get_composition" is deprecated') warnings.warn( - f'PPM/FHIR: "get_composition" is deprecated, use "query_consent_compositions" instead', DeprecationWarning + 'PPM/FHIR: "get_composition" is deprecated, use "query_consent_compositions" instead', DeprecationWarning ) # Just return the first from querying @@ -3758,7 +3758,7 @@ def update_points_of_care_list(patient, points_of_care): if not points_of_care_list: # Set the list to persist points_of_care = [points_of_care] - logger.debug(f"PPM/FHIR: POC list doesn't exist, will create") + logger.debug("PPM/FHIR: POC list doesn't exist, will create") FHIR.create_point_of_care_list(patient, points_of_care) return points_of_care @@ -4124,7 +4124,7 @@ def update_questionnaire_response(patient, study, questionnaire_id, questionnair logger.error( f"PPM/{patient}/FHIR: Cannot update Questionnaire" f"Response for Questionnaire/{questionnaire_id} as " - f"it does not exist" + "it does not exist" ) return False @@ -4483,7 +4483,7 @@ def delete_consent(patient_id, project): elif PPM.Study.get(project) is PPM.Study.NEER: # Delete questionnaire responses - questionnaire_ids = ["neer-signature", "neer-signature-v2"] + questionnaire_ids = ["neer-signature", "neer-signature-v2", "neer-signature-v3"] for questionnaire_id in questionnaire_ids: transaction["entry"].append( { @@ -4756,7 +4756,7 @@ def flatten_participant(bundle, study=None, questionnaires=None): f"PPM/{ppm_id}: Multiple PPM studies: {studies}", extra={"study": study, "ppm_id": ppm_id, "studies": studies}, ) - raise ValueError(f"Participant has multiple studies but requested study has not been defined") + raise ValueError("Participant has multiple studies but requested study has not been defined") # If study wasn't passed, get it from the single entry list elif not study: @@ -5707,7 +5707,7 @@ def get_answer_indices(questionnaire, questions): if len(parts) == 3: # Ensure we have siblings - if len([l for l in questions.keys() if linkId.rsplit(parts[2], 1)[0] in l]) == 1: + if len([link_id for link_id in questions.keys() if linkId.rsplit(parts[2], 1)[0] in link_id]) == 1: continue i_count = int(parts[2]) @@ -7258,7 +7258,7 @@ def run(self, *args, **kwargs): else: logger.error("----- FHIR/Ops: Failed '{}' ----".format(op.__name__)) logger.error("----- FHIR/Ops: '{}' Message: ----\n{}\n".format(op.__name__, message)) - logger.info("----- FHIR/Ops: Operation failed, halting operations ----".format(op.__name__)) + logger.info("----- FHIR/Ops: Operation failed, halting operations ----") break def _op_fix_asd_researchstudy_20201031(*args, **kwargs): @@ -7331,7 +7331,7 @@ def _op_fix_asd_researchstudy_20201031(*args, **kwargs): bundle.entry.append(research_study_delete_entry) else: - logger.debug(f"PPM/FHIR/Ops/fix_asd_research_study: No ResearchStudy for 'ppm-autism' found") + logger.debug("PPM/FHIR/Ops/fix_asd_research_study: No ResearchStudy for 'ppm-autism' found") # Else, get all referencing ResearchSubjects research_subjects = FHIR.query_ppm_research_subjects() @@ -7339,9 +7339,9 @@ def _op_fix_asd_researchstudy_20201031(*args, **kwargs): r for r in research_subjects if r["study"]["reference"].replace("ResearchStudy/", "") == "ppm-autism" ] logger.debug( - f"PPM/FHIR/Ops/fix_asd_research_study: Found " + "PPM/FHIR/Ops/fix_asd_research_study: Found " f"{len(research_subjects)} ResearchSubject resources" - f"for 'ppm-autism'" + "for 'ppm-autism'" ) # Filter for those referencing 'ppm-autism' @@ -7390,9 +7390,9 @@ def _op_fix_asd_researchstudy_20201031(*args, **kwargs): in [r["ref"]["reference"].replace("ResearchStudy/", "") for r in d["context"]["related"]] ] logger.debug( - f"PPM/FHIR/Ops/fix_asd_research_study: Found " + "PPM/FHIR/Ops/fix_asd_research_study: Found " f"{len(document_references)} DocumentReference resources " - f"for 'ppm-autism'" + "for 'ppm-autism'" ) # Filter for those referencing 'ppm-autism' @@ -7429,14 +7429,14 @@ def _op_fix_asd_researchstudy_20201031(*args, **kwargs): query = {"type": f"{FHIR.ppm_consent_type_system}|{FHIR.ppm_consent_type_value}"} # Check for ppm-autism study - query["entry"] = f"ResearchStudy/ppm-autism" + query["entry"] = "ResearchStudy/ppm-autism" # Get resources compositions = FHIR._query_resources("Composition", query=query) logger.debug( - f"PPM/FHIR/Ops/fix_asd_research_study: Found " + "PPM/FHIR/Ops/fix_asd_research_study: Found " f"{len(compositions)} Composition resources with ref " - f"to 'ppm-autism'" + "to 'ppm-autism'" ) # Filter for those referencing 'ppm-autism' diff --git a/ppmutils/ppm.py b/ppmutils/ppm.py index 17fd5ba..47bb2d5 100644 --- a/ppmutils/ppm.py +++ b/ppmutils/ppm.py @@ -819,7 +819,7 @@ class Questionnaire(PPMEnum): # Consents (Current) EXAMPLEConsent = "example-signature" - NEERConsent = "neer-signature-v2" + NEERConsent = "neer-signature-v3" ASDGuardianConsentQuestionnaire = "ppm-asd-consent-guardian-quiz" ASDIndividualConsentQuestionnaire = "ppm-asd-consent-individual-quiz" ASDConsentIndividualSignatureQuestionnaire = "individual-signature-part-1" @@ -1134,9 +1134,10 @@ def exceptions(questionnaire_id): if questionnaire_id == PPM.Questionnaire.NEERConsent.value: return { "question-1": "82078001", - "question-2": "258435002", - "question-3": "284036006", - "question-4": "702475000", + "question-2": "165334004", + "question-3": "258435002", + "question-4": "284036006", + "question-5": "702475000", } elif questionnaire_id == PPM.Questionnaire.EXAMPLEConsent.value: @@ -1356,7 +1357,7 @@ def service_url(cls): if environment and cls.default_url_for_env(environment): return cls.default_url_for_env(environment) - raise ValueError("Service URL not defined in settings".format(cls.service.upper())) + raise ValueError("Service URL not defined in settings") @classmethod def default_url_for_env(cls, environment): @@ -1517,6 +1518,8 @@ def post(cls, request=None, path="/", data=None, raw=False): if not data: data = {} + # Set placeholders for debugging + content = status_code = None try: # Prepare the request. response = requests.post( @@ -1524,6 +1527,8 @@ def post(cls, request=None, path="/", data=None, raw=False): headers=cls.headers(request), data=json.dumps(data), ) + content = response.content + status_code = response.status_code # Check response type if raw: @@ -1531,13 +1536,28 @@ def post(cls, request=None, path="/", data=None, raw=False): else: return response.json() + except requests.HTTPError as e: + logger.debug(f"{cls.service} request error: {data}/{path} -> [{status_code}] {content}") + logger.exception( + "{} request error: {}".format(cls.service, e), + extra={ + "data": data, + "path": path, + "content": content, + "status_code": status_code, + }, + ) + except Exception as e: + logger.debug(f"{cls.service} error: {data}/{path} -> [{status_code}] {content}") logger.exception( "{} error: {}".format(cls.service, e), exc_info=True, extra={ "data": data, "path": path, + "content": content, + "status_code": status_code, }, )