Сообщить об ошибке.

Фабрика веб-приложений модуля Flask в Python

Если вы уже создаете веб-приложения, используя структуру пакета и схемы blueprint, то есть несколько способов улучшить свой опыт. Распространенным шаблоном проектирования является создание объекта приложения при импорте схемы blueprint. Но если переместить создание этого объекта в функцию, то можно позже создать несколько экземпляров этого приложения.

А зачем это делать?

  1. Тестирование. Появляются экземпляры веб-приложения с разными настройками для проверки каждого случая.
  2. Несколько экземпляров приложения. Представьте, что необходимо запустить разные версии одного и того же приложения. Конечно, на веб-сервере может быть настроено несколько экземпляров этого приложения с разными конфигурациями, но если использовать фабрики, то может быть несколько экземпляров одного и того же приложения, работающих в одном процессе веб-приложения, что может быть удобно.

Итак, как это реализовать?

Содержание:


Базовое использование фабрики приложений во Flask.

Базовое использование фабрики приложений во Flask довольно простое. Идея состоит в том, чтобы настроить приложение в функции. Как это:

def create_app(config_filename):
    app = Flask(__name__)
    app.config.from_pyfile(config_filename)

    from yourapplication.model import db
    db.init_app(app)

    from yourapplication.views.admin import admin
    from yourapplication.views.frontend import frontend
    app.register_blueprint(admin)
    app.register_blueprint(frontend)

    return app

Недостатком является то, что нельзя использовать объект приложения в схемах приложения blueprint во время импорта, но можно его использовать из запроса. Как получить доступ к приложению из конфигурацией? Используйте flask.current_app:

from flask import current_app, Blueprint, render_template
admin = Blueprint('admin', __name__, url_prefix='/admin')

@admin.route('/')
def index():
    return render_template(current_app.config['INDEX_TEMPLATE'])

Здесь ищется имя шаблона в current_app.config.

Фабрики приложений и расширения/дополнения Flask.

Желательно создавать расширения/дополнения и фабрики приложений так, чтобы объект расширения/дополнения изначально не привязывался к приложению.

Используя Flask-SQLAlchemy, например, не делайте что-то в этом роде:

def create_app(config_filename):
    app = Flask(__name__)
    app.config.from_pyfile(config_filename)

    db = SQLAlchemy(app)

Вот правильный подход. Скорее всего в model.py или эквивалентном файле:

db = SQLAlchemy()

А в application.py или эквивалентном файле:

def create_app(config_filename):
    app = Flask(__name__)
    app.config.from_pyfile(config_filename)

    # импортируем модель
    from yourapplication.model import db
    # инициализация `Flask-SQLAlchemy`
    db.init_app(app)

При использовании этого шаблона проектирования в объекте расширения Flask-SQLAlchemy не сохраняется состояние, зависящее от приложения, поэтому один объект расширения может использоваться для нескольких приложений.

Запуск приложений с фабрикой.

Чтобы запустить такое приложение, можно использовать команду flask:

# Bash
$ export FLASK_APP=myapp
$ flask run
# CMD
> set FLASK_APP=myapp
> flask run
# Powershell
> $env:FLASK_APP = "myapp"
> flask run

Flask автоматически обнаружит фабрику (create_app или make_app) в myapp. Также можно передать аргументы фабрике следующим образом:

# Bash
$ export FLASK_APP="myapp:create_app('dev')"
$ flask run
# CMD
> set FLASK_APP="myapp:create_app('dev')"
> flask run
# Powershell
> $env:FLASK_APP = "myapp:create_app('dev')"
> flask run

Затем в myapp вызывается фабрика create_app со строкой 'dev' в качестве аргумента.

Как улучшить фабрику приложений Flask?

Вышеупомянутая фабричная функция не очень умна, но можно ее улучшить. Следующие изменения легко реализовать:

  1. Предоставьте возможность передавать значения конфигурации для модульных тестов, чтобы не приходилось потом создавать файлы конфигурации в файловой системе.
  2. Вызов функции из blueprint при настройке приложения, чтобы было место для изменения атрибутов приложения (например, подключение обработчиков запросов до/после и т. д.)
  3. При необходимости добавьте промежуточное ПО WSGI при создании приложения.