Механизм сессий Beaker для веб-программирования на Python. Использование с фреймворком Pyramid
Задача:
Имеем веб-приложение, создаваемое с помощью фреймворка Pyramid. Нужна поддержка сессий пользователей.
Вручную писать совсем не хочется.
Писать плугин для подключения какого-либо существующего механизма поддержки сессий - тоже не хочется.
В Pyramid встроенные сессии - неполноценны для серьезного применения - в частности данные сессий хронятся в куках браузера, как я понял.
Для поддержки сессий с Pyramid будет использован Beaker. Ибо существует и описан в официальной документации к Pyramid механизм подключения Beaker к Pyramid.
Качать, официальная англ. дока:
http://pypi.python.org/pypi/Beaker/
http://beaker.groovie.org/
Для использования механизма поддержки сессий Beaker с веб-фреймворком Pyramid нужно:
Установить помимо Pyramid модуля: pyramid_beaker и Beaker, ибо штатно Pyramid не укомплектован никаким механизмом поддержки сессий:
easy_install -U Beaker
easy_install -U pyramid_beaker
Здесь рассмотрен только вариант инициализации Beaker с использованием ini-файла, совместимого с Paster.
Добавить в код инициализации веб-приложения:
from pyramid_beaker import session_factory_from_settings
и после "config = Configurator(...)"
session_factory = session_factory_from_settings(settings)
config.set_session_factory(session_factory)
Здесь настройки берутся из ini-файла в формате "Paste". Обычно это "development.ini" или "production.ini"
В ini-файле в секцию "[app:название веб-приложения]" необходимо добавить:
session.type = file
session.data_dir = %(here)s/data/sessions/data
session.lock_dir = %(here)s/data/sessions/lock
session.key = mykeyllkjlkjlkjklafadfwegc
session.secret = mysecretewsdfgio43nbvd56adsfsgyhj78kkujmny
session.cookie_on_exception = true
Здесь прописано, что сессии хранятся в файле (другой вариант - хранение сессий в базе данных - здесь не описан).
Каталог для хранения данных будет создан (разумеется, если у веб-приложения имеются соответствующие права для работы с файловой системой) внутри того каталога, где размещен ini-файл.
В качестве ключа и секрета (session.key и session.secret) может быть использована произвольная строка с буквами и цифрами. Сгенерированная случайным образом и длинная. Знаки препинания в этих строках использовать нельзя.
Параметр "session.cookie_on_exception = true" говорит, что куки для поддержки сессии должны быть отправлены клиентскому приложению (браузеру) в какой-то момент, близкий к генерации представления (view). Точнее - не разбирался.
Как использовать в обработчике представления (view):
has_count = 'счетчик' in request.session
if has_count: request.session['счетчик']=request.session['счетчик']+1
else: request.session['счетчик']=1
result = {'count':str(request.session['счетчик'])}
if request.session['счетчик'] > 9: request.session.invalidate()
return result
В примере выше в момент генерации представления получаем через "request.session" доступ к сессии.
Проверяем есть ли у сессии атрибут (параметр, реквизит, поле), называющееся "счетчик".
Ежели нет, то инициализируем атрибут "счетчик" значением 1.
Если есть, то инкрементируем его.
По достижении 10 - инициализируем сессию заново с помощью вызова "request.session.invalidate()". Таким образом, атрибут "счетчик" - уничтожается.
Многократное обновление страницы выводит клиентской программе (браузеру) странички с возрастающими от 1 до 10 номерами и затем нумерация страничек повторяется, начиная с 1. Для каждого пользователя - независимо - ведь данные хранятся в сессии.
Вывод результата в переменную "result" сделан до того как сессия была сделана недействительной через вызов "invalidate()". Иначе программа бы не смогла получить значение "счетчик" из сессии.
Еще одним вариантом уничтожения сессии является вызов "delete()" вместо "invalidate()". Отличается тем, что "delete()" посылает на клиента указание очистить куки, соответствующую сессии. А invalidate() очищает сессию при сохранении старых куки.
Вариант с "delete()" создает больше трафика между клиентом и сервером, но более с точки зрения безопасности предпочтителен, имхо.
Прочие, описанные в документации к Beaker функции API не пригодились. Все и так - работает.
Возможно, для высоконагруженных сайтов придется как-то специфически сконфигурировать Beaker, например, отключить автоматическую запись сессий.
Важный момент: Beaker сам НЕ удаляет устаревшие сессии.
Удаление сессий нужно реализовывать самому. При этом можно опираться на атрибут сессии "last_accessed", например. Этот атрибут автоматически обновляется механизмом Beaker.