AWS SDK for Python (boto3)
boto3 is the AWS SDK for Python and works with Filebase by overriding endpoint_url and region_name.
Install
pip install boto3
For typed code, install the corresponding stubs:
pip install boto3-stubs[s3] mypy-boto3-s3
Initialize the client
filebase_client.py
import os
import boto3
from botocore.config import Config
s3 = boto3.client(
's3',
endpoint_url='https://s3.filebase.io',
region_name='auto',
aws_access_key_id=os.environ['FILEBASE_KEY'],
aws_secret_access_key=os.environ['FILEBASE_SECRET'],
config=Config(
signature_version='s3v4',
retries={'max_attempts': 5, 'mode': 'standard'},
),
)
List buckets
for bucket in s3.list_buckets()['Buckets']:
print(bucket['Name'])
Create a bucket
s3.create_bucket(Bucket='my-bucket')
# Public bucket
s3.create_bucket(Bucket='my-public-bucket', ACL='public-read')
Upload an object
with open('photo.jpg', 'rb') as f:
s3.put_object(
Bucket='my-bucket',
Key='photo.jpg',
Body=f,
ContentType='image/jpeg',
CacheControl='public, max-age=31536000',
)
For large files, use the high-level upload_file:
from boto3.s3.transfer import TransferConfig
config = TransferConfig(
multipart_threshold=8 * 1024 * 1024,
multipart_chunksize=8 * 1024 * 1024,
max_concurrency=4,
)
s3.upload_file(
Filename='./video.mp4',
Bucket='my-bucket',
Key='video.mp4',
Config=config,
ExtraArgs={'ContentType': 'video/mp4'},
)
upload_file automatically switches to multipart upload above the threshold.
List objects
paginator = s3.get_paginator('list_objects_v2')
for page in paginator.paginate(Bucket='my-bucket', Prefix='photos/'):
for obj in page.get('Contents', []):
print(obj['Key'], obj['Size'])
The paginator handles continuation tokens for you.
Download an object
# To a file
s3.download_file(
Bucket='my-bucket',
Key='photo.jpg',
Filename='downloaded.jpg',
)
# To memory
response = s3.get_object(Bucket='my-bucket', Key='photo.jpg')
data = response['Body'].read()
Delete an object
s3.delete_object(Bucket='my-bucket', Key='photo.jpg')
# Bulk delete
s3.delete_objects(
Bucket='my-bucket',
Delete={'Objects': [{'Key': 'a.jpg'}, {'Key': 'b.jpg'}]},
)
Pre-signed URLs
# Download URL
url = s3.generate_presigned_url(
'get_object',
Params={'Bucket': 'my-bucket', 'Key': 'private.pdf'},
ExpiresIn=3600,
)
# Upload URL
url = s3.generate_presigned_url(
'put_object',
Params={
'Bucket': 'uploads',
'Key': f'user-{user_id}/{filename}',
'ContentType': 'image/jpeg',
},
ExpiresIn=600,
)
# Pre-signed POST (form-data uploads with constraints)
post = s3.generate_presigned_post(
Bucket='uploads',
Key='user-${user_id}/${filename}',
Conditions=[
['content-length-range', 0, 10 * 1024 * 1024], # 10 MB max
['starts-with', '$Content-Type', 'image/'],
],
ExpiresIn=600,
)
Resource API
Prefer the higher-level resource interface? boto3 supports it:
import boto3
from botocore.config import Config
resource = boto3.resource(
's3',
endpoint_url='https://s3.filebase.io',
region_name='auto',
aws_access_key_id=os.environ['FILEBASE_KEY'],
aws_secret_access_key=os.environ['FILEBASE_SECRET'],
config=Config(signature_version='s3v4'),
)
bucket = resource.Bucket('my-bucket')
for obj in bucket.objects.filter(Prefix='photos/'):
print(obj.key, obj.size)
obj = bucket.Object('photo.jpg')
obj.upload_file('./photo.jpg')
obj.download_file('./downloaded.jpg')
Error handling
from botocore.exceptions import ClientError
try:
s3.head_object(Bucket='my-bucket', Key='maybe-exists.jpg')
except ClientError as e:
if e.response['Error']['Code'] == '404':
print('Object does not exist')
else:
raise
What's next
- Pre-signed URLs
- Django integration
- Apache Libcloud — alternative cloud-storage abstraction
- Migrating from AWS S3