TIL

Download an S3 object and display a progress bar

If you don't want to depend on the AWS CLI, you can use boto3 to download an S3 object and rich to display a progress bar:

#!/usr/bin/env python3

import boto3
from rich.progress import BarColumn, DownloadColumn, Progress, TransferSpeedColumn

BUCKET_NAME = "your-bucket"
KEY = "path/to/object.ext"


def download(bucket: str, key: str) -> None:
    s3 = boto3.resource("s3")
    # Get the file size
    s3_object = s3.Object(bucket, key)
    file_size = s3_object.content_length

    # Set up the progress bar
    progress = Progress(BarColumn(), DownloadColumn(), TransferSpeedColumn())

    # Download the file
    with progress:
        task_id = progress.add_task("Downloading", total=file_size)
        s3.Bucket(bucket).download_file(
            key,
            key.split("/")[-1],
            Callback=lambda bytes_downloaded: progress.update(
                task_id, advance=bytes_downloaded
            ),
        )


if __name__ == "__main__":
    download(bucket=BUCKET_NAME, key=KEY)