Riad-Quadratic commited on
Commit
d75dabd
1 Parent(s): c399fb5

INI: deploy app's first version

Browse files
Files changed (7) hide show
  1. app.py +241 -0
  2. config.py +6 -0
  3. data/circuit.zip +0 -0
  4. data/paris_quadratic_edges.geojson +0 -0
  5. network.py +41 -0
  6. requirements.txt +334 -0
  7. utils.py +47 -0
app.py ADDED
@@ -0,0 +1,241 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from concrete import fhe
2
+ import folium
3
+ import geopandas
4
+ from shapely.geometry import Point
5
+ import streamlit as st
6
+ from streamlit_folium import st_folium
7
+
8
+ import config
9
+ from network import get_frames
10
+ from utils import generate_path, set_up_server, set_up_client, display_encrypted
11
+
12
+
13
+ st.set_page_config(layout="wide")
14
+ ways = geopandas.read_file(config.roads_filepath)
15
+ nodes, _, rel = get_frames(ways)
16
+
17
+ server = set_up_server()
18
+ client = set_up_client(server.client_specs.serialize())
19
+
20
+ m = nodes.explore(
21
+ color="red",
22
+ marker_kwds=dict(radius=5, fill=True, name='node_id'),
23
+ tooltip="node_id",
24
+ tooltip_kwds=dict(labels=False),
25
+ zoom_control=False,
26
+ )
27
+
28
+
29
+ c1, c2, c3 = st.columns([1, 3, 1])
30
+
31
+ with c1:
32
+ st.write("**Client-side**")
33
+
34
+ with c3:
35
+ st.write("**Server-side**")
36
+
37
+
38
+ if 'evaluation_key' not in st.session_state:
39
+ with c1:
40
+ if st.button('Generate keys'):
41
+ with st.spinner('Generating keys'):
42
+ client.keys.load_if_exists_generate_and_save_otherwise(config.keys_filepath)
43
+ # client.keys.save(config.keys_filepath)
44
+ st.session_state['evaluation_key'] = client.evaluation_keys.serialize()
45
+ st.rerun()
46
+ else:
47
+ with c1:
48
+ st.write("Encryption/decryption keys and evaluation keys are generated.")
49
+ st.write("The evaluation key is sent to the server.")
50
+ with c3:
51
+ st.write(f"Evaluation key: {display_encrypted(st.session_state['evaluation_key'])}")
52
+
53
+
54
+ if 'origin' not in st.session_state :
55
+ with c1:
56
+ st.write("Select the origin on the map")
57
+
58
+ with c2:
59
+ st_data_origin = st_folium(m, width=725, key="origin", returned_objects=["last_object_clicked"])
60
+
61
+ with c3:
62
+ st.write("")
63
+
64
+ if st_data_origin["last_object_clicked"]:
65
+ origin = Point(st_data_origin["last_object_clicked"]["lng"], st_data_origin["last_object_clicked"]["lat"])
66
+ origin_node = nodes[nodes['geometry'] == origin]['node_id'].values[0]
67
+ st.session_state['origin'] = origin
68
+ st.session_state['origin_node'] = origin_node
69
+ st.write(f"Selected node is node number: {origin_node}")
70
+ st.rerun()
71
+
72
+ if 'origin' in st.session_state and 'destination' not in st.session_state:
73
+ origin = st.session_state['origin']
74
+ folium.Marker([origin.y, origin.x], popup="Origin", tooltip="Origin").add_to(m)
75
+ origin_node = st.session_state['origin_node']
76
+ with c1:
77
+ st.write(f"Selected origin is node number: {origin_node}")
78
+ st.write("Select the destination on the map")
79
+ with c2:
80
+ st_data_destination = st_folium(m, width=725, key="destination", returned_objects=["last_object_clicked"])
81
+ with c3:
82
+ st.write("")
83
+ st.write("")
84
+
85
+ if st_data_destination["last_object_clicked"]:
86
+ destination = Point(st_data_destination["last_object_clicked"]["lng"], st_data_destination["last_object_clicked"]["lat"])
87
+ st.session_state['destination'] = destination
88
+ st.session_state['destination_node'] = nodes[nodes['geometry'] == destination]['node_id'].values[0]
89
+ st.write(st_data_destination["last_object_clicked"])
90
+ st.rerun()
91
+
92
+ if 'origin' in st.session_state and 'destination' in st.session_state and 'encrypted_origin' not in st.session_state :
93
+ origin = st.session_state['origin']
94
+ folium.Marker([origin.y, origin.x], popup="Origin", tooltip="Origin").add_to(m)
95
+ destination = st.session_state['destination']
96
+ folium.Marker([destination.y, destination.x], popup="Destination", tooltip="Destination").add_to(m)
97
+ # breakpoint()
98
+ origin_node = st.session_state['origin_node']
99
+ destination_node = st.session_state['destination_node']
100
+ with c1:
101
+ st.write(f"Selected origin is node number: {origin_node}")
102
+ st.write(f"Selected destination is node number: {destination_node}")
103
+ if st.button('Encrypt and send inputs'):
104
+ with st.spinner('Encrypting inputs'):
105
+ client.keys.load(config.keys_filepath)
106
+ origin, destination = client.encrypt(origin_node, destination_node)
107
+ st.session_state['encrypted_origin'] = origin.serialize()
108
+ st.session_state['encrypted_destination'] = destination.serialize()
109
+ st.rerun()
110
+ with c2:
111
+ st_data_final = st_folium(m, width=725, key="destination", returned_objects=[])
112
+ with c3:
113
+ st.write("")
114
+ st.write("")
115
+
116
+ if 'encrypted_origin' in st.session_state and 'encrypted_shortest_path' not in st.session_state:
117
+ origin = st.session_state['origin']
118
+ folium.Marker([origin.y, origin.x], popup="Origin", tooltip="Origin").add_to(m)
119
+ destination = st.session_state['destination']
120
+ folium.Marker([destination.y, destination.x], popup="Destination", tooltip="Destination").add_to(m)
121
+
122
+ origin_node = st.session_state['origin_node']
123
+ destination_node = st.session_state['destination_node']
124
+ with c1:
125
+ st.write(f"Selected origin is node number: {origin_node}")
126
+ st.write(f"Selected destination is node number: {destination_node}")
127
+ with c2:
128
+ origin = st.session_state['origin']
129
+ folium.Marker([origin.y, origin.x], popup="Origin", tooltip="Origin").add_to(m)
130
+ destination = st.session_state['destination']
131
+ folium.Marker([destination.y, destination.x], popup="Destination", tooltip="Destination").add_to(m)
132
+ st_data_final = st_folium(m, width=725, key="destination", returned_objects=[])
133
+ with c3:
134
+ st.write("")
135
+ st.write("")
136
+ st.write(f"Received origin: {display_encrypted(st.session_state['encrypted_origin'])}")
137
+ st.write(f"Received destination: {display_encrypted(st.session_state['encrypted_destination'])}")
138
+ if st.button('Compute shortest path'):
139
+ with st.spinner('Computing'):
140
+ deserialized_origin = fhe.Value.deserialize(st.session_state['encrypted_origin'])
141
+ deserialized_destination = fhe.Value.deserialize(st.session_state['encrypted_destination'])
142
+ deserialized_evaluation_keys = fhe.EvaluationKeys.deserialize(st.session_state['evaluation_key'])
143
+ client.keys.load_if_exists_generate_and_save_otherwise(config.keys_filepath)
144
+ origin = st.session_state['origin_node']
145
+ destination = st.session_state['destination_node']
146
+ path = [origin, ]
147
+ encrypted_path = [st.session_state['encrypted_origin'], ]
148
+ o, d = deserialized_origin, deserialized_destination
149
+ for _ in range(nodes.shape[0] - 1):
150
+ # Careful: breaking early could lead to information leak
151
+ if origin == destination:
152
+ break
153
+ o = server.run(o, d, evaluation_keys=client.evaluation_keys)
154
+ origin = client.decrypt(o)
155
+ encrypted_path.append(o.serialize())
156
+ path.append(origin)
157
+
158
+ st.session_state['encrypted_shortest_path'] = encrypted_path
159
+ st.session_state['decrypted_shortest_path'] = path
160
+ st.rerun()
161
+
162
+ if 'encrypted_shortest_path' in st.session_state and 'decrypted_result' not in st.session_state :
163
+ origin = st.session_state['origin']
164
+ folium.Marker([origin.y, origin.x], popup="Origin", tooltip="Origin").add_to(m)
165
+ destination = st.session_state['destination']
166
+ folium.Marker([destination.y, destination.x], popup="Destination", tooltip="Destination").add_to(m)
167
+
168
+ origin_node = st.session_state['origin_node']
169
+ destination_node = st.session_state['destination_node']
170
+ with c1:
171
+ st.write(f"Selected origin is node number: {origin_node}")
172
+ st.write(f"Selected destination is node number: {destination_node}")
173
+ st.write("Received path is:")
174
+ st.write(f"{display_encrypted(st.session_state['encrypted_shortest_path'][0])}")
175
+ st.write("...")
176
+ st.write(f"{display_encrypted(st.session_state['encrypted_shortest_path'][-1])}")
177
+
178
+ if st.button('Decrypt and show shortest path'):
179
+ with st.spinner('Computing'):
180
+ client.keys.load_if_exists_generate_and_save_otherwise(config.keys_filepath)
181
+ path = []
182
+ for enc_value in st.session_state['encrypted_shortest_path']:
183
+ deserialized_result = fhe.Value.deserialize(enc_value)
184
+ path.append(client.decrypt(deserialized_result))
185
+ st.session_state['decrypted_result'] = path
186
+ st.rerun()
187
+ with c2:
188
+
189
+ origin = st.session_state['origin']
190
+ folium.Marker([origin.y, origin.x], popup="Origin", tooltip="Origin").add_to(m)
191
+
192
+ destination = st.session_state['destination']
193
+ folium.Marker([destination.y, destination.x], popup="Destination", tooltip="Destination").add_to(m)
194
+ st_data_final = st_folium(m, width=725, key="destination", returned_objects=[])
195
+ with c3:
196
+ st.write("")
197
+ st.write("")
198
+ st.write(f"Received origin: {display_encrypted(st.session_state['encrypted_origin'])}")
199
+ st.write(f"Received destination: {display_encrypted(st.session_state['encrypted_destination'])}")
200
+ # st.write(f"Next node is {display_encrypted(st.session_state['encrypted_shortest_path'])} and is sent to client")
201
+ if 'decrypted_result' in st.session_state :
202
+ origin = st.session_state['origin']
203
+ folium.Marker([origin.y, origin.x], popup="Origin", tooltip="Origin").add_to(m)
204
+ destination = st.session_state['destination']
205
+ folium.Marker([destination.y, destination.x], popup="Destination", tooltip="Destination").add_to(m)
206
+
207
+ origin_node = st.session_state['origin_node']
208
+ destination_node = st.session_state['destination_node']
209
+ with c1:
210
+ st.write(f"Selected origin is node number: {origin_node}")
211
+ st.write(f"Selected destination is node number: {destination_node}")
212
+ st.write("Received path is:")
213
+ st.write(f"{display_encrypted(st.session_state['encrypted_shortest_path'][0])}")
214
+ st.write("...")
215
+ st.write(f"{display_encrypted(st.session_state['encrypted_shortest_path'][-1])}")
216
+ st.write(f"Decrypted result is: {st.session_state['decrypted_result']}")
217
+ if st.button('Restart'):
218
+ for key in st.session_state.keys():
219
+ del st.session_state[key]
220
+ st.rerun()
221
+ with c2:
222
+ origin = st.session_state['origin']
223
+ folium.Marker([origin.y, origin.x], popup="Origin", tooltip="Origin").add_to(m)
224
+ destination = st.session_state['destination']
225
+ folium.Marker([destination.y, destination.x], popup="Destination", tooltip="Destination").add_to(m)
226
+ shortest_path_list = st.session_state['decrypted_result']
227
+ final_result = generate_path(shortest_path_list, rel)
228
+ final_result.explore(
229
+ m=m,
230
+ color="green",
231
+ style_kwds = {"weight":5},
232
+ tooltip="name",
233
+ popup=["name"],
234
+ name="Quadratic-Paris",
235
+ )
236
+ st_data_final = st_folium(m, width=725, key="destination", returned_objects=[])
237
+ with c3:
238
+ st.write("")
239
+ st.write("")
240
+ st.write(f"Received origin: {display_encrypted(st.session_state['encrypted_origin'])}")
241
+ st.write(f"Received destination: {display_encrypted(st.session_state['encrypted_destination'])}")
config.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+
3
+ data_path = Path(__file__).parent / "data"
4
+ roads_filepath = data_path / "paris_quadratic_edges.geojson"
5
+ circuit_filepath = data_path / "circuit.zip"
6
+ keys_filepath = data_path / "keys.zip"
data/circuit.zip ADDED
Binary file (5.24 kB). View file
 
data/paris_quadratic_edges.geojson ADDED
The diff for this file is too large to render. See raw diff
 
network.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import geopandas
2
+ import networkx
3
+ import numpy
4
+
5
+
6
+ def get_frames(ways: geopandas.GeoDataFrame):
7
+ edges = ways.explode(index_parts=False)[["id", "name", "geometry"]]
8
+ edges.index.name = "way_id"
9
+ edges = edges.reset_index()
10
+ nodes = geopandas.GeoDataFrame({"geometry": edges.boundary.explode(index_parts=False).geometry.unique()})
11
+ nodes.index.name = "node_id"
12
+ nodes.reset_index(inplace=True)
13
+ rel = edges.sjoin(nodes).to_crs("epsg:2154")
14
+ return nodes, edges, rel
15
+
16
+
17
+ def get(ways: geopandas.GeoDataFrame) -> networkx.Graph:
18
+ nodes, edges, rel = get_frames(ways)
19
+ graph = networkx.Graph()
20
+ for node in rel['node_id'].unique():
21
+ graph.add_node(node, shape=nodes.loc[node, "geometry"])
22
+ for idx in rel['way_id'].unique():
23
+ node_id1, node_id2 = rel.loc[idx]['node_id']
24
+ way = edges.loc[idx]
25
+ way_length = rel.loc[idx]['geometry'].iloc[0].length
26
+ graph.add_edge(
27
+ node_id1, node_id2,
28
+ weight=way.geometry.length,
29
+ shape=way.geometry,
30
+ id_=idx,
31
+ )
32
+ return graph
33
+
34
+
35
+ def weighted_adjacency_matrix(graph: networkx.Graph) -> numpy.ndarray:
36
+ weights = numpy.full((graph.number_of_nodes(),)*2, numpy.inf)
37
+ numpy.fill_diagonal(weights, 0., wrap=False)
38
+ for i in graph:
39
+ for j in graph[i]:
40
+ weights[i, j] = graph[i][j]["weight"]
41
+ return weights
requirements.txt ADDED
@@ -0,0 +1,334 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #
2
+ # This file is autogenerated by pip-compile with Python 3.10
3
+ # by the following command:
4
+ #
5
+ # pip-compile requirements.in
6
+ #
7
+ altair==5.1.1
8
+ # via streamlit
9
+ asttokens==2.4.0
10
+ # via stack-data
11
+ attrs==23.1.0
12
+ # via
13
+ # fiona
14
+ # jsonschema
15
+ # referencing
16
+ backcall==0.2.0
17
+ # via ipython
18
+ blinker==1.6.2
19
+ # via streamlit
20
+ branca==0.6.0
21
+ # via
22
+ # folium
23
+ # streamlit-folium
24
+ cachetools==5.3.1
25
+ # via streamlit
26
+ certifi==2023.7.22
27
+ # via
28
+ # fiona
29
+ # pyproj
30
+ # requests
31
+ charset-normalizer==3.2.0
32
+ # via requests
33
+ click==8.1.7
34
+ # via
35
+ # click-plugins
36
+ # cligj
37
+ # fiona
38
+ # streamlit
39
+ click-plugins==1.1.1
40
+ # via fiona
41
+ cligj==0.7.2
42
+ # via fiona
43
+ cmake==3.27.5
44
+ # via triton
45
+ comm==0.1.4
46
+ # via ipykernel
47
+ concrete-python==2.0.0
48
+ # via -r requirements.in
49
+ contourpy==1.1.1
50
+ # via matplotlib
51
+ cycler==0.11.0
52
+ # via matplotlib
53
+ debugpy==1.8.0
54
+ # via ipykernel
55
+ decorator==5.1.1
56
+ # via ipython
57
+ exceptiongroup==1.1.3
58
+ # via ipython
59
+ executing==1.2.0
60
+ # via stack-data
61
+ filelock==3.12.4
62
+ # via
63
+ # torch
64
+ # triton
65
+ fiona==1.9.4.post1
66
+ # via geopandas
67
+ folium==0.14.0
68
+ # via
69
+ # -r requirements.in
70
+ # streamlit-folium
71
+ fonttools==4.42.1
72
+ # via matplotlib
73
+ geopandas==0.14.0
74
+ # via -r requirements.in
75
+ gitdb==4.0.10
76
+ # via gitpython
77
+ gitpython==3.1.37
78
+ # via streamlit
79
+ idna==3.4
80
+ # via requests
81
+ importlib-metadata==6.8.0
82
+ # via streamlit
83
+ ipykernel==6.25.2
84
+ # via -r requirements.in
85
+ ipython==8.15.0
86
+ # via ipykernel
87
+ jedi==0.19.0
88
+ # via ipython
89
+ jinja2==3.1.2
90
+ # via
91
+ # altair
92
+ # branca
93
+ # folium
94
+ # pydeck
95
+ # streamlit-folium
96
+ # torch
97
+ joblib==1.3.2
98
+ # via scikit-learn
99
+ jsonschema==4.19.1
100
+ # via altair
101
+ jsonschema-specifications==2023.7.1
102
+ # via jsonschema
103
+ jupyter-client==8.3.1
104
+ # via ipykernel
105
+ jupyter-core==5.3.1
106
+ # via
107
+ # ipykernel
108
+ # jupyter-client
109
+ kiwisolver==1.4.5
110
+ # via matplotlib
111
+ lit==16.0.6
112
+ # via triton
113
+ mapclassify==2.6.0
114
+ # via -r requirements.in
115
+ markdown-it-py==3.0.0
116
+ # via rich
117
+ markupsafe==2.1.3
118
+ # via jinja2
119
+ matplotlib==3.8.0
120
+ # via -r requirements.in
121
+ matplotlib-inline==0.1.6
122
+ # via
123
+ # ipykernel
124
+ # ipython
125
+ mdurl==0.1.2
126
+ # via markdown-it-py
127
+ mpmath==1.3.0
128
+ # via sympy
129
+ nest-asyncio==1.5.8
130
+ # via ipykernel
131
+ networkx==3.1
132
+ # via
133
+ # concrete-python
134
+ # mapclassify
135
+ # torch
136
+ numpy==1.26.0
137
+ # via
138
+ # -r requirements.in
139
+ # altair
140
+ # concrete-python
141
+ # contourpy
142
+ # folium
143
+ # mapclassify
144
+ # matplotlib
145
+ # pandas
146
+ # pyarrow
147
+ # pydeck
148
+ # scikit-learn
149
+ # scipy
150
+ # shapely
151
+ # streamlit
152
+ nvidia-cublas-cu11==11.10.3.66
153
+ # via
154
+ # nvidia-cudnn-cu11
155
+ # nvidia-cusolver-cu11
156
+ # torch
157
+ nvidia-cuda-cupti-cu11==11.7.101
158
+ # via torch
159
+ nvidia-cuda-nvrtc-cu11==11.7.99
160
+ # via torch
161
+ nvidia-cuda-runtime-cu11==11.7.99
162
+ # via torch
163
+ nvidia-cudnn-cu11==8.5.0.96
164
+ # via torch
165
+ nvidia-cufft-cu11==10.9.0.58
166
+ # via torch
167
+ nvidia-curand-cu11==10.2.10.91
168
+ # via torch
169
+ nvidia-cusolver-cu11==11.4.0.1
170
+ # via torch
171
+ nvidia-cusparse-cu11==11.7.4.91
172
+ # via torch
173
+ nvidia-nccl-cu11==2.14.3
174
+ # via torch
175
+ nvidia-nvtx-cu11==11.7.91
176
+ # via torch
177
+ packaging==23.1
178
+ # via
179
+ # altair
180
+ # geopandas
181
+ # ipykernel
182
+ # matplotlib
183
+ # streamlit
184
+ pandas==2.1.1
185
+ # via
186
+ # altair
187
+ # geopandas
188
+ # mapclassify
189
+ # streamlit
190
+ parso==0.8.3
191
+ # via jedi
192
+ pexpect==4.8.0
193
+ # via ipython
194
+ pickleshare==0.7.5
195
+ # via ipython
196
+ pillow==9.5.0
197
+ # via
198
+ # matplotlib
199
+ # streamlit
200
+ platformdirs==3.10.0
201
+ # via jupyter-core
202
+ prompt-toolkit==3.0.39
203
+ # via ipython
204
+ protobuf==4.24.3
205
+ # via streamlit
206
+ psutil==5.9.5
207
+ # via ipykernel
208
+ ptyprocess==0.7.0
209
+ # via pexpect
210
+ pure-eval==0.2.2
211
+ # via stack-data
212
+ pyarrow==13.0.0
213
+ # via streamlit
214
+ pydeck==0.8.1b0
215
+ # via streamlit
216
+ pygments==2.16.1
217
+ # via
218
+ # ipython
219
+ # rich
220
+ pyparsing==3.1.1
221
+ # via matplotlib
222
+ pyproj==3.6.1
223
+ # via geopandas
224
+ python-dateutil==2.8.2
225
+ # via
226
+ # jupyter-client
227
+ # matplotlib
228
+ # pandas
229
+ # streamlit
230
+ pytz==2023.3.post1
231
+ # via pandas
232
+ pyzmq==25.1.1
233
+ # via
234
+ # ipykernel
235
+ # jupyter-client
236
+ referencing==0.30.2
237
+ # via
238
+ # jsonschema
239
+ # jsonschema-specifications
240
+ requests==2.31.0
241
+ # via
242
+ # folium
243
+ # streamlit
244
+ rich==13.5.3
245
+ # via streamlit
246
+ rpds-py==0.10.3
247
+ # via
248
+ # jsonschema
249
+ # referencing
250
+ scikit-learn==1.3.1
251
+ # via mapclassify
252
+ scipy==1.11.2
253
+ # via
254
+ # concrete-python
255
+ # mapclassify
256
+ # scikit-learn
257
+ shapely==2.0.1
258
+ # via
259
+ # -r requirements.in
260
+ # geopandas
261
+ six==1.16.0
262
+ # via
263
+ # asttokens
264
+ # fiona
265
+ # python-dateutil
266
+ smmap==5.0.1
267
+ # via gitdb
268
+ stack-data==0.6.2
269
+ # via ipython
270
+ streamlit==1.27.0
271
+ # via
272
+ # -r requirements.in
273
+ # streamlit-folium
274
+ streamlit-folium==0.14.0
275
+ # via -r requirements.in
276
+ sympy==1.12
277
+ # via torch
278
+ tenacity==8.2.3
279
+ # via streamlit
280
+ threadpoolctl==3.2.0
281
+ # via scikit-learn
282
+ toml==0.10.2
283
+ # via streamlit
284
+ toolz==0.12.0
285
+ # via altair
286
+ torch==2.0.1
287
+ # via
288
+ # concrete-python
289
+ # triton
290
+ tornado==6.3.3
291
+ # via
292
+ # ipykernel
293
+ # jupyter-client
294
+ # streamlit
295
+ traitlets==5.10.0
296
+ # via
297
+ # comm
298
+ # ipykernel
299
+ # ipython
300
+ # jupyter-client
301
+ # jupyter-core
302
+ # matplotlib-inline
303
+ triton==2.0.0
304
+ # via torch
305
+ typing-extensions==4.8.0
306
+ # via
307
+ # altair
308
+ # streamlit
309
+ # torch
310
+ tzdata==2023.3
311
+ # via pandas
312
+ tzlocal==5.0.1
313
+ # via streamlit
314
+ urllib3==2.0.5
315
+ # via requests
316
+ validators==0.22.0
317
+ # via streamlit
318
+ watchdog==3.0.0
319
+ # via streamlit
320
+ wcwidth==0.2.6
321
+ # via prompt-toolkit
322
+ wheel==0.41.2
323
+ # via
324
+ # nvidia-cublas-cu11
325
+ # nvidia-cuda-cupti-cu11
326
+ # nvidia-cuda-runtime-cu11
327
+ # nvidia-curand-cu11
328
+ # nvidia-cusparse-cu11
329
+ # nvidia-nvtx-cu11
330
+ zipp==3.17.0
331
+ # via importlib-metadata
332
+
333
+ # The following packages are considered to be unsafe in a requirements file:
334
+ # setuptools
utils.py ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ from concrete import fhe
3
+ from config import circuit_filepath
4
+
5
+
6
+ def set_up_server():
7
+ # Setting up a server
8
+ try:
9
+ server = fhe.Server.load(circuit_filepath)
10
+ except Exception:
11
+ raise Exception(f"Something went wrong with the circuit. Make sure that the circuit exists in {circuit_filepath}. If not run python generate_circuit.py.")
12
+
13
+ return server
14
+
15
+ def set_up_client(serialized_client_specs):
16
+ # Setting up client
17
+ client_specs = fhe.ClientSpecs.deserialize(serialized_client_specs)
18
+ client = fhe.Client(client_specs)
19
+
20
+ return client
21
+
22
+ def display_encrypted(encrypted_object):
23
+ encoded_text = encrypted_object.hex()
24
+ res = '...' + encoded_text[-10:]
25
+ return res
26
+
27
+ def shortest_path(circuit, N_NODES, origin, destination):
28
+ path = [origin, ]
29
+ o, d = circuit.encrypt(origin, destination)
30
+ for _ in range(N_NODES - 1):
31
+ # Careful: breaking early could lead to information leak
32
+ if origin == destination:
33
+ break
34
+ o = circuit.run(o, d)
35
+ origin = circuit.decrypt(o)
36
+ path.append(origin)
37
+ return path
38
+
39
+ def generate_path(shortest_path_list, rel):
40
+ pairs_list = []
41
+ for i in range(len(shortest_path_list) - 1):
42
+ current_element = shortest_path_list[i]
43
+ next_element = shortest_path_list[i + 1]
44
+ result = rel.groupby('way_id').filter(lambda x: set([current_element, next_element]).issubset(x['node_id']))
45
+ pairs_list.append(result)
46
+ final_result = pd.concat(pairs_list)
47
+ return final_result