Django storage backend for RustFS; an S3-compatible object storage server.
pip install django-rustfsInstallation - Quick Start - Configuration - Advanced Usage - Contributing
You can already use RustFS with Django via django-storages + boto3. So why another package?
django-storages is great for AWS S3, but using it with RustFS means:
- Pretending RustFS is AWS (
AWS_S3_ENDPOINT_URL,AWS_ACCESS_KEY_ID...) - Configuring 10+ settings you do not need
- No built-in health checks or bucket setup tools
- Writing custom code for static files
django-rustfs is purpose-built for RustFS:
| Feature | django-storages + boto3 | django-rustfs |
|---|---|---|
| Configuration | 10+ AWS-branded settings | 4 clean settings (RUSTFS_ENDPOINT, RUSTFS_ACCESS_KEY, RUSTFS_SECRET_KEY, RUSTFS_BUCKET_NAME) |
| Scope | General-purpose (S3, Azure, GCP...) | Built exclusively for RustFS |
| Bucket setup | Manual CLI/console | python manage.py rustfs_init_buckets |
| Health checks | None | python manage.py rustfs_health |
| Static files | Custom subclass required | RustFSStaticStorage included |
| Dependencies | django-storages + boto3 |
boto3 only |
| Codebase | ~1,500 lines | ~400 lines focused on RustFS |
Bottom line: If you are using RustFS,
django-rustfsremoves the mental overhead of pretending you are configuring AWS S3.
pip install django-rustfsRequirements:
- Python 3.9+
- Django 4.2+
- boto3 1.28+
# settings.py
INSTALLED_APPS = [
# ... your apps
"django_rustfs",
]# settings.py
# Required
RUSTFS_ENDPOINT = "http://localhost:9000"
RUSTFS_ACCESS_KEY = "your-access-key"
RUSTFS_SECRET_KEY = "your-secret-key"
# Optional (defaults shown)
RUSTFS_BUCKET_NAME = "django-media"
RUSTFS_AUTO_CREATE_BUCKET = TrueDjango 4.2+ (recommended):
# settings.py
STORAGES = {
"default": {
"BACKEND": "django_rustfs.storage.RustFSStorage",
},
"staticfiles": {
"BACKEND": "django_rustfs.storage.RustFSStaticStorage",
},
}Django < 4.2:
DEFAULT_FILE_STORAGE = "django_rustfs.storage.RustFSStorage"
STATICFILES_STORAGE = "django_rustfs.storage.RustFSStaticStorage"python manage.py rustfs_init_bucketspython manage.py rustfs_healthOutput:
🔍 Checking RustFS health...
Endpoint: http://localhost:9000
Bucket: django-media
✅ Bucket 'django-media' is accessible
Response time: 12.3ms
✅ List operation works (0 objects visible)
🧪 Running upload/download roundtrip test...
✅ Upload/download roundtrip successful
✅ RustFS health check completed successfully!
All settings use the RUSTFS_ prefix for clarity.
| Setting | Description |
|---|---|
RUSTFS_ENDPOINT |
RustFS server URL, e.g. "http://localhost:9000" |
RUSTFS_ACCESS_KEY |
RustFS access key |
RUSTFS_SECRET_KEY |
RustFS secret key |
| Setting | Default | Description |
|---|---|---|
RUSTFS_BUCKET_NAME |
"django-media" |
Default bucket for media files |
RUSTFS_STATIC_BUCKET_NAME |
"django-static" |
Bucket for static files |
RUSTFS_AUTO_CREATE_BUCKET |
True |
Auto-create buckets on first use |
RUSTFS_CUSTOM_DOMAIN |
"" |
CDN domain, e.g. "cdn.example.com" |
RUSTFS_SECURE_URLS |
True |
Use HTTPS in generated URLs |
RUSTFS_URL_EXPIRATION |
3600 |
Presigned URL expiry (seconds) |
RUSTFS_DEFAULT_ACL |
"private" |
Default ACL (private, public-read) |
RUSTFS_FILE_OVERWRITE |
False |
Allow overwriting existing files |
RUSTFS_LOCATION |
"" |
Prefix path for uploads, e.g. "media/" |
RUSTFS_REGION |
"us-east-1" |
Region name |
RUSTFS_USE_SSL |
False |
Use SSL/TLS for connections |
RUSTFS_VERIFY_SSL |
True |
Verify SSL certificates |
Check connectivity, authentication, and run an upload/download roundtrip test:
python manage.py rustfs_health
python manage.py rustfs_health --bucket=my-bucketCreate and configure RustFS buckets:
python manage.py rustfs_init_buckets # Create all buckets
python manage.py rustfs_init_buckets --bucket=X # Create specific bucket
python manage.py rustfs_init_buckets --public # Make buckets public
python manage.py rustfs_init_buckets --dry-run # Preview changesConfigure different buckets for different model fields:
from django.db import models
from django_rustfs.storage import RustFSStorage
# Private storage for documents
private_storage = RustFSStorage(
bucket_name="user-documents",
default_acl="private",
)
# Public storage for avatars
public_storage = RustFSStorage(
bucket_name="public-avatars",
default_acl="public-read",
presign_urls=False,
)
class UserProfile(models.Model):
avatar = models.ImageField(storage=public_storage, upload_to="avatars/")
documents = models.FileField(storage=private_storage, upload_to="docs/")Let browsers upload directly to RustFS without going through your Django server:
from django_rustfs.storage import RustFSStorage
storage = RustFSStorage()
post_data = storage.get_presigned_post_url(
name="uploads/user123/photo.jpg",
expires_in=600,
)
# Returns:
# {
# "url": "http://localhost:9000/django-media",
# "fields": {
# "key": "uploads/user123/photo.jpg",
# "AWSAccessKeyId": "...",
# "policy": "...",
# "signature": "..."
# }
# }storage = RustFSStorage()
meta = storage.get_object_metadata("uploads/photo.jpg")
print(meta["etag"]) # "d41d8cd98f00b204e9800998ecf8427e"
print(meta["content_length"]) # 2048
print(meta["storage_class"]) # "STANDARD"
print(meta["version_id"]) # "uuid-v1"storage.copy_object("uploads/photo.jpg", "backups/photo-backup.jpg")┌─────────────┐ ┌─────────────────┐ ┌─────────────┐
│ Django │──────│ django-rustfs │──────│ boto3 │
│ │ │ (this package) │ │ (AWS SDK) │
└─────────────┘ └─────────────────┘ └──────┬──────┘
│
HTTP/HTTPS
│
┌─────────┐
│ RustFS │
│ Server │
└─────────┘
django-rustfs uses boto3 to communicate with RustFS. RustFS is fully S3-compatible, so the AWS SDK works out of the box - we just wrap it in a purpose-built API.
git clone https://github.com/CasualEngineerZombie/django-rustfs.git
cd django-rustfs
pip install -e ".[dev]"pytestWith coverage:
pytest --cov=django_rustfs --cov-report=htmlruff check . # Linting
ruff format . # Formatting
mypy django_rustfs # Type checkingdjango-rustfs/
├── django_rustfs/ # Main package
│ ├── storage.py # Core storage backend
│ ├── conf.py # Settings configuration
│ └── management/ # Management commands
│ └── commands/
│ ├── rustfs_health.py
│ └── rustfs_init_buckets.py
├── tests/ # Test suite
├── .github/workflows/ # CI/CD
├── pyproject.toml # Package config
└── README.md # This file
Contributions are welcome! See CONTRIBUTING.md for guidelines.
Quick start for contributors:
git clone https://github.com/CasualEngineerZombie/django-rustfs.git
cd django-rustfs
pip install -e ".[dev]"
pytestSee RELEASE_GUIDE.md for step-by-step instructions on publishing to PyPI.
- RustFS-native features - Expose RustFS-specific capabilities (replication, lifecycle rules, event notifications)
- Django Admin integration - View bucket contents and storage statistics
- Management commands -
sync_to_rustfs,sync_from_rustfs,clean_orphaned - Async support -
aioboto3-based async storage backend - URL caching - Cache presigned URLs with Django's cache framework
- Multipart upload - Resumable multipart uploads for large files
- Streaming responses - Memory-efficient
FileResponsewrapper
Apache 2.0 - see LICENSE file.