33import json
44import multiprocessing
55import sys
6+ import random
7+ import string
68from datetime import datetime
79from logging import DEBUG , Formatter
810from logging .handlers import RotatingFileHandler
3335 system_namespace ,
3436)
3537
36- neurosift_file_registry = list ()
38+ neurosift_file_registry = dict ()
3739
3840flask_app = Flask (__name__ )
3941
@@ -71,15 +73,15 @@ def exception_handler(error: Exception) -> Dict[str, str]:
7173 return {"message" : str (error ), "type" : type (error ).__name__ }
7274
7375
74- @flask_app .route ("/files/<int:index >" )
75- def handle_get_file_request (index ) -> Union [str , None ]:
76+ @flask_app .route ("/files/<string:file_id >" )
77+ def handle_get_file_request (file_id ) -> Union [str , None ]:
7678 """
7779 This endpoint is used to access a file that has been registered with the Neurosift service.
7880 """
79- if request .method == "GET" and ( index >= len ( neurosift_file_registry ) or index < 0 ) :
80- raise KeyError (f"Resource at index { index } is not accessible." )
81+ if request .method == "GET" and file_id not in neurosift_file_registry :
82+ raise KeyError (f"File with internal id { file_id } is not accessible." )
8183
82- file_path = neurosift_file_registry [index ]
84+ file_path = neurosift_file_registry [file_id ]
8385 if not isabs (file_path ):
8486 file_path = f"/{ file_path } "
8587
@@ -95,17 +97,20 @@ def handle_file_request(file_path) -> Union[str, None]:
9597 if not file_path .endswith (".nwb" ):
9698 raise ValueError ("This endpoint must be called on an NWB file that ends with '.nwb'!" )
9799
98- # NOTE: It may be faster to look for the file in the registry and return a URL that has already been received
99- # by GUIDE because of caching, but in testing, it seemed that GUIDE/Neurosift was not caching the files.
100- neurosift_file_registry .append (file_path )
101- index = len (neurosift_file_registry ) - 1
100+ file_id = '' .join (random .choices (string .ascii_uppercase + string .digits , k = 8 ))
101+ neurosift_file_registry [file_id ] = file_path
102102
103- # files/<index > is the URL that can be used to access the file
103+ # files/<file_id > is the URL that can be used to access the file
104104 # NOTE: This endpoint used to be files/<file_path> but file_path would become URL-decoded
105105 # by Neurosift which changed + signs to spaces before making the GET request. This broke local reading
106106 # of files with + signs in the filename. Other symbols may be affected as well.
107- # This is why we use the safer, but less transparent, files/<index> instead.
108- return request .host_url + "/files/" + str (index )
107+ # This is why we use the safer, but less transparent, files/<file_id> instead.
108+ # We do not use an incremental index because Neurosift caches information about the file in persistent
109+ # Chrome storage (IndexedDB) that is based on the URL and cannot be cleared by NWB GUIDE. Subsequent loads
110+ # of a file would return cached information from host/files/0. So, we use a random string instead.
111+ # We also want to make sure multiple loads of the same file do not return the same URL because cached
112+ # information about the file that is no longer valid may be returned.
113+ return request .host_url + "/files/" + file_id
109114
110115
111116@api .route ("/log" )
0 commit comments