API:Исследователь:Example

Материал из КардиоКВАРК
Перейти к: навигация, поиск
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# example.py
# функции API для роли Исследователь
# Copyright (C) CardioQVARK 2015-2016, All rights reserved

import datetime
import json
import re
import ssl
import urllib
from http.client import HTTPSConnection

api = 'b-api.cardioqvark.ru'     # сервер API
api_port = 1443
my_id = 'XXXX'
my_pass = 'YYYYYYYYYYYYYYYY'


# HTTPS запрос с проверкой статуса ответа
def request(host, method, url, context, status, body = None, headers = {}, port = api_port):
	conn = HTTPSConnection(host, port, context = context, timeout = 10)
	conn.request(method, url, body = body, headers = headers)
	resp = conn.getresponse()
	print(method + ' ' + url + ': ' + str(resp.status))
	assert status == resp.status
	head = resp.getheaders()
	body = resp.read()
	conn.close()
	return (head, body)


if __name__ == '__main__':

	# SSL контекст без клиентского сертификата
	nobody = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)

	# получаем корневой сертификат
	(head, ca) = request(api, 'GET', '/ca?media=PEM', nobody, 200)
	assert len(ca) > 0

	# получаем сертификат Исследователя
	(head, pem) = request(api, 'POST', '/account?media=PEM', nobody, 200, '{"id":' + my_id + ',"password":"' + my_pass + '","role":3}')
	assert len(pem) > 0

	# формируем файл с цепочкой сертификатов для ssl.SSLContext
	f = open('researcher.pem', 'wb'); f.write(pem); f.write(ca); f.close();


	# далее работаем только с файлом сертификата

	# SSL контекст Исследователя
	con = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
	con.load_cert_chain('researcher.pem')

	# получаем настройки
	(head, body) = request(api, 'GET', '/settings', con, 200)
	j = json.loads(body.decode('utf-8'))
	assert j['role'] == 3
	api = j['api'][0] # далее работаем с первым сервером из кластера API
	g1 = j['cloud'][0] # берем первый сервер в облаке

	# читаем данные кардиограммы
	cardiogram_id = '7612'
	(head, body) = request(api, 'GET', '/cardiogram/' + cardiogram_id, con, 200)
	j = json.loads(body.decode('utf-8'))
	assert len(j) == 1
	assert cardiogram_id == str(j[0]['id'])
	patient_id = str(j[0]['accountId'])
	print(patient_id)

	# профиль пациента
	(head, body) = request(api, 'GET', '/profile/' + patient_id, con, 200)
	j = json.loads(body.decode('utf-8')) # массив профилей
	assert len(j) == 1
	profile = j[0]
	assert patient_id == str(profile['id'])
	assert not 'lastname' in profile # без персональных данных
	if 'birthdate' in profile:
		patient_birthdate = datetime.datetime.fromtimestamp(profile['birthdate']).strftime('%Y-%m-%d')
	else:
		patient_birthdate = None
	patient_gender = None
	if 'gender' in profile:
		if profile['gender'] == 1:
			patient_gender = 'М'
		elif profile['gender'] == 2:
			patient_gender = 'Ж'

	# токен на чтение кардиограммы (1 КГц фильтрованная)
	(head, body) = request(api, 'GET', '/token?id=' + cardiogram_id + '&type=2', con, 200)
	j = json.loads(body.decode('utf-8'))
	token = j['token']

	# читаем файл из облака (порт 443)
	# context = nоbody при работе с облаком
	(head, body) = request(g1, 'GET', '/cardiogram/' + cardiogram_id + '?type=2', nobody, 200, headers = {
		'Authorization': 'Token ' + token
	}, port = 443)
	assert len(body) > 0

	# получаем расчет ВСР
	(head, body) = request(api, 'GET', '/analysis/' + cardiogram_id + '/vsr', con, 200)
	j = json.loads(body.decode('utf-8'))
	assert len(j) == 1
	vsra = j[0]
	assert cardiogram_id == str(vsra['cardiogramId'])
	assert 'vsr' == vsra['methodId']

	# описание метода ВСР
	(head, body) = request(api, 'GET', '/method/vsr', con, 200)
	j = json.loads(body.decode('utf-8'))
	assert len(j) == 1
	vsrm = j[0]

	# покажем результат
	if not 'error' in vsra or vsra['error'] == 0:
		print('###################################')
		if patient_birthdate != None:
			print('дата рожд.: ' + patient_birthdate)
		if patient_gender != None:
			print('пол: ' + patient_gender)
		desc = {}
		for v in vsrm['fields']:
			desc[v['id']] = v
		for v in vsra['values']:
			id = v['id']
			if id == 'psd' or id == 'spline': # массивы для графиков - пропускаем
				continue
			text = '[' + id + '] ' + desc[id]['name'] + ': ' + str(v['value'])
			if 'unit' in desc[id]:
				text += ' (' + desc[id]['unit'] + ')'
			if 'grade' in v:
				text += ', оценка: ' + str(v['grade'])
				if 'grades' in desc[id]:
					for g in desc[id]['grades']:
						if g['value'] == v['grade']:
							text += ' - ' + g['text']
							break
			print(text)
		print('###################################')

	# первые 10 кардиограмм
	(head, body) = request(api, 'GET', '/cardiogram?order=id', con, 200, headers = {'Range': 'items=0-9'})
	j = json.loads(body.decode('utf-8'))
	assert len(j) == 10
	max_id = 0
	for v in j:
		if v['id'] > max_id:
			max_id = v['id']
	# общее кол-во кардиограмм (не было фильтрации в запросе)
	total = None
	for (k, v) in head:
		if 'content-range' == k.lower():
			m = re.match(r'items \d+-\d+/(\d+)', v)
			total = int(m.group(1))
	print('total: ' + str(total))

	# следующие 10 (длина блока от 10 до 100)
	(head, body) = request(api, 'GET', '/cardiogram?order=id&minId=' + str(max_id + 1), con, 200, headers = {'Range': 'items=0-9'})
	# или
	(head, body) = request(api, 'GET', '/cardiogram?order=id', con, 200, headers = {'Range': 'items=10-19'})

	# поиск пациента (кириллицу -> в urlencode)
	search = urllib.parse.quote('панкреатит')
	(head, body) = request(api, 'GET', '/profile?search=' + search, con, 200, headers = {'Range': 'items=0-99'})
	j = json.loads(body.decode('utf-8'))
	print(len(j))

	# поиск по болезням пациента (код по МКБ-10))
	(head, body) = request(api, 'GET', '/event?type=1&code=E10', con, 200)
	j = json.loads(body.decode('utf-8'))
	print(len(j))

	# поиск по принимаемым лекарствам
	(head, body) = request(api, 'GET', '/event?type=2&code=' + urllib.parse.quote('Релиум'), con, 200)
	j = json.loads(body.decode('utf-8'))             
	print(len(j))

	# кардиограммы пациентов, удаленные начиная с minTs (размер страницы 100-1000)
	(head, body) = request(api, 'GET', '/cardiogram/deleted?minTs=0', con, 200, headers = {'Range': 'items=0-199'})
	j = json.loads(body.decode('utf-8'))
	for c in j:
		print('cardiogram deleted: {0}'.format(c['id']))