general tidy up and version bump

This commit is contained in:
Edd Robinson
2013-03-10 16:17:31 +00:00
parent 23d3f4ada8
commit 1081e6754e
5 changed files with 120 additions and 89 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Edward Robinson <me@eddrobinson.net>
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
+57 -51
View File
@@ -2,8 +2,9 @@ Flask-S3
********
.. module:: flask_s3
Flask-S3 allows you to easily serve all your `Flask`_ application's static
assets from `Amazon S3`_, without having to modify your templates.
Flask-S3 allows you to easily serve all your `Flask`_ application's
static assets from `Amazon S3`_, without having to modify your
templates.
.. _Amazon S3: http://aws.amazon.com/s3
.. _Flask: http://flask.pocoo.org/
@@ -14,24 +15,26 @@ How it works
Flask-S3 has two main functions:
1. Walk through your application's static folders, gather all your static
assets together, and upload them to a bucket of your choice on S3;
1. Walk through your application's static folders, gather all your
static assets together, and upload them to a bucket of your choice
on S3;
2. Replace the URLs that Flask's :func:`flask.url_for` function would insert
into your templates, with URLs that point to the static assets in your S3
bucket.
2. Replace the URLs that Flask's :func:`flask.url_for` function would
insert into your templates, with URLs that point to the static
assets in your S3 bucket.
The process of gathering and uploading your static assets to S3 need only be
done once, and your application does not need to be running for it to work. The
location of the S3 bucket can be inferred from Flask-S3 `settings`_ specified in
your Flask application, therefore when your application is running there need
not be any communication between the Flask application and Amazon S3.
The process of gathering and uploading your static assets to S3 need
only be done once, and your application does not need to be running for
it to work. The location of the S3 bucket can be inferred from Flask-S3
`settings`_ specified in your Flask application, therefore when your
application is running there need not be any communication between the
Flask application and Amazon S3.
Internally, every time ``url_for`` is called in one of your application's
templates, `flask_s3.url_for` is instead invoked. If the endpoint provided is
deemed to refer to static assets, then the S3 URL for the asset specified in the
`filename` argument is instead returned. Otherwise, `flask_s3.url_for` passes
the call on to `flask.url_for`.
Internally, every time ``url_for`` is called in one of your
application's templates, `flask_s3.url_for` is instead invoked. If the
endpoint provided is deemed to refer to static assets, then the S3 URL
for the asset specified in the `filename` argument is instead returned.
Otherwise, `flask_s3.url_for` passes the call on to `flask.url_for`.
Installation
@@ -52,9 +55,10 @@ You can also install Flask-S3 via Easy Install::
Dependencies
------------
Aside from the obvious dependency of Flask itself, Flask-S3 makes use of the
`boto`_ library for uploading assets to Amazon S3. **Note**: Flask-S3 currently
only supports applications that use the `jinja2`_ templating system.
Aside from the obvious dependency of Flask itself, Flask-S3 makes use of
the `boto`_ library for uploading assets to Amazon S3. **Note**:
Flask-S3 currently only supports applications that use the `jinja2`_
templating system.
.. _boto: http://docs.pythonboto.org/en/latest/
.. _jinja2: http://jinja.pocoo.org/docs/
@@ -63,9 +67,9 @@ only supports applications that use the `jinja2`_ templating system.
Using Flask-S3
==============
Flask-S3 is incredibly simple to use. In order to start serving your Flask
application's assets from Amazon S3, the first thing to do is let Flask-S3 know
about your :class:`flask.Flask` application object.
Flask-S3 is incredibly simple to use. In order to start serving your
Flask application's assets from Amazon S3, the first thing to do is let
Flask-S3 know about your :class:`flask.Flask` application object.
.. code-block:: python
@@ -76,11 +80,11 @@ about your :class:`flask.Flask` application object.
app.config['S3_BUCKET_NAME'] = 'mybucketname'
s3 = FlaskS3(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-S3 provides a simple function, ``init_app``, which takes your
application as an argument.
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-S3 provides a simple function,
``init_app``, which takes your application as an argument.
.. code-block:: python
@@ -94,20 +98,21 @@ application as an argument.
s3.init_app(app)
return app
In terms of getting your application to use external Amazon S3 URLs when
referring to your application's static assets, passing your ``Flask`` object to
the ``FlaskS3`` object is all that needs to be done. Once your app is running,
any templates that contained relative static asset locations, will instead
contain hosted counterparts on Amazon S3.
In terms of getting your application to use external Amazon S3 URLs when
referring to your application's static assets, passing your ``Flask``
object to the ``FlaskS3`` object is all that needs to be done. Once your
app is running, any templates that contained relative static asset
locations, will instead contain hosted counterparts on Amazon S3.
Uploading your Static Assets
----------------------------
You only need to upload your static assets to Amazon S3 once. Of course, if you
add or modify your existing assets then you will need to repeat the uploading
process.
You only need to upload your static assets to Amazon S3 once. Of course,
if you add or modify your existing assets then you will need to repeat
the uploading process.
Uploading your static assets from a Python console is as simple as follows.
Uploading your static assets from a Python console is as simple as
follows.
.. code-block:: python
@@ -116,23 +121,23 @@ Uploading your static assets from a Python console is as simple as follows.
>>> flask_s3.create_all(app)
>>>
Flask-S3 will proceed to walk through your application's static assets,
including those belonging to *registered* `blueprints`_, and upload them to your
Amazon S3 bucket.
Flask-S3 will proceed to walk through your application's static assets,
including those belonging to *registered* `blueprints`_, and upload them
to your Amazon S3 bucket.
.. _blueprints: http://flask.pocoo.org/docs/blueprints/
Static Asset URLs
~~~~~~~~~~~~~~~~~
Within your bucket on S3, Flask-S3 replicates the static file hierarchy defined
in your application object and any registered blueprints. URLs generated by
Flask-S3 will look like the following:
Within your bucket on S3, Flask-S3 replicates the static file hierarchy
defined in your application object and any registered blueprints. URLs
generated by Flask-S3 will look like the following:
``/static/foo/style.css`` becomes
``https://mybucketname.s3.amazonaws.com/static/foo/style.css``,
assuming that ``mybucketname`` is the name of your S3 bucket, and you have
chosen to have assets served over HTTPS.
``https://mybucketname.s3.amazonaws.com/static/foo/style.css``, assuming
that ``mybucketname`` is the name of your S3 bucket, and you have chosen
to have assets served over HTTPS.
.. _settings:
@@ -141,9 +146,10 @@ chosen to have assets served over HTTPS.
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 required, but if
not present, some will need to be provided when uploading assets to S3.
Within your Flask application's settings you can provide the following
settings to control the behvaiour of Flask-S3. None of the settings are
required, but if not present, some will need to be provided when
uploading assets to S3.
=========================== ===================================================
`AWS_ACCESS_KEY_ID` Your AWS access key. This does not need to be
@@ -188,8 +194,8 @@ not present, some will need to be provided when uploading assets to S3.
API Documentation
=================
Flask-S3 is a very simple extension. The few exposed objects, methods and
functions are as follows.
Flask-S3 is a very simple extension. The few exposed objects, methods
and functions are as follows.
The FlaskS3 Object
------------------
+49 -29
View File
@@ -18,10 +18,11 @@ def url_for(endpoint, **values):
generated, otherwise the call is passed on to `flask.url_for`.
Because this function is set as a jinja environment variable when
`FlaskS3.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.
`FlaskS3.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.
"""
app = current_app
if 'S3_BUCKET_NAME' not in app.config:
@@ -42,7 +43,8 @@ def url_for(endpoint, **values):
def _bp_static_url(blueprint):
""" builds the absolute url path for a blueprint's static folder """
return u'%s%s' % (blueprint.url_prefix or '', blueprint.static_url_path or '')
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."""
@@ -76,8 +78,9 @@ def _static_folder_path(static_url, static_folder, static_asset):
Returns a path relative to static_url for static_asset
"""
# first get the asset path relative to the static folder. static_asset is
# not simply a filename because it could be sub-directory then file etc.
# first get the asset path relative to the static folder.
# static_asset is not simply a filename because it could be
# sub-directory then file etc.
if not static_asset.startswith(static_folder):
raise ValueError("%s startic asset must be under %s static folder" %
(static_asset, static_folder))
@@ -90,8 +93,10 @@ def _write_files(app, static_url_loc, static_folder, files, bucket,
""" 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, asset_loc)
logger.debug("Uploading %s to %s as %s" % (file_path, bucket, key_name))
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)
if ex_keys and key_name in ex_keys:
logger.debug("%s excluded from upload" % key_name)
else:
@@ -109,38 +114,53 @@ def _upload_files(app, files_, bucket):
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 Amazon S3.
Uploads of the static assets associated with a Flask application to
Amazon S3.
All static assets are identified on the local filesystem, including
any static assets associated with *registered* blueprints. In turn, each
asset is uploaded to the bucket described by `bucket_name`. If the bucket
does not exist then it is created.
any static assets associated with *registered* blueprints. In turn,
each asset is uploaded to the bucket described by `bucket_name`. If
the bucket does not exist then it is created.
Flask-S3 creates the same relative static asset folder structure on S3 as
can be found within your Flask application.
Flask-S3 creates the same relative static asset folder structure on
S3 as can be found within your Flask application.
Many of the optional arguments to `create_all` can be specified instead in
your application's configuration using the Flask-S3 `configuration`_ variables.
Many of the optional arguments to `create_all` can be specified
instead in your application's configuration using the Flask-S3
`configuration`_ variables.
:param app: a :class:`flask.Flask` application object.
:param user: an AWS Access Key ID. You can find this key in the Security Credentials section of your AWS account.
:param user: an AWS Access Key ID. You can find this key in the
Security Credentials section of your AWS account.
:type user: `basestring` or None
:param password: an AWS Secret Access Key. You can find this key in the Security Credentials section of your AWS account.
:param password: an AWS Secret Access Key. You can find this key in
the Security Credentials section of your AWS
account.
:type password: `basestring` or None
:param bucket_name: the name of the bucket you wish to server your static assets from. **Note**: while a valid character, it is recommended that you do not include periods in bucket_name if you wish to serve over HTTPS. See Amazon's `bucket restrictions`_ for more details.
:param bucket_name: the name of the bucket you wish to server your
static assets from. **Note**: while a valid
character, it is recommended that you do not
include periods in bucket_name if you wish to
serve over HTTPS. See Amazon's `bucket
restrictions`_ for more details.
:type bucket_name: `basestring` or None
:param location: the AWS region to host the bucket in; an empty string indicates the default region should be used, which is the US Standard region. Possible location values include: `'DEFAULT'`, `'EU'`, `'USWest'`, `'APSoutheast'`
:param location: the AWS region to host the bucket in; an empty
string indicates the default region should be used,
which is the US Standard region. Possible location
values include: `'DEFAULT'`, `'EU'`, `'USWest'`,
`'APSoutheast'`
:type location: `basestring` or None
:param include_hidden: by default Flask-S3 will not upload hidden files. Set this to true to force the upload of hidden files.
:param include_hidden: by default Flask-S3 will not upload hidden
files. Set this to true to force the upload of hidden files.
:type include_hidden: `bool`
.. _bucket restrictions: http://docs.amazonwebservices.com/AmazonS3/latest\
/dev/BucketRestrictions.html
.. _bucket restrictions: http://docs.amazonwebservices.com/AmazonS3\
/latest/dev/BucketRestrictions.html
"""
if user is None and 'AWS_ACCESS_KEY_ID' in app.config:
@@ -169,8 +189,8 @@ class FlaskS3(object):
The FlaskS3 object allows your application to use Flask-S3.
When initialising a FlaskS3 object you may optionally provide your
:class:`flask.Flask` application object if it is ready. Otherwise, you may
provide it later by using the :meth:`init_app` method.
:class:`flask.Flask` application object if it is ready. Otherwise,
you may provide it later by using the :meth:`init_app` method.
:param app: optional :class:`flask.Flask` application object
:type app: :class:`flask.Flask` or None
@@ -181,9 +201,9 @@ class FlaskS3(object):
def init_app(self, app):
"""
An alternative way to pass your :class:`flask.Flask` application object
to Flask-S3. :meth:`init_app` also takes care of some default
`settings`_.
An alternative way to pass your :class:`flask.Flask` application
object to Flask-S3. :meth:`init_app` also takes care of some
default `settings`_.
:param app: the :class:`flask.Flask` application object.
"""
+2 -2
View File
@@ -9,11 +9,11 @@ from setuptools import setup
setup(
name='Flask-S3',
version='0.1.3',
version='0.1.4',
url='http://github.com/e-dard/flask-s3',
license='WTFPL',
author='Edward Robinson',
author_email='me@eddrobinson.net',
author_email='hi@edd.io',
description='Seamlessly serve the static files of your Flask app from Amazon S3',
long_description=__doc__,
py_modules=['flask_s3'],
+11 -6
View File
@@ -3,7 +3,6 @@ import ntpath
from mock import Mock, patch, call
from flask import Flask, render_template_string, Blueprint
from boto.s3.key import Key
import flask_s3
from flask_s3 import FlaskS3
@@ -64,7 +63,9 @@ class UrlTests(unittest.TestCase):
return client.get('/%s' % ufs)
def test_required_config(self):
""" Tests that ValueError raised if bucket address not provided."""
"""
Tests that ValueError raised if bucket address not provided.
"""
raises = False
del self.app.config['S3_BUCKET_NAME']
@@ -77,7 +78,9 @@ class UrlTests(unittest.TestCase):
self.assertTrue(raises)
def test_url_for(self):
"""Tests that correct url formed for static asset in self.app."""
"""
Tests that correct url formed for static asset in self.app.
"""
# non static endpoint url_for in template
self.assertEquals(self.client_get('').data, '/')
# static endpoint url_for in template
@@ -97,7 +100,9 @@ class UrlTests(unittest.TestCase):
self.assertEquals(self.client_get(ufs).data, exp)
def test_url_for_blueprint(self):
"""Tests that correct url formed for static asset in blueprint."""
"""
Tests that correct url formed for static asset in blueprint.
"""
# static endpoint url_for in template
ufs = "{{url_for('admin.static', filename='bah.js')}}"
exp = 'https://foo.s3.amazonaws.com/admin-static/bah.js'
@@ -159,8 +164,8 @@ class S3Tests(unittest.TestCase):
@patch('os.path.isdir')
def test__gather_files_no_blueprints_no_files(self, path_mock, os_mock):
"""
Tests that _gather_files works when there are no blueprints and no
files available in the static folder
Tests that _gather_files works when there are no blueprints and
no files available in the static folder
"""
self.app.static_folder = '/foo'
dirs = {'/foo': [('/foo', None, [])]}