1717from rich .text import Text
1818from rich_toolkit import RichToolkit
1919from rich_toolkit .menu import Option
20+ from rich_toolkit .progress import Progress
2021
2122from fastapi_cloud_cli .commands .login import login
2223from fastapi_cloud_cli .utils .api import (
2930from fastapi_cloud_cli .utils .apps import AppConfig , get_app_config , write_app_config
3031from fastapi_cloud_cli .utils .auth import Identity
3132from fastapi_cloud_cli .utils .cli import get_rich_toolkit , handle_http_errors
33+ from fastapi_cloud_cli .utils .progress_file import ProgressFile
3234
3335logger = logging .getLogger (__name__ )
3436
@@ -201,16 +203,32 @@ class RequestUploadResponse(BaseModel):
201203 fields : dict [str , str ]
202204
203205
204- def _upload_deployment (deployment_id : str , archive_path : Path ) -> None :
206+ def _format_size (size_in_bytes : int ) -> str :
207+ if size_in_bytes >= 1024 * 1024 :
208+ return f"{ size_in_bytes / (1024 * 1024 ):.2f} MB"
209+ elif size_in_bytes >= 1024 :
210+ return f"{ size_in_bytes / 1024 :.2f} KB"
211+ else :
212+ return f"{ size_in_bytes } bytes"
213+
214+
215+ def _upload_deployment (
216+ deployment_id : str , archive_path : Path , progress : Progress
217+ ) -> None :
218+ archive_size = archive_path .stat ().st_size
219+ archive_size_str = _format_size (archive_size )
220+
221+ progress .log (f"Uploading deployment ({ archive_size_str } )..." )
205222 logger .debug (
206223 "Starting deployment upload for deployment: %s" ,
207224 deployment_id ,
208225 )
209- logger .debug (
210- "Archive path: %s, size: %s bytes" ,
211- archive_path ,
212- archive_path .stat ().st_size ,
213- )
226+ logger .debug ("Archive path: %s, size: %s bytes" , archive_path , archive_size )
227+
228+ def progress_callback (bytes_read : int ):
229+ progress .log (
230+ f"Uploading deployment ({ _format_size (bytes_read )} of { archive_size_str } )..."
231+ )
214232
215233 with APIClient () as fastapi_client , Client () as client :
216234 # Get the upload URL
@@ -223,10 +241,13 @@ def _upload_deployment(deployment_id: str, archive_path: Path) -> None:
223241
224242 logger .debug ("Starting file upload to S3" )
225243 with open (archive_path , "rb" ) as archive_file :
244+ archive_file_with_progress = ProgressFile (
245+ archive_file , progress_callback = progress_callback
246+ )
226247 upload_response = client .post (
227248 upload_data .url ,
228249 data = upload_data .fields ,
229- files = {"file" : archive_file },
250+ files = {"file" : archive_file_with_progress },
230251 )
231252
232253 upload_response .raise_for_status ()
@@ -767,9 +788,7 @@ def deploy(
767788 f"Deployment created successfully! Deployment slug: { deployment .slug } "
768789 )
769790
770- progress .log ("Uploading deployment..." )
771-
772- _upload_deployment (deployment .id , archive_path )
791+ _upload_deployment (deployment .id , archive_path , progress = progress )
773792
774793 progress .log ("Deployment uploaded successfully!" )
775794 except KeyboardInterrupt :
0 commit comments