Submit static files from CDN, not to flask in production

In my Flask application, I serve static assets through the application in dev env, but I would like to use CDN in production. Each asset is loaded into a template called base.hmtl , so I think the easiest solution is to pass the variable to the rendering function and use it in the template, for example:

 <script src="{{ STATIC_URL }}/js/main.js"></script> 

Normally this would be an empty line in dev env and url cdn during production. I would like to avoid passing this STATIC_URL variable for each view. I could make it work with

 @bp.context_processor def set_static_path(): return dict(STATIC_URL='https://foo.bar.com') 

But for me it seems a bit hacked. Is there a better way to solve this problem?

+8
python flask jinja2
source share
3 answers

There is no need to change the way static files are referenced, you can still use url_for('static', filename='myfile.txt') . Replace the default static view with the one that redirects to the CDN, if configured.

 from urllib.parse import urljoin # or for python 2: from urlparse import urljoin from flask import redirect @app.endpoint('static') def static(filename): static_url = app.config.get('STATIC_URL') if static_url: return redirect(urljoin(static_url, filename)) return app.send_static_file(filename) 

Regardless of whether you work on the developer's computer or on STATIC_URL , set STATIC_URL configuration to CDN, and requests for static files will be redirected there.


Redirects are relatively cheap and remembered by browsers. If you get to the point where they will significantly affect performance, you can write a function that communicates directly when using CDN.

 @app.template_global() def static_url(filename): static_url = app.config.get('STATIC_URL') if static_url: return urljoin(static_url, filename) return url_for('static', filename=filename) 

The template_global decorator makes the function available in all templates. Use it instead of url_for when you need links for static files.


There may be a Flask extension that already does this for you. For example, Flask-S3 provides url_for which serves static files from AWS S3.

+13
source share

This cdn flask integration guide may be worth a read. Basically, you can install the Flask-CDN extension and define your CDN URL in the app.py file as follows:

 from flask import Flask from flask.ext.cdn import CDN app = Flask(__name__) app.config['CDN_DOMAIN'] = 'cdn.yourdomain.com' CDN(app) 
+2
source share

I had a similar problem using Flask Assets and Flask-CDN. I found that Flask-CDN is trying and cannot generate timestamps for each asset. If unsuccessful, it will return to the relative URL.

Adding app.config['CDN_TIMESTAMP'] = False problem.

0
source share

All Articles