2
2
import logging
3
3
import os
4
4
import re
5
+ from hashlib import sha256
5
6
from pathlib import Path
7
+ from typing import Any , Dict
6
8
7
9
from fastapi import APIRouter , Body , Depends , Header , HTTPException , status
8
10
from starlette .responses import HTMLResponse , JSONResponse , RedirectResponse , Response
@@ -112,12 +114,12 @@ async def get_all_workflows():
112
114
stat_info = json_file .stat ()
113
115
try :
114
116
with json_file .open ("r" , encoding = "utf-8" ) as f :
115
- config_contents = json .load (f )
117
+ config_contents : Dict [ str , Any ] = json .load (f )
116
118
except json .JSONDecodeError as e :
117
119
logger .error (f"Error decoding JSON from { json_file } : { e } " )
118
120
continue
119
121
120
- data [json_file .stem ] = {
122
+ data [config_contents . get ( "id" , json_file .stem ) ] = {
121
123
"createTime" : int (stat_info .st_ctime ),
122
124
"updateTime" : int (stat_info .st_mtime ),
123
125
"config" : config_contents ,
@@ -139,7 +141,8 @@ async def get_workflow(workflow_id: str):
139
141
if not re .match (r"^[\w\-]+$" , workflow_id ):
140
142
return JSONResponse ({"error" : "invalid id" }, status_code = HTTP_400_BAD_REQUEST )
141
143
142
- file_path = workflow_local_dir / f"{ workflow_id } .json"
144
+ workflow_hash = sha256 (workflow_id .encode ()).hexdigest ()
145
+ file_path = workflow_local_dir / f"{ workflow_hash } .json"
143
146
if not file_path .exists ():
144
147
return JSONResponse ({"error" : "not found" }, status_code = HTTP_404_NOT_FOUND )
145
148
@@ -148,7 +151,7 @@ async def get_workflow(workflow_id: str):
148
151
with file_path .open ("r" , encoding = "utf-8" ) as f :
149
152
config_contents = json .load (f )
150
153
except json .JSONDecodeError as e :
151
- logger .error (f"Error reading JSON from { file_path } : { e } " )
154
+ logger .error (f"Error reading JSON for { workflow_id } from ' { file_path } ' : { e } " )
152
155
return JSONResponse ({"error" : "invalid JSON" }, status_code = 500 )
153
156
154
157
return Response (
@@ -179,32 +182,34 @@ async def create_or_overwrite_workflow(
179
182
if not re .match (r"^[\w\-]+$" , workflow_id ):
180
183
return JSONResponse ({"error" : "invalid id" }, status_code = HTTP_400_BAD_REQUEST )
181
184
182
- file_path = workflow_local_dir / f"{ workflow_id } .json"
183
185
workflow_local_dir .mkdir (parents = True , exist_ok = True )
184
186
185
187
# If the body claims a different ID, treat that as a "rename".
186
188
if request_body .get ("id" ) and request_body .get ("id" ) != workflow_id :
187
- old_id = request_body ["id" ]
189
+ old_id : str = request_body ["id" ]
188
190
if not re .match (r"^[\w\-]+$" , old_id ):
189
191
return JSONResponse (
190
192
{"error" : "invalid id" }, status_code = HTTP_400_BAD_REQUEST
191
193
)
192
194
193
- old_file_path = workflow_local_dir / f"{ old_id } .json"
195
+ old_workflow_hash = sha256 (old_id .encode ()).hexdigest ()
196
+ old_file_path = workflow_local_dir / f"{ old_workflow_hash } .json"
194
197
if old_file_path .exists ():
195
198
try :
196
199
old_file_path .unlink ()
197
200
except Exception as e :
198
- logger .error (f"Error deleting { old_file_path } : { e } " )
201
+ logger .error (f"Error deleting { old_id } from { old_file_path } : { e } " )
199
202
return JSONResponse ({"error" : "unable to delete file" }, status_code = 500 )
200
203
201
- request_body ["id" ] = workflow_id
204
+ request_body ["id" ] = workflow_id
202
205
206
+ workflow_hash = sha256 (workflow_id .encode ()).hexdigest ()
207
+ file_path = workflow_local_dir / f"{ workflow_hash } .json"
203
208
try :
204
209
with file_path .open ("w" , encoding = "utf-8" ) as f :
205
210
json .dump (request_body , f , indent = 2 )
206
211
except Exception as e :
207
- logger .error (f"Error writing JSON to { file_path } : { e } " )
212
+ logger .error (f"Error writing JSON for { workflow_id } to { file_path } : { e } " )
208
213
return JSONResponse ({"error" : "unable to write file" }, status_code = 500 )
209
214
210
215
return JSONResponse (
@@ -223,14 +228,15 @@ async def delete_workflow(workflow_id: str):
223
228
if not re .match (r"^[\w\-]+$" , workflow_id ):
224
229
return JSONResponse ({"error" : "invalid id" }, status_code = HTTP_400_BAD_REQUEST )
225
230
226
- file_path = workflow_local_dir / f"{ workflow_id } .json"
231
+ workflow_hash = sha256 (workflow_id .encode ()).hexdigest ()
232
+ file_path = workflow_local_dir / f"{ workflow_hash } .json"
227
233
if not file_path .exists ():
228
234
return JSONResponse ({"error" : "not found" }, status_code = HTTP_404_NOT_FOUND )
229
235
230
236
try :
231
237
file_path .unlink ()
232
238
except Exception as e :
233
- logger .error (f"Error deleting { file_path } : { e } " )
239
+ logger .error (f"Error deleting { workflow_id } from { file_path } : { e } " )
234
240
return JSONResponse ({"error" : "unable to delete file" }, status_code = 500 )
235
241
236
242
return JSONResponse (
@@ -253,7 +259,8 @@ async def builder_maybe_redirect(workflow_id: str):
253
259
if not re .match (r"^[\w\-]+$" , workflow_id ):
254
260
return RedirectResponse (url = "/build" , status_code = 302 )
255
261
256
- file_path = workflow_local_dir / f"{ workflow_id } .json"
262
+ workflow_hash = sha256 (workflow_id .encode ()).hexdigest ()
263
+ file_path = workflow_local_dir / f"{ workflow_hash } .json"
257
264
if file_path .exists ():
258
265
return RedirectResponse (url = f"/build/edit/{ workflow_id } " , status_code = 302 )
259
266
else :
0 commit comments