Flask-CDN-NG

Flask-CDN-NG allows you to easily serve all your Flask application’s static assets from a CDN (like Amazon Cloudfront), without having to modify your templates.

How it works

Flask-CDN-NG replaces the URLs that Flask’s flask.url_for() function would insert into your templates, with URLs that point to your CDN. This makes setting up an origin pull CDN extremely easy.

Internally, every time url_for is called in one of your application’s templates, flask_cdn.url_for is instead invoked. If the endpoint provided is deemed to refer to static assets, then the CDN URL for the asset specified in the filename argument is instead returned. Otherwise, flask_cdn.url_for passes the call on to flask.url_for.

Installation

If you use pip then installation is simply:

$ pip install flask-cdn-ng

or, if you want the latest github version:

$ pip install git+git://git@github.com:s-m-i-t-a/flask-cdn-ng.git

You can also install Flask-CDN-NG via Easy Install:

$ easy_install flask-cdn-ng

Dependencies

  • Flask
  • requests

Note: Flask-CDN-NG currently only supports applications that use the jinja2 templating system.

Using Flask-CDN-NG

Flask-CDN-NG is incredibly simple to use. In order to start serving your Flask application’s assets from Amazon CDN, the first thing to do is let Flask-CDN-NG know about your flask.Flask application object.

from flask import Flask
from flask.ext.cdn import CDN

app = Flask(__name__)
app.config['CDN_DOMAIN'] = 'mycdnname.cloudfront.net'
CDN(app)

In many cases, however, one cannot expect a Flask instance to be ready at import time, and a common pattern is to return a Flask instance from within a function only after other configuration details have been taken care of. In these cases, Flask-CDN-NG provides a simple function, init_app, which takes your application as an argument.

from flask import Flask
from flask.ext.cdn import CDN

cdn = CDN()

def start_app():
    app = Flask(__name__)
    cdn.init_app(app)
    return app

In terms of getting your application to use external CDN URLs when referring to your application’s static assets, passing your Flask object to the CDN object is all that needs to be done. Once your app is running, any templates that contained relative static asset locations, will instead be pulled from your CDN.

Static Asset URLs

URLs generated by Flask-CDN-NG will look like the following:

/static/foo/style.css becomes https://mycdnname.cloudfront.net/static/foo/style.css, assuming that mycdnname.cloudfront.net is the domain of your CDN, and you have chosen to have assets served over HTTPS.

Flask-CDN-NG Options

Within your Flask application’s settings you can provide the following settings to control the behaviour of Flask-CDN-NG. None of the settings are required.

CDN_DEBUG Activate Debug mode to return relative url rather than CDN enabled ones. Default: app.debug
CDN_DOMAIN Set the base domain for your CDN here. Default: None
CDN_HTTPS Specifies whether or not to serve your assets over HTTPS. If not specified the asset will be served by the same method the request comes in as. Default: None
CDN_TIMESTAMP Specifies whether or not to add a timestamp to the generated urls. Default: True
CDN_MANIFEST Specifies whether or not to add a checksum from manifest file to the generated url. Default False
CDN_MANIFEST_URL URI to a manifest file. Eg. http://my.host.net/MANIFEST Default None

Serve Static Assets with CloudFront

CloudFront is a very simple way to seamlessly serve your static assets with it’s CDN. When a request comes into CloudFront, if the asset is not on the CDN or has expired, then CloudFront can get the asset from an “origin server”. This type of setup is called an origin pull CDN.

To setup a new CloudFront “Distribution”:

  • Signup for an AWS Account
  • Open the Cloudfront Management Console
  • Select Create Distribution
  • Leave Download selected as the delivery method and select Continue
  • In the Origin Domain Name field enter the domain name for your application
  • Change Forward Query Strings to Yes
  • Keep the other default values as-is and select Create Distribution

It will now take a few minutes for AWS to create the CloudFront distribution.

  • Set CDN_DOMAIN in your Flask app to the newly created ‘Domain Name’ of your Cloudfront CDN.

Then you are done! Next time someone visits your site Cloudfront will cache and serve everything under the /static/ directory.

API Documentation

Flask-CDN-NG is a very simple extension. The few exposed objects, methods and functions are as follows.

Manifest file format

Each line contains a checksum and two spaces separated relative file path.

afb9d1dccb6ae4b29df7a48dbd65fc4e  static/js/script.js
7fde23188113df6aa5a0ef2dd875e597  static/css/style.css

The CDN Object

class flask_cdn.CDN(app=None)[source]

The CDN object allows your application to use Flask-CDN.

When initialising a CDN object you may optionally provide your flask.Flask application object if it is ready. Otherwise, you may provide it later by using the init_app() method.

Parameters:app (flask.Flask or None) – optional flask.Flask application object
init_app(app)[source]
flask_cdn.url_for(endpoint, **values)[source]

Generates a URL to the given endpoint.

If the endpoint is for a static resource then a URL to the CDN is generated, otherwise the call is passed on to flask.url_for.

Because this function is set as a jinja environment variable when CDN.init_app is invoked, this function replaces flask.url_for in templates automatically. It is unlikely that this function will need to be directly called from within your application code, unless you need to refer to static assets outside of your templates.