minis3 is a modern, maintained fork of the popular tinys3 library. It provides a simple, Pythonic interface for interacting with Amazon S3 and S3-compatible storage services like MinIO, with enhanced features and better Python 2/3 compatibility.
- S3-Compatible: Works with AWS S3, MinIO, and other S3-compatible storage services.
- Modern Python Support: Compatible with Python 2.7 and Python 3.6+.
- Enhanced Security: AWS Signature Version 4 support by default.
- Flexible Connection: Support for custom endpoints, SSL/TLS control, and path-style requests.
- High-Performance Operations: Built-in connection pooling for concurrent uploads, downloads, and more.
- Rich Functionality: Full range of bucket and object operations, including multipart uploads.
- Easy to Use: Simple,
requests-inspired API.
pip install minis3Connect to your S3-compatible service by creating a Connection object.
import minis3
# Connect to AWS S3
conn = minis3.Connection(
access_key='YOUR_ACCESS_KEY',
secret_key='YOUR_SECRET_KEY',
tls=True # Use HTTPS (default)
)
# Upload a file
with open('local_file.txt', 'rb') as f:
conn.upload('remote_key.txt', f, bucket='my-bucket')
# Download a file
response = conn.get('remote_key.txt', bucket='my-bucket')
with open('downloaded_file.txt', 'wb') as f:
f.write(response.content)To connect to other S3-compatible services like MinIO, you need to specify the endpoint and adjust tls settings if necessary. For local development, you might also need path_style=True.
import minis3
# Connect to a local MinIO server
conn = minis3.Connection(
access_key='minioadmin',
secret_key='minioadmin',
endpoint='localhost:9000', # Your MinIO endpoint
tls=False, # Use HTTP for local dev
path_style=True, # Required for MinIO
verify=False # Disable SSL cert verification for self-signed certs
)
# Now you can use the connection as usual
# conn.create_bucket('my-new-bucket')minis3.Connection and minis3.Pool accept the following parameters:
access_key: Your S3 access key.secret_key: Your S3 secret key.endpoint: The S3 endpoint URL. Defaults to's3.amazonaws.com'.default_bucket: (Optional) A default bucket name to use for all operations.tls: (Default:True) Use HTTPS ifTrue, HTTP ifFalse.verify: (Default:True) Verify SSL certificates. Set toFalsefor services with self-signed certificates.signature_version: (Default:'s3v4') The AWS signature version. Use's3'for legacy services.path_style: (Default:False) IfTrue, use path-style URLs (endpoint/bucket/key) instead of virtual host-style (bucket.endpoint/key). Required for some S3-compatible services like MinIO.
You can create and delete buckets directly.
# Create a new bucket
conn.create_bucket('my-new-bucket')
print("Bucket 'my-new-bucket' created.")
# Delete a bucket
conn.delete_bucket('my-new-bucket')
print("Bucket 'my-new-bucket' deleted.")minis3 supports a wide range of object-level operations.
The upload method is highly flexible. You can control metadata, caching, and public access.
# Upload a file with custom metadata and caching
with open('profile.jpg', 'rb') as f:
conn.upload(
'user_profiles/profile.jpg',
f,
bucket='images',
public=True, # Make the object publicly readable
expires='max', # Cache for 1 year
content_type='image/jpeg',
headers={
'x-amz-storage-class': 'STANDARD_IA',
'x-amz-meta-user-id': '12345'
}
)The get method returns a requests.Response object.
response = conn.get('user_profiles/profile.jpg', bucket='images')
print(f"Status Code: {response.status_code}")
print(f"Content-Type: {response.headers['Content-Type']}")
# Save the content to a file
with open('downloaded_profile.jpg', 'wb') as f:
f.write(response.content)The list method returns an iterator for the objects in a bucket.
# List all objects with a given prefix
for obj in conn.list('user_profiles/', bucket='images'):
print(
f"Key: {obj['key']}, "
f"Size: {obj['size']}, "
f"Modified: {obj['last_modified']}"
)conn.delete('user_profiles/profile.jpg', bucket='images')Copy objects between buckets or within the same bucket.
conn.copy(
from_key='user_profiles/profile.jpg',
from_bucket='images',
to_key='archived_profiles/profile_old.jpg',
to_bucket='archive-bucket'
)You can retrieve an object's metadata with head_object or update it with update_metadata.
# Get object metadata
metadata = conn.head_object('remote_key.txt', bucket='my-bucket')
print(metadata)
# Update metadata for an existing object
conn.update_metadata(
'remote_key.txt',
bucket='my-bucket',
metadata={'x-amz-meta-reviewed': 'true'}
)For high-throughput applications, use minis3.Pool to perform operations concurrently using a thread pool. The API is the same as minis3.Connection, but methods return a Future object.
import minis3
import os
# Create a connection pool
pool = minis3.Pool(
access_key='YOUR_ACCESS_KEY',
secret_key='YOUR_SECRET_KEY',
size=20 # Number of worker threads
)
# Upload all files in a directory concurrently
futures = []
for filename in os.listdir('./my_files'):
filepath = os.path.join('./my_files', filename)
if os.path.isfile(filepath):
with open(filepath, 'rb') as f:
# Note: The file handle must remain open until the future completes
future = pool.upload(f'uploads/{filename}', f.read(), bucket='my-bucket')
futures.append(future)
# Wait for all uploads to complete and check results
for future in pool.as_completed(futures):
response = future.result()
print(f"Upload completed with status: {response.status_code}")
# The pool can also be used as a context manager
with minis3.Pool(access_key, secret_key, size=10) as pool:
# ... perform operations
pass # Pool is automatically closedFor files larger than a few megabytes, minis3 supports multipart uploads. This process is handled by the MultipartUpload helper.
from minis3 import MultipartUpload
# The source file
file_path = 'large_video.mp4'
# Initiate the multipart upload
with MultipartUpload(conn, file_path, 'videos/large_video.mp4', bucket='my-bucket') as uploader:
# The uploader will automatically read the file in chunks and upload them.
# You can monitor progress if needed.
print(f"Started multipart upload for {file_path} with ID: {uploader.upload_id}")
print("Multipart upload completed successfully.")'s3v4'(default): AWS Signature Version 4. Required for all modern AWS regions.'s3': AWS Signature Version 2. Legacy support for older storage systems.
minis3 is designed as a drop-in replacement for tinys3. Simply update your import statement:
# Old tinys3 code
# import tinys3
# conn = tinys3.Connection('key', 'secret')
# New minis3 code
import minis3
conn = minis3.Connection('key', 'secret')This project is licensed under the MIT License - see the LICENSE file for details.
- Original smore-inc/tinys3 library by Shlomi Atar
- Inspired by the excellent
requestslibrary - AWS S3 API documentation