Фабрики приложений
Если вы уже используете пакеты и чертежи для своего приложения (Модульные приложения с чертежами), есть несколько отличных способов улучшить опыт. Распространённым шаблоном является создание объекта приложения при импорте чертежа. Но если вы перенесёте создание этого объекта в функцию, вы сможете позже создать несколько экземпляров этого приложения.
Так зачем вам это нужно?
- Тестирование. Вы можете иметь экземпляры приложения с различными настройками для проверки каждого случая.
- Несколько экземпляров. Представьте, что вы хотите запустить разные версии одного и того же приложения. Конечно, вы можете иметь несколько экземпляров с различными конфигурациями, настроенными в вашем веб-сервере, но если вы используете фабрики, вы можете иметь несколько экземпляров одного и того же приложения, работающих в одном процессе приложения, что может быть удобно.
Итак, как вы это реализуете?
Базовые фабрики
Идея состоит в том, чтобы настроить приложение в функции. Вот так:
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 не сможет его найти. Вот пример exampleapp.py файла, который создаёт такое приложение:
from yourapplication import create_app
app = create_app('/path/to/config.cfg')
Затем его можно использовать с командой flask:
export FLASK_APP=exampleapp flask run
Улучшения фабрики
Функция фабрики из вышеприведённого примера пока не очень умная, вы можете её улучшить. Следующие изменения просты и возможны:
- сделать возможным передавать значения конфигурации для юнит-тестов, чтобы вам не приходилось создавать файлы конфигурации на файловой системе
- вызвать функцию из чертежа при настройке приложения, чтобы у вас была возможность изменить атрибуты приложения (например, подключение обработчиков до/после запроса и т. д.)
- Добавить WSGI-средства разработки при создании приложения, если необходимо.
© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/0.12.x/patterns/appfactories/