Flask static_folder托管在S3上

时间:2012-02-25 04:58:45

标签: python amazon-s3 flask jinja2

我正在尝试将所有我的/静态内容重新路由到Amazon S3上。我的第一个想法是在我的jinja模板中使用全局配置['path'],但这不适用于外部css和js文件,而且它有点混乱。我发现在0.7中发布了static_folder和static_url_path,这看起来就像我想要的那样。但是,当我转到http://localhost:8000/static/img/abc.jpg时,它找不到S3上的文件。我是否正确使用此功能或是否有其他方法可以执行此操作?

谢谢!

4 个答案:

答案 0 :(得分:8)

我最近开发了一个Flask扩展来处理这种情况。它被称为Flask-S3,您可以阅读它的文档here

例如,以下是将它集成到Flask应用程序中的方法:

from flask import Flask
from flask_s3 import FlaskS3

app = Flask(__name__)
app.config['S3_BUCKET_NAME'] = 'mybucketname'
s3 = FlaskS3(app)

您可以使用扩展程序将资源上传到您选择的存储区:

>>> from my_application import app
>>> from flask_s3 import create_all
>>> create_all(app)

Flask-S3可识别蓝图,并将上传与任何已注册的蓝图相关联的所有资产。

答案 1 :(得分:6)

我希望flask.Flask构造函数的static_url_path参数接受完整的URI,但是当你尝试时,它会尖叫到需要一个前导斜杠的路径。如果它接受了,您可以在设置url_for左右后使用static_url_path='http://my_s3_bucket.aws.amazon.com/'

另一种可能的解决方案是使用上下文处理器。我相信这是最干净的解决方案,但我对烧瓶没有多少经验。确定看起来干净。使用上下文处理器,我从环境中提取URL(我正在使用heroku,因此很容易设置它)。然后上下文处理器使我的模板中的static_url变量可用。

在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
    )

在模板中:

<link rel="stylesheet" type="text/css" href="{{ static_url }}css/main.css" />

结果

<link rel="stylesheet" type="text/css" href="http://my_s3_bucket.aws.amazon.com/css/main.css" />

答案 2 :(得分:0)

您需要的是Amazon S3公共文件网址而不是http://localhost:8000/static/img/abc.jpg。如果它只是几个文件,可能会在您的模板中使用完整的URL对它们进行硬编码,或者如果您要在生产站点上使用本地版本进行测试并使用S3(就像我们一样),那么您可以尝试以下方法。

在基本模板的顶部定义一个可能名为STATIC_ROOT的新变量(其他模板继承),并将其用作文件路径前缀。

例如:

{% if app.debug %}
    {% set  STATIC_ROOT = url_for('static', filename='') %}
{% else %}
    {% set STATIC_ROOT = 'http://s3.amazonaws.com/bucketname/' }
{% endif %}

这将为您提供本地测试应用程序时的默认路径,以及生产时的公共S3 URL(基于调试标志)。

使用它:

<script src="{{ STATIC_ROOT }}js/jquery.min.js">

答案 3 :(得分:0)

我知道这是一个古老的问题,但这是我如何解决这个问题。

  • 使用其他名称导入Flask的gcc (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010 方法(例如<%= error_tag f, :firstname %>
  • 创建您自己的自定义 url_for方法,该方法调用flask_url_for,然后使用字符串替换添加到您的S3存储桶网址中。

我喜欢这种策略,因为它使用简单直观,界面与原始url_for方法完全相同。

flask_url_for