1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
|
.. _zodb_sessions:
Using ZODB-Based Sessions
=========================
Sessions are server-side namespaces which are associated with a site
user that expire automatically after some period of disuse.
If your application is ZODB-based (e.g. you've created an application
from the ``bfg_zodb`` paster template, or you've followed the
instructions in :ref:`zodb_with_zeo`), you can make use of the
``repoze.session`` and ``repoze.browserid`` packages to add
sessioning to your application.
.. note:: You can use the ``repoze.session`` package even if your
application is not ZODB-based, but its backing store requires ZODB,
so it makes the most sense to use this package if your application
already uses ZODB. This tutorial does not cover usage of
``repoze.session``-based sessions in applications that don't
already use ZODB. For this, see `the standalone repoze.session
usage documentation <http://docs.repoze.org/session/usage.html>`_.
If you don't want to use ZODB to do sessioning, you might choose to
use a relational/filestorage sessioning system such as `Beaker
<http://pypi.python.org/pypi/Beaker>`_. :app:`Pyramid` is fully
compatible with this system too.
Installing Dependencies
-----------------------
#. Edit your :app:`Pyramid` application's ``setup.py`` file, adding
the following packages to the ``install_requires`` of the
application:
- ``repoze.session``
- ``repoze.browserid``
For example, the relevant portion of your application's
``setup.py`` file might look like so when you're finished adding
the dependencies.
.. code-block:: python
:linenos:
setup(
# ... other elements left out for brevity
install_requires=[
'pyramid',
'repoze.folder',
'repoze.retry',
'repoze.tm2',
'repoze.zodbconn',
'repoze.session'
'repoze.browserid',
],
# ... other elements left out for brevity
)
#. Rerun your application's ``setup.py`` file (e.g. using ``python
setup.py develop``) to get these packages installed.
Configuration
-------------
#. Edit your application's Paste ``.ini`` file.
If you already have an ``app`` section in the ``.ini`` file named
``main``, rename this section to ``myapp`` (e.g. ``app:main`` ->
``app:myapp``). Add a key to it named ``zodb_uri``, e.g.
.. code-block:: python
:linenos:
[app:myapp]
use = egg:myapp#app
zodb_uri = zeo://%(here)s/zeo.sock
reload_templates = true
debug_authorization = false
debug_notfound = false
Add a ``filter`` section to the ``.ini`` file named "browserid":
.. code-block:: python
:linenos:
[filter:browserid]
use = egg:repoze.browserid#browserid
secret_key = my-secret-key
Replace ``my-secret-key`` with any random string. This string
represents the value which the client-side "browser id" cookie is
encrypted with, to prevent tampering.
If a ``pipeline`` named ``main`` does not already exist in the
paste ``.ini`` file , add a ``pipeline`` section named ``main``.
Put the names ``connector``, ``egg:repoze.retry#retry``, and
``egg:repoze.tm2#tm`` to the top of the pipeline.
.. code-block:: python
:linenos:
[pipeline:main]
pipeline =
browserid
egg:repoze.retry#retry
egg:repoze.tm2#tm
myapp
When you're finished, your ``.ini`` file might look like so:
.. code-block:: ini
:linenos:
[DEFAULT]
debug = true
[app:myapp]
use = egg:myapp#app
zodb_uri = zeo://%(here)s/zeo.sock
reload_templates = true
debug_authorization = false
debug_notfound = false
[filter:browserid]
use = egg:repoze.browserid#browserid
secret_key = my-secret-key
[pipeline:main]
pipeline =
browserid
egg:repoze.retry#retry
egg:repoze.tm2#tm
myapp
[server:main]
use = egg:Paste#http
host = 0.0.0.0
port = 6543
See :ref:`MyProject_ini` for more information about project Paste
``.ini`` files.
#. Add a ``get_session`` API to your application. I've chosen to add
it directly to my ``views.py`` file, although it can live anywhere.
.. code-block:: python
:linenos:
from repoze.session.manager import SessionDataManager
from pyramid.traversal import find_root
def get_session(context, request):
root = find_root(context)
if not hasattr(root, '_sessions'):
root._sessions = SessionDataManager(3600, 5)
session = root._sessions.get(request.environ['repoze.browserid'])
return session
Note in the call to ``SessionDataManager`` that '3600' represents
the disuse timeout (60 minutes == 3600 seconds), and '5' represents
a write granularity time (the session will be marked as active at
most every five seconds). Vary these values as necessary.
#. Whenever you want to use a session in your application, call this API:
.. code-block:: python
:linenos:
from repoze.session.manager import SessionDataManager
from pyramid.traversal import find_root
from pyramid.chameleon_zpt import render_template_to_response
def my_view(context, request):
session = get_session(context, request)
session['abc'] = '123'
return render_template_to_response('templates/mytemplate.pt',
request = request,
project = 'sess')
def get_session(context, request):
root = find_root(context)
if not hasattr(root, '_sessions'):
root._sessions = SessionDataManager(3600, 5)
session = root._sessions.get(request.environ['repoze.browserid'])
return session
For more information, see the `repoze.session documentation
<http://docs.repoze.org/session/>`_ and the `repoze.browserid
documentation <http://pypi.python.org/pypi/repoze.browserid>`_.
|