def change_enrolment_status(business_id, respondent_id, survey_id, change_flag): logger.info('Changing enrolment status', business_id=business_id, respondent_id=respondent_id, survey_id=survey_id, change_flag=change_flag) url = f'{app.config["PARTY_URL"]}/party-api/v1/respondents/change_enrolment_status' enrolment_json = { 'respondent_id': respondent_id, 'business_id': business_id, 'survey_id': survey_id, 'change_flag': change_flag } response = requests.put(url, json=enrolment_json, auth=app.config['BASIC_AUTH']) try: response.raise_for_status() except requests.exceptions.HTTPError: logger.error('Failed to change enrolment status', business_id=business_id, respondent_id=respondent_id, survey_id=survey_id, change_flag=change_flag) raise ApiError(response) logger.info('Successfully changed enrolment status', business_id=business_id, respondent_id=respondent_id, survey_id=survey_id, change_flag=change_flag)
def change_respondent_status(respondent_id, change_flag): if change_flag == 'ACTIVE': logger.info('Changing respondent status', respondent_id=respondent_id, change_flag=change_flag) url = f'{app.config["PARTY_URL"]}/party-api/v1/respondents/edit-account-status/{respondent_id}' enrolment_json = { 'respondent_id': respondent_id, 'status_change': change_flag } response = requests.put(url, json=enrolment_json, auth=app.config['BASIC_AUTH']) try: response.raise_for_status() except HTTPError: logger.error('Failed to change respondent status', respondent_id=respondent_id, change_flag=change_flag) raise ApiError(response) logger.info('Successfully changed respondent status', respondent_id=respondent_id, change_flag=change_flag) else: logger.error('Incorrect change_flag given', respondent_id=respondent_id, change_flag=change_flag) raise ValueError('Incorrect change_flag given')
def download_dashboard_data(collection_exercise_id, survey_id): """ This goes to the reporting api and retrieves a set of data that is used for the dashboard. This is the easiest way to get high level information about the sample for a collection instrument. :param collection_exercise_id: A uuid representing the collection exercise :param survey_id: A uuid representing the survey :raises ApiError: Raised when the reporting api returns a 4xx or 5xx response :raises ConnectionError: Raised when a connection to the reporting api cannot be made :return: A json representation of the data. """ logger.info("Downloading dashboard data for collection exercise", collection_exercise_id=collection_exercise_id, survey_id=survey_id) url = ( f"{app.config['REPORT_URL']}" f"/reporting-api/v1/response-dashboard/survey/{survey_id}/collection-exercise/{collection_exercise_id}" ) response = requests.get(url) try: response.raise_for_status() except HTTPError: logger.error("Error retrieving dashboard data", collection_exercise_id=collection_exercise_id, survey_id=survey_id) raise ApiError(response) logger.info("Successfully downloaded dashboard data", collection_exercise_id=collection_exercise_id, survey_id=survey_id) return response.json()
def update_close_conversation_status(thread_id, status): url = f"{current_app.config['SECURE_MESSAGE_URL']}/threads/{thread_id}" data = {"is_closed": status} logger.info("Updating close conversation status", thread_id=thread_id, status=status) response = requests.patch(url, headers={ "Authorization": _get_jwt(), "Content-Type": "application/json" }, json=data) try: response.raise_for_status() logger.info("Successfully updated close conversation status", thread_id=thread_id, status=status) except HTTPError: logger.error("Failed to update close conversation status", thread_id=thread_id, status=status, exc_info=True) raise ApiError(response)
def get_cases_by_business_party_id(business_party_id): logger.info('Retrieving cases', business_party_id=business_party_id) url = f'{app.config["CASE_URL"]}/cases/partyid/{business_party_id}' response = requests.get(url, auth=app.config['CASE_AUTH'], params={ "iac": "True", "max_cases_per_survey": app.config['MAX_CASES_RETRIEVED_PER_SURVEY'] }) try: response.raise_for_status() except requests.exceptions.HTTPError: if response.status_code == 404 or response.status_code == 204: logger.info('No cases found for business', business_party_id=business_party_id) return [] logger.exception('Error retrieving cases', business_party_id=business_party_id) raise ApiError(response) logger.info('Successfully retrieved cases', business_party_id=business_party_id) return response.json()
def get_linked_sample_summary_id(collection_exercise_id): logger.info("Retrieving sample linked to collection exercise", collection_exercise_id=collection_exercise_id) url = f'{app.config["COLLECTION_EXERCISE_URL"]}/collectionexercises/link/{collection_exercise_id}' response = requests.get(url, auth=app.config["BASIC_AUTH"]) if response.status_code == 204: logger.info("No samples linked to collection exercise", collection_exercise_id=collection_exercise_id) return try: response.raise_for_status() except HTTPError: logger.error( "Error retrieving sample summaries linked to collection exercise", collection_exercise_id=collection_exercise_id, ) raise ApiError(response) # currently, we only want a single sample summary sample_summary_id = response.json()[0] logger.info( "Successfully retrieved linked sample summary", collection_exercise_id=collection_exercise_id, sample_summary_id=sample_summary_id, ) return sample_summary_id
def update_collection_exercise_period(collection_exercise_id, period): logger.info("Updating collection exercise period", collection_exercise_id=collection_exercise_id, period=period) header = {"Content-Type": "text/plain"} url = f'{app.config["COLLECTION_EXERCISE_URL"]}/collectionexercises/{collection_exercise_id}/exerciseRef' response = requests.put(url, headers=header, data=period, auth=app.config["BASIC_AUTH"]) try: response.raise_for_status() except HTTPError: if response.status_code == 404: logger.error( "Error retrieving collection exercise", collection_exercise_id=collection_exercise_id, period=period ) else: logger.error( "Failed to update collection exercise period", collection_exercise_id=collection_exercise_id, period=period, ) raise ApiError(response) logger.info( "Successfully updated collection exercise period", collection_exercise_id=collection_exercise_id, period=period )
def create_collection_exercise(survey_id, survey_name, user_description, period, eq_version=None): logger.info("Creating a new collection exercise for", survey_id=survey_id, survey_name=survey_name) header = {"Content-Type": "application/json"} url = f'{app.config["COLLECTION_EXERCISE_URL"]}/collectionexercises' collection_exercise_details = { "surveyId": survey_id, "name": survey_name, "userDescription": user_description, "exerciseRef": period, } if eq_version != "": collection_exercise_details["eqVersion"] = eq_version response = requests.post( url, json=collection_exercise_details, headers=header, auth=app.config["BASIC_AUTH"], ) try: response.raise_for_status() except HTTPError: logger.exception("Error creating new collection exercise", survey_id=survey_id, survey_name=survey_name) raise ApiError(response) logger.info("Successfully created collection exercise for", survey_id=survey_id, survey_name=survey_name)
def download_report(collection_exercise_id, survey_id): logger.info( "Downloading response chasing report", collection_exercise_id=collection_exercise_id, survey_id=survey_id ) url = ( f"{app.config['REPORT_URL']}" f"/reporting-api/v1/response-chasing/download-report/{collection_exercise_id}/{survey_id}" ) response = requests.get(url) try: response.raise_for_status() except HTTPError: logger.error( "Error retrieving collection exercise", collection_exercise_id=collection_exercise_id, survey_id=survey_id ) raise ApiError(response) logger.info( "Successfully downloaded response chasing report", collection_exercise_id=collection_exercise_id, survey_id=survey_id, ) return response
def create_collection_exercise_event(collection_exercise_id, tag, timestamp): logger.info("Creating event date", collection_exercise_id=collection_exercise_id, tag=tag) url = f'{app.config["COLLECTION_EXERCISE_URL"]}/collectionexercises/{collection_exercise_id}/events' formatted_timestamp = timestamp.isoformat(timespec="milliseconds") response = requests.Session().post( url=url, auth=app.config["BASIC_AUTH"], json={"tag": tag, "timestamp": formatted_timestamp} ) try: response.raise_for_status() except HTTPError: if response.status_code == 400: response_content = response.content.decode() response_json = json.loads(response_content) logger.error( "Bad request creating event", message=response_json["error"]["message"], collection_exercise_id=collection_exercise_id, tag=tag, timestamp=formatted_timestamp, status=response.status_code, ) return response_json["error"]["message"] logger.error( "Failed to create collection exercise event", collection_exercise_id=collection_exercise_id, tag=tag ) raise ApiError(response) logger.info( "Successfully created collection exercise event", collection_exercise_id=collection_exercise_id, tag=tag ) return None
def update_collection_exercise_user_description(collection_exercise_id, user_description): logger.info('Updating collection exercise user description', collection_exercise_id=collection_exercise_id) header = {'Content-Type': "text/plain"} url = f'{app.config["COLLECTION_EXERCISE_URL"]}/collectionexercises/{collection_exercise_id}/userDescription' response = requests.put(url, headers=header, data=user_description, auth=app.config['COLLECTION_EXERCISE_AUTH']) try: response.raise_for_status() except HTTPError: if response.status_code == 404: logger.error('Error retrieving collection exercise', collection_exercise_id=collection_exercise_id) else: logger.error( 'Failed to update collection exercise user description', collection_exercise_id=collection_exercise_id) raise ApiError(response) logger.info('Successfully updated collection exercise user description', collection_exercise_id=collection_exercise_id)
def get_business_by_party_id(business_party_id: str, collection_exercise_id=None): logger.info("Retrieving business party", business_party_id=business_party_id, collection_exercise_id=collection_exercise_id) url = f'{app.config["PARTY_URL"]}/party-api/v1/businesses/id/{business_party_id}' params = { "collection_exercise_id": collection_exercise_id, "verbose": True } response = requests.get(url, params=params, auth=app.config["BASIC_AUTH"]) try: response.raise_for_status() except requests.exceptions.HTTPError: log_level = logger.warning if response.status_code in ( 400, 404) else logger.exception log_level( "Error retrieving business party", business_party_id=business_party_id, collection_exercise_id=collection_exercise_id, ) raise ApiError(response) logger.info( "Successfully retrieved business party", business_party_id=business_party_id, collection_exercise_id=collection_exercise_id, ) return response.json()
def get_collection_instruments_by_classifier(survey_id=None, collection_exercise_id=None, ci_type=None): logger.info('Retrieving collection instruments', survey_id=survey_id, collection_exercise_id=collection_exercise_id, ci_type=ci_type) url = (f'{app.config["COLLECTION_INSTRUMENT_URL"]}' f'/collection-instrument-api/1.0.2/collectioninstrument') classifiers = _build_classifiers(collection_exercise_id, survey_id, ci_type) response = requests.get(url, auth=app.config['COLLECTION_INSTRUMENT_AUTH'], params={'searchString': json.dumps(classifiers)}) try: response.raise_for_status() except requests.exceptions.HTTPError: logger.error('Error retrieving collection instruments') raise ApiError(response) logger.info('Successfully retrieved collection instruments', survey_id=survey_id, collection_exercise_id=collection_exercise_id, ci_type=ci_type) return response.json()
def get_collection_exercises_by_survey(survey_id): """ Gets all the collection exercises for an individual survey :param survey_id: A uuid that represents the survey in the survey service. :type survey_id: str :raises ApiError: Raised when collection exercise services returns a 4xx or 5xx status. :return: A list of collection exercises for the survey """ logger.info("Retrieving collection exercises", survey_id=survey_id) url = f'{app.config["COLLECTION_EXERCISE_URL"]}/collectionexercises/survey/{survey_id}' response = requests.get(url, auth=app.config["BASIC_AUTH"]) if response.status_code == 204: return [] try: response.raise_for_status() except HTTPError: logger.exception("Failed to retrieve collection exercises by survey", survey_id=survey_id) raise ApiError(response) logger.info("Successfully retrieved collection exercises by survey", survey_id=survey_id) return response.json()
def link_collection_instrument_to_survey(survey_uuid, eq_id, form_type): """This links an eq_id and form_type to a survey so they can be used by a collection exercise. This only relates to EQ surveys. These values map to filenames of schemas in EQ. An example of this would be stocks_0001.json. The eq_id here would be 'stocks', the form_type would be '0001' and the survey_uuid would match the stocks survey in the survey service. :param survey_uuid: A uuid of a survey :type survey_uuid: str :param eq_id: The first part of an eq filename, typically the name of the survey :type eq_id: str :param form_type: The formtype of the collection instrument and the second part of the eq filename :type form_type: str """ logger.info('Linking collection instrument to survey', survey_uuid=survey_uuid, eq_id=eq_id, form_type=form_type) url = f'{app.config["COLLECTION_INSTRUMENT_URL"]}/collection-instrument-api/1.0.2/upload' payload = { "survey_id": survey_uuid, "classifiers": f'{{"form_type":"{form_type}","eq_id":"{eq_id}"}}', } response = requests.post(url, params=payload, auth=app.config['BASIC_AUTH']) try: response.raise_for_status() except requests.exceptions.HTTPError: logger.error('Failed to link collection instrument to survey', survey_uuid=survey_uuid, eq_id=eq_id, form_type=form_type, status=response.status_code, exc_info=True) raise ApiError(response) logger.info('Successfully linked collection instrument to survey', survey_uuid=survey_uuid, eq_id=eq_id, form_type=form_type)
def change_respondent_status(respondent_id, change_flag): if change_flag == "ACTIVE": logger.info("Changing respondent status", respondent_id=respondent_id, change_flag=change_flag) url = f'{app.config["PARTY_URL"]}/party-api/v1/respondents/edit-account-status/{respondent_id}' enrolment_json = { "respondent_id": respondent_id, "status_change": change_flag } response = requests.put(url, json=enrolment_json, auth=app.config["BASIC_AUTH"]) try: response.raise_for_status() except HTTPError: logger.error("Failed to change respondent status", respondent_id=respondent_id, change_flag=change_flag) raise ApiError(response) logger.info("Successfully changed respondent status", respondent_id=respondent_id, change_flag=change_flag) else: logger.error("Incorrect change_flag given", respondent_id=respondent_id, change_flag=change_flag) raise ValueError("Incorrect change_flag given")
def generate_new_enrolment_code(case_id): """Generates a new enrolment code from a case id by hitting the case service :param case_id: A case_id """ logger.info("Generating new enrolment code", case_id=case_id) url = f'{app.config["CASE_URL"]}/cases/{case_id}/events' case_event = { "description": "Generating new enrolment code", "category": "GENERATE_ENROLMENT_CODE", "subCategory": None, "createdBy": "ROPS", } response = requests.post(url, json=case_event, auth=app.config["BASIC_AUTH"]) try: response.raise_for_status() except requests.exceptions.HTTPError: logger.error("Failed to generate new enrolment code", case_id=case_id) raise ApiError(response) logger.info("Successfully generated new enrolment code", case_id=case_id)
def link_sample_summary_to_collection_exercise(collection_exercise_id, sample_summary_id): logger.info( "Linking sample summary to collection exercise", collection_exercise_id=collection_exercise_id, sample_summary_id=sample_summary_id, ) url = f'{app.config["COLLECTION_EXERCISE_URL"]}/collectionexercises/link/{collection_exercise_id}' # Currently we only need to link a single sample to a single collection exercise payload = {"sampleSummaryIds": [str(sample_summary_id)]} response = requests.put(url, auth=app.config["BASIC_AUTH"], json=payload) try: response.raise_for_status() except HTTPError: logger.error( "Error retrieving collection exercise", collection_exercise_id=collection_exercise_id, sample_summary_id=sample_summary_id, ) raise ApiError(response) logger.info( "Successfully linked sample summary with collection exercise", collection_exercise_id=collection_exercise_id, sample_summary_id=sample_summary_id, ) return response.json()
def get_pending_surveys_by_party_id(respondent_party_id): """ Gets pending surveys list against the originator respondent party uuid :param respondent_party_id: respondent party id :type respondent_party_id: uuid :return: list of pending surveys :rtype: list """ logger.info("Retrieving pending surveys", respondent_party_id=respondent_party_id) url = f'{app.config["PARTY_URL"]}/party-api/v1/pending-surveys/originator/{respondent_party_id}' response = requests.get(url, auth=app.config["BASIC_AUTH"]) try: response.raise_for_status() except requests.exceptions.HTTPError: log_level = logger.warning if response.status_code in ( 400, 404) else logger.exception log_level("Error retrieving pending surveys", respondent_party_id=respondent_party_id) if response.status_code == 404: return {} raise ApiError(response) logger.info("Successfully retrieved pending surveys", respondent_party_id=respondent_party_id) return response.json()
def test_new_api_error_contains_correct_data(self): exception = ApiError( fake_response(url='TESTURL', status_code=318, text='TESTMSG', exception='EXCEPTION')) self.assertEqual(exception.url, 'TESTURL') self.assertEqual(exception.status_code, 318) self.assertEqual(exception.message, 'TESTMSG')
def get_survey_ci_classifier(survey_id): logger.info('Retrieving classifier type selectors', survey_id=survey_id) url = f'{app.config["SURVEY_URL"]}/surveys/{survey_id}/classifiertypeselectors' response = requests.get(url, auth=app.config['SURVEY_AUTH']) if response.status_code == 204: logger.error('classifiers missing for survey', survey_id=survey_id) raise ApiError(response) try: response.raise_for_status() except HTTPError: logger.error('Error classifier type selectors', survey_id=survey_id) raise ApiError(response) logger.info('Successfully retrieved classifier type selectors', survey_id=survey_id) classifier_type_selectors = response.json() ci_selector = None for selector in classifier_type_selectors: if selector['name'] == "COLLECTION_INSTRUMENT": ci_selector = selector break logger.info('Retrieving classifiers for CI selector type', survey_id=survey_id, ci_selector=ci_selector['id']) url = f'{app.config["SURVEY_URL"]}/surveys/{survey_id}/classifiertypeselectors/{ci_selector["id"]}' response = requests.get(url, auth=app.config['SURVEY_AUTH']) try: response.raise_for_status() except HTTPError: logger.error('Error retrieving classifiers for CI selector type', survey_id=survey_id, ci_selector=ci_selector['id']) raise ApiError(response) logger.info('Successfully retrieved classifiers for CI selector type', survey_id=survey_id, ci_selector=ci_selector['id']) return response.json()
def create_survey(survey_ref, short_name, long_name, legal_basis, survey_mode): logger.info( "Creating new survey", survey_ref=survey_ref, short_name=short_name, long_name=long_name, legal_basis=legal_basis, ) url = f'{app.config["SURVEY_URL"]}/surveys' survey_details = { "surveyRef": survey_ref, "shortName": short_name, "longName": long_name, "legalBasisRef": legal_basis, "surveyType": "Business", "surveyMode": survey_mode, "classifiers": [ { "name": "COLLECTION_INSTRUMENT", "classifierTypes": ["FORM_TYPE"] }, { "name": "COMMUNICATION_TEMPLATE", "classifierTypes": ["LEGAL_BASIS", "REGION"] }, ], "eqVersion": "v2" if survey_mode != "SEFT" else "", } response = requests.post(url, json=survey_details, auth=app.config["BASIC_AUTH"]) try: response.raise_for_status() except HTTPError: logger.error( "Error creating new survey", survey_ref=survey_ref, short_name=short_name, long_name=long_name, legal_basis=legal_basis, survey_mode=survey_mode, status_code=response.status_code, ) raise ApiError(response) logger.info("Successfully created new survey", survey_ref=survey_ref)
def update_survey_details(survey_ref, short_name, long_name): logger.info('Updating survey details', survey_ref=survey_ref) url = f'{app.config["SURVEY_URL"]}/surveys/ref/{survey_ref}' survey_details = {"ShortName": short_name, "LongName": long_name} response = requests.put(url, json=survey_details, auth=app.config['SURVEY_AUTH']) if response.status_code == 404: logger.warning('Error retrieving survey details', survey_ref=survey_ref) raise ApiError(response) try: response.raise_for_status() except HTTPError: logger.error('Failed to update survey details', survey_ref=survey_ref) raise ApiError(response) logger.info('Successfully updated survey details', survey_ref=survey_ref)