The Fastest Way to Download from Amazon S3 (using Raycast)
Tags: aws, productivity, webdev, programming
Published: 2024-06-20 10:22:18

If you are a heavy Amazon S3 user like me, you might have wondered if there is a quick way to download a file from S3. After all, AWS created this wonderful `s3://` protocol that contains all the information needed to get the file.

Usually, I have to log in to the AWS console, fight with the multi-factor authentication, navigate to S3, search for the bucket, and then find the right file to download. It's annoying!

I have created a [Raycast Script Command](https://www.raycast.com/blog/getting-started-with-script-commands) to optimize this process. Raycast is a shortcut manager that allows you to quickly launch an application or make a search query. It has replaced the Spotlight search on my macOS, which is usually opened with `CMD+Space`. A Script Command is a programmatic way to add a new shortcut to Raycast. In this case, my Script Command downloads a file from Amazon S3.

Here is a short video of this action: I open Raycast with `CMD+Space`, type `S3` to find the script, paste the S3 URL and hit Enter. The Script downloads the file from S3 and opens the folder `Downloads`:

{% embed https://vimeo.com/963047788?share=copy %}

The Script Command is available on the official [GitHub repository](https://github.com/raycast/script-commands/blob/master/commands/developer-utils/aws/amazon-s3-download.sh), but I have pasted it here for convenience:

```sh
#!/bin/bash

# Required parameters:
# @raycast.schemaVersion 1
# @raycast.title S3 Download
# @raycast.mode fullOutput

# Optional parameters:
# @raycast.icon images/amazon-s3.png
# @raycast.packageName AWS

# Documentation:
# @raycast.description Download from Amazon S3 via URL
# @raycast.argument1 { "type": "text", "placeholder": "S3 URL" }
# @raycast.author Chris Cook
# @raycast.authorURL https://github.com/zirkelc

URL=$1

# Ensure AWS CLI is installed
if ! command -v aws &> /dev/null; then
	echo "AWS CLI not found. Please install AWS CLI."
	echo "Installation instructions: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html"
	exit 1
fi

# Try matching different S3 URL patterns
# https://dev.to/aws-builders/format-and-parse-amazon-s3-url-5e10
if [[ $URL =~ ^https?://s3\.([a-z0-9-]+)\.amazonaws\.com/([^/]+)/(.*)$ ]]; then
    # Regional hostname with path-style
		BUCKET="${BASH_REMATCH[2]}"
		KEY="${BASH_REMATCH[3]}"
elif [[ $URL =~ ^https?://([^/]+)\.s3\.([a-z0-9-]+)\.amazonaws\.com/(.*)$ ]]; then
    # Regional hostname with virtual-hosted-style
		BUCKET="${BASH_REMATCH[1]}"
		KEY="${BASH_REMATCH[3]}"
elif [[ $URL =~ ^https?://s3\.amazonaws\.com/([^/]+)/(.*)$ ]]; then
    # Legacy hostname with path-style
		BUCKET="${BASH_REMATCH[1]}"
		KEY="${BASH_REMATCH[2]}"
elif [[ $URL =~ ^https?://([^/]+)\.s3\.amazonaws\.com/(.*)$ ]]; then
    # Legacy hostname with virtual-hosted-style
		BUCKET="${BASH_REMATCH[1]}"
		KEY="${BASH_REMATCH[2]}"
elif [[ $URL =~ ^s3://([^/]+)/(.*)$ ]]; then
    # S3 URI
		BUCKET="${BASH_REMATCH[1]}"
		KEY="${BASH_REMATCH[2]}"		
else
    echo "Invalid URL: $URL"
    echo "URL must match recognized S3 patterns."
    exit 1
fi

# Check for empty bucket or key
if [[ -z "$BUCKET" || -z "$KEY" ]]; then
    echo "Error extracting bucket and key from URL: $URL"
    exit 1
fi

# Remove trailing slash if present and set recursive download flag
RECURSIVE=""
if [[ "$KEY" =~ .*/$ ]]; then
	KEY="${KEY%/}"  # Remove trailing slash for directory key
	RECURSIVE="--recursive"
fi

# Set download path
DOWNLOAD_FOLDER="$HOME/Downloads"
DOWNLOAD_PATH="$DOWNLOAD_FOLDER/$KEY"

if [[ -n "$RECURSIVE" ]]; then
	echo "Downloading directory $URL to $DOWNLOAD_PATH..."
else
	echo "Downloading file $URL to $DOWNLOAD_PATH..."
fi

# Print bucket and key
echo "Bucket: $BUCKET"
echo "Key: $KEY"

# Use recursive if necessary
if aws s3 cp "s3://$BUCKET/$KEY" "$DOWNLOAD_PATH" $RECURSIVE; then
	echo "Downloaded successfully."
	open "$DOWNLOAD_FOLDER"
else
	echo "Download failed."
	exit 1
fi
```

I assume the code with the comments is explanatory enough. The cool thing is, it uses the AWS CLI installed on your local machine. So you don't have to expose your access keys to a third-party service; it stays on your machine. It also supports different [S3 URL formats](https://dev.to/aws-builders/format-and-parse-amazon-s3-url-5e10), including the HTTPS endpoints, and you can even download an entire folder.

If you want to use it yourself, follow these steps to add the Script to your own Raycast: [Install script commands from this repository](https://github.com/raycast/script-commands/tree/master?tab=readme-ov-file#install-script-commands-from-this-repository).