Skip to main content

An S3 adapter for the Flask-Caching framework

Project description

When installed and configured, this package will allow you to utilize an AWS S3 bucket as the backend for Flask-Cache.

Yes, S3 is not a very good cache. But if millisecond performance is not a concern, S3 is a low-effort and simple to implement alternative that is far less costly than Redis or Memcache.

Installation

Install via pip directly, or whatever your preferred dependency/package environment manager may be (poetry, pipenv, …):

pip install flask-cache-s3

Configuration

Configuration is straightforward, and is identical to the usual process for configuring Flask-Cache. Note that the mechanism by which you choose to configure is up to you; the example below is simply for illustrative purposes:

from flask import Flask
from flask_caching import Cache

config = {
    # The import path of the S3 cache backend
    "CACHE_TYPE": "flask_caching_s3.S3Cache",
    # The bucket name where you'd like cache artifacts to be stored/queried
    "CACHE_S3_BUCKET": "your-unique-bucket-name",
    # Optional key prefix
    "CACHE_KEY_PREFIX": "cache_",
}

app = Flask(__name__)
app.config.from_mapping(config)
cache = Cache(app)

Of course, an application-factory is also supported:

from flask import Flask
from flask_caching import Cache

configuration = {
    # The import path of the S3 cache backend
    "CACHE_TYPE": "flask_caching_s3.S3Cache",
    # The bucket name where you'd like cache artifacts to be stored/queried
    "CACHE_S3_BUCKET": "your-unique-bucket-name",
    # Optional key prefix
    "CACHE_KEY_PREFIX": "cache_",
}

# Initialize the extension without the application object present,
# as is typical in the Flask application factory pattern
cache = Cache()

def create_app():
    """Create and configure an application instance."""

    app = Flask("factory-app")
    app.config.from_mapping(configuration)

    cache.init_app(app)

    return app

And in situations where you may want to have _multiple_ caching strategies with different backends, a per-object configuration is supported:

from flask import Flask
from flask_caching import Cache

s3_cache = Cache()
redis_cache = Cache()

def create_app():
    """Create and configure an application instance."""

    app = Flask("factory-app")

    # Setup our s3 cache
    s3_cache.init_app(
        app,
        config={
            "CACHE_TYPE": "flask_caching_s3.S3Cache",
            "CACHE_S3_BUCKET": "the-tholian-initiative"
        }
    )

    # And now, separately, we can setup our redis cache,
    # with redis-specific configuration options.
    redis_cache.init_app(
        app,
        config={
            "CACHE_TYPE": "RedisCache",
            "CACHE_REDIS_HOST": "example.com"
        }
    )

    return app

Configuration Options

Required

  • CACHE_S3_BUCKET: There’s only one required configuration, and that’s the S3 bucket name. Your bucket must already exist in S3, and you must set the correct ACLs/permissions for your application to read and write from it. This backend will do none of that work for you.

Optional

The following options can be provided to the S3Cache, but are entirely optional:

  • CACHE_KEY_PREFIX: A string that will be prepended to /every/ cache key, for both reads and writes. Useful if you want to use the same bucket for non-cache related things and avoid disaster when you call cache.clear() and wonder where all your S3 bucket contents have gone.

  • CACHE_DEFAULT_TIMEOUT: The number of seconds that an item in the cache is valid for. After this time has elapsed, the item is considered expired, and even if the item is still in the S3 bucket, a cache miss will occur.

  • CACHE_S3_ENDPOINT_URL: The endpoint for the S3 service. Typically this is only utilized when using something like localstack for local development/testing.

  • CACHE_OPTIONS: A dictionary of key/value pairs for more fine-grained configuration of how the cache will behave.

    s3_cache.init_app(
        app,
        config={
            "CACHE_TYPE": "flask_caching_s3.S3Cache",
            "CACHE_S3_BUCKET": "the-tholian-initiative",
            "CACHE_OPTIONS": {"purge_expired_on_read": True}
        }
    )

    The only key currently supported in CACHE_OPTIONS is the boolean purge_expired_on_read, which defaults to False. If set to True, items will be evicted from S3 if Flask-Cache`` attempts to read them (via cache.get() or cache.has(), for example) and they have expired.

S3 Object Lifecycle Management

The use of purge_expired_on_read does incur a performance penalty since the eviction/deletion is performed in the same operation, and it also means that if some items are never accessed, they will continue to exist in the bucket far beyond their expiration.

The proper solution to this is to create an S3 object lifecycle rule which can clean up objects for you. Care must be taken here, though, since you cannot rely on the CACHE_DEFAULT_TIMEOUT value as the boundary value for object lifetimes; users of Flask-Cache can always override the default timeout at call-time with e.g.:

@app.route("/")
@cache.cached(timeout=50)
def index():
    return render_template('index.html')

Where cache.cached(timeout=3600) indicates that the cached object is valid for 3600 seconds, even though our default may be set to 300.

Thus, if you do choose to go with an Object Lifecycle Management rule, pick an Expiration policy that is beyond whatever maximum timeout value that you would conceivably apply.

Testing

  1. Have Docker installed and running

  2. Clone this repository

  3. Ensure you have poetry available on your system

  4. poetry run pytest

The test suite will spin up an ephemeral Docker container; it may take a few seconds for it to load. The relevant test fixtures will handle creating objects and their values in the Localstack S3 service.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flask_caching_s3-0.1.5.tar.gz (7.4 kB view details)

Uploaded Source

Built Distribution

flask_caching_s3-0.1.5-py3-none-any.whl (8.7 kB view details)

Uploaded Python 3

File details

Details for the file flask_caching_s3-0.1.5.tar.gz.

File metadata

  • Download URL: flask_caching_s3-0.1.5.tar.gz
  • Upload date:
  • Size: 7.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.4.2 CPython/3.10.13 Linux/6.2.0-1014-azure

File hashes

Hashes for flask_caching_s3-0.1.5.tar.gz
Algorithm Hash digest
SHA256 b6217370f68073707ba85c692d965913677995dc8b07da94c9e753773ac3c4ad
MD5 76075ee38b34a840b2886312911c0850
BLAKE2b-256 eb96e2e98f69b8511f35bf8304ca658281061d58310d68d9195a3828bd0b3dec

See more details on using hashes here.

File details

Details for the file flask_caching_s3-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: flask_caching_s3-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 8.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.4.2 CPython/3.10.13 Linux/6.2.0-1014-azure

File hashes

Hashes for flask_caching_s3-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 e8b823fd9239554f681dfda1837afe6f5d842f30fba2991861a21b86abf00cfe
MD5 2e279d61881ac20bf06f2575b281269a
BLAKE2b-256 78ac2f363245afbcb25fed69244827c9eb4258ce23850dadb02025d5ec3a5d5d

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page