1414
1515"""Artifact downloaders for different storage backends."""
1616
17+ import asyncio
18+ import functools
1719import os
1820from abc import ABC , abstractmethod
1921from pathlib import Path
@@ -58,6 +60,18 @@ class S3ArtifactDownloader(ArtifactDownloader):
5860
5961 async def download (
6062 self , source_url : str , local_path : str , credentials : Optional [Dict ] = None
63+ ) -> str :
64+ """
65+ Download from S3 (Async wrapper).
66+ """
67+ loop = asyncio .get_running_loop ()
68+ return await loop .run_in_executor (
69+ None ,
70+ functools .partial (self ._download_sync , source_url , local_path , credentials ),
71+ )
72+
73+ def _download_sync (
74+ self , source_url : str , local_path : str , credentials : Optional [Dict ] = None
6175 ) -> str :
6276 """
6377 Download from S3.
@@ -154,7 +168,7 @@ def _download_s3_directory(
154168 local_file_path = os .path .join (local_path , relative_path )
155169
156170 # Ensure directory exists
157- os . makedirs (os .path .dirname (local_file_path ), exist_ok = True )
171+ self . _ensure_directory (os .path .dirname (local_file_path ))
158172
159173 # Download file
160174 s3_client .download_file (bucket_name , key , local_file_path )
@@ -168,6 +182,18 @@ class GCSArtifactDownloader(ArtifactDownloader):
168182
169183 async def download (
170184 self , source_url : str , local_path : str , credentials : Optional [Dict ] = None
185+ ) -> str :
186+ """
187+ Download from GCS (Async wrapper).
188+ """
189+ loop = asyncio .get_running_loop ()
190+ return await loop .run_in_executor (
191+ None ,
192+ functools .partial (self ._download_sync , source_url , local_path , credentials ),
193+ )
194+
195+ def _download_sync (
196+ self , source_url : str , local_path : str , credentials : Optional [Dict ] = None
171197 ) -> str :
172198 """
173199 Download from GCS.
@@ -227,7 +253,7 @@ async def download(
227253 local_file_path = os .path .join (local_path , relative_path )
228254
229255 # Ensure directory exists
230- os . makedirs (os .path .dirname (local_file_path ), exist_ok = True )
256+ self . _ensure_directory (os .path .dirname (local_file_path ))
231257
232258 # Download file
233259 blob .download_to_filename (local_file_path )
@@ -257,6 +283,18 @@ class HuggingFaceArtifactDownloader(ArtifactDownloader):
257283
258284 async def download (
259285 self , source_url : str , local_path : str , credentials : Optional [Dict ] = None
286+ ) -> str :
287+ """
288+ Download from HuggingFace Hub (Async wrapper).
289+ """
290+ loop = asyncio .get_running_loop ()
291+ return await loop .run_in_executor (
292+ None ,
293+ functools .partial (self ._download_sync , source_url , local_path , credentials ),
294+ )
295+
296+ def _download_sync (
297+ self , source_url : str , local_path : str , credentials : Optional [Dict ] = None
260298 ) -> str :
261299 """
262300 Download from HuggingFace Hub.
0 commit comments