I am trying to reroute all of my /static content to host on Amazon S3. My first thought was to use global config['path'] throughout my jinja templates, but this won't work for external css and js files, plus it is kind of messy. I found the static_folder and static_url_path released in 0.7 and this seems like what I want. However, when I go to http://localhost:8000/static/img/abc.jpg it does not locate the files on S3. Am I using this feature right or is there some other way to do this?
Thanks!
Static files in Flask have a special route. All application URLs that begin with "/static", by convention, are served from a folder located at "/static" inside your application's root folder.
You can use Amazon S3 to host a static website. On a static website, individual webpages include static content. They might also contain client-side scripts. By contrast, a dynamic website relies on server-side processing, including server-side scripts, such as PHP, JSP, or ASP.NET.
Flask – Static Files Usually, the web server is configured to serve them for you, but during the development, these files are served from static folder in your package or next to your module and it will be available at /static on the application. A special endpoint 'static' is used to generate URL for static files.
I recently developed a Flask extension to deal with just this situation. It's called Flask-S3, and you can read the documentation for it here.
As an example, here is how you would integrate it into your Flask application:
from flask import Flask
from flask_s3 import FlaskS3
app = Flask(__name__)
app.config['S3_BUCKET_NAME'] = 'mybucketname'
s3 = FlaskS3(app)
You can use the extension to upload your assets to your chosen bucket:
>>> from my_application import app
>>> from flask_s3 import create_all
>>> create_all(app)
Flask-S3 is blueprint aware, and will upload all assets associated with any registered blueprints.
I wish the flask.Flask
constructor's static_url_path
argument would accept a full URI, but it screams about the path needing a leading slash when you try that. If it accepted it, you could just use url_for
after setting static_url_path='http://my_s3_bucket.aws.amazon.com/'
or so.
Another possible solution is to use a context processor. I believe this is the cleanest solution, but I don't have much experience with flask. It sure looks clean. Using a context processor, I pull the URL from the environment (I'm using heroku so it's wicked easy to set). Then the context processor makes the static_url variable available in my templates.
In app.py:
# Environment has STATIC_URL='http://my_s3_bucket.aws.amazon.com/'
@app.context_processor
def inject_static_url():
"""
Inject the variable 'static_url' into the templates. Grab it from
the environment variable STATIC_URL, or use the default.
Template variable will always have a trailing slash.
"""
static_url = os.environ.get('STATIC_URL', app.static_url_path)
if not static_url.endswith('/'):
static_url += '/'
return dict(
static_url=static_url
)
In the template:
<link rel="stylesheet" type="text/css" href="{{ static_url }}css/main.css" />
The result
<link rel="stylesheet" type="text/css" href="http://my_s3_bucket.aws.amazon.com/css/main.css" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With