1- import  errno 
21import  io 
32import  itertools 
43import  json 
@@ -56,10 +55,10 @@ def backfill(
5655        user_id : str ,
5756        output_dir : str ,
5857        start_date : str  =  BACKFILL_START_DATE ,
59-         data_streams : list [str ] =  None ,
60-         lock : list  =  None ,
61-         passphrase : str  =  None ,
62-     ):
58+         data_streams : list [str ] |   None   =  None ,
59+         lock : list [ str ]  |   None  =  None ,
60+         passphrase : str  |   None   =  None ,
61+     )  ->   None :
6362    """ 
6463    Backfill a user (participant) 
6564    """ 
@@ -123,8 +122,11 @@ def backfill(
123122
124123
125124def  download (Keyring : dict [str , str ], study_id : str , user_ids : list [str ],
126-              data_streams : list [str ] =  None , time_start : str  =  None , time_end : str  =  None ,
127-              registry : dict  =  None , progress : bool  =  False ) ->  zipfile .ZipFile :
125+              data_streams : list [str ] |  None  =  None ,
126+              time_start : str  |  datetime  |  None  =  None ,
127+              time_end : str  |  datetime  |  None  =  None ,
128+              registry : dict [str , str ] |  None  =  None ,
129+              progress : int  =  0 ) ->  zipfile .ZipFile  |  None :
128130    """ 
129131    Request data archive from Beiwe API 
130132
@@ -145,16 +147,18 @@ def download(Keyring: dict[str, str], study_id: str, user_ids: list[str],
145147
146148    # process start_time 
147149    if  time_start :
148-         time_start : datetime  =  dateutil .parser .parse (time_start )
150+         if  isinstance (time_start , str ):
151+             time_start  =  dateutil .parser .parse (time_start )
149152    else :
150153        epoch  =  time .gmtime (0 )
151-         time_start :  datetime  =  datetime (epoch .tm_year , epoch .tm_mon , epoch .tm_mday )
154+         time_start  =  datetime (epoch .tm_year , epoch .tm_mon , epoch .tm_mday )
152155
153156    # process end_time 
154157    if  time_end :
155-         time_end : datetime  =  dateutil .parser .parse (time_end )
158+         if  isinstance (time_end , str ):
159+             time_end  =  dateutil .parser .parse (time_end )
156160    else :
157-         time_end :  datetime  =  datetime .today ()
161+         time_end  =  datetime .today ()
158162
159163    # sanity check start and end times 
160164    if  time_start  >  time_end :
@@ -225,7 +229,7 @@ def download(Keyring: dict[str, str], study_id: str, user_ids: list[str],
225229    return  zf 
226230
227231
228- def  _window (timestamp : str , window : int  |  float ) ->  tuple [str , str , str ]:
232+ def  _window (timestamp : str , window : int  |  float ) ->  tuple [str , str , str   |   None ]:
229233    """ 
230234    Generate a backfill window (start, stop, and resume) 
231235    """ 
@@ -235,7 +239,7 @@ def _window(timestamp: str, window: int | float) -> tuple[str, str, str]:
235239    # by default, the download window will *stop* at `win_start` + `window`, 
236240    # and the next *resume* point will be the same... 
237241    win_stop  =  win_start  +  timedelta (days = window )
238-     resume  =  win_stop 
242+     resume :  datetime   |   None  =  win_stop 
239243
240244    # ...unless the next projected window stop point extends into the future, in which case the 
241245    # window stop point will be set to the present time, but and next resume time will be null 
@@ -245,16 +249,15 @@ def _window(timestamp: str, window: int | float) -> tuple[str, str, str]:
245249        resume  =  None 
246250
247251    # convert all timestamps to string representation before returning 
248-     win_start  =  win_start .strftime (mano .TIME_FORMAT )
249-     win_stop  =  win_stop .strftime (mano .TIME_FORMAT )
250-     if  resume :
251-         resume  =  resume .strftime (mano .TIME_FORMAT )
252+     win_start_str  =  win_start .strftime (mano .TIME_FORMAT )
253+     win_stop_str  =  win_stop .strftime (mano .TIME_FORMAT )
254+     resume_str  =  resume .strftime (mano .TIME_FORMAT ) if  resume  else  None 
252255
253-     return  win_start ,  win_stop ,  resume 
256+     return  win_start_str ,  win_stop_str ,  resume_str 
254257
255258
256- def  save (Keyring : dict [str , str ], archive : zipfile .ZipFile , user_id : str , output_dir : str ,
257-          lock : list = None , passphrase = None ):
259+ def  save (Keyring : dict [str , str ], archive : zipfile .ZipFile   |   None , user_id : str , output_dir : str ,
260+          lock : list [ str ]  |   None   =   None , passphrase :  str   |   None   =   None )  ->   int :
258261    """ 
259262    The order of operations here is important to ensure the ability to reach a state of consistency: 
260263        1. Save the file 
@@ -330,24 +333,21 @@ def save(Keyring: dict[str, str], archive: zipfile.ZipFile, user_id: str, output
330333    return  num_saved 
331334
332335
333- def  _makedirs (path : str , umask : int  =  None , exist_ok : bool  =  True ):
336+ def  _makedirs (path : str , umask : int  |   None   =  None , exist_ok : bool  =  True ):
334337    """ 
335338    Create directories recursively with a temporary umask 
336339    """ 
337-     if  umask  is  None :
338-         umask  =  os .umask (umask )
340+     old_umask  =  None 
341+     if  umask  is  not   None :
342+         old_umask  =  os .umask (umask )
339343    try :
340-         os .makedirs (path )
341-     except  OSError  as  e :
342-         if  e .errno  ==  errno .EEXIST  and  exist_ok :
343-             pass 
344-         else :
345-             raise  e 
346-     if  umask  is  None :
347-         os .umask (umask )
344+         os .makedirs (path , exist_ok = exist_ok )
345+     finally :
346+         if  old_umask  is  not   None :
347+             os .umask (old_umask )
348348
349349
350- def  _atomic_write (filename : str , content : bytes , overwrite = True , permissions = 0o0644 ):
350+ def  _atomic_write (filename : str , content : bytes , overwrite :  bool   =   True , permissions :  int   =   0o0644 ):
351351    """ 
352352    Write a file by first saving the content to a temporary file first, then 
353353    renaming the file. Overwrites silently by default o_o 
@@ -376,15 +376,3 @@ def _parse_datatype(member: str, user_id: str):
376376            f'expecting 1 capture group, found { numgroups }  : regex="{ expr }  ", string="{ member }  "' 
377377        )
378378    return  match .group (1 )
379- 
380- 
381- # function unused 
382- # def _masked_payload(p: Dict, masked_keys=['registry', 'secret_key', 'access_key']) -> Dict: 
383- #     """ 
384- #     Copy and mask a request payload to safely print to console 
385- #     """ 
386- #     _p = p.copy() 
387- #     for k in masked_keys: 
388- #         if k in _p and _p[k]: 
389- #             _p[k] = "***" 
390- #     return _p 
0 commit comments