Конфигурирование обработчиков (callable view) в веб-фреймворке Pyramid
Обработчик, или представление-обработчик - это тот код, который формирует данные передаваемые веб-сервером в ответ на веб-запрос.
Обработчики - это самая большая часть кода, которую пишет программист, разрабатывающий сайт на веб-фреймворке Pyramid.
Кроме того, существует статический обработчик - который просто отдает определенные файлы с диска согласно URI - для этого обработчика программисту писать код не нужно, нужно только написать код конфигурирования этого обработчика.
Обработчик Pyramid полностью самостоятельно сгенерировать полный ответ, готовый для отправки в ответ на веб-запрос.
Также обработчик может сгенерировать только массив данных (словарь языка программирования Python), который перед отправкой веб-клиенту (браузеру) фреймворк Pyramid отправит для приведения в окончательную форму (на рендеринг) в специализированный механизм ("renderer").
Чаще всего для рендеринга используется шаблонизатор, принимающий на входе массив данных и файл с шаблоном HTML-странички и выдающий на выходе готовую HTML-страницу.
Обработка запроса в фреймворке Pyramid (в той части, что видна программисту через API Pyramid) состоит из 2 основных частей:
- Диспетчеризации запроса посредством гибкого метода "Traversal" или более простого метода "URL Dispath", в результате которого фреймворк Pyramid находит некую структуру, называемую в дальнейшем контекстом ("context").
- Определение соответствующего контексту обработчика и вызов этого обработчика.
Здесь рассмотрена вторая часть - определение обработчика. Первая часть - диспетчеризация URI, обход "дерева ресурсов" - описан в другом моем тексте.
Итак, разбор URI закончен. Определен контекст, который совпадает с оконцовкой (листом) "дерева ресурсов".
Теперича нужно определить какой именно программный код будет будет генерировать ответ клиентскому приложения (браузеру).
Этим занимаются "представления-обработчики". В Pyramid эти обработчики могут быть созданы с помощью различных лингвистических конструкций языка программирования.
Как веб-приложение определяет обработчик?
Используемые обработчики описываются при конфигурировании при первичном запуске (инициализации) веб-приложения. Рядом с указанием конфигуратору Pyramid корня "дерева ресурсов" для алгоритма "Traversal" и рядом с конфигурированием URI для метода "URL Dispath".
Возможны и другие методы конфигурировани обработчиков, но они здесь не рассматриваются.
Статический обработчик (просто файлы, считываемые Pyramid с диска и отдаваемые в ответ на веб-запрос) здесь не рассматривается.
Пример конфигурирования обработчика для URI "/admin/xchng1c/load" из примера выше, где рассматривался алгоритм "Traversal":
config.add_view('eshoppython.admin.views.Xchng1c_load',
context="eshoppython:admin.resources.Xchng1c",
name="load",
renderer='eshoppython:admin/templates/xchng1c_load.pt')
Здесь:
"eshoppython" - название веб-приложения и, по совместительству, название пакета Python, в котором размещается веб-приложение и, по совместительству, название каталога, в котором расположены файлы веб-приложения.
"eshoppython:admin.resources.Xchng1c" - объект, который алгоритм "Traversal" из примеров выше нашел при обходе "дерева ресурсов".
"load" - название представления-обработчика как оно указано в последней части URI.
"eshoppython.admin.views.Xchng1c_load" - название структуры языка Python (класс или функция), которая и есть обработчик.
"eshoppython:admin/templates/xchng1c_load.pt" - название файла шаблона, который будет обрабатывать результаты, возвращенные обработчиком, для генерации веб-страницы.
Дополнительно при конфигурировании можно прописать еще кучу интересных параметров.
Эти параметры можно разбить на 2 группы:
- Параметры, которые изменяют поведение Pyramid при поиске обработчика, то есть влияют на выбор конкретного обработчика
- И параметры, которые изменяют поведение фреймворка Pyramid, когда он уже нашел соответствующий обработчик. Например, проверка прав доступа (по ACL) к конкретному обработчику
Параметры конфигурирования обработчика, не влияющие на его поиск (автоматическое определение обработчика фреймворком Pyramid по URL):
- "permission" - права доступа, которые требуются для вызова обработчика. Если "permission=None" или параметр "permission" не указан, то доступ к обработчику (и к веб-странице или другим результатам, которые обработчик генерирует) осуществляется с ограничениями заданными для всего веб-приложения. По умолчанию это "есть доступ для всех, без ограничений".
-
"attr" - если обработчик является классом, то вместо вызова атрибута класса (метода класса) "__call__(...)" будет использован указанный в "attr" атрибут (метод) класса.
В документации по Pyramid указано, что этот параметр может быть использован не только с обработчиками-классами, но и с другими реализациями обработчиков (например, функциями?). Однако не пишет как именно. Пример в документации приведен только по классам.
Если этот параметр не указан или указан как "None", то, ежели обработчик является классом, система для генерации веб-страницы (или т.п.) вызывает метод "__call__(...)" этого класса. -
"renderer" - ответ, полученный из обработчика будет подвергнут преобразованию через указанный в этом параметре механизм рендеринга.
Типичное применение - указать в этом параметре название шаблона (ну и, следовательно, неявным образом, указывается и шаблонизатор) для генерации HTML.
Другое типичное применение - если в веб-приложении используется технология AJAX - указать "json", тогда полученные из обработчика данные будут преобразованы в формат JSON.
Если параметр "renderer" не указан, то данные, возвращаемые из обработчика никак не преобразуются. Фреймворк Pyramid в этом случае считает, что обработчик сам полностью сгенерировал результат веб-запроса. -
"wrapper" - имя другого обработчика, который получит результат сформированный конфигурируемым обработчиком.
Таким образом можно строить цепочки обработчиков.
Указанные во "wrapper" обработчик получит данные в запросе в поле "request.wrapped_response".
Сам этот другой обработчик будет найден фреймворком Pyramid именно по имени обработчика, среди сконфигурированных (например, через "Configurator.add_view(...)"), а не по имени функции или класса языка программирования Python. -
"decorator" - декоратор обработчика, то есть функция, которая будет вызвана вместо обработчика и уже в свою очередь сама вызовет обработчик. В качестве параметров принимает контекст и веб-запрос "(context, request).
Этот параметр - это название структуры так как она названа в программе на языке Python. -
"mapper" - используется для расширения фремворка Pyramid авторами плуг-инов. При обычном программирование с использованием фреймворка Pyramid обычно не нужно.
Параметр "mapper" - это название класса так, как она названа в программе на языке Python, если не указана или указана как "None", то будет использован маппинг по умолчанию.
Поскольку для обычного программирования, согласно документации к Pyramid, сие не нужно, то что это и зачем - не стал разбираться.
Параметры конфигурирования обработчиков, которые влияют на поиск фреймворком Pyramid обработчика, подходящего для обработки веб-запроса (рассмотрены с позиции использования для диспетчеризации URL прежде всего механизма "Traveral", а не механизма "URL Dispath"):
-
"name" - имя обработчика. Не название структуры обработчика на языке программирования Python, а имя, определяемое, в общем случае, из URI в ходе работы диспетчеризатора URL по алгоритму "Traversal".
Допустимы пустые имена обработчиков.
Типичная ситуация - когда весь URI полностью до конца разобран в процессе обхода "дерева ресурсов".
См. пример чуть ниже, в описании параметра "context". -
"context" - последний "ресурс", определенный в результате обхода механизмом "Traversal" по "дереву ресурсов" при разборе URL. Обычно это элемент "дерева ресурсов", отвечающий за часть URI, непосредственно предшествующую названию обработчика в URI.
Например, для URI "/a/b/c" это "листок" "дерева ресурсов", отвечающий за часть URI "c", если имя обрабочика является пустой строкой.
Или же, для того же URI "/a/b/c" это "листок" "дерева ресурсов", отвечающий за часть URI "b", если имя обрабочика "c"
Продолжение следует...