DragandDropGroup commited on
Commit
38f2380
·
verified ·
1 Parent(s): 0b203f2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +55 -266
app.py CHANGED
@@ -1,290 +1,79 @@
1
  import streamlit as st
2
- import requests
3
- import json
4
  import web3
 
 
5
 
6
- abi = [{"anonymous":False,"inputs":[{"indexed":False,"internalType":"string","name":"ipfsHash","type":"string"}],"name":"Store","type":"event"},{"inputs":[],"name":"getHashes","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"storeHash","outputs":[],"stateMutability":"nonpayable","type":"function"}]
7
- # function that uploads the results to ipfs
8
- def upload_json_to_ipfs(data):
9
- try:
10
- url = "https://api.pinata.cloud/pinning/pinJSONToIPFS"
11
-
12
- print("starting upload to ipfs")
13
-
14
- # check for JWT secret
15
- if "PinataJWT" not in st.secrets:
16
- st.write("No JWT secret found, please add your JWT in a secret titled \"PinataJWT\"")
17
- return
18
-
19
- jwt_token = st.secrets["PinataJWT"].strip()
20
- headers = {
21
- "Authorization": f"Bearer {jwt_token}",
22
- "Content-Type": "application/json"
23
- }
24
-
25
- # Convert Python dictionary to JSON string
26
- response = requests.post(url, headers=headers, json=data)
27
-
28
- if response.status_code == 200:
29
- # Print the IPFS hash from the successful response
30
- ipfs_hash = response.json().get("IpfsHash")
31
- return ipfs_hash
32
- else:
33
- st.write(f"Failed to upload JSON. Status code: {response.status_code}")
34
- st.write(response.text)
35
- return None
36
- except Exception as e:
37
- st.write(f"Error uploading to Pinata: {e}")
38
-
39
- # function that uploads to blockchain
40
- def upload_to_blockchain(hash):
41
- print("starting blockchain upload")
42
- w3 = web3.Web3(web3.HTTPProvider(st.secrets["infura"]))
43
-
44
- # create an instance of our contract
45
- contract = w3.eth.contract(address=st.secrets["ContractAddress"], abi = abi)
46
-
47
- # Call your function: 11155111 is Sepolia's id
48
- call_function = contract.functions.storeHash(hash).build_transaction({"chainId": 11155111,
49
- "from": st.secrets["EthWallet"],
50
- "nonce": w3.eth.get_transaction_count(st.secrets["EthWallet"])})
51
-
52
- # Sign transaction
53
- signed_tx = w3.eth.account.sign_transaction(call_function, private_key=st.secrets["pk"])
54
-
55
- # Send transaction
56
- send_tx = w3.eth.send_raw_transaction(signed_tx.raw_transaction)
57
-
58
- # Wait for transaction receipt
59
- tx_receipt = w3.eth.wait_for_transaction_receipt(send_tx)
60
-
61
- print("ETH Hash:")
62
- print(tx_receipt.logs[0].transactionHash.hex())
63
-
64
- return tx_receipt.logs[0].transactionHash.hex()
65
-
66
- def get_ipfs_hashes():
67
- w3 = web3.Web3(web3.HTTPProvider(st.secrets["infura"]))
68
-
69
- # Create an instance of the contract
70
- contract = w3.eth.contract(address=st.secrets["ContractAddress"], abi=abi)
71
-
72
- # Call the getHashes function
73
- try:
74
- ipfs_hashes = contract.functions.getHashes().call()
75
- return ipfs_hashes
76
- except Exception as e:
77
- st.write(f"Error retrieving hashes: {e}")
78
- return []
79
-
80
- def retreive_ipfs_hash_data(hashes):
81
- results = []
82
- for ipfs_hash in hashes:
83
- url = f"https://gateway.pinata.cloud/ipfs/{ipfs_hash}"
84
- try:
85
- response = requests.get(url)
86
- if response.status_code == 200:
87
- data = response.json()
88
- results.append({"hash": ipfs_hash, "data": data})
89
- else:
90
- results.append({"hash": ipfs_hash, "error": f"Failed to retrieve data (status {response.status_code})"})
91
- except Exception as e:
92
- results.append({"hash": ipfs_hash, "error": str(e)})
93
- return results
94
-
95
-
96
- # function that handles survey submission
97
- # sets up ipfs and blockchain
98
- def submission(survey_data):
99
- ipfs_hash = upload_json_to_ipfs(survey_data)
100
- if ipfs_hash:
101
- print("IPFS Upload Successful")
102
- print(ipfs_hash)
103
- upload_to_blockchain(ipfs_hash)
104
- total_number_pages = 4
105
- placeholder_buttons = None
106
-
107
- Q1_radio_options = ["Pizza","Burgers","Pasta","Hot Dogs"]
108
- Q3_radio_options = ["Yes","No"]
109
- Q4_radio_options = ["N/A", "Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree"]
110
-
111
-
112
- # Function that records radio element changes
113
- def radio_change(element, state, key):
114
- st.session_state[state] = element.index(st.session_state[key]) # Setting previously selected option
115
-
116
- def multi_change(element, state, key):
117
- st.session_state[state] = []
118
- for selected_option in st.session_state[key]:
119
- st.session_state[state].append(selected_option)
120
 
121
- # Function that disables the last button while data is uploaded to IPFS
122
- def button_disable():
123
- st.session_state['disabled'] = True
124
 
125
- def answer_change(state, key):
126
- st.session_state[state] = st.session_state[key]
127
 
128
- st.set_page_config(page_title='IPFS-Based Survey',)
129
- st.title('Survey Test')
130
 
 
131
  st.markdown("<style>.row-widget.stButton {text-align: center;}</style>", unsafe_allow_html=True)
132
- st.markdown("<style>.big-font {font-size:24px;}</style>", unsafe_allow_html=True)
133
-
134
-
135
- if "current_page" not in st.session_state:
136
- st.session_state["current_page"] = 1
137
- st.session_state["Q1"] = None
138
- st.session_state["Q2"] = None
139
- st.session_state["Q3"] = None
140
- st.session_state["Q4"] = None
141
- st.session_state["Q5"] = None
142
- st.session_state["disabled"] = False
143
-
144
- # Page 1; Video
145
- if st.session_state["current_page"] == 1:
146
-
147
- st.markdown("""<p style='font-size:18px ;'>Survey Test</p>""", unsafe_allow_html=True)
148
-
149
- st.markdown("""<p style='font-size:18px;'>This is a test survey</p>""", unsafe_allow_html=True)
150
- st.radio(label = "What is your favorite food?",
151
- options = Q1_radio_options,
152
- index = None if st.session_state["Q1"] == None else st.session_state["Q1"],
153
- key = 'Q1_radio',
154
- on_change = radio_change,
155
- args = (Q1_radio_options, "Q1", "Q1_radio",))
156
-
157
- st.markdown("""<style> div[class*="stRadio"] > label > div[data-testid="stMarkdownContainer"] > p {font-size: 18px;}</style> <br><br>""", unsafe_allow_html=True)
158
-
159
-
160
- st.text_area(label = "How is your day?",
161
- value= "" if st.session_state["Q2"] == None else st.session_state["Q2"],
162
- key = 'Q2_text',
163
- on_change = answer_change,
164
- args = ( "Q2", "Q2_text",))
165
 
166
- st.markdown("""<style> div[class*="stText"] > label > div[data-testid="stMarkdownContainer"] > p {font-size: 18px;}</style> <br><br>""", unsafe_allow_html=True)
 
 
167
 
168
 
169
- placeholder = st.empty()
 
170
 
171
- if st.button('Next', key='next_button_page_1'):
172
- all_answered = True
173
- if st.session_state["Q1"] == None or st.session_state["Q1"] == []:
174
- all_answered = False
175
- if st.session_state["Q2"] == None or st.session_state["Q2"] == []:
176
- all_answered = False
177
- if all_answered:
178
- st.session_state["current_page"] += 1
179
- st.rerun()
180
- else:
181
- with placeholder.container():
182
- st.warning("Please answer all the questions on this page.", icon="⚠️")
183
 
184
- st.progress(st.session_state["current_page"]/total_number_pages, text="Progress")
 
185
 
 
 
186
 
187
- elif st.session_state["current_page"] == 2:
 
188
 
189
- st.video("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
190
- st.markdown("""<p style='font-size:18px;'>Get RickRolled!</p>""", unsafe_allow_html=True)
191
- st.selectbox(label = "Was that a good joke?",
192
- options = Q3_radio_options,
193
- index = None if st.session_state["Q3"] == None else st.session_state["Q3"],
194
- key = 'Q3_radio',
195
- on_change = radio_change,
196
- args = (Q3_radio_options, "Q3", "Q3_radio",))
197
 
198
- st.markdown("""<style> div[class*="stSelectbox"] > label > div[data-testid="stMarkdownContainer"] > p {font-size: 18px;}</style> <br><br>""", unsafe_allow_html=True)
 
199
 
 
200
 
201
- placeholder = st.empty()
 
202
 
203
- col1, col2 = st.columns(2)
204
- with col1:
205
- if st.button('Back'):
206
- st.session_state["current_page"] -= 1
207
- st.rerun()
208
- with col2:
209
- if st.button('Next'):
210
- all_answered = True
211
- if st.session_state["Q3"] == None or st.session_state["Q3"] == []:
212
- all_answered = False
213
- if all_answered:
214
- st.session_state["current_page"] += 1
215
- st.rerun()
216
- else:
217
- with placeholder.container():
218
- st.warning("Please answer all the questions on this page.", icon="⚠️")
219
 
220
- st.progress(st.session_state["current_page"]/total_number_pages, text="Progress")
 
 
 
 
 
 
 
221
 
 
 
222
 
223
- elif st.session_state["current_page"] == 3:
 
 
 
224
 
225
- st.radio(label = "Miami is the best school.", # Likert
226
- options = Q4_radio_options,
227
- index = None if st.session_state["Q4"] == None else st.session_state["Q4"],
228
- key = 'Q4_radio',
229
- on_change = radio_change,
230
- args = (Q4_radio_options, "Q4", "Q4_radio",))
231
-
232
- st.markdown("""<style> div[class*="stRadio"] > label > div[data-testid="stMarkdownContainer"] > p {font-size: 18px;}</style> <br><br>""", unsafe_allow_html=True)
233
-
234
-
235
- if st.session_state["Q5"] == None:
236
- st.session_state["Q5"] = 50
237
- st.slider(label="How much do you enjoy food?",min_value=0,max_value=100,
238
- value= st.session_state["Q5"],
239
- key = "Q5_slider",
240
- on_change = answer_change,
241
- args = ("Q5", "Q5_slider",))
242
- st.markdown("""<style> div[class*="stSlider"] > label > div[data-testid="stMarkdownContainer"] > p {font-size: 18px;}</style> <br><br>""", unsafe_allow_html=True)
243
-
244
-
245
- placeholder = st.empty()
246
-
247
- col1, col2 = st.columns(2)
248
- with col1:
249
- if st.button('Back'):
250
- st.session_state["current_page"] -= 1
251
- st.rerun()
252
- with col2:
253
- if st.button('Next'):
254
- all_answered = True
255
- if st.session_state["Q4"] == None or st.session_state["Q4"] == []:
256
- all_answered = False
257
- if st.session_state["Q5"] == None or st.session_state["Q5"] == []:
258
- all_answered = False
259
- if all_answered:
260
- st.session_state["current_page"] += 1
261
- st.rerun()
262
- else:
263
- with placeholder.container():
264
- st.warning("Please answer all the questions on this page.", icon="⚠️")
265
-
266
- st.progress(st.session_state["current_page"]/total_number_pages, text="Progress")
267
-
268
-
269
- elif st.session_state["current_page"] == 4: # Last Page
270
- st.markdown('<p class="big-font">Thank you for participating! <br> Click on the button below to submit your answers. </p>', unsafe_allow_html=True)
271
- st.button('Submit Responses', disabled = st.session_state["disabled"], on_click = button_disable)
272
- if st.session_state["disabled"]:
273
- with st.spinner(r"$\textsf{\normalsize Storing data on IPFS and Ethereum. This operation might take a few minutes. Please wait to receive your confirmation code!}$"):
274
- try:
275
- response = {
276
- "Q1": Q1_radio_options[st.session_state["Q1"]],
277
- "Q2": st.session_state["Q2"],
278
- "Q3": st.session_state["Q3"],
279
- "Q4": st.session_state["Q4"],
280
- "Q5": st.session_state["Q5"],
281
- }
282
- submission(response)
283
- except Exception as e:
284
- print(e)
285
- st.error(f'An error ocurred. Here is the error message: {e}', icon="🚨")
286
-
287
- if st.button('Back'):
288
- st.session_state["current_page"] -= 1
289
- st.rerun()
290
- st.progress(st.session_state["current_page"]/total_number_pages, text="Progress")
 
1
  import streamlit as st
 
 
2
  import web3
3
+ import requests
4
+ import pandas
5
 
6
+ # Connect to the Sepolia Ethereum blockchain
7
+ w3 = web3.Web3(web3.HTTPProvider(st.secrets["infura"]))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
+ # Variables
10
+ ABI = '[ { "anonymous": false, "inputs": [ { "indexed": false, "internalType": "string", "name": "data", "type": "string" } ], "name": "Store", "type": "event" }, { "inputs": [ { "internalType": "string", "name": "_IPFSHash", "type": "string" } ], "name": "storeHash", "outputs": [], "stateMutability": "nonpayable", "type": "function" } ]'
 
11
 
12
+ # Changing the App title
13
+ st.set_page_config(page_title="Survey Data Retriever",)
14
 
 
 
15
 
16
+ # The following code centralizes all the buttons
17
  st.markdown("<style>.row-widget.stButton {text-align: center;}</style>", unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
+ # Title
20
+ st.title('Survey Data Retriever')
21
+ st.write("# ")
22
 
23
 
24
+ # Text field
25
+ contract_address = st.text_input(r"$\textsf{\Large Smart Contract Address}$", '0x42b76d8c32f914630627bf924bd1e06055673cf8')
26
 
27
+ # Button
28
+ button = st.button("Retrieve Survey Responses")
 
 
 
 
 
 
 
 
 
 
29
 
30
+ # Button is pressed
31
+ if button:
32
 
33
+ # Starts the progression bar
34
+ my_bar = st.progress(0, text= "Operation in progress. Please wait.")
35
 
36
+ # data frame with the data
37
+ df = pandas.DataFrame()
38
 
39
+ # Getting logs from ETH contract
40
+ contract = w3.eth.contract( address = w3.to_checksum_address(contract_address), abi = ABI)
41
+ logs = contract.events.Store.get_logs(fromBlock= 4635673)
 
 
 
 
 
42
 
43
+ # Writing a label
44
+ st.write(r"$\textsf{\normalsize \textbf{IPFS Hashes}}$")
45
 
46
+ for i, log in enumerate(logs):
47
 
48
+ # Adjusting progression bard
49
+ my_bar.progress((i+1)/len(logs), text= "Operation in progress. Please wait.")
50
 
51
+ # Writing the hashes
52
+ st.write(f"**Hash**: {log.args.data}; **Block number**: {log.blockNumber}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
+ # Requesting data from IPFS using INFURA API
55
+ params = (('arg', log.args.data),)
56
+ response = requests.post('https://ipfs.infura.io:5001/api/v0/cat',
57
+ params=params,
58
+ auth=(st.secrets["username"], st.secrets["password"]))
59
+
60
+ # create a row for the values associated with the 'data' key
61
+ json_to_row = pandas.json_normalize(response.json())
62
 
63
+ # append data to empty data frame
64
+ df = pandas.concat([df,json_to_row], ignore_index=True)
65
 
66
+ # Printing df
67
+ st.write("# ")
68
+ st.write(r" $\textsf{\normalsize \textbf{Response Data}}$")
69
+ st.write(df)
70
 
71
+ # Download button
72
+ st.download_button("Press to Download",
73
+ df.to_csv(index=False).encode('utf-8'),
74
+ "responses.csv",
75
+ "text/csv",
76
+ key='download-csv')
77
+
78
+ # Clearing progression bar
79
+ my_bar.empty()