Подтвердить что ты не робот

Флажок static_folder, размещенный на S3

Я пытаюсь перенаправить весь мой/статический контент для размещения на Amazon S3. Моя первая мысль заключалась в том, чтобы использовать глобальную конфигурацию ['path'] во всех моих шаблонах jinja, но это не будет работать для внешних файлов css и js, плюс это будет беспорядочно. Я обнаружил, что static_folder и static_url_path выпущены в 0.7, и это похоже на то, что я хочу. Однако, когда я перехожу в http://localhost:8000/static/img/abc.jpg, он не находит файлы на S3. Я правильно использую эту функцию или есть какой-то другой способ сделать это?

Спасибо!

4b9b3361

Ответ 1

Недавно я разработал расширение 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)

Вы можете использовать расширение для загрузки своих активов в выбранный вами ковш:

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

Flask-S3 информирует о проекте и загружает все активы, связанные с любыми зарегистрированными чертежами.

Ответ 2

Я бы хотел, чтобы конструктор flask.Flask конструктор static_url_path аргумент принял полный URI, но он кричит о пути, требующем ведущей косой черты, когда вы это пытаетесь. Если он примет это, вы можете просто использовать url_for после установки static_url_path='http://my_s3_bucket.aws.amazon.com/' или так.

Другим возможным решением является использование контекстного процессора. Я считаю, что это самое чистое решение, но у меня нет большого опыта в колбе. Это, конечно, выглядит чистым. Используя контекстный процессор, я вытаскиваю URL из среды (я использую героку, чтобы это было легко установить). Затем процессор контекста делает переменную 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" />

Ответ 3

то, что вы пытаетесь выполнить, - это написать

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

и иметь это решение для URL-адреса в s3?

Я считаю, что static_folder и static_url_path настроены так, что если вы вызываете

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

затем перейдем к

вышеуказанный url_for будет выводить

http://localhost:8000/bar/img/abc.jpg и он будет искать static/img/abc.jpg в файловой системе.

Я думаю, что вы хотите написать потенциальный фильтр, который переведет ваш путь к URL-адресу s3, чтобы вы могли сделать что-то вроде

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

там есть документация по этому поводу: флажные пользовательские фильтры

Ответ 4

Вам нужен URL-адрес открытого файла 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 %}

Это даст вам путь по умолчанию, когда вы можете тестировать ваше приложение локально, и общедоступный URL-адрес S3 при создании (на основе флага отладки).

Используя его:

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

Ответ 5

Я знаю, что это старый вопрос, но вот как я обошел эту проблему.

  • Метод импорта флагов url_for под другим именем (например, flask_url_for)
  • Создайте свой собственный метод url_for, который вызывает flask_url_for, а затем использует замену строк для добавления в ваш URL-адрес ведра S3.

Мне нравится эта стратегия, потому что она проста и интуитивно понятна в использовании, а интерфейс точно так же, как и оригинальный метод url_for.

from flask import url_for as flask_url_for
from flask import current_app

PRODUCTION_URL = 'https://s3.amazonaws.com/MY-BUCKET-NAME'

def url_for(path, **kwargs):
    url = flask_url_for(path, **kwargs)
    if url.startswith("/static") and not current_app.debug:
        url = url.replace("/static", "", 1)
        return PRODUCTION_URL + url
    return url