-
Notifications
You must be signed in to change notification settings - Fork 211
/
flask_app.py
executable file
·134 lines (107 loc) · 4.08 KB
/
flask_app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env python3
import logging
from fhirclient import client
from fhirclient.models.medication import Medication
from fhirclient.models.medicationrequest import MedicationRequest
from flask import Flask, request, redirect, session
# app setup
smart_defaults = {
'app_id': 'my_web_app',
'api_base': None,
'redirect_uri': 'http://localhost:8000/fhir-app/',
}
app = Flask(__name__)
def _save_state(state):
session['state'] = state
def _get_smart():
state = session.get('state')
if state:
return client.FHIRClient(state=state, save_func=_save_state)
elif smart_defaults['api_base']:
return client.FHIRClient(settings=smart_defaults, save_func=_save_state)
else:
return None
def _logout():
if 'state' in session:
smart = _get_smart()
smart.reset_patient()
def _reset():
if 'state' in session:
del session['state']
def _get_prescriptions(smart):
search = MedicationRequest.where({'patient': smart.patient_id})
return list(search.perform_resources_iter(smart.server))
def _get_medication_by_ref(ref, smart):
med_id = ref.split("/")[1]
return Medication.read(med_id, smart.server).code
def _med_name(med):
if med.coding:
name = next((coding.display for coding in med.coding if coding.system == 'http://www.nlm.nih.gov/research/umls/rxnorm'), None)
if name:
return name
if med.text and med.text:
return med.text
return "Unnamed Medication(TM)"
def _get_med_name(prescription, client=None):
if prescription.medicationCodeableConcept is not None:
med = prescription.medicationCodeableConcept
return _med_name(med)
elif prescription.medicationReference is not None and client is not None:
med = _get_medication_by_ref(prescription.medicationReference.reference, client)
return _med_name(med)
else:
return 'Error: medication not found'
# views
@app.route('/')
@app.route('/index.html')
def index():
""" The app's main page.
"""
smart = _get_smart()
body = "<h1>Hello</h1>"
if smart is None:
body += """<p>Please edit flask_app.py and set a value for 'api_base', """
body += """pointing at your own OAuth-capable server.</p>"""
# "ready" may be true but the access token may have expired, making smart.patient = None
elif smart.ready and smart.patient is not None:
name = smart.human_name(smart.patient.name[0] if smart.patient.name and len(smart.patient.name) > 0 else 'Unknown')
# generate simple body text
body += "<p>You are authorized and ready to make API requests for <em>{0}</em>.</p>".format(name)
pres = _get_prescriptions(smart)
if pres:
body += "<p>{0} prescriptions: <ul><li>{1}</li></ul></p>".format("His" if 'male' == smart.patient.gender else "Her", '</li><li>'.join([_get_med_name(p,smart) for p in pres]))
else:
body += "<p>(There are no prescriptions for {0})</p>".format("him" if 'male' == smart.patient.gender else "her")
body += """<p><a href="/logout">Change patient</a></p>"""
else:
auth_url = smart.authorize_url
if auth_url is not None:
body += """<p>Please <a href="{0}">authorize</a>.</p>""".format(auth_url)
else:
body += """<p>Running against a no-auth server, nothing to demo here. """
body += """<p><a href="/reset" style="font-size:small;">Reset</a></p>"""
return body
@app.route('/fhir-app/')
def callback():
""" OAuth2 callback interception.
"""
smart = _get_smart()
try:
smart.handle_callback(request.url)
except Exception as e:
return """<h1>Authorization Error</h1><p>{0}</p><p><a href="/">Start over</a></p>""".format(e)
return redirect('/')
@app.route('/logout')
def logout():
_logout()
return redirect('/')
@app.route('/reset')
def reset():
_reset()
return redirect('/')
# start the app
if '__main__' == __name__:
import flaskbeaker
flaskbeaker.FlaskBeaker.setup_app(app)
logging.basicConfig(level=logging.DEBUG)
app.run(debug=True, port=8000)