-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathEMRBapp.py
151 lines (135 loc) · 5.54 KB
/
EMRBapp.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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import os
import json
from turtle import update
from urllib import request
import requests
from web3 import Web3
from pathlib import Path
from dotenv import load_dotenv
import streamlit as st
import time
from pinata import pin_file_to_ipfs, pin_json_to_ipfs, convert_data_to_json, hash_json_metadata
load_dotenv()
# Define and connect a new Web3 provider
w3 = Web3(Web3.HTTPProvider(os.getenv("WEB3_PROVIDER_URI")))
# Loads contract using cache and connect ausing ddress and ABI
@st.cache(allow_output_mutation=True)
def load_contract():
with open(Path('./contracts/compiled/emrblocks_abi.json')) as f:
contract_abi = json.load(f)
contract_address = os.getenv("SMART_CONTRACT_ADDRESS")
contract = w3.eth.contract(
address=contract_address,
abi=contract_abi
)
return contract
contract = load_contract()
# IPFS helper functions
def pin_patient(patientName,dateOfBirth,gender,weight,height, patientImage):
#pin patient image
ipfs_file_hash = pin_file_to_ipfs(patientImage.getvalue())
#build an patient metadata JSON file
patientJSON = {
'name': patientName,
'DOB': dateOfBirth,
'gender': gender,
'weight': weight,
'height': height
}
# json_data = convert_data_to_json(patientJSON)
payload = {
'pinataOptions': {
'cidVersion': 1
},
'pinataMetadata': {
'name': f'{patientName} EMRB',
'keyvalues': patientJSON
},
'pinataContent': {
'image': f'https://ipfs.io/ipfs/{ipfs_file_hash}'
}
}
json_data = json.dumps(payload)
#pin patient json file
ipfs_json_hash = pin_json_to_ipfs(json_data)
return ipfs_json_hash
### Streamlit Frontend
# Account and Function selection
st.sidebar.title('Blockchain EMR System')
st.sidebar.write('Choose an account to get started')
accounts = w3.eth.accounts
address = st.sidebar.selectbox('Select Account', options=accounts)
st.markdown('---')
st.sidebar.write('Select a function from the dropdown menu below')
menu = ['Register Patient', 'Update Patient Info', 'View Patient Info']
function = st.sidebar.selectbox('Menu', options=menu)
# Register New Patient
if function == 'Register Patient':
st.markdown('## Register New Patient')
patientName = st.text_input('Enter patient name')
dateOfBirth = st.date_input('Enter patient date of birth')
gender = st.selectbox('Select gender', options=['male','female'])
weight = st.number_input('Insert patient weight in lbs', min_value=0, step=1)
height = st.number_input('Insert patient height in inches', min_value=0, step=1)
patientImage = st.file_uploader('Upload patient picture', type=["jpg", "jpeg", "png"])
if st.button('Register Patient'):
patient_ipfs_hash = pin_patient(patientName,str(dateOfBirth),gender,weight,height, patientImage)
patient_uri = f'ipfs://{patient_ipfs_hash}'
tx_hash = contract.functions.registerPatient(
address,
patientName,
int(time.mktime(dateOfBirth.timetuple())),
patient_uri
).transact({'from': address, 'gas': 1000000})
receipt = w3.eth.waitForTransactionReceipt(tx_hash)
st.write("Transaction receipt mined:")
st.write(dict(receipt))
st.write("You can view the pinned patient record with the following IPFS Gateway Link")
st.markdown(f"[EMRB IPFS Gateway Link](https://ipfs.io/ipfs/{patient_ipfs_hash})")
st.markdown("---")
# Update Patient Info
elif function == 'Update Patient Info':
#choose patient to be updated
st.title('Update Patient Info')
tokens = contract.functions.balanceOf(address).call()
token_id = st.selectbox("Select which patient's info you would like to update", list(range(tokens)))
retrieve_uri = contract.functions.tokenURI(token_id).call()
PinHash = retrieve_uri.replace('ipfs://', '')
patientName = st.text_input('Enter patient name')
# Update a patients weight
st.markdown('## Update Patients Weight')
newWeight = st.number_input('Insert new patient weight in lbs', min_value=0, step=1)
if st.button('Update Weight'):
payload = json.dumps({
"ipfsPinHash": PinHash,
"name": f'{patientName} EMRB',
"keyvalues": {
"weight": newWeight
}
})
update_result = hash_json_metadata(payload)
st.write(f"Patient weight has been updated: {update_result}")
st.markdown('---')
# Update a patients height
st.markdown('## Update Patients Height')
newHeight = st.number_input('Insert new patient height in inches', min_value=0, step=1)
if st.button('Update Height'):
payload = json.dumps({
"ipfsPinHash": PinHash,
"name": f'{patientName} EMRB',
"keyvalues": {
"height": newHeight
}
})
update_result = hash_json_metadata(payload)
st.write(f"Patient height has been updated: {update_result}")
elif function == 'View Patient Info':
st.title('View Patient Info')
tokens = contract.functions.totalSupply().call()
token_id = st.selectbox("Select your Patient ID", list(range(tokens)))
if st.button("Retrieve Patient Info"):
retrieve_uri = contract.functions.tokenURI(token_id).call()
PinHash = retrieve_uri.replace('ipfs://', '')
# st.write(requests.get(url='https://ipfs.io/ipfs/'+PinHash).text)
st.write("You can view the patient record with the following IPFS Gateway Link")
st.markdown(f"[EMRB IPFS Gateway Link](https://ipfs.io/ipfs/{PinHash})")