Skip to content

Cloudflare R2

The utkit.store.cloudflare.r2 module provides a simple interface for interacting with Cloudflare R2 storage using boto3.

Installation

Install boto3 as an optional dependency:

pip install "utkit[store]"
# or
pip install boto3

Quick start

from utkit.store.cloudflare import R2Client

# Configure R2 credentials
r2 = R2Client(
    account_id="your-account-id",
    access_key="your-access-key",
    secret_key="your-secret-key",
)

try:
    # List buckets
    response = r2.s3.list_buckets()
    for bucket in response['Buckets']:
        print(f"  {bucket['Name']}")

    # Upload a file
    r2.s3.upload_file(
        'local_file.txt', 
        'my-bucket', 
        'remote_file.txt'
    )

    # Download a file
    r2.s3.download_file(
        'my-bucket', 
        'remote_file.txt', 
        'local_file.txt'
    )

    # Generate presigned URL (for sharing)
    url = r2.s3.generate_presigned_url(
        'my-bucket', 
        'remote_file.txt', 
        expiration=3600
    )
    print(url)
except Exception as e:
    print(f"Error: {e}")

R2Client

Configuration for Cloudflare R2 credentials and endpoint.

class R2Client:
    def __init__(
        self,
        account_id: Optional[str] = None,
        access_key: Optional[str] = None,
        secret_key: Optional[str] = None,
    ):
        # Fetch from environment variables if not provided
        self.account_id = account_id or os.getenv("R2_ACCESS_KEY_ID")
        self.access_key = access_key or os.getenv("R2_ACCESS_KEY")
        self.secret_key = secret_key or os.getenv("R2_SECRET_ACCESS_KEY")

        # Validate required values
        if not self.account_id or not self.access_key or not self.secret_key:
            raise ValueError(
                "R2 credentials missing. Please provide account_id, access_key, and secret_key either as parameters or via environment variables (R2_ACCESS_KEY_ID, R2_ACCESS_KEY, R2_SECRET_ACCESS_KEY)"
            )

        # Get endpoint from environment or generate from account_id
        endpoint = os.getenv("R2_ENDPOINT")
        if endpoint:
            self.base_url = endpoint
        else:
            self.base_url = f"https://{self.account_id}.r2.cloudflarestorage.com"

        # Initialize boto3 client for R2
        self.s3 = boto3.client(
            service_name='s3',
            endpoint_url=self.base_url,
            aws_access_key_id=self.access_key,
            aws_secret_access_key=self.secret_key,
            region_name='auto',
        )
Field Type Description
account_id Optional[str] Cloudflare R2 account ID
access_key Optional[str] R2 access key
secret_key Optional[str] R2 secret access key

Environment Variables:

Variable Description
R2_ACCESS_KEY_ID Cloudflare R2 account ID (alternative to parameter)
R2_ACCESS_KEY R2 access key (alternative to parameter)
R2_SECRET_ACCESS_KEY R2 secret access key (alternative to parameter)
R2_ENDPOINT Custom endpoint URL (alternative to auto-generated)

Environment Configuration:

For production deployments, it's recommended to use environment variables instead of passing credentials directly:

export R2_ACCESS_KEY_ID="your-account-id"
export R2_ACCESS_KEY="your-access-key"
export R2_SECRET_ACCESS_KEY="your-secret-key"
export R2_ENDPOINT="https://your-custom-endpoint.com"

Then initialize the client without parameters:

from utkit.store.cloudflare import R2Client

r2 = R2Client()

Method: - s3 — boto3 S3 client configured for R2 (read-only property)


Using R2 with boto3

The R2Client class initializes a boto3 S3 client configured specifically for Cloudflare R2. All standard boto3 S3 operations are available through the s3 property:

Available Operations

s3.list_buckets()

Retrieve the list of existing R2 buckets.

s3.upload_file(local_path, bucket_name, object_name)

Upload a file to R2.

s3.download_file(bucket_name, object_name, local_path)

Download a file from R2.

s3.generate_presigned_url(bucket_name, object_name, expiration)

Generate a presigned URL for sharing objects.

s3.head_object(bucket_name, object_name)

Get metadata about an object.

s3.delete_object(bucket_name, object_name)

Delete an object from R2.

s3.put_object(bucket_name, object_name, body)

Upload an object with content.

s3.get_object(bucket_name, object_name)

Retrieve an object with content.


Environment Configuration

For production deployments, it's recommended to use environment variables instead of passing credentials directly:

export R2_ACCESS_KEY_ID="your-account-id"
export R2_ACCESS_KEY="your-access-key"
export R2_SECRET_ACCESS_KEY="your-secret-key"
export R2_ENDPOINT="https://your-custom-endpoint.com"

Then initialize the client without parameters:

from utkit.store.cloudflare import R2Client

r2 = R2Client()

Error Handling

The R2Client class raises ValueError if any required credentials are missing:

try:
    r2 = R2Client()
except ValueError as e:
    print(f"Configuration error: {e}")

Common error scenarios: - Missing environment variables - Invalid credentials - Network connectivity issues - Bucket not found


Performance Tips

  1. Connection Pooling: The boto3 client uses connection pooling by default
  2. Batch Operations: Use batch operations for multiple file uploads/downloads
  3. Presigned URLs: Use presigned URLs for temporary file sharing instead of direct downloads
  4. Error Retries: Configure retry settings for transient failures

Migration from AWS S3

Cloudflare R2 is S3-compatible, so most AWS S3 code will work with R2 with minimal changes:

  • Replace AWS credentials with R2 credentials
  • Update endpoint URL to R2 endpoint
  • Consider using region_name='auto' for R2
  • R2 pricing is typically more cost-effective than AWS S3