Skip to main content

DJ KAOS Storages

A set of django media storage classes for different use cases such as private file storage on S3. An extension of jschneier 's django-storages

Quick Start

pip install dj-kaos-storages
# settings.py
import os

AWS_ACCESS_KEY_ID = os.environ['DJANGO_AWS_ACCESS_KEY_ID']
AWS_SECRET_ACCESS_KEY = os.environ['DJANGO_AWS_SECRET_ACCESS_KEY']
AWS_STORAGE_BUCKET_NAME = os.environ['DJANGO_AWS_STORAGE_BUCKET_NAME']
AWS_S3_REGION_NAME = os.environ.get('DJANGO_AWS_S3_REGION_NAME', None)

STORAGES_PUBLIC_MEDIA_LOCATION = 'media'
STORAGES_PRIVATE_MEDIA_LOCATION = 'private-media'
PUBLIC_FILE_STORAGE = 'kaos_storages.s3.PublicMediaFilesS3Storage'
PRIVATE_FILE_STORAGE = 'kaos_storages.s3.PrivateMediaFilesS3Storage'

# default storage is set to private, switch to PUBLIC_FILE_STORAGE for public default storage
DEFAULT_FILE_STORAGE = PRIVATE_FILE_STORAGE

if DEFAULT_FILE_STORAGE == PRIVATE_FILE_STORAGE:
    MEDIA_URL = f'https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/{STORAGES_PRIVATE_MEDIA_LOCATION}/'
if DEFAULT_FILE_STORAGE == PUBLIC_FILE_STORAGE:
    MEDIA_URL = f'https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/{STORAGES_PUBLIC_MEDIA_LOCATION}/'

Now if somebody goes to the url https://your-bucket.s3.amazonaws.com/private-media/path/to/your/file, they would get a 403, effectively making your media files private. The project loads the private media assets by appending a signature url param, that is only valid for a short period of time.

Rationale

It is a good idea to not store user uploaded files (i.e. media files) on the server you are running your application in. If you need to shut down the server, or it goes down for any reason, all those files are lost. Also storing user uploaded files on a server would potentially take up a massive amount of storage space on the server. For that reason it is better to store such files on a storage service such as S3. This package is an extension of django-storages and allows a few more granular common use cases.

Public vs Private media files

If you want media files to be only accessible through your application, and want to prevent users to put in the url in their browsers and access the files, you'd want to use a private media file storage. For example your application might generate confidential PDF report files that you want to only be accessible through your dashboard and not using a publicly available URL.

AWS S3

dj-kaos-storage comes with 3 classes to handle external storage on Amazon S3. All the following classes require adding the necessary settings for django-storages. Refer to django-storages's documentation for more details.

AWS_ACCESS_KEY_ID = os.environ['DJANGO_AWS_ACCESS_KEY_ID']
AWS_SECRET_ACCESS_KEY = os.environ['DJANGO_AWS_SECRET_ACCESS_KEY']
AWS_STORAGE_BUCKET_NAME = os.environ['DJANGO_AWS_STORAGE_BUCKET_NAME']
AWS_S3_REGION_NAME = os.environ.get('DJANGO_AWS_S3_REGION_NAME', None)

StaticFilesS3Storage

To store static files on S3. The management command collectstaic will put all your static files on S3 at the location described by settings.STORAGES_STATICFILES_LOCATION. In order to use this class:

# settings.py 
STORAGES_STATICFILES_LOCATION = 'static'  # or anything else for that matter
STATICFILES_STORAGE = 'kaos_storages.s3.StaticFilesS3Storage'

Note you can omit settings.STORAGES_STATICFILES_LOCATION, and by default it is set to static.

PublicMediaFilesS3Storage

To store public media files on S3. In order to use:

# settings.py 
STORAGES_PUBLIC_MEDIA_LOCATION = 'media'  # or anything else for that matter
PUBLIC_FILE_STORAGE = 'kaos_storages.s3.PublicMediaFilesS3Storage'
DEFAULT_FILE_STORAGE = PUBLIC_FILE_STORAGE
MEDIA_URL = f'https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/{STORAGES_PUBLIC_MEDIA_LOCATION}/'

PrivateMediaFilesS3Storage

To store private media files on S3. In order to use:

# settings.py 
STORAGES_PRIVATE_MEDIA_LOCATION = 'private-media'  # or anything else for that matter
PRIVATE_FILE_STORAGE = 'kaos_storages.s3.PrivateMediaFilesS3Storage'
DEFAULT_FILE_STORAGE = PRIVATE_FILE_STORAGE
MEDIA_URL = f'https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/{STORAGES_PRIVATE_MEDIA_LOCATION}/'

How to use both private and public media storage in a project

It is possible to use both public and private media storage in a project. In order to do so, first decide which mode of storage is going to be the default one. We suggest if you are developing an internal facing application (such as a company dashboard) to use private media storage as the default. If you are developing a public facing application (i.e. a social network) to use public media storage as the default. In the case you need to store some file privately when the default is public (and vice versa) use the following method:

# settings.py 
STORAGES_PUBLIC_MEDIA_LOCATION = 'media'
STORAGES_PRIVATE_MEDIA_LOCATION = 'private-media'
PUBLIC_FILE_STORAGE = 'kaos_storages.s3.PublicMediaFilesS3Storage'
PRIVATE_FILE_STORAGE = 'kaos_storages.s3.PrivateMediaFilesS3Storage'

# default being public 
DEFAULT_FILE_STORAGE = PUBLIC_FILE_STORAGE
MEDIA_URL = f'https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/{STORAGES_PUBLIC_MEDIA_LOCATION}/'

# default being private 
DEFAULT_FILE_STORAGE = PRIVATE_FILE_STORAGE
MEDIA_URL = f'https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/{STORAGES_PRIVATE_MEDIA_LOCATION}/'

In your django models, say the default is private storage, and you want some model's field's uploaded files to be public:

from django.db import models
from kaos_storages.s3 import PublicMediaFilesS3Storage


# models.py
class SomeModelWithPublicFileField(models.Model):
    file = models.FileField(storage=PublicMediaFilesS3Storage)

Keep in mind, you might have different settings for your local and production environments. Most likely your local environment doesn't differentiate between public and private file uploads, and has no concept of S3 and PublicMediaFilesS3Storage.

PublicFileField and PrivateFileField

For your convenience dj-kaos-storages comes with a number of FileField classes and mixins that abstracts the above that set the storage class of the field to class importable from the path described by settings.PUBLIC_FILE_STORAGE and settings.PRIVATE_FILE_STORAGE for public and private uploads, respectively. When DEBUG=True which signals a dev environment, PUBLIC_FILE_STORAGE and PRIVATE_FILE_STORAGE are set by default to django.core.files.storage.FileSystemStorage, which is the Django default. This way the helper classes such as PublicFileField and PrivateFileField will save to your filesystem in your local development environment. If your settings has set PUBLIC_FILE_STORAGE and/or PRIVATE_FILE_STORAGE they are respected and won't be overridden (e.g. you turn on DEBUG = True in a staging environment).

In the example above:

from django.db import models
from kaos_storages.fields import PublicFileField


# models.py
class SomeModelWithPublicFileField(models.Model):
    file = PublicFileField()

Notice how we swapped the default models.FileField with kaos_storages.fields.PublicFileField.

List of all fields available:

  • PublicFileField
  • PrivateFileField
  • PublicImageField
  • PrivateImageField

There are also two mixins classes available, so you can create your own children of FileField:

  • PublicFileFieldMixin
  • PrivateFileFieldMixin

Development and Testing

IDE Setup

Add the example directory to the PYTHONPATH in your IDE to avoid seeing import warnings in the tests modules. If you are using PyCharm, this is already set up.

Running the Tests

Install requirements

pip install -r requirements.txt

For local environment

pytest

For all supported environments

tox

Metadata

Release files for dj-kaos-storages 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dj-kaos-storages 0.1.1
File Size Uploaded Provenance
dj-kaos-storages-0.1.1.tar.gz 6.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for dj-kaos-storages 0.1.1
File Interpreter ABI Platform
dj_kaos_storages-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 13.6 kB

Release files / dj-kaos-storages-0.1.1.tar.gz

Download URL dj-kaos-storages-0.1.1.tar.gz
Size 6.3 kB
Tags Source
SHA-256 checksum
How to use checksums
dc0ff645736175fdf9c517762cc390b7f2bd251b538514dd51293158f8dac6b5
BLAKE2b-256 checksum
How to use checksums
4029ef90be4cfa557991e4c2c9f15548721421f8510e4cd10e90fdce92643894
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.5.0 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.10

Release files / dj_kaos_storages-0.1.1-py3-none-any.whl

Download URL dj_kaos_storages-0.1.1-py3-none-any.whl
Size 7.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f7b24b3310bd32a7cb28fa1e00641f75297ec953f722fcfb298648c8edc9f58c
BLAKE2b-256 checksum
How to use checksums
16d92e243aa471d048f1656a0ef0b817dd503d4e5db9a3d89cfbb14f94e49413
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.5.0 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.10

Security for dj-kaos-storages 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page