Рубрики
Без рубрики

Организация приложений Flask с чертежом

Мне неясно, когда и почему это случилось, но в какой -то момент за последние пару лет я стал … помеченной флакой, Python, SoftwareDeplosment.

Мне неясно, когда и почему это произошло, но в какой -то момент за последние пару лет я стал эмоционально и, возможно, романтически связан с колкой (я уверен, что вы заметили). С тех пор я принял свою судьбу как Guy-Who-Writes-Flask-tutorials-on-the-internet-for-no-ar-ar-aresse-reason С небольшим сожалением. С этим названием не так много льгот, но он, безусловно, предлагает некоторую уникальную перспективу, особенно когда речь идет о широко распространенных заблуждениях о том, что люди верят в колбу. Из этих заблуждений два особенно популярны так же, как и ложные:

  1. Колба предназначена для создания мелких приложений, в то время как Джанго лучше подходит для более масштабных приложений (я могу обратиться к этому напрямую, хотя природа этого учебника должна достичь этого самостоятельно).
  2. Колба – это MicroFrameWork , что, следовательно, подразумевает, что мы должны писать «Микропроекты» где вся логика сбрасывается в один файл с именем app.py.

Неудивительно, почему новички Flask считают, что структурирование целых проектов в одиночные app.py Файлы нормальны и приемлемы. Почти Каждое руководство по колбе это структурировано таким образом, предположительно из удобства, но кажется, что в этих учебниках отсутствует звездочка, которые должны читать _ *Это не хороший способ создания приложений. _

Хорошее программное обеспечение организовано путем разделения проблем. Легко придумать приложение как единое сущность, но реальность показывает нам, что хорошо структурированные приложения-это Коллекции автономного модули , Услуги , или классы . Я имею в виду Одно отвечаемость принципала : Обычно понятная концепция, в которой каждая часть приложения должна быть ограничена не более чем одной ответственностью. Это та же самая причина, по которой ванные комнаты и кухни – отдельные комнаты: одна комната предназначена для шитья, а одна комната для еды. Это беспорядок для дерьма, где вы едите, и это именно то, что происходит при создании приложений без структуры или инкапсуляции.

Мы можем организовать наши приложения Flask с помощью встроенной концепции под названием Чертежи , которые, по сути, являются колбами, эквивалентными модулям Python. Blueprints предназначены для инкапсуляции разделов размером с функционального размера нашего приложения, таких как кассовые потоки, пользовательская авторитет, профили пользователей и т. Д. (в основном все, что подходит для представленного в качестве эпоса Jira). Главные чертежи держат связанную логику, а активы сгруппированы и отделены друг от друга, что необходимо для разработки поддерживаемого проекта. Blueprints также позволяет получить преимущества производительности, связанные с расщеплением кода, аналогично WebPack Анкет

Обычная структура колбы

Лучший способ взглянуть на преимущества, связанные с использованием чертежей, – это увидеть влияние, которое они оказывают на структуру приложения. Во -первых, давайте посмотрим, как может выглядеть большое приложение без Чертежи.

Познакомьтесь с Билли. Билли довольно новичок в колбе, но уверен в своих способностях создавать крупномасштабные приложения колбы после прочтения части 1-5 в этой серии. Вооружен только этим знанием, его приложение выглядит примерно так:

/myapp
├── /templates
├── /static
├── app.py
├── routes.py
├── models.py
├── config.py
└── requirements.txt

У Билли много того, что вы можете ожидать на первый взгляд. У него есть его удобное app.py Файл (тьфу), папка для шаблонов, папка для статических активов и так далее. Не зная, что делает приложение Билли, все это кажется разумным. Как оказалось, однако, Не зная, что делает приложение это наше падение в проведении такой оценки.

Оказывается, Билли строит портал обслуживания, обращенный на клиенту для Boeing. После того, как Boeing 737 на рынок и убийство сотни людей с преступной халатностью Боинг нанял Билли для построения дружественного обслуживания, чтобы на полевых жалобах семей жертв. Служные столы – сложные технологии. Рассмотрим основные части того, что может войти в что -то вроде Zendesk:

  • Общественная целевая страница.
  • Зарегистрированный опыт как для клиентов, так и для агентов (сотрудников Boeing).
  • Монитоны с показателями производительности для администраторов.
  • Непреодолимое количество логики, которое даже не стоит упоминать.

Приложение Билли внезапно выглядит как тип оскорбления для инженерии, который комиссию только создатели Boeing 737. Это Билли Действительно Хранение маршрутов, шаблонов и активов для всех этих вещей в одном месте?

Структура приложений с чертежами

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

/flask-blueprint-tutorial
├── /application
│   ├── __init__.py
│   ├── assets.py
│   ├── api.py
│   ├── /home
│   │   ├── /templates
│   │   ├── /static
│   │   └── home.py
│   ├── /profile
│   │   ├── /templates
│   │   ├── /static
│   │   └── profile.py
│   ├── /products
│   │   ├── /templates
│   │   ├── /static
│   │   └── product.py
│   ├── /static
│   └── /templates
├── README.md
├── config.py
├── requirements.txt
└── wsgi.py

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

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

Важной вещью, которую следует указать, является наличие верхнего уровня /шаблоны и/ Статический папки Кроме того, к их специфическим эквивалентам. В то время как чертежи не могут получить доступ к шаблонам или статическим файлам своих сверстников, они может Используйте общие активы, которые будут обмены всеми чертежами (например, шаблон Mayout.html Мы рассмотрим, как активы и чертежи работают вместе, но давайте начнем с определения нашего первого плана.

Если вы оказались человеком Джанго, это может показаться знакомым. Это потому, что мы можем приравнивать чертежи Флески к концепции приложений Джанго. Есть различия и дополнительная гибкость, но концепция остается прежней.

Определение плана

Нашим первым планом будет наш «домашний» план, который будет жить все маршруты, шаблоны и логика, касающиеся домашней страницы. Внутри /Главная каталог, мы создадим файл с именем home.py Чтобы определить наш план и его маршруты:

from flask import Blueprint
from flask import current_app as app


# Blueprint Configuration
home_bp = Blueprint('home_bp', __name__,
                    template_folder='templates',
                    static_folder='static')

Мы настраиваем наш план как переменную с именем home_bp Анкет Первый параметр, который мы переходим к Blueprint () Имя, которое мы хотим назначить нашему плану для целей внутренней маршрутизации Фласк. Имеет смысл поддерживать все согласованные, назвав наш план home_bp чтобы оставаться в соответствии с нашим именем переменной.

Мы также передаем два дополнительных аргумента ключевых слов, называемых Template_folder и static_folder Анкет Определение этих аргументов сообщает нашему плану, что у нас будут шаблоны специфичных для чертежа и статические файлы. Эти каталоги разрешены по отношению к текущему файлу , таким образом, регистрируя шаблон нашего Blueprint и статические каталоги как Приложение/Главная/Шаблоны и Приложение/Home/Static , соответственно.

Настройка static_folder имитирует поведение настройки Template_folder , кроме того, что обслуживает статические активы.

Создание маршрутов внутри чертежа

Теперь, когда у нас создан план, мы можем начать добавлять маршруты в этот подраздел нашего приложения! Вот как это выглядит:

from flask import Blueprint, render_template
from flask import current_app as app
from application.api import fetch_products

# Blueprint Configuration
home_bp = Blueprint('home_bp', __name__,
                    template_folder='templates',
                    static_folder='static')


@home_bp.route('/', methods=['GET'])
def home():
    """Homepage."""
    products = fetch_products(app)
    return render_template('index.jinja2',
                           title='Flask Blueprint Tutorial',
                           subtitle='Demonstration of Flask blueprints.',
                           template='home-template',
                           products=products)

Единственное заметное отличие здесь заключается в том, что теперь мы регистрируем наш маршрут, используя @home_bp.route ('...') вместо @app.route ('...') . Создание нашего home_bp Blueprint автоматически дает нам функцию декоратора под названием @home_bp с которым мы можем зарегистрировать наши маршруты.

Регистрируя наш план

Мы создали план и зарегистрировали наш первый маршрут к нему, но как мы можем сказать нашему приложению Flask, что этот план и его маршруты существуют?

Здесь мы врываемся в нашу точку входа верхнего уровня, например, __ init__.py в колбе Фабрика приложений шаблон. Вот самый простой пример регистрации плана с использованием этого шаблона:

"""Initialize Flask app."""
from flask import Flask


def create_app():
    """Create Flask application."""
    app = Flask(__name__, instance_relative_config=False)
    app.config.from_object('config.Config')

    with app.app_context():
        # Import parts of our application
        from .home import home

        # Register Blueprints
        app.register_blueprint(home.home_bp)

        return app

Мы импортируем Home/Home.py Внутри нашего app_context () через эту строку:

from .home import home

Со всем содержимым home.py Импортировано, мы можем затем использовать метод на нашем приложение объект называется .register_blueprint () Чтобы сказать Флеску, распознать этот раздел нашего приложения. Мы проходим в переменная название home_bp от home.py В и это все! Наше приложение Flask теперь будет уважать маршруты, зарегистрированные на home_bp , что в этом случае оказывается нашей домашней страницей.

У нас почти наверняка будет больше, чем один план, поскольку модуляризация нашего приложения бесполезна, если у нас будет только один модуль. Зарегистрировать несколько чертежей проста:

"""Initialize Flask app."""
from flask import Flask


def create_app():
    """Create Flask application."""
    app = Flask(__name__, instance_relative_config=False)
    app.config.from_object('config.Config')

    with app.app_context():
        # Import parts of our application
        from .profile import profile
        from .home import home
        from .products import products

        # Register Blueprints
        app.register_blueprint(profile.account_bp)
        app.register_blueprint(home.home_bp)
        app.register_blueprint(products.product_bp)

        return app

Теперь мы зарегистрировали три чертежа, которые мы видели в нашем примере: Главная , профиль и Продукты Анкет

Шаблоны джинджи маршрутинг с чертежом

Предостережение, о котором мы должны знать, – это то, как шаблоны джинджи находят URL -адреса для маршрутов, зарегистрированных для чертежей. Допустим, мы хотим создать ссылку на домашнюю страницу нашего приложения. В приложении без Главные, вы найдете маршрут для нашей домашней страницы, используя следующую:

Это ищет маршрут с именем Главная зарегистрировано непосредственно в наше приложение, но в Наш Дело, у нас нет маршрутов, зарегистрированных в нашем приложении. В нашем приложении мы не регистрируем маршруты непосредственно в приложение Flask – мы зарегистрировали их в чертежи вместо_._

Вот где 'home_bp' часть home_bp ('home_bp') вступает в игру: строка 'home_bp' Мы перешли в наш план – это внутреннее имя, которое Flask использует для разрешения маршрутов! Теперь мы можем найти нашу домашнюю страницу, выполнив следующую:

Джинджа Blueprint

Поскольку Джинджа контекст осведомлен о чертепе, мы можем использовать несколько прохладных тегов, чтобы проверить, где мы находимся в нашем приложении. Вот несколько полезных инструментов, чтобы продемонстрировать, насколько мощный находится джинджа, когда дело доходит до знания контекста шаблона каждой страницы:

  • {{request.blueprint}} : Вывод имени плана, которому принадлежит текущий шаблон страницы.
  • {{self._templateReference__context.name}} : Отдает имя файла шаблона текущей страницы.
  • {{request.endpoint}} Выходы оба Название текущего плана, а также название маршрута, который обслуживал шаблон страницы.
  • {{request.path}} : URL -адрес текущего шаблона страницы.

Просто для удовольствия, я развернула рабочую демонстрацию нашего примера приложения Здесь Анкет Вот что возвращает домашняя страница для всех вышеуказанных значений:

Джинджа Блюпринт осознание.

Конспецифичные активы

Наиболее сложным аспектом чертежных чертежей является концепция активов, специфичных для чертежа. На мой взгляд, лучший способ получить максимальную отдачу от активов, специфичных для чертежа,-это Флэк-Ассовые Анкет Использование библиотеки Flask-Assets сама по себе является учебником (ясно, как я только что связал с ней), но я с радостью дам вам аварийный курс, который вы едва ли сохраните.

Для инициализации флезов ( PIP установить фланг-ассеты , кстати), нам нужно вернуться __init__.py :

"""Initialize Flask app."""
from flask import Flask
from flask_assets import Environment  # <-- Import `Environment`


def create_app():
    """Create Flask application."""
    app = Flask(__name__, instance_relative_config=False)
    app.config.from_object('config.Config')
    assets = Environment()  # <-- Create an assets environment
    assets.init_app(app)  # <-- Initialize Flask-Assets

    with app.app_context():
        # Import parts of our application
        from .profile import profile
        from .home import home
        from .products import products
        from .assets import compile_static_assets  # <-- Import logic

        # Register Blueprints
        app.register_blueprint(profile.account_bp)
        app.register_blueprint(home.home_bp)
        app.register_blueprint(products.product_bp)

        # Compile static assets
        compile_static_assets(assets)  # <-- Execute logic

        return app

Сначала мы создаем пустые активы «среда» под названием активы с линией Assets () Анкет Как и во всех плагинах Flask/Addons/Awhate-The-re-Called, мы затем инициализируем колбы после нашего приложение Объект был создан путем вызова .init_App () на указанном приложение объект.

Внутри app_context () , Затем я тяну в помощь функции, называемой compile_static_assets () который я импортировал из файла с именем Assets.py :

"""Compile static assets."""
from flask import current_app as app
from flask_assets import Bundle


def compile_static_assets(assets):
    """Create stylesheet bundles."""
    assets.auto_build = True
    assets.debug = False
    common_less_bundle = Bundle('src/less/*.less',
                                filters='less,cssmin',
                                output='dist/css/style.css',
                                extra={'rel': 'stylesheet/less'})
    home_less_bundle = Bundle('home_bp/less/home.less',
                              filters='less,cssmin',
                              output='dist/css/home.css',
                              extra={'rel': 'stylesheet/less'})
    profile_less_bundle = Bundle('profile_bp/less/profile.less',
                                 filters='less,cssmin',
                                 output='dist/css/profile.css',
                                 extra={'rel': 'stylesheet/less'})
    product_less_bundle = Bundle('products_bp/less/products.less',
                                 filters='less,cssmin',
                                 output='dist/css/products.css',
                                 extra={'rel': 'stylesheet/less'})
    assets.register('common_less_bundle', common_less_bundle)
    assets.register('home_less_bundle', home_less_bundle)
    assets.register('profile_less_bundle', profile_less_bundle)
    assets.register('product_less_bundle', product_less_bundle)
    if app.config['FLASK_ENV'] == 'development':
        common_less_bundle.build()
        home_less_bundle.build()
        profile_less_bundle.build()
        product_less_bundle.build()
    return assets

Аа и вот где все, вероятно, выглядит немного пугающе (я упоминал, что есть отдельный учебник для этого)? Суть того, что происходит, заключается в том, что мы создали четыре актива стиля. ” Это один пакет активов на план, а также пакет для глобальных стилей.

Первый аргумент Bundle () FilePath статических исходных файлов, чтобы составить нашу пакет. common_less_bundle дано 'src/mess/*. меньше' , что на самом деле решается к следующему в нашем приложении:

application/static/src/less/*.less

Bundle () предполагает Приложение/Статический Часть нашего FilePath, так как это статическая папка по умолчанию, определяющая с нашим приложением. Чтобы увидеть, где вещи становятся все интереснее, проверьте, что мы передаем home_less_bundle :

'home_bp/less/home.less'

Колба может разрешить это на местоположении нашего чертежа так же, как Джинджа:

application/home/static/less/home.less

И вот как мы на самом деле подали полученный CSS из указанного пакета в шаблоне джинджи:

{% assets "home_less_bundle" %}
  
{% endassets %}

{% активы $} Block-это тег Jinja, добавленный Flask-Assets, чтобы помочь нам обслуживать пучки по их зарегистрированному имени! Вместо того, чтобы запомнить, где наши статические активы выводят и жестко кодируют эти пути файла, флаг-ассеты способны различить, что {{Asset_url}} из home_less_bundle это 'dist/css/home.css' , так же, как мы указали в Assets.py

Вы все это получили?

Это явно легче сказать, чем сделать. В знак признания этого факта я пошел дальше и создал репозиторий GitHub, который содержит рабочий источник демонстрации, который мы только что рассмотрели. Единственное предостережение для запуска кода ниже – это то, что я использовал API BestBuy для поиска дерьмовых продуктов для страниц продукта, поэтому вам, возможно, придется взять ключ BestBuy API, чтобы начать (извините):

https://github.com/hackersandslackers/flask-blueprint-tutorial

Просто чтобы доказать, что это не какая -то чепуха, репо используется как работающая демонстрация здесь:

https://flaskblueprints.hackersandslackers.app/

Определенно отправляйтесь на круиз демонстрации, чтобы увидеть, как чертежи работают вместе, обращая внимание на модуль «Информация о черте» внизу каждой страницы. Как всегда, не стесняйтесь украсть мой исходный код и используйте его для себя в любом проекте, на который вы могли бы поспешно согласиться. Mi Code Es SU Code.

Объединение того, что мы видели здесь с вашими знаниями о Флагская фабрика приложений и Флэк-Ассовые Должно быть все, что вам нужно, чтобы начать создавать логические, организованные приложения колбы. Godspeed, и винт Боинг.

Оригинал: “https://dev.to/hackersandslackers/organizing-flask-apps-with-blueprints-4phd”