Skip to content

Commit cfd095c

Browse files
committed
adding new session and render_template examples for flask
1 parent 8b9a521 commit cfd095c

File tree

3 files changed

+1016
-1
lines changed

3 files changed

+1016
-1
lines changed
Lines changed: 374 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,374 @@
1+
title: flask.globals session Python code examples
2+
category: page
3+
slug: flask-globals-session-examples
4+
sortorder: 500021001
5+
toc: False
6+
sidebartitle: flask.globals session
7+
meta: Python example code for the session function from the flask.globals module of the Flask project.
8+
9+
10+
session is a function within the flask.globals module of the Flask project.
11+
12+
13+
## Example 1 from Flask AppBuilder
14+
[Flask-AppBuilder](https://github.com/dpgaspar/Flask-AppBuilder)
15+
([documentation](https://flask-appbuilder.readthedocs.io/en/latest/)
16+
and
17+
[example apps](https://github.com/dpgaspar/Flask-AppBuilder/tree/master/examples))
18+
is a web application generator that uses Flask to automatically create
19+
the code for database-driven applications based on parameters set
20+
by the user. The generated applications include default security settings,
21+
forms, and internationalization support.
22+
23+
Flask App Builder is provided under the
24+
[BSD 3-Clause "New" or "Revised" license](https://github.com/dpgaspar/Flask-AppBuilder/blob/master/LICENSE).
25+
26+
[**Flask AppBuilder / flask_appbuilder / security / registerviews.py**](https://github.com/dpgaspar/Flask-AppBuilder/blob/master/flask_appbuilder/security/registerviews.py)
27+
28+
```python
29+
# registerviews.py
30+
__author__ = "Daniel Gaspar"
31+
32+
import logging
33+
34+
~~from flask import flash, redirect, request, session, url_for
35+
from flask_babel import lazy_gettext
36+
from flask_openid import OpenIDResponse, SessionWrapper
37+
from openid.consumer.consumer import CANCEL, Consumer, SUCCESS
38+
39+
from .forms import LoginForm_oid, RegisterUserDBForm, RegisterUserOIDForm
40+
from .. import const as c
41+
from .._compat import as_unicode
42+
from ..validators import Unique
43+
from ..views import expose, PublicFormView
44+
45+
log = logging.getLogger(__name__)
46+
47+
48+
def get_first_last_name(fullname):
49+
names = fullname.split()
50+
if len(names) > 1:
51+
return names[0], " ".join(names[1:])
52+
elif names:
53+
return names[0], ""
54+
55+
56+
class BaseRegisterUser(PublicFormView):
57+
"""
58+
Make your own user registration view and inherit from this class if you
59+
60+
61+
## ... source file abbreviated to get to session examples ...
62+
63+
64+
class RegisterUserOIDView(BaseRegisterUser):
65+
"""
66+
View for Registering a new user, auth OID mode
67+
"""
68+
69+
route_base = "/register"
70+
71+
form = RegisterUserOIDForm
72+
default_view = "form_oid_post"
73+
74+
@expose("/formoidone", methods=["GET", "POST"])
75+
def form_oid_post(self, flag=True):
76+
if flag:
77+
self.oid_login_handler(self.form_oid_post, self.appbuilder.sm.oid)
78+
form = LoginForm_oid()
79+
if form.validate_on_submit():
80+
session["remember_me"] = form.remember_me.data
81+
return self.appbuilder.sm.oid.try_login(
82+
form.openid.data, ask_for=["email", "fullname"]
83+
)
84+
~~ resp = session.pop("oid_resp", None)
85+
if resp:
86+
self._init_vars()
87+
form = self.form.refresh()
88+
self.form_get(form)
89+
form.username.data = resp.email
90+
first_name, last_name = get_first_last_name(resp.fullname)
91+
form.first_name.data = first_name
92+
form.last_name.data = last_name
93+
form.email.data = resp.email
94+
widgets = self._get_edit_widget(form=form)
95+
# self.update_redirect()
96+
return self.render_template(
97+
self.form_template,
98+
title=self.form_title,
99+
widgets=widgets,
100+
form_action="form",
101+
appbuilder=self.appbuilder,
102+
)
103+
else:
104+
flash(as_unicode(self.error_message), "warning")
105+
return redirect(self.get_redirect())
106+
107+
def oid_login_handler(self, f, oid):
108+
"""
109+
110+
111+
## ... source file continues with no further session examples...
112+
113+
114+
```
115+
116+
117+
## Example 2 from FlaskBB
118+
[FlaskBB](https://github.com/flaskbb/flaskbb)
119+
([project website](https://flaskbb.org/)) is a [Flask](/flask.html)-based
120+
forum web application. The web app allows users to chat in an open
121+
message board or send private messages in plain text or
122+
[Markdown](/markdown.html).
123+
124+
FlaskBB is provided as open source
125+
[under this license](https://github.com/flaskbb/flaskbb/blob/master/LICENSE).
126+
127+
[**FlaskBB / flaskbb / utils / helpers.py**](https://github.com/flaskbb/flaskbb/blob/master/flaskbb/utils/helpers.py)
128+
129+
```python
130+
# helpers.py
131+
"""
132+
import ast
133+
import itertools
134+
import logging
135+
import operator
136+
import os
137+
import re
138+
import time
139+
import warnings
140+
from datetime import datetime, timedelta
141+
from email import message_from_string
142+
from functools import wraps
143+
144+
import pkg_resources
145+
import requests
146+
import unidecode
147+
from babel.core import get_locale_identifier
148+
from babel.dates import format_date as babel_format_date
149+
from babel.dates import format_datetime as babel_format_datetime
150+
from babel.dates import format_timedelta as babel_format_timedelta
151+
~~from flask import flash, g, redirect, request, session, url_for
152+
from flask_allows import Permission
153+
from flask_babelplus import lazy_gettext as _
154+
from flask_login import current_user
155+
from flask_themes2 import get_themes_list, render_theme_template
156+
from jinja2 import Markup
157+
from PIL import ImageFile
158+
from pytz import UTC
159+
from werkzeug.local import LocalProxy
160+
from werkzeug.utils import ImportStringError, import_string
161+
162+
from flaskbb._compat import (iteritems, range_method, string_types, text_type,
163+
to_bytes, to_unicode)
164+
from flaskbb.extensions import babel, redis_store
165+
from flaskbb.utils.settings import flaskbb_config
166+
167+
try: # compat
168+
FileNotFoundError
169+
except NameError:
170+
FileNotFoundError = IOError
171+
172+
logger = logging.getLogger(__name__)
173+
174+
_punct_re = re.compile(r'[\t !"#$%&\'()*\-/<=>?@\[\\\]^_`{|},.]+')
175+
176+
177+
178+
## ... source file abbreviated to get to session examples ...
179+
180+
181+
result.append(word)
182+
return text_type(delim.join(result))
183+
184+
185+
def redirect_or_next(endpoint, **kwargs):
186+
"""Redirects the user back to the page they were viewing or to a specified
187+
endpoint. Wraps Flasks :func:`Flask.redirect` function.
188+
189+
:param endpoint: The fallback endpoint.
190+
"""
191+
return redirect(request.args.get("next") or endpoint, **kwargs)
192+
193+
194+
def render_template(template, **context): # pragma: no cover
195+
"""A helper function that uses the `render_theme_template` function
196+
without needing to edit all the views
197+
"""
198+
if current_user.is_authenticated and current_user.theme:
199+
theme = current_user.theme
200+
else:
201+
~~ theme = session.get("theme", flaskbb_config["DEFAULT_THEME"])
202+
return render_theme_template(theme, template, **context)
203+
204+
205+
# TODO(anr): clean this up
206+
def do_topic_action(topics, user, action, reverse): # noqa: C901
207+
"""Executes a specific action for topics. Returns a list with the modified
208+
topic objects.
209+
210+
:param topics: A iterable with ``Topic`` objects.
211+
:param user: The user object which wants to perform the action.
212+
:param action: One of the following actions: locked, important and delete.
213+
:param reverse: If the action should be done in a reversed way.
214+
For example, to unlock a topic, ``reverse`` should be
215+
set to ``True``.
216+
"""
217+
if not topics:
218+
return False
219+
220+
from flaskbb.utils.requirements import (
221+
IsAtleastModeratorInForum,
222+
CanDeleteTopic,
223+
Has,
224+
)
225+
226+
227+
228+
## ... source file continues with no further session examples...
229+
230+
231+
```
232+
233+
234+
## Example 3 from Flask-WTF
235+
[Flask-WTF](https://github.com/lepture/flask-wtf)
236+
([project documentation](https://flask-wtf.readthedocs.io/en/stable/)
237+
and
238+
[PyPI page](https://pypi.org/project/Flask-WTF/))
239+
provides a bridge between [Flask](/flask.html) and the the
240+
[WTForms](https://wtforms.readthedocs.io/en/2.3.x/) form-handling library.
241+
It makes it easier to use WTForms by reducing boilerplate code and
242+
shorter examples for common form operations as well as common security
243+
practices such as [CSRF](/cross-site-request-forgery-csrf.html).
244+
245+
[**Flask-WTF / flask_wtf / csrf.py**](https://github.com/lepture/flask-wtf/blob/master/flask_wtf/./csrf.py)
246+
247+
```python
248+
# csrf.py
249+
import hashlib
250+
import logging
251+
import os
252+
import warnings
253+
from functools import wraps
254+
255+
~~from flask import Blueprint, current_app, g, request, session
256+
from itsdangerous import BadData, SignatureExpired, URLSafeTimedSerializer
257+
from werkzeug.exceptions import BadRequest
258+
from werkzeug.security import safe_str_cmp
259+
from wtforms import ValidationError
260+
from wtforms.csrf.core import CSRF
261+
262+
from ._compat import FlaskWTFDeprecationWarning, string_types, urlparse
263+
264+
__all__ = ('generate_csrf', 'validate_csrf', 'CSRFProtect')
265+
logger = logging.getLogger(__name__)
266+
267+
268+
def generate_csrf(secret_key=None, token_key=None):
269+
"""Generate a CSRF token. The token is cached for a request, so multiple
270+
calls to this function will generate the same token.
271+
272+
During testing, it might be useful to access the signed token in
273+
``g.csrf_token`` and the raw token in ``session['csrf_token']``.
274+
275+
:param secret_key: Used to securely sign the token. Default is
276+
``WTF_CSRF_SECRET_KEY`` or ``SECRET_KEY``.
277+
:param token_key: Key where token is stored in session for comparison.
278+
Default is ``WTF_CSRF_FIELD_NAME`` or ``'csrf_token'``.
279+
"""
280+
281+
secret_key = _get_config(
282+
secret_key, 'WTF_CSRF_SECRET_KEY', current_app.secret_key,
283+
message='A secret key is required to use CSRF.'
284+
)
285+
field_name = _get_config(
286+
token_key, 'WTF_CSRF_FIELD_NAME', 'csrf_token',
287+
message='A field name is required to use CSRF.'
288+
)
289+
290+
if field_name not in g:
291+
s = URLSafeTimedSerializer(secret_key, salt='wtf-csrf-token')
292+
293+
~~ if field_name not in session:
294+
session[field_name] = hashlib.sha1(os.urandom(64)).hexdigest()
295+
296+
try:
297+
token = s.dumps(session[field_name])
298+
except TypeError:
299+
session[field_name] = hashlib.sha1(os.urandom(64)).hexdigest()
300+
token = s.dumps(session[field_name])
301+
302+
setattr(g, field_name, token)
303+
304+
return g.get(field_name)
305+
306+
307+
def validate_csrf(data, secret_key=None, time_limit=None, token_key=None):
308+
"""Check if the given data is a valid CSRF token. This compares the given
309+
signed token to the one stored in the session.
310+
311+
:param data: The signed CSRF token to be checked.
312+
:param secret_key: Used to securely sign the token. Default is
313+
``WTF_CSRF_SECRET_KEY`` or ``SECRET_KEY``.
314+
:param time_limit: Number of seconds that the token is valid. Default is
315+
``WTF_CSRF_TIME_LIMIT`` or 3600 seconds (60 minutes).
316+
:param token_key: Key where token is stored in session for comparison.
317+
Default is ``WTF_CSRF_FIELD_NAME`` or ``'csrf_token'``.
318+
319+
320+
## ... source file abbreviated to get to session examples ...
321+
322+
323+
.. versionchanged:: 0.14
324+
Raises ``ValidationError`` with a specific error message rather than
325+
returning ``True`` or ``False``.
326+
"""
327+
328+
secret_key = _get_config(
329+
secret_key, 'WTF_CSRF_SECRET_KEY', current_app.secret_key,
330+
message='A secret key is required to use CSRF.'
331+
)
332+
field_name = _get_config(
333+
token_key, 'WTF_CSRF_FIELD_NAME', 'csrf_token',
334+
message='A field name is required to use CSRF.'
335+
)
336+
time_limit = _get_config(
337+
time_limit, 'WTF_CSRF_TIME_LIMIT', 3600, required=False
338+
)
339+
340+
if not data:
341+
raise ValidationError('The CSRF token is missing.')
342+
343+
~~ if field_name not in session:
344+
raise ValidationError('The CSRF session token is missing.')
345+
346+
s = URLSafeTimedSerializer(secret_key, salt='wtf-csrf-token')
347+
348+
try:
349+
token = s.loads(data, max_age=time_limit)
350+
except SignatureExpired:
351+
raise ValidationError('The CSRF token has expired.')
352+
except BadData:
353+
raise ValidationError('The CSRF token is invalid.')
354+
355+
if not safe_str_cmp(session[field_name], token):
356+
raise ValidationError('The CSRF tokens do not match.')
357+
358+
359+
def _get_config(
360+
value, config_name, default=None,
361+
required=True, message='CSRF is not configured.'
362+
):
363+
"""Find config value based on provided value, Flask config, and default
364+
value.
365+
366+
:param value: already provided config value
367+
:param config_name: Flask ``config`` key
368+
369+
370+
## ... source file continues with no further session examples...
371+
372+
373+
```
374+

0 commit comments

Comments
 (0)