def employees(self) -> List[dict]: r = requests.get(f"{self._baseUrl}/employees") if r.status_code != 200: raise ApiError(f"Endpoint responded with an error: {r.status_code}") else: response = r.json() if 'data' not in response: raise ApiError("Unexpected response contents for /employees") data = response['data'] return data
def wrapper(self, url, *args, **kwargs): kwargs['headers'] = { 'Authorization': 'Token {}'.format(self._token), 'Content-Type': 'application/json' } kwargs['verify'] = self._verify url = self._base_url + url try: response = func(self, url, *args, **kwargs) except requests.RequestException as e: raise ApiConnectionError('Connection to Management Console failed', e) if response.status_code >= 400: try: message = response.json().get('message', '') except JSONDecodeError: message = response.text if response.status_code == 401: raise ApiUnauthorizedError(message) raise ApiError(message) return response
def send_message(): from models import Patient, Doctor, Message from errors import ApiError, ErrorCodes from tools import ok request_body = request.json patient_id = request_body["patient_id"] doctor_id = request_body["doctor_id"] from_patient = request_body["from_patient"] message_text = request_body["message_text"] patient = db.session.query(Patient).filter( Patient.id == patient_id).first() doctor = db.session.query(Doctor).filter(Doctor.id == doctor_id).first() if not patient or not doctor: return ApiError( status_code=ErrorCodes.BAD_REQUEST, message="Patient or doctor does not exist. Unable to send message" ).to_json() message = Message() message.date_sent = int(time.time()) message.from_patient = from_patient message.message_text = message_text message.doctor_id = doctor_id message.patient_id = patient_id patient.messages.append(message) db.session.commit() return ok(message.to_json())
def get_providers(self) -> tuple: url = urllib.parse.urljoin(self.__base_url, 'providers') response = requests.get(url, auth=self.__auth, timeout=20) if response.status_code != HTTPStatus.OK: raise ApiError(f"failed to query for providers {response}") payload = json.loads(response.content.decode('utf-8')) return tuple(self._to_provider(item) for item in payload)
def get_patient_data_in_time_window(last_name, first_name): from models import Patient, ActivityType, HeartRate, Steps from sqlalchemy import func from errors import ApiError, ErrorCodes from tools import ok start_unix_time = request.args.get("start") end_unix_time = request.args.get("end") if not start_unix_time or not end_unix_time: return ApiError( status_code=ErrorCodes.BAD_REQUEST, message= "Must include unix timestamps in query parameters start and end." ).to_json() try: start_unix_time = int(start_unix_time) end_unix_time = int(end_unix_time) except ValueError: return ApiError( status_code=ErrorCodes.BAD_REQUEST, message="Unix timestamps given in start and end must be integers" ).to_json() finally: patient = db.session.query(Patient).filter( func.lower(Patient.last_name) == func.lower(last_name) and func.lower(Patient.first_name) == func.lower(first_name)).first() activity_measures = patient.activity_type_measures.filter( (ActivityType.unix_timestamp >= start_unix_time) & (ActivityType.unix_timestamp <= end_unix_time)).all() heart_rates = patient.heart_rate_measures.filter( (HeartRate.unix_timestamp >= start_unix_time) & (HeartRate.unix_timestamp <= end_unix_time)).all() steps = patient.step_measures.filter( (Steps.unix_timestamp >= start_unix_time) & (Steps.unix_timestamp <= end_unix_time)).all() patient.activity_type_measures = activity_measures patient.heart_rate_measures = heart_rates patient.step_measures = steps return ok(patient.to_json())
def get(self, only_current: bool = True) -> tuple: url_end = "notifications?only_current=" + 'true' if only_current else 'false' url = urllib.parse.urljoin(self.__base_url, url_end) r = requests.get(url, auth=self.__auth, timeout=5) if r.status_code != HTTPStatus.OK: raise ApiError(f"failed to query for notifications {r}") payload = json.loads(r.content.decode('utf-8')) return tuple( NotificationsRepo._to_notification(item) for item in payload)
def create(self, notif: Notification) -> uuid: url = urllib.parse.urljoin(self.__base_url, 'notifications') data = NotificationsRepo._from_notification(notif) r = requests.post(url, auth=self.__auth, json=data, timeout=20) if r.status_code != HTTPStatus.CREATED: raise ApiError(f"error while storing notification {r.content}") if 'Location' in r.headers: location = r.headers.get('Location') return location.split('/')[-1] return
def get_response(self, url): count = 0 while True: try: response = requests.get(url) if response.status_code == 200: break else: raise except: if count > 5: raise ApiError("Too many API failures %s" % url) time.sleep(10 * count) count += 1 continue return response
def _get_json(self, *args, **kwargs): r = self._get(*args, **kwargs) try: return r.json() except JSONDecodeError as e: raise ApiError('Response is not a json: {}. {}'.format(r.text, e))
def _create(self, *args, **kwargs): r = self._post(*args, **kwargs) try: return r.json()['id'] except JSONDecodeError as e: raise ApiError('Response is not a json: {}. {}'.format(r.text, e))
def compute_health_metrics_in_time_window(patient_id): from models import HeartRate from errors import ApiError, ErrorCodes from tools import ok start_unix_time = request.args.get("start") end_unix_time = request.args.get("end") if not start_unix_time or not end_unix_time: return ApiError( status_code=ErrorCodes.BAD_REQUEST, message= "Must include unix timestamps in query parameters start and end." ).to_json() try: start_unix_time = int(start_unix_time) end_unix_time = int(end_unix_time) except ValueError: return ApiError( status_code=ErrorCodes.BAD_REQUEST, message="Unix timestamps given in start and end must be integers" ).to_json() finally: payload = dict() # Produce a list of RR intervals based on time window rr_list = db.session.query(HeartRate).filter( (HeartRate.patient_id == patient_id) & (HeartRate.unix_timestamp >= start_unix_time) & (HeartRate.unix_timestamp <= end_unix_time)).with_entities( HeartRate.rr).all() rrs = [rr for rr_sublist in rr_list for rr in rr_sublist] if len(rrs) < 1: return ApiError( status_code=ErrorCodes.BAD_REQUEST, message="Insufficient RR intervals in time window {} to {}". format(start_unix_time, end_unix_time)).to_json() time_domain_measures = dict() non_linear_measures = dict() non_linear_measures["poincare"] = dict() def time_domain_worker(): [ann, sdnn, p_nn50, p_nn20, r_mssd] = timeDomain(rrs) time_domain_measures["ann"] = ann time_domain_measures["sdnn"] = sdnn time_domain_measures["pnn50"] = p_nn50 time_domain_measures["pnn20"] = p_nn20 time_domain_measures["rmssd"] = r_mssd def sample_entropy_worker(): try: r = 0.2 * np.std(rrs) non_linear_measures["sample_entropy"] = sampEn(rrs, 2, r) except ValueError: non_linear_measures["sample_entropy"] = 0.0 def dfa_worker(): non_linear_measures["dfa"] = dict() if len(rrs) > 0: upper_scale_limit = min(1000, len(rrs)) [scales, f, alpha] = scalingExponent(rrs, 5, upper_scale_limit, 20, 1, 2) non_linear_measures["dfa"]["scales"] = scales.tolist() non_linear_measures["dfa"][ "fluctuation_coefficients"] = f.tolist() non_linear_measures["dfa"]["alpha"] = alpha def poincare_coefficient(): coefficient = correlation_coef(rrs) non_linear_measures["poincare"][ "correlation_coefficient"] = coefficient def eclipse_fitting(): standard_deviations = eclipse_fitting_methods(rrs) non_linear_measures["poincare"]["standard_deviations"] = dict() non_linear_measures["poincare"]["standard_deviations"][ "sd1"] = standard_deviations["SD1"] non_linear_measures["poincare"]["standard_deviations"][ "sd2"] = standard_deviations["SD2"] non_linear_measures["poincare"]["rr1"] = rrs[:-1] non_linear_measures["poincare"]["rr2"] = rrs[1:] t1 = Thread(target=time_domain_worker) t2 = Thread(target=sample_entropy_worker) t3 = Thread(target=dfa_worker) t4 = Thread(target=poincare_coefficient) t5 = Thread(target=eclipse_fitting) threads = [t1, t2, t3, t4, t5] t1.start() t2.start() t3.start() t4.start() t5.start() for thread in threads: thread.join() payload["time_domain_measures"] = time_domain_measures payload["non_linear_measures"] = non_linear_measures return ok(payload)
def delete(self, notif_uuid: uuid) -> bool: url = urllib.parse.urljoin(self.__base_url, f"notifications/{notif_uuid}") r = requests.delete(url, auth=self.__auth, timeout=20) if r.status_code != HTTPStatus.NO_CONTENT: raise ApiError(f"error while deleting notification {r.content}")