Flask static_folder托管在S3上

Tim*_*Tim 13 python amazon-s3 jinja2 flask

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

谢谢!

Edw*_*rdr 8

我最近开发了一个Flask扩展来处理这种情况.它叫做Flask-S3,你可以在这里阅读它的文档.

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

from flask import Flask
from flask_s3 import FlaskS3

app = Flask(__name__)
app.config['S3_BUCKET_NAME'] = 'mybucketname'
s3 = FlaskS3(app)
Run Code Online (Sandbox Code Playgroud)

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

>>> from my_application import app
>>> from flask_s3 import create_all
>>> create_all(app)
Run Code Online (Sandbox Code Playgroud)

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


Col*_*lau 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
    )
Run Code Online (Sandbox Code Playgroud)

在模板中:

<link rel="stylesheet" type="text/css" href="{{ static_url }}css/main.css" />
Run Code Online (Sandbox Code Playgroud)

结果

<link rel="stylesheet" type="text/css" href="http://my_s3_bucket.aws.amazon.com/css/main.css" />
Run Code Online (Sandbox Code Playgroud)


小智 1

你想要完成的是能够写

{{ url_for(app.static, file='img/abc.jpg', _external=True) }}

并解析为 s3 中的 url 吗?

我相信 static_folder 和 static_url_path 已设置,因此如果您致电

app = Application('app', static_folder='foo', static_url_path='bar')

然后去

上面的 url_for 将输出

http://localhost:8000/bar/img/abc.jpgstatic/img/abc.jpg它会在文件系统中查找。

我认为你想要做的可能是编写一个自定义过滤器,将你的路径转换为 ​​s3 url,以便你可以进行类似的调用

{{ 'img/abc.jpg'|s3_static_url }}

这里有一些关于此的文档: Flask Custom Filter