mirror of
https://github.com/wassname/flask-s3.git
synced 2026-09-10 12:00:58 +08:00
Updates issue #7 - Brings back S3_USE_CACHE_CONTROL setting and fixes
some documentation issues.
This commit is contained in:
+25
-12
@@ -139,6 +139,22 @@ generated by Flask-S3 will look like the following:
|
||||
that ``mybucketname`` is the name of your S3 bucket, and you have chosen
|
||||
to have assets served over HTTPS.
|
||||
|
||||
Setting Custom HTTP Headers
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
To set custom HTTP headers on the files served from S3 specify what
|
||||
headers you want to use with the `S3_HEADERS` option.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
S3_HEADERS = {
|
||||
'Expires': 'Thu, 15 Apr 2010 20:00:00 GMT',
|
||||
'Cache-Control': 'max-age=86400',
|
||||
}
|
||||
|
||||
See `yahoo`_ more information on how to set good values for your headers.
|
||||
|
||||
.. _yahoo: http://developer.yahoo.com/performance/rules.html#expires
|
||||
|
||||
.. _settings:
|
||||
.. _configuration:
|
||||
@@ -147,7 +163,7 @@ Flask-S3 Options
|
||||
----------------
|
||||
|
||||
Within your Flask application's settings you can provide the following
|
||||
settings to control the behvaiour of Flask-S3. None of the settings are
|
||||
settings to control the behaviour of Flask-S3. None of the settings are
|
||||
required, but if not present, some will need to be provided when
|
||||
uploading assets to S3.
|
||||
|
||||
@@ -181,18 +197,15 @@ uploading assets to S3.
|
||||
templates will always include asset locations
|
||||
specified by `flask.url_for`.
|
||||
`S3_HEADERS` Sets custom headers to be sent with each file to S3.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
S3_HEADERS = {
|
||||
'Expires': 'Thu, 15 Apr 2010 20:00:00 GMT',
|
||||
'Cache-Control': 'max-age=86400',
|
||||
}
|
||||
|
||||
See http://developer.yahoo.com/performance/rules.html#expires
|
||||
for more information.
|
||||
|
||||
**Default:** `{}`
|
||||
`S3_CACHE_CONTROL` **Deprecated**. Please use `S3_HEADERS` instead.
|
||||
This sets the value of the Cache-Control header that
|
||||
is set in the metadata when `S3_USE_CACHE_CONTRL` is
|
||||
set to `True`.
|
||||
`S3_USE_CACHE_CONTROL` **Deprecated**. Please use `S3_HEADERS` instead.
|
||||
Specifies whether or not to set the metadata for the
|
||||
Cache-Control headers.
|
||||
**Default:** `False`
|
||||
=========================== ===================================================
|
||||
|
||||
.. _debug: http://flask.pocoo.org/docs/config/#configuration-basics
|
||||
|
||||
+22
-10
@@ -10,6 +10,7 @@ from boto.s3.key import Key
|
||||
|
||||
logger = logging.getLogger('flask_s3')
|
||||
|
||||
|
||||
def url_for(endpoint, **values):
|
||||
"""
|
||||
Generates a URL to the given endpoint.
|
||||
@@ -27,25 +28,27 @@ def url_for(endpoint, **values):
|
||||
app = current_app
|
||||
if 'S3_BUCKET_NAME' not in app.config:
|
||||
raise ValueError("S3_BUCKET_NAME not found in app configuration.")
|
||||
|
||||
|
||||
if app.debug and not app.config['USE_S3_DEBUG']:
|
||||
return flask_url_for(endpoint, **values)
|
||||
|
||||
|
||||
if endpoint == 'static' or endpoint.endswith('.static'):
|
||||
scheme = 'http'
|
||||
if app.config['S3_USE_HTTPS']:
|
||||
scheme = 'https'
|
||||
bucket_path = '%s.%s' % (app.config['S3_BUCKET_NAME'],
|
||||
bucket_path = '%s.%s' % (app.config['S3_BUCKET_NAME'],
|
||||
app.config['S3_BUCKET_DOMAIN'])
|
||||
urls = app.url_map.bind(bucket_path, url_scheme=scheme)
|
||||
return urls.build(endpoint, values=values, force_external=True)
|
||||
return flask_url_for(endpoint, **values)
|
||||
|
||||
|
||||
def _bp_static_url(blueprint):
|
||||
""" builds the absolute url path for a blueprint's static folder """
|
||||
u = u'%s%s' % (blueprint.url_prefix or '', blueprint.static_url_path or '')
|
||||
return u
|
||||
|
||||
|
||||
def _gather_files(app, hidden):
|
||||
""" Gets all files in static folders and returns in dict."""
|
||||
dirs = [(unicode(app.static_folder), app.static_url_path)]
|
||||
@@ -53,7 +56,7 @@ def _gather_files(app, hidden):
|
||||
blueprints = app.blueprints.values()
|
||||
bp_details = lambda x: (x.static_folder, _bp_static_url(x))
|
||||
dirs.extend([bp_details(x) for x in blueprints if x.static_folder])
|
||||
|
||||
|
||||
valid_files = defaultdict(list)
|
||||
for static_folder, static_url_loc in dirs:
|
||||
if not os.path.isdir(static_folder):
|
||||
@@ -67,10 +70,12 @@ def _gather_files(app, hidden):
|
||||
valid_files[(static_folder, static_url_loc)].extend(files)
|
||||
return valid_files
|
||||
|
||||
|
||||
def _path_to_relative_url(path):
|
||||
""" Converts a folder and filename into a ralative url path """
|
||||
return os.path.splitdrive(path)[1].replace('\\', '/')
|
||||
|
||||
|
||||
def _static_folder_path(static_url, static_folder, static_asset):
|
||||
"""
|
||||
Returns a path to a file based on the static folder, and not on the
|
||||
@@ -88,12 +93,13 @@ def _static_folder_path(static_url, static_folder, static_asset):
|
||||
# Now bolt the static url path and the relative asset location together
|
||||
return u'%s/%s' % (static_url.rstrip('/'), rel_asset.lstrip('/'))
|
||||
|
||||
def _write_files(app, static_url_loc, static_folder, files, bucket,
|
||||
|
||||
def _write_files(app, static_url_loc, static_folder, files, bucket,
|
||||
ex_keys=None):
|
||||
""" Writes all the files inside a static folder to S3. """
|
||||
for file_path in files:
|
||||
asset_loc = _path_to_relative_url(file_path)
|
||||
key_name = _static_folder_path(static_url_loc, static_folder,
|
||||
key_name = _static_folder_path(static_url_loc, static_folder,
|
||||
asset_loc)
|
||||
msg = "Uploading %s to %s as %s" % (file_path, bucket, key_name)
|
||||
logger.debug(msg)
|
||||
@@ -101,17 +107,22 @@ def _write_files(app, static_url_loc, static_folder, files, bucket,
|
||||
logger.debug("%s excluded from upload" % key_name)
|
||||
else:
|
||||
k = Key(bucket=bucket, name=key_name)
|
||||
if (app.config['S3_USE_CACHE_CONTROL'] and
|
||||
'S3_CACHE_CONTROL' in app.config):
|
||||
k.set_metadata('Cache-Control', app.config['S3_CACHE_CONTROL'])
|
||||
# Set custom headers
|
||||
for header, value in app.config['S3_HEADERS'].items():
|
||||
for header, value in app.config['S3_HEADERS'].iteritems():
|
||||
k.set_metadata(header, value)
|
||||
k.set_contents_from_filename(file_path)
|
||||
k.make_public()
|
||||
|
||||
|
||||
def _upload_files(app, files_, bucket):
|
||||
for (static_folder, static_url), names in files_.iteritems():
|
||||
_write_files(app, static_url, static_folder, names, bucket)
|
||||
|
||||
def create_all(app, user=None, password=None, bucket_name=None,
|
||||
|
||||
def create_all(app, user=None, password=None, bucket_name=None,
|
||||
location='', include_hidden=False):
|
||||
"""
|
||||
Uploads of the static assets associated with a Flask application to
|
||||
@@ -207,10 +218,11 @@ class FlaskS3(object):
|
||||
|
||||
:param app: the :class:`flask.Flask` application object.
|
||||
"""
|
||||
defaults = [('S3_USE_HTTPS', True),
|
||||
('USE_S3', True),
|
||||
defaults = [('S3_USE_HTTPS', True),
|
||||
('USE_S3', True),
|
||||
('USE_S3_DEBUG', False),
|
||||
('S3_BUCKET_DOMAIN', 's3.amazonaws.com'),
|
||||
('S3_USE_CACHE_CONTROL', False),
|
||||
('S3_HEADERS', {})]
|
||||
for k, v in defaults:
|
||||
app.config.setdefault(k, v)
|
||||
|
||||
@@ -7,6 +7,7 @@ from flask import Flask, render_template_string, Blueprint
|
||||
import flask_s3
|
||||
from flask_s3 import FlaskS3
|
||||
|
||||
|
||||
class FlaskStaticTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.app = Flask(__name__)
|
||||
@@ -28,12 +29,11 @@ class FlaskStaticTest(unittest.TestCase):
|
||||
""" Tests configuration vars exist. """
|
||||
FlaskS3(self.app)
|
||||
defaults = ('S3_USE_HTTPS', 'USE_S3', 'USE_S3_DEBUG',
|
||||
'S3_BUCKET_DOMAIN', 'S3_HEADERS')
|
||||
'S3_BUCKET_DOMAIN', 'S3_USE_CACHE_CONTROL', 'S3_HEADERS')
|
||||
for default in defaults:
|
||||
self.assertIn(default, self.app.config)
|
||||
|
||||
|
||||
|
||||
class UrlTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.app = Flask(__name__)
|
||||
@@ -117,10 +117,10 @@ class S3Tests(unittest.TestCase):
|
||||
self.app.testing = True
|
||||
self.app.config['S3_BUCKET_NAME'] = 'foo'
|
||||
self.app.config['S3_USE_CACHE_CONTROL'] = True
|
||||
self.app.config['S3_CACHE_CONTROL'] = 'cache instruction'
|
||||
self.app.config['S3_HEADERS'] = {
|
||||
'Expires': 'Thu, 31 Dec 2037 23:59:59 GMT',
|
||||
'Content-Encoding': 'gzip',
|
||||
'Cache-Control': 'max-age=86400'
|
||||
}
|
||||
|
||||
def test__bp_static_url(self):
|
||||
@@ -213,8 +213,8 @@ class S3Tests(unittest.TestCase):
|
||||
exclude = ['/foo/static/foo.css', '/foo/static/foo/bar.css']
|
||||
# we expect foo.css to be excluded and not uploaded
|
||||
expected = [call(bucket=None, name=u'/foo/static/bar.css'),
|
||||
call().set_metadata('Cache-Control', 'cache instruction'),
|
||||
call().set_metadata('Expires', 'Thu, 31 Dec 2037 23:59:59 GMT'),
|
||||
call().set_metadata('Cache-Control', 'max-age=86400'),
|
||||
call().set_metadata('Content-Encoding', 'gzip'),
|
||||
call().set_contents_from_filename('/home/z/bar.css')]
|
||||
flask_s3._write_files(self.app, static_url_loc, static_folder, assets,
|
||||
|
||||
Reference in New Issue
Block a user