Разработка web-приложений с repoze.bfg
-
Upload
andrey-popp -
Category
Education
-
view
1.473 -
download
0
Transcript of Разработка web-приложений с repoze.bfg
Разработка web-приложений с repoze.bfg
Андрей Попп
http://braintrace.ru
@andreypopp
Что такое repoze.bfg
Это минималистичный web-фрэймворк, вобравший в себя идеиZope, Django, Pylons.
Андрей Попп: Разработка web-приложений с repoze.bfg
Что такое repoze.bfg
Ключевые моменты:
WSGI.MVC (скорее даже MTV).Компонентная архитектура.100% покрытие тестами (по отчётам утилиты Coverage).Отличная документация.
Андрей Попп: Разработка web-приложений с repoze.bfg
Что такое repoze.bfg
Фрэймворк предоставляет инструменты, помогающие решениюследующих проблем:
Конфигурация приложения.Маршрутизация запросов.Шаблонизация.Аутентификация и авторизация.Интернационализация и локализация.Тестирование приложения.
Андрей Попп: Разработка web-приложений с repoze.bfg
Что такое repoze.bfg
Остальное вопросы остаются за разработчиком:
Где и как хранятся данные приложения.Как генерировать и обрабатывать формы.Где хранить данные сессии.Кэширование.
Андрей Попп: Разработка web-приложений с repoze.bfg
Что такое repoze.bfg
Repoze.bfg использует хорошо знакомые и проверенныетехнологии:
WebOb/Paste – уровень WSGI.ZCA/ZCML – компонентная архитектура и конфигурация.Babel – интернационализация и локализация.Zope Page Templates – система шаблонизации.
Андрей Попп: Разработка web-приложений с repoze.bfg
Неужели repoze.bfg использует библиотеки Zope?!
Андрей Попп: Разработка web-приложений с repoze.bfg
Использование Zope библиотек
Да, repoze.bfg использует Zope библиотеки, но:
Их использование – это просто деталь реализациифрэймворка.Пользователь фрэймворка не обязан знать и использоватьбиблиотеки Zope.Библиотеки Zope не так уж плохи.
Андрей Попп: Разработка web-приложений с repoze.bfg
Начинаем работать с repoze.bfg
Чтобы создать проект repoze.bfg, можно воспользоватьсяодним из шаблонов Paste:
paster create -t <template_name > <project_name >
Шаблонов всего три: bfg_starter, bfg_zodb, bfg_alchemy,bfg_routesalchemy, но об этом позже.
Андрей Попп: Разработка web-приложений с repoze.bfg
Начинаем работать с repoze.bfg
В результате получаем готовую структуру пакета подуправлением setuptools (или distribute).
Приложение уже настроено для запуска с помощью Paste:
paster serve paste.ini --reload
Андрей Попп: Разработка web-приложений с repoze.bfg
Конфигурация приложения
Конфигурация приложения это:
URL приложения и как они отображаются напредставления.Статические ресурсы и используемые шаблоны.Политики аутентификации и авторизации.Файлы с локализацией.Компоненты, специфичные для приложения.
Почти как settings.py и urls.py в Django.
Андрей Попп: Разработка web-приложений с repoze.bfg
Конфигурация приложения
Конфигурацию приложения не стоит путать с настройкамиприложения.
Андрей Попп: Разработка web-приложений с repoze.bfg
Конфигурация приложения
Конфигурация выполняется с помощью объекта Configurator:
Императивно – c помощью вызововConfigurator.add_route, Configurator.add_view и т.д.Декларативно – с помощью ZCML.С помощью декораторов.
После выполнения конфигурации необходимо вызвать методConfigurator.make_wsgi_app(), чтобы создатьсконфигурированное WSGI приложение.
Андрей Попп: Разработка web-приложений с repoze.bfg
Конфигурация приложенияПример: императивная конфигурация
myproject/run.py:
...config = Configurator ()config.begin()config.add_view(views.show_entries)config.add_view(views.show_comments)config.end()wsgi_app = config.make_wsgi_app ()...
Андрей Попп: Разработка web-приложений с repoze.bfg
Конфигурация приложенияПример: конфигурация с помощью декораторов
myproject/run.py:
...config = Configurator ()config.begin()config.scan()config.end()wsgi_app = config.make_wsgi_app ()...
myproject/views.py:
...@bfg_view ()def show_entries(request ):
return Response ()...
Андрей Попп: Разработка web-приложений с repoze.bfg
Конфигурация приложенияПример: декларативная конфигурация с помощью ZCML
myproject/run.py:
...config = Configurator ()config.begin()config.load_zcml(’configure.zcml ’)config.end()wsgi_app = config.make_wsgi_app ()...
myproject/configure.zcml:
...<view view=" myproject.views.show_entries"><view view=" myproject.views.show_comments">...
Андрей Попп: Разработка web-приложений с repoze.bfg
Конфигурация приложения
Все три приведённых примера абсолютно идентичны в планеконечного результата.
Андрей Попп: Разработка web-приложений с repoze.bfg
Конфигурация приложения
Но использование ZCML позволяет разрабатыватьрасширяемые приложения.
Андрей Попп: Разработка web-приложений с repoze.bfg
Конфигурация приложенияЧто такое ZCML
ZCML (Zope Configuration Markup Language) – декларативный,основанный на XML, язык для описания конфигураций.
Для repoze.bfg cуществует набор директив ZCML (таких какview), которые потом преобразуются в вызовы функций (вслучае с view – в вызов метода Configuration.add_view).
Андрей Попп: Разработка web-приложений с repoze.bfg
Конфигурация приложенияДиректива ZCML – include
С помощью директивы include можно подгружатьконфигурацию из других ZCML файлов других пакетов:
...<include package =" anotherproject" /><include package =" yetanotherproject" />...
Порядок таких включений имеет значение, потому чтодирективы, встречающиеся в файлах конфигурации могутпереопределять друг друга.
Андрей Попп: Разработка web-приложений с repoze.bfg
Конфигурация приложения
Преобразование директив конфигурации в вызовы функцийпроизводится только после считывания всех необходимых
файлов конфигурации.
Андрей Попп: Разработка web-приложений с repoze.bfg
Конфигурация приложения
Именно потому, что с ZCML возможно переопределятьконфигурацию приложения, его необходимо использовать для
разработки расширяемых приложений.
Андрей Попп: Разработка web-приложений с repoze.bfg
Конфигурация приложенияПример организации ZCML конфигурации в приложении
Обычно экземпляр установленного приложения содержитследующую ZCML конфигурацию:
...<include package =" myproject.core" /><include package =" myproject.additional_module" />...
Андрей Попп: Разработка web-приложений с repoze.bfg
Конфигурация приложенияПример организации ZCML конфигурации в приложении
Если нам нужно добавить ещё функционала в приложение:
...<include package =" myproject.core" /><include package =" myproject.additional_module" /><include package="myproject.plugins.openid"/>...
Мы просто подключаем конфигурацию пакета, которыйпредоставляет нужный функционал.
Андрей Попп: Разработка web-приложений с repoze.bfg
Поговорим о представлениях в repoze.bfg.
Андрей Попп: Разработка web-приложений с repoze.bfg
Представления в repoze.bfg
Представлением может служить, как функция вида
def my_view(request ):return Response(’Hello , world!’)
так и класс с методом __call__
class MyView(object ):def __init__(self , request ):
passdef __call__(self):
return Response(’Hello , world!’)
Андрей Попп: Разработка web-приложений с repoze.bfg
Представления в repoze.bfg
Аргумент request – это объект WebOb.Request.
Представление должно возвращать объект с атрибутами:
status – строка HTTP статуса.headerlist – список HTTP заголовков.app_iter – итератор по телу ответа.
Таким объектом, например, является WebOb.Response.
Андрей Попп: Разработка web-приложений с repoze.bfg
Представления в repoze.bfg
Кроме того, представление может зависеть от контекста
def my_view(context, request ):return Response(’Hello , world!’)
или
class MyView(object ):def __init__(self , context, request ):
passdef __call__(self):
return Response(’Hello , world!’)
Андрей Попп: Разработка web-приложений с repoze.bfg
Представления в repoze.bfg
Контекст представления – это объект из предметной областиприложения.
Для каждого запроса он определяется с помощью механизманахождения контекста, но об этом позже.
Андрей Попп: Разработка web-приложений с repoze.bfg
Представления в repoze.bfg
Почему хорошо иметь в приложении контекстно-зависимыепредставления:
Для разных типов контекста можно определять разныепредставления.Можно устанавливать ограничения на представления взависимости от контекста.
Но использование контекстно-зависимых представлений вприложении полностью опционально, если хочется – можноделать как в Django, Pylons. . .
Андрей Попп: Разработка web-приложений с repoze.bfg
Как происходит маршрутизация запросов в repoze.bfg или какURL запроса отображается на представление?
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросов
Весь процесс маршрутизации запроса происходит в две фазы:
Нахождение контекста для запроса.Выбор представления для запроса и найденного контекста.
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросов
Существует три способа организовать маршрутизациюзапросов в приложении:
Нахождение контекста с помощью обхода графа объектови последующий выбор представления.Сопоставление URL запроса с шаблонами, контекстуказывается явно для шаблона URL.Гибридный способ – сначала идёт сопоставление с нужнымURL-шаблоном, а потом обход графа объектов.
Аналогично первому способу работает Zope, второй способхарактерен для Django, Pylons и т.п.
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросовОбход графа
Удобно использовать, когда:
Множество объектов предметной области имеет структуруграфа.URL приложения можно интерпретировать как пути в этомграфе.
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросовОбход графа
Обход графа начинается с корневого объекта.
Фабрика для создания корневого объекта указывается на этапеконфигурации:
config = Configurator(root_factory=some_factory , ...)
Где some_factory – это функция, которая принимает requestединственным аргументом и возвращает корневой объект.
def some_factory(request ):return RootObject ()
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросовОбход графа
Обычно, в качестве корневого объекта используется интерфейск БД или любому другому механизму хранения данных.
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросовОбход графа
Допустим, что мы проектируем приложение для управлениястатическими страницами.
Кроме корневого объекта RootObject, у нас есть следующиеобъекты предметной области:
Объект PageManager – это менеджер статических страниц,через него мы можем получить нужную страницу по еёидентификатору.Объект Page – представляет отдельную страницу.
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросовОбход графа
Как происходит обход графа на примере URL /pages/page1:
1 URL разбивается на части: [’pages’, ’page1’].2 Вызывается метод RootObject.__getitem__ с аргументом
’pages’. Этот метод возвращает объект PageManager.3 Вызывается метод PageManager.__getitem__ с
аргументом ’page1’. В результате получаем объект Page.
Так как частей URL у нас больше не осталось, найденныйобъект Page является контекстом данного запроса.
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросовВыбор представления
После того, как мы нашли контекст, нам нужно выбратьподходящее представление.
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросовВыбор представления
Представления для объектов предметной областиопределяются на этапе конфигурации.
Императивно:
config.add_view(show_page , for_=Page)config.add_view(show_comment , for_=Comment)
или с помощью ZCML:
<view view=" views.show_page" for=" models.Page" /><view view=" views.show_comment" for=" models.Comment" />
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросовВыбор представления
Выбор представления учитывает Method Resolution Order.
Если не найдено представления для конкретного типа, будетиспользовано представление для его супертипа.
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросовВыбор представления
Кроме этого, можно определять разные представления дляразных HTTP методов, разных значений HTTP заголовков и на
основе других предикатов.
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросовШаблоны URL
Если маршрутизация запросов с помощью обхода графа неподходит, можно использовать сопоставление URL с
шаблонами.
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросовШаблоны URL
Механизм сопоставления URL с шаблонами работает также,как и в Django, Routes и т.д.
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросовШаблоны URL
Шаблоны URL приложения определяются на этапеконфигурации.
Императивно:
config.add_route(view=show_page ,path ="/ pages/: page_id")
или с помощью ZCML:
<routeview="views.show_page"path ="/p/: page_id"/>
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросовШаблоны URL
Контекст указывается явно:
config.add_route(view=show_page ,path ="/ pages/: page_id",factory=" some_factory")
или с помощью ZCML:
<routeview="views.show_page"path ="/p/: page_id"factory=" some_factory"/>
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросовШаблоны URL
Для каждого шаблона можно определить несколькопредставлений для разных типов контекста:
<routename="pages"path ="/p/: page_id"factory =" some_factory"/>
<viewroute_name ="pages"for="Page"/>
<viewroute_name ="pages"for=" MainPage"/>
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросовГибридный метод
Можно комбинировать обход графа и шаблоны URL:
<routename="pages"path ="/ pages/: category_id /* traverse"factory =" some_factory"/>
В этом случае первая URL сначала будет сопоставляться с/pages/:category_id, а оставшаяся часть будетиспользоована для обхода графа объектов начиная с объекта,произведённого с some_factory.
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросовОбработка исключений
Что происходит, если во время выполнения представленияпроисходит исключение?
Андрей Попп: Разработка web-приложений с repoze.bfg
Маршрутизация запросовОбработка исключений
В этом случае контекст запроса изменяется на текущееисключение и происходит выбор подходящего представления.
Представления для исключений регистрируются обычнымобразом:
<viewfor=" webob.exc.HTTPNotFound"view=" notfound_view"/>
Если во время исполнения любого представления произойдётисключение webob.exc.HTTPNotFound, то исполнение перейдётк notfound_view.
Андрей Попп: Разработка web-приложений с repoze.bfg
Шаблонизация
По-умолчанию, repoze.bfg предлагает использоватьшаблонизатор Chameleon – это реализация Zope Page
Templates и Genshi.
Кроме того, на pypi присутствует пакет repoze.bfg.jinja2 – дляработы с шаблонизатором Jinja2.
Андрей Попп: Разработка web-приложений с repoze.bfg
Шаблонизация
Как уже упоминалось, представление должно возращатьобъект с интерфейсом Response.
Это не всегда удобно, особенно когда дело касаетсятестирования, а представление рендерит тяжёлый шаблон:
response = myview(request)assert ’Some text ’ in ’’.join(response.app_iter)
Андрей Попп: Разработка web-приложений с repoze.bfg
Шаблонизация
Repoze.bfg предлагает следующее решение:
Представления возвращает dict() объект.За преобразование этого объекта в конечный Responseответственнен отдельный объект – рендерер.Рендерер определяется для каждого представления наэтапе конфигурации.Шаблоны являются рендерерами.
<viewview="views.some_pages"renderer =" list_pages.jinja2"/>
Андрей Попп: Разработка web-приложений с repoze.bfg
Шаблонизация
В repoze.bfg по-умолчанию присутствуют рендереры длявывода JSON и ZPT шаблонов.
Андрей Попп: Разработка web-приложений с repoze.bfg
Шаблонизация
Пакет repoze.bfg.jinja2 предоставляет рендерер для шаблоновJinja2.
Андрей Попп: Разработка web-приложений с repoze.bfg
Заключение
На этом всё. Читайте документацию –http://docs.repoze.org/bfg/.
Андрей Попп: Разработка web-приложений с repoze.bfg
Спасибо! Вопросы?
Андрей Попп: Разработка web-приложений с repoze.bfg