11import os
22from datetime import date
3+ from os import PathLike
34from pathlib import Path
45from typing import Any , Dict , List , Optional , Tuple , Union
56
2324 optional_symbols_list_to_string ,
2425 optional_values_list_to_string ,
2526)
26- from databento .common .validation import validate_enum
27+ from databento .common .validation import validate_enum , validate_path
2728from databento .historical .api import API_VERSION
2829from databento .historical .http import (
2930 BentoHttpAPI ,
@@ -212,7 +213,7 @@ def list_files(self, job_id: str) -> List[Dict[str, Any]]:
212213
213214 def download (
214215 self ,
215- output_dir : Union [Path , str ],
216+ output_dir : Union [PathLike [ str ] , str ],
216217 job_id : str ,
217218 filename_to_download : Optional [str ] = None ,
218219 enable_partial_downloads : bool = True ,
@@ -227,7 +228,7 @@ def download(
227228
228229 Parameters
229230 ----------
230- output_dir: Path or str
231+ output_dir: PathLike or str
231232 The directory to download the file(s) to.
232233 job_id : str
233234 The batch job identifier.
@@ -238,6 +239,7 @@ def download(
238239 If partially downloaded files will be resumed using range request(s).
239240
240241 """
242+ output_dir = validate_path (output_dir , "output_dir" )
241243 self ._check_api_key ()
242244
243245 params : List [Tuple [str , Optional [str ]]] = [
@@ -271,12 +273,12 @@ def download(
271273 return
272274
273275 # Prepare job directory
274- job_dir = os . path . join (output_dir , job_id )
276+ job_dir = Path (output_dir ) / job_id
275277 os .makedirs (job_dir , exist_ok = True )
276278
277279 for details in job_files :
278280 filename = str (details ["filename" ])
279- output_path = os . path . join ( job_dir , filename )
281+ output_path = job_dir / filename
280282 log_info (
281283 f"Downloading batch job file to { output_path } ..." ,
282284 )
@@ -305,7 +307,7 @@ def _download_file(
305307 self ,
306308 url : str ,
307309 filesize : int ,
308- output_path : str ,
310+ output_path : Path ,
309311 enable_partial_downloads : bool ,
310312 ) -> None :
311313 headers , mode = self ._get_file_download_headers_and_mode (
@@ -329,7 +331,7 @@ def _download_file(
329331
330332 async def download_async (
331333 self ,
332- output_dir : Union [Path , str ],
334+ output_dir : Union [PathLike [ str ] , str ],
333335 job_id : str ,
334336 filename_to_download : Optional [str ] = None ,
335337 enable_partial_downloads : bool = True ,
@@ -345,7 +347,7 @@ async def download_async(
345347
346348 Parameters
347349 ----------
348- output_dir: Path or str
350+ output_dir: PathLike or str
349351 The directory to download the file(s) to.
350352 job_id : str
351353 The batch job identifier.
@@ -356,6 +358,7 @@ async def download_async(
356358 If partially downloaded files will be resumed using range request(s).
357359
358360 """
361+ output_dir = validate_path (output_dir , "output_dir" )
359362 self ._check_api_key ()
360363
361364 params : List [Tuple [str , Optional [str ]]] = [
@@ -389,12 +392,12 @@ async def download_async(
389392 return
390393
391394 # Prepare job directory
392- job_dir = os . path . join (output_dir , job_id )
395+ job_dir = Path (output_dir ) / job_id
393396 os .makedirs (job_dir , exist_ok = True )
394397
395398 for details in job_files :
396399 filename = str (details ["filename" ])
397- output_path = os . path . join ( job_dir , filename )
400+ output_path = job_dir / filename
398401 log_info (
399402 f"Downloading batch job file to { output_path } ..." ,
400403 )
@@ -423,7 +426,7 @@ async def _download_file_async(
423426 self ,
424427 url : str ,
425428 filesize : int ,
426- output_path : str ,
429+ output_path : Path ,
427430 enable_partial_downloads : bool ,
428431 ) -> None :
429432 headers , mode = self ._get_file_download_headers_and_mode (
@@ -449,15 +452,15 @@ async def _download_file_async(
449452 def _get_file_download_headers_and_mode (
450453 self ,
451454 filesize : int ,
452- output_path : str ,
455+ output_path : Path ,
453456 enable_partial_downloads : bool ,
454457 ) -> Tuple [Dict [str , str ], str ]:
455458 headers : Dict [str , str ] = self ._headers .copy ()
456459 mode = "wb"
457460
458461 # Check if file already exists in partially downloaded state
459- if enable_partial_downloads and os . path . isfile ( output_path ):
460- existing_size = os . path . getsize ( output_path )
462+ if enable_partial_downloads and output_path . is_file ( ):
463+ existing_size = output_path . stat (). st_size
461464 if existing_size < filesize :
462465 # Make range request for partial download,
463466 # will be from next byte to end of file.
0 commit comments