Заводы по производству приложений

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

Так зачем вам это нужно?

  1. Тестирование. Вы можете иметь экземпляры приложения с различными настройками для тестирования каждого случая.

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

Как же вы будете это реализовывать?

Основные фабрики

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

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

Недостатком является то, что вы не можете использовать объект приложения в чертежах во время импорта. Однако вы можете использовать его из запроса. Как получить доступ к приложению с помощью конфигурации? Используйте 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'])

Здесь мы ищем имя шаблона в конфигурации.

Фабрики и пристройки

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

Используя 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
    db.init_app(app)

При использовании этого шаблона проектирования в объекте расширения не хранится состояние, специфичное для конкретного приложения, поэтому один объект расширения может использоваться для нескольких приложений. Для получения дополнительной информации о проектировании расширений обратитесь к Разработка расширений для Flask.

Использование приложений

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

$ flask --app hello run

Flask автоматически определит фабрику, если она имеет имя create_app или make_app в hello. Вы также можете передавать аргументы фабрике следующим образом:

$ flask --app hello:create_app(local_auth=True) run``

Затем фабрика create_app в myapp вызывается с аргументом ключевого слова local_auth=True. Более подробно см. в разделе Интерфейс командной строки.

Улучшение фабрики

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

  1. Сделайте возможным передавать значения конфигурации для модульных тестов, чтобы не создавать конфигурационные файлы в файловой системе.

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

  3. При необходимости добавьте промежуточные модули WSGI во время создания приложения.

Вернуться на верх