Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Vladislav Rykov
THSO.server
Commits
ff4a13ed
Commit
ff4a13ed
authored
Apr 17, 2020
by
Vladislav Rykov
Browse files
major changes
parent
51f76a47
Pipeline
#38
failed with stages
Changes
394
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Too many changes to show.
To preserve performance only
20 of 394+
files are displayed.
Plain diff
Email patch
env/lib/python3.5/site-packages/flask/json/tag.py
0 → 100644
View file @
ff4a13ed
# -*- coding: utf-8 -*-
"""
Tagged JSON
~~~~~~~~~~~
A compact representation for lossless serialization of non-standard JSON types.
:class:`~flask.sessions.SecureCookieSessionInterface` uses this to serialize
the session data, but it may be useful in other places. It can be extended to
support other types.
.. autoclass:: TaggedJSONSerializer
:members:
.. autoclass:: JSONTag
:members:
Let's seen an example that adds support for :class:`~collections.OrderedDict`.
Dicts don't have an order in Python or JSON, so to handle this we will dump
the items as a list of ``[key, value]`` pairs. Subclass :class:`JSONTag` and
give it the new key ``' od'`` to identify the type. The session serializer
processes dicts first, so insert the new tag at the front of the order since
``OrderedDict`` must be processed before ``dict``. ::
from flask.json.tag import JSONTag
class TagOrderedDict(JSONTag):
__slots__ = ('serializer',)
key = ' od'
def check(self, value):
return isinstance(value, OrderedDict)
def to_json(self, value):
return [[k, self.serializer.tag(v)] for k, v in iteritems(value)]
def to_python(self, value):
return OrderedDict(value)
app.session_interface.serializer.register(TagOrderedDict, index=0)
:copyright: 2010 Pallets
:license: BSD-3-Clause
"""
from
base64
import
b64decode
from
base64
import
b64encode
from
datetime
import
datetime
from
uuid
import
UUID
from
jinja2
import
Markup
from
werkzeug.http
import
http_date
from
werkzeug.http
import
parse_date
from
.._compat
import
iteritems
from
.._compat
import
text_type
from
..json
import
dumps
from
..json
import
loads
class
JSONTag
(
object
):
"""Base class for defining type tags for :class:`TaggedJSONSerializer`."""
__slots__
=
(
"serializer"
,)
#: The tag to mark the serialized object with. If ``None``, this tag is
#: only used as an intermediate step during tagging.
key
=
None
def
__init__
(
self
,
serializer
):
"""Create a tagger for the given serializer."""
self
.
serializer
=
serializer
def
check
(
self
,
value
):
"""Check if the given value should be tagged by this tag."""
raise
NotImplementedError
def
to_json
(
self
,
value
):
"""Convert the Python object to an object that is a valid JSON type.
The tag will be added later."""
raise
NotImplementedError
def
to_python
(
self
,
value
):
"""Convert the JSON representation back to the correct type. The tag
will already be removed."""
raise
NotImplementedError
def
tag
(
self
,
value
):
"""Convert the value to a valid JSON type and add the tag structure
around it."""
return
{
self
.
key
:
self
.
to_json
(
value
)}
class
TagDict
(
JSONTag
):
"""Tag for 1-item dicts whose only key matches a registered tag.
Internally, the dict key is suffixed with `__`, and the suffix is removed
when deserializing.
"""
__slots__
=
()
key
=
" di"
def
check
(
self
,
value
):
return
(
isinstance
(
value
,
dict
)
and
len
(
value
)
==
1
and
next
(
iter
(
value
))
in
self
.
serializer
.
tags
)
def
to_json
(
self
,
value
):
key
=
next
(
iter
(
value
))
return
{
key
+
"__"
:
self
.
serializer
.
tag
(
value
[
key
])}
def
to_python
(
self
,
value
):
key
=
next
(
iter
(
value
))
return
{
key
[:
-
2
]:
value
[
key
]}
class
PassDict
(
JSONTag
):
__slots__
=
()
def
check
(
self
,
value
):
return
isinstance
(
value
,
dict
)
def
to_json
(
self
,
value
):
# JSON objects may only have string keys, so don't bother tagging the
# key here.
return
dict
((
k
,
self
.
serializer
.
tag
(
v
))
for
k
,
v
in
iteritems
(
value
))
tag
=
to_json
class
TagTuple
(
JSONTag
):
__slots__
=
()
key
=
" t"
def
check
(
self
,
value
):
return
isinstance
(
value
,
tuple
)
def
to_json
(
self
,
value
):
return
[
self
.
serializer
.
tag
(
item
)
for
item
in
value
]
def
to_python
(
self
,
value
):
return
tuple
(
value
)
class
PassList
(
JSONTag
):
__slots__
=
()
def
check
(
self
,
value
):
return
isinstance
(
value
,
list
)
def
to_json
(
self
,
value
):
return
[
self
.
serializer
.
tag
(
item
)
for
item
in
value
]
tag
=
to_json
class
TagBytes
(
JSONTag
):
__slots__
=
()
key
=
" b"
def
check
(
self
,
value
):
return
isinstance
(
value
,
bytes
)
def
to_json
(
self
,
value
):
return
b64encode
(
value
).
decode
(
"ascii"
)
def
to_python
(
self
,
value
):
return
b64decode
(
value
)
class
TagMarkup
(
JSONTag
):
"""Serialize anything matching the :class:`~flask.Markup` API by
having a ``__html__`` method to the result of that method. Always
deserializes to an instance of :class:`~flask.Markup`."""
__slots__
=
()
key
=
" m"
def
check
(
self
,
value
):
return
callable
(
getattr
(
value
,
"__html__"
,
None
))
def
to_json
(
self
,
value
):
return
text_type
(
value
.
__html__
())
def
to_python
(
self
,
value
):
return
Markup
(
value
)
class
TagUUID
(
JSONTag
):
__slots__
=
()
key
=
" u"
def
check
(
self
,
value
):
return
isinstance
(
value
,
UUID
)
def
to_json
(
self
,
value
):
return
value
.
hex
def
to_python
(
self
,
value
):
return
UUID
(
value
)
class
TagDateTime
(
JSONTag
):
__slots__
=
()
key
=
" d"
def
check
(
self
,
value
):
return
isinstance
(
value
,
datetime
)
def
to_json
(
self
,
value
):
return
http_date
(
value
)
def
to_python
(
self
,
value
):
return
parse_date
(
value
)
class
TaggedJSONSerializer
(
object
):
"""Serializer that uses a tag system to compactly represent objects that
are not JSON types. Passed as the intermediate serializer to
:class:`itsdangerous.Serializer`.
The following extra types are supported:
* :class:`dict`
* :class:`tuple`
* :class:`bytes`
* :class:`~flask.Markup`
* :class:`~uuid.UUID`
* :class:`~datetime.datetime`
"""
__slots__
=
(
"tags"
,
"order"
)
#: Tag classes to bind when creating the serializer. Other tags can be
#: added later using :meth:`~register`.
default_tags
=
[
TagDict
,
PassDict
,
TagTuple
,
PassList
,
TagBytes
,
TagMarkup
,
TagUUID
,
TagDateTime
,
]
def
__init__
(
self
):
self
.
tags
=
{}
self
.
order
=
[]
for
cls
in
self
.
default_tags
:
self
.
register
(
cls
)
def
register
(
self
,
tag_class
,
force
=
False
,
index
=
None
):
"""Register a new tag with this serializer.
:param tag_class: tag class to register. Will be instantiated with this
serializer instance.
:param force: overwrite an existing tag. If false (default), a
:exc:`KeyError` is raised.
:param index: index to insert the new tag in the tag order. Useful when
the new tag is a special case of an existing tag. If ``None``
(default), the tag is appended to the end of the order.
:raise KeyError: if the tag key is already registered and ``force`` is
not true.
"""
tag
=
tag_class
(
self
)
key
=
tag
.
key
if
key
is
not
None
:
if
not
force
and
key
in
self
.
tags
:
raise
KeyError
(
"Tag '{0}' is already registered."
.
format
(
key
))
self
.
tags
[
key
]
=
tag
if
index
is
None
:
self
.
order
.
append
(
tag
)
else
:
self
.
order
.
insert
(
index
,
tag
)
def
tag
(
self
,
value
):
"""Convert a value to a tagged representation if necessary."""
for
tag
in
self
.
order
:
if
tag
.
check
(
value
):
return
tag
.
tag
(
value
)
return
value
def
untag
(
self
,
value
):
"""Convert a tagged representation back to the original type."""
if
len
(
value
)
!=
1
:
return
value
key
=
next
(
iter
(
value
))
if
key
not
in
self
.
tags
:
return
value
return
self
.
tags
[
key
].
to_python
(
value
[
key
])
def
dumps
(
self
,
value
):
"""Tag the value and dump it to a compact JSON string."""
return
dumps
(
self
.
tag
(
value
),
separators
=
(
","
,
":"
))
def
loads
(
self
,
value
):
"""Load data from a JSON string and deserialized any tagged objects."""
return
loads
(
value
,
object_hook
=
self
.
untag
)
env/lib/python3.5/site-packages/flask/logging.py
0 → 100644
View file @
ff4a13ed
# -*- coding: utf-8 -*-
"""
flask.logging
~~~~~~~~~~~~~
:copyright: 2010 Pallets
:license: BSD-3-Clause
"""
from
__future__
import
absolute_import
import
logging
import
sys
import
warnings
from
werkzeug.local
import
LocalProxy
from
.globals
import
request
@
LocalProxy
def
wsgi_errors_stream
():
"""Find the most appropriate error stream for the application. If a request
is active, log to ``wsgi.errors``, otherwise use ``sys.stderr``.
If you configure your own :class:`logging.StreamHandler`, you may want to
use this for the stream. If you are using file or dict configuration and
can't import this directly, you can refer to it as
``ext://flask.logging.wsgi_errors_stream``.
"""
return
request
.
environ
[
"wsgi.errors"
]
if
request
else
sys
.
stderr
def
has_level_handler
(
logger
):
"""Check if there is a handler in the logging chain that will handle the
given logger's :meth:`effective level <~logging.Logger.getEffectiveLevel>`.
"""
level
=
logger
.
getEffectiveLevel
()
current
=
logger
while
current
:
if
any
(
handler
.
level
<=
level
for
handler
in
current
.
handlers
):
return
True
if
not
current
.
propagate
:
break
current
=
current
.
parent
return
False
#: Log messages to :func:`~flask.logging.wsgi_errors_stream` with the format
#: ``[%(asctime)s] %(levelname)s in %(module)s: %(message)s``.
default_handler
=
logging
.
StreamHandler
(
wsgi_errors_stream
)
default_handler
.
setFormatter
(
logging
.
Formatter
(
"[%(asctime)s] %(levelname)s in %(module)s: %(message)s"
)
)
def
_has_config
(
logger
):
"""Decide if a logger has direct configuration applied by checking
its properties against the defaults.
:param logger: The :class:`~logging.Logger` to inspect.
"""
return
(
logger
.
level
!=
logging
.
NOTSET
or
logger
.
handlers
or
logger
.
filters
or
not
logger
.
propagate
)
def
create_logger
(
app
):
"""Get the the Flask apps's logger and configure it if needed.
The logger name will be the same as
:attr:`app.import_name <flask.Flask.name>`.
When :attr:`~flask.Flask.debug` is enabled, set the logger level to
:data:`logging.DEBUG` if it is not set.
If there is no handler for the logger's effective level, add a
:class:`~logging.StreamHandler` for
:func:`~flask.logging.wsgi_errors_stream` with a basic format.
"""
logger
=
logging
.
getLogger
(
app
.
name
)
# 1.1.0 changes name of logger, warn if config is detected for old
# name and not new name
for
old_name
in
(
"flask.app"
,
"flask"
):
old_logger
=
logging
.
getLogger
(
old_name
)
if
_has_config
(
old_logger
)
and
not
_has_config
(
logger
):
warnings
.
warn
(
"'app.logger' is named '{name}' for this application,"
" but configuration was found for '{old_name}', which"
" no longer has an effect. The logging configuration"
" should be moved to '{name}'."
.
format
(
name
=
app
.
name
,
old_name
=
old_name
)
)
break
if
app
.
debug
and
not
logger
.
level
:
logger
.
setLevel
(
logging
.
DEBUG
)
if
not
has_level_handler
(
logger
):
logger
.
addHandler
(
default_handler
)
return
logger
env/lib/python3.5/site-packages/flask/sessions.py
0 → 100644
View file @
ff4a13ed
# -*- coding: utf-8 -*-
"""
flask.sessions
~~~~~~~~~~~~~~
Implements cookie based sessions based on itsdangerous.
:copyright: 2010 Pallets
:license: BSD-3-Clause
"""
import
hashlib
import
warnings
from
datetime
import
datetime
from
itsdangerous
import
BadSignature
from
itsdangerous
import
URLSafeTimedSerializer
from
werkzeug.datastructures
import
CallbackDict
from
._compat
import
collections_abc
from
.helpers
import
is_ip
from
.helpers
import
total_seconds
from
.json.tag
import
TaggedJSONSerializer
class
SessionMixin
(
collections_abc
.
MutableMapping
):
"""Expands a basic dictionary with session attributes."""
@
property
def
permanent
(
self
):
"""This reflects the ``'_permanent'`` key in the dict."""
return
self
.
get
(
"_permanent"
,
False
)
@
permanent
.
setter
def
permanent
(
self
,
value
):
self
[
"_permanent"
]
=
bool
(
value
)
#: Some implementations can detect whether a session is newly
#: created, but that is not guaranteed. Use with caution. The mixin
# default is hard-coded ``False``.
new
=
False
#: Some implementations can detect changes to the session and set
#: this when that happens. The mixin default is hard coded to
#: ``True``.
modified
=
True
#: Some implementations can detect when session data is read or
#: written and set this when that happens. The mixin default is hard
#: coded to ``True``.
accessed
=
True
class
SecureCookieSession
(
CallbackDict
,
SessionMixin
):
"""Base class for sessions based on signed cookies.
This session backend will set the :attr:`modified` and
:attr:`accessed` attributes. It cannot reliably track whether a
session is new (vs. empty), so :attr:`new` remains hard coded to
``False``.
"""
#: When data is changed, this is set to ``True``. Only the session
#: dictionary itself is tracked; if the session contains mutable
#: data (for example a nested dict) then this must be set to
#: ``True`` manually when modifying that data. The session cookie
#: will only be written to the response if this is ``True``.
modified
=
False
#: When data is read or written, this is set to ``True``. Used by
# :class:`.SecureCookieSessionInterface` to add a ``Vary: Cookie``
#: header, which allows caching proxies to cache different pages for
#: different users.
accessed
=
False
def
__init__
(
self
,
initial
=
None
):
def
on_update
(
self
):
self
.
modified
=
True
self
.
accessed
=
True
super
(
SecureCookieSession
,
self
).
__init__
(
initial
,
on_update
)
def
__getitem__
(
self
,
key
):
self
.
accessed
=
True
return
super
(
SecureCookieSession
,
self
).
__getitem__
(
key
)
def
get
(
self
,
key
,
default
=
None
):
self
.
accessed
=
True
return
super
(
SecureCookieSession
,
self
).
get
(
key
,
default
)
def
setdefault
(
self
,
key
,
default
=
None
):
self
.
accessed
=
True
return
super
(
SecureCookieSession
,
self
).
setdefault
(
key
,
default
)
class
NullSession
(
SecureCookieSession
):
"""Class used to generate nicer error messages if sessions are not
available. Will still allow read-only access to the empty session
but fail on setting.
"""
def
_fail
(
self
,
*
args
,
**
kwargs
):
raise
RuntimeError
(
"The session is unavailable because no secret "
"key was set. Set the secret_key on the "
"application to something unique and secret."
)
__setitem__
=
__delitem__
=
clear
=
pop
=
popitem
=
update
=
setdefault
=
_fail
del
_fail
class
SessionInterface
(
object
):
"""The basic interface you have to implement in order to replace the
default session interface which uses werkzeug's securecookie
implementation. The only methods you have to implement are
:meth:`open_session` and :meth:`save_session`, the others have
useful defaults which you don't need to change.
The session object returned by the :meth:`open_session` method has to
provide a dictionary like interface plus the properties and methods
from the :class:`SessionMixin`. We recommend just subclassing a dict
and adding that mixin::
class Session(dict, SessionMixin):
pass
If :meth:`open_session` returns ``None`` Flask will call into
:meth:`make_null_session` to create a session that acts as replacement
if the session support cannot work because some requirement is not
fulfilled. The default :class:`NullSession` class that is created
will complain that the secret key was not set.
To replace the session interface on an application all you have to do
is to assign :attr:`flask.Flask.session_interface`::
app = Flask(__name__)
app.session_interface = MySessionInterface()
.. versionadded:: 0.8
"""
#: :meth:`make_null_session` will look here for the class that should
#: be created when a null session is requested. Likewise the
#: :meth:`is_null_session` method will perform a typecheck against
#: this type.
null_session_class
=
NullSession
#: A flag that indicates if the session interface is pickle based.
#: This can be used by Flask extensions to make a decision in regards
#: to how to deal with the session object.
#:
#: .. versionadded:: 0.10
pickle_based
=
False
def
make_null_session
(
self
,
app
):
"""Creates a null session which acts as a replacement object if the
real session support could not be loaded due to a configuration
error. This mainly aids the user experience because the job of the
null session is to still support lookup without complaining but
modifications are answered with a helpful error message of what
failed.
This creates an instance of :attr:`null_session_class` by default.
"""
return
self
.
null_session_class
()
def
is_null_session
(
self
,
obj
):
"""Checks if a given object is a null session. Null sessions are
not asked to be saved.
This checks if the object is an instance of :attr:`null_session_class`
by default.
"""
return
isinstance
(
obj
,
self
.
null_session_class
)
def
get_cookie_domain
(
self
,
app
):
"""Returns the domain that should be set for the session cookie.
Uses ``SESSION_COOKIE_DOMAIN`` if it is configured, otherwise
falls back to detecting the domain based on ``SERVER_NAME``.
Once detected (or if not set at all), ``SESSION_COOKIE_DOMAIN`` is
updated to avoid re-running the logic.
"""
rv
=
app
.
config
[
"SESSION_COOKIE_DOMAIN"
]
# set explicitly, or cached from SERVER_NAME detection
# if False, return None
if
rv
is
not
None
:
return
rv
if
rv
else
None
rv
=
app
.
config
[
"SERVER_NAME"
]
# server name not set, cache False to return none next time
if
not
rv
:
app
.
config
[
"SESSION_COOKIE_DOMAIN"
]
=
False
return
None
# chop off the port which is usually not supported by browsers
# remove any leading '.' since we'll add that later
rv
=
rv
.
rsplit
(
":"
,
1
)[
0
].
lstrip
(
"."
)
if
"."
not
in
rv
:
# Chrome doesn't allow names without a '.'
# this should only come up with localhost
# hack around this by not setting the name, and show a warning
warnings
.
warn
(
'"{rv}" is not a valid cookie domain, it must contain a ".".'
" Add an entry to your hosts file, for example"
' "{rv}.localdomain", and use that instead.'
.
format
(
rv
=
rv
)
)
app
.
config
[
"SESSION_COOKIE_DOMAIN"
]
=
False
return
None
ip
=
is_ip
(
rv
)
if
ip
:
warnings
.
warn
(
"The session cookie domain is an IP address. This may not work"
" as intended in some browsers. Add an entry to your hosts"
' file, for example "localhost.localdomain", and use that'
" instead."
)
# if this is not an ip and app is mounted at the root, allow subdomain
# matching by adding a '.' prefix
if
self
.
get_cookie_path
(
app
)
==
"/"
and
not
ip
:
rv
=
"."
+
rv
app
.
config
[
"SESSION_COOKIE_DOMAIN"
]
=
rv
return
rv
def
get_cookie_path
(
self
,
app
):
"""Returns the path for which the cookie should be valid. The
default implementation uses the value from the ``SESSION_COOKIE_PATH``
config var if it's set, and falls back to ``APPLICATION_ROOT`` or
uses ``/`` if it's ``None``.
"""
return
app
.
config
[
"SESSION_COOKIE_PATH"
]
or
app
.
config
[
"APPLICATION_ROOT"
]
def
get_cookie_httponly
(
self
,
app
):
"""Returns True if the session cookie should be httponly. This
currently just returns the value of the ``SESSION_COOKIE_HTTPONLY``
config var.
"""
return
app
.
config
[
"SESSION_COOKIE_HTTPONLY"
]
def
get_cookie_secure
(
self
,
app
):
"""Returns True if the cookie should be secure. This currently
just returns the value of the ``SESSION_COOKIE_SECURE`` setting.
"""
return
app
.
config
[
"SESSION_COOKIE_SECURE"
]
def
get_cookie_samesite
(
self
,
app
):
"""Return ``'Strict'`` or ``'Lax'`` if the cookie should use the
``SameSite`` attribute. This currently just returns the value of
the :data:`SESSION_COOKIE_SAMESITE` setting.
"""
return
app
.
config
[
"SESSION_COOKIE_SAMESITE"
]
def
get_expiration_time
(
self
,
app
,
session
):
"""A helper method that returns an expiration date for the session
or ``None`` if the session is linked to the browser session. The
default implementation returns now + the permanent session
lifetime configured on the application.
"""
if
session
.
permanent
:
return
datetime
.
utcnow
()
+
app
.
permanent_session_lifetime
def
should_set_cookie
(
self
,
app
,
session
):
"""Used by session backends to determine if a ``Set-Cookie`` header
should be set for this session cookie for this response. If the session
has been modified, the cookie is set. If the session is permanent and
the ``SESSION_REFRESH_EACH_REQUEST`` config is true, the cookie is
always set.
This check is usually skipped if the session was deleted.
.. versionadded:: 0.11
"""
return
session
.
modified
or
(
session
.
permanent
and
app
.
config
[
"SESSION_REFRESH_EACH_REQUEST"
]
)
def
open_session
(
self
,
app
,
request
):
"""This method has to be implemented and must either return ``None``
in case the loading failed because of a configuration error or an
instance of a session object which implements a dictionary like
interface + the methods and attributes on :class:`SessionMixin`.
"""
raise
NotImplementedError
()
def
save_session
(
self
,
app
,
session
,
response
):
"""This is called for actual sessions returned by :meth:`open_session`
at the end of the request. This is still called during a request
context so if you absolutely need access to the request you can do
that.
"""
raise
NotImplementedError
()
session_json_serializer
=
TaggedJSONSerializer
()
class
SecureCookieSessionInterface
(
SessionInterface
):
"""The default session interface that stores sessions in signed cookies
through the :mod:`itsdangerous` module.
"""
#: the salt that should be applied on top of the secret key for the
#: signing of cookie based sessions.
salt
=
"cookie-session"
#: the hash function to use for the signature. The default is sha1
digest_method
=
staticmethod
(
hashlib
.
sha1
)
#: the name of the itsdangerous supported key derivation. The default
#: is hmac.
key_derivation
=
"hmac"
#: A python serializer for the payload. The default is a compact
#: JSON derived serializer with support for some extra Python types
#: such as datetime objects or tuples.
serializer
=
session_json_serializer
session_class
=
SecureCookieSession
def
get_signing_serializer
(
self
,
app
):
if
not
app
.
secret_key
:
return
None
signer_kwargs
=
dict
(
key_derivation
=
self
.
key_derivation
,
digest_method
=
self
.
digest_method
)
return
URLSafeTimedSerializer
(
app
.
secret_key
,
salt
=
self
.
salt
,
serializer
=
self
.
serializer
,
signer_kwargs
=
signer_kwargs
,
)
def
open_session
(
self
,
app
,
request
):
s
=
self
.
get_signing_serializer
(
app
)
if
s
is
None
:
return
None
val
=
request
.
cookies
.
get
(
app
.
session_cookie_name
)
if
not
val
:
return
self
.
session_class
()
max_age
=
total_seconds
(
app
.
permanent_session_lifetime
)
try
:
data
=
s
.
loads
(
val
,
max_age
=
max_age
)
return
self
.
session_class
(
data
)
except
BadSignature
:
return
self
.
session_class
()
def
save_session
(
self
,
app
,
session
,
response
):
domain
=
self
.
get_cookie_domain
(
app
)
path
=
self
.
get_cookie_path
(
app
)
# If the session is modified to be empty, remove the cookie.
# If the session is empty, return without setting the cookie.
if
not
session
:
if
session
.
modified
:
response
.
delete_cookie
(
app
.
session_cookie_name
,
domain
=
domain
,
path
=
path
)
return
# Add a "Vary: Cookie" header if the session was accessed at all.
if
session
.
accessed
:
response
.
vary
.
add
(
"Cookie"
)
if
not
self
.
should_set_cookie
(
app
,
session
):
return
httponly
=
self
.
get_cookie_httponly
(
app
)
secure
=
self
.
get_cookie_secure
(
app
)
samesite
=
self
.
get_cookie_samesite
(
app
)
expires
=
self
.
get_expiration_time
(
app
,
session
)
val
=
self
.
get_signing_serializer
(
app
).
dumps
(
dict
(
session
))
response
.
set_cookie
(
app
.
session_cookie_name
,
val
,
expires
=
expires
,
httponly
=
httponly
,
domain
=
domain
,
path
=
path
,
secure
=
secure
,
samesite
=
samesite
,
)
env/lib/python3.5/site-packages/flask/signals.py
0 → 100644
View file @
ff4a13ed
# -*- coding: utf-8 -*-
"""
flask.signals
~~~~~~~~~~~~~
Implements signals based on blinker if available, otherwise
falls silently back to a noop.
:copyright: 2010 Pallets
:license: BSD-3-Clause
"""
try
:
from
blinker
import
Namespace
signals_available
=
True
except
ImportError
:
signals_available
=
False
class
Namespace
(
object
):
def
signal
(
self
,
name
,
doc
=
None
):
return
_FakeSignal
(
name
,
doc
)
class
_FakeSignal
(
object
):
"""If blinker is unavailable, create a fake class with the same
interface that allows sending of signals but will fail with an
error on anything else. Instead of doing anything on send, it
will just ignore the arguments and do nothing instead.
"""
def
__init__
(
self
,
name
,
doc
=
None
):
self
.
name
=
name
self
.
__doc__
=
doc
def
send
(
self
,
*
args
,
**
kwargs
):
pass
def
_fail
(
self
,
*
args
,
**
kwargs
):
raise
RuntimeError
(
"Signalling support is unavailable because the blinker"
" library is not installed."
)
connect
=
connect_via
=
connected_to
=
temporarily_connected_to
=
_fail
disconnect
=
_fail
has_receivers_for
=
receivers_for
=
_fail
del
_fail
# The namespace for code signals. If you are not Flask code, do
# not put signals in here. Create your own namespace instead.
_signals
=
Namespace
()
# Core signals. For usage examples grep the source code or consult
# the API documentation in docs/api.rst as well as docs/signals.rst
template_rendered
=
_signals
.
signal
(
"template-rendered"
)
before_render_template
=
_signals
.
signal
(
"before-render-template"
)
request_started
=
_signals
.
signal
(
"request-started"
)
request_finished
=
_signals
.
signal
(
"request-finished"
)
request_tearing_down
=
_signals
.
signal
(
"request-tearing-down"
)
got_request_exception
=
_signals
.
signal
(
"got-request-exception"
)
appcontext_tearing_down
=
_signals
.
signal
(
"appcontext-tearing-down"
)
appcontext_pushed
=
_signals
.
signal
(
"appcontext-pushed"
)
appcontext_popped
=
_signals
.
signal
(
"appcontext-popped"
)
message_flashed
=
_signals
.
signal
(
"message-flashed"
)
env/lib/python3.5/site-packages/flask/templating.py
0 → 100644
View file @
ff4a13ed
# -*- coding: utf-8 -*-
"""
flask.templating
~~~~~~~~~~~~~~~~
Implements the bridge to Jinja2.
:copyright: 2010 Pallets
:license: BSD-3-Clause
"""
from
jinja2
import
BaseLoader
from
jinja2
import
Environment
as
BaseEnvironment
from
jinja2
import
TemplateNotFound
from
.globals
import
_app_ctx_stack
from
.globals
import
_request_ctx_stack
from
.signals
import
before_render_template
from
.signals
import
template_rendered
def
_default_template_ctx_processor
():
"""Default template context processor. Injects `request`,
`session` and `g`.
"""
reqctx
=
_request_ctx_stack
.
top
appctx
=
_app_ctx_stack
.
top
rv
=
{}
if
appctx
is
not
None
:
rv
[
"g"
]
=
appctx
.
g
if
reqctx
is
not
None
:
rv
[
"request"
]
=
reqctx
.
request
rv
[
"session"
]
=
reqctx
.
session
return
rv
class
Environment
(
BaseEnvironment
):
"""Works like a regular Jinja2 environment but has some additional
knowledge of how Flask's blueprint works so that it can prepend the
name of the blueprint to referenced templates if necessary.
"""
def
__init__
(
self
,
app
,
**
options
):
if
"loader"
not
in
options
:
options
[
"loader"
]
=
app
.
create_global_jinja_loader
()
BaseEnvironment
.
__init__
(
self
,
**
options
)
self
.
app
=
app
class
DispatchingJinjaLoader
(
BaseLoader
):
"""A loader that looks for templates in the application and all
the blueprint folders.
"""
def
__init__
(
self
,
app
):
self
.
app
=
app
def
get_source
(
self
,
environment
,
template
):
if
self
.
app
.
config
[
"EXPLAIN_TEMPLATE_LOADING"
]:
return
self
.
_get_source_explained
(
environment
,
template
)
return
self
.
_get_source_fast
(
environment
,
template
)
def
_get_source_explained
(
self
,
environment
,
template
):
attempts
=
[]
trv
=
None
for
srcobj
,
loader
in
self
.
_iter_loaders
(
template
):
try
:
rv
=
loader
.
get_source
(
environment
,
template
)
if
trv
is
None
:
trv
=
rv
except
TemplateNotFound
:
rv
=
None
attempts
.
append
((
loader
,
srcobj
,
rv
))
from
.debughelpers
import
explain_template_loading_attempts
explain_template_loading_attempts
(
self
.
app
,
template
,
attempts
)
if
trv
is
not
None
:
return
trv
raise
TemplateNotFound
(
template
)
def
_get_source_fast
(
self
,
environment
,
template
):
for
_srcobj
,
loader
in
self
.
_iter_loaders
(
template
):
try
:
return
loader
.
get_source
(
environment
,
template
)
except
TemplateNotFound
:
continue
raise
TemplateNotFound
(
template
)
def
_iter_loaders
(
self
,
template
):
loader
=
self
.
app
.
jinja_loader
if
loader
is
not
None
:
yield
self
.
app
,
loader
for
blueprint
in
self
.
app
.
iter_blueprints
():
loader
=
blueprint
.
jinja_loader
if
loader
is
not
None
:
yield
blueprint
,
loader
def
list_templates
(
self
):
result
=
set
()
loader
=
self
.
app
.
jinja_loader
if
loader
is
not
None
:
result
.
update
(
loader
.
list_templates
())
for
blueprint
in
self
.
app
.
iter_blueprints
():
loader
=
blueprint
.
jinja_loader
if
loader
is
not
None
:
for
template
in
loader
.
list_templates
():
result
.
add
(
template
)
return
list
(
result
)
def
_render
(
template
,
context
,
app
):
"""Renders the template and fires the signal"""
before_render_template
.
send
(
app
,
template
=
template
,
context
=
context
)
rv
=
template
.
render
(
context
)
template_rendered
.
send
(
app
,
template
=
template
,
context
=
context
)
return
rv
def
render_template
(
template_name_or_list
,
**
context
):
"""Renders a template from the template folder with the given
context.
:param template_name_or_list: the name of the template to be
rendered, or an iterable with template names
the first one existing will be rendered
:param context: the variables that should be available in the
context of the template.
"""
ctx
=
_app_ctx_stack
.
top
ctx
.
app
.
update_template_context
(
context
)
return
_render
(
ctx
.
app
.
jinja_env
.
get_or_select_template
(
template_name_or_list
),
context
,
ctx
.
app
,
)
def
render_template_string
(
source
,
**
context
):
"""Renders a template from the given template source string
with the given context. Template variables will be autoescaped.
:param source: the source code of the template to be
rendered
:param context: the variables that should be available in the
context of the template.
"""
ctx
=
_app_ctx_stack
.
top
ctx
.
app
.
update_template_context
(
context
)
return
_render
(
ctx
.
app
.
jinja_env
.
from_string
(
source
),
context
,
ctx
.
app
)
env/lib/python3.5/site-packages/flask/testing.py
0 → 100644
View file @
ff4a13ed
# -*- coding: utf-8 -*-
"""
flask.testing
~~~~~~~~~~~~~
Implements test support helpers. This module is lazily imported
and usually not used in production environments.
:copyright: 2010 Pallets
:license: BSD-3-Clause
"""
import
warnings
from
contextlib
import
contextmanager
import
werkzeug.test
from
click.testing
import
CliRunner
from
werkzeug.test
import
Client
from
werkzeug.urls
import
url_parse
from
.
import
_request_ctx_stack
from
.cli
import
ScriptInfo
from
.json
import
dumps
as
json_dumps
class
EnvironBuilder
(
werkzeug
.
test
.
EnvironBuilder
):
"""An :class:`~werkzeug.test.EnvironBuilder`, that takes defaults from the
application.
:param app: The Flask application to configure the environment from.
:param path: URL path being requested.
:param base_url: Base URL where the app is being served, which
``path`` is relative to. If not given, built from
:data:`PREFERRED_URL_SCHEME`, ``subdomain``,
:data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`.
:param subdomain: Subdomain name to append to :data:`SERVER_NAME`.
:param url_scheme: Scheme to use instead of
:data:`PREFERRED_URL_SCHEME`.
:param json: If given, this is serialized as JSON and passed as
``data``. Also defaults ``content_type`` to
``application/json``.
:param args: other positional arguments passed to
:class:`~werkzeug.test.EnvironBuilder`.
:param kwargs: other keyword arguments passed to
:class:`~werkzeug.test.EnvironBuilder`.
"""
def
__init__
(
self
,
app
,
path
=
"/"
,
base_url
=
None
,
subdomain
=
None
,
url_scheme
=
None
,
*
args
,
**
kwargs
):
assert
not
(
base_url
or
subdomain
or
url_scheme
)
or
(
base_url
is
not
None
)
!=
bool
(
subdomain
or
url_scheme
),
'Cannot pass "subdomain" or "url_scheme" with "base_url".'
if
base_url
is
None
:
http_host
=
app
.
config
.
get
(
"SERVER_NAME"
)
or
"localhost"
app_root
=
app
.
config
[
"APPLICATION_ROOT"
]
if
subdomain
:
http_host
=
"{0}.{1}"
.
format
(
subdomain
,
http_host
)
if
url_scheme
is
None
:
url_scheme
=
app
.
config
[
"PREFERRED_URL_SCHEME"
]
url
=
url_parse
(
path
)
base_url
=
"{scheme}://{netloc}/{path}"
.
format
(
scheme
=
url
.
scheme
or
url_scheme
,
netloc
=
url
.
netloc
or
http_host
,
path
=
app_root
.
lstrip
(
"/"
),
)
path
=
url
.
path
if
url
.
query
:
sep
=
b
"?"
if
isinstance
(
url
.
query
,
bytes
)
else
"?"
path
+=
sep
+
url
.
query
self
.
app
=
app
super
(
EnvironBuilder
,
self
).
__init__
(
path
,
base_url
,
*
args
,
**
kwargs
)
def
json_dumps
(
self
,
obj
,
**
kwargs
):
"""Serialize ``obj`` to a JSON-formatted string.
The serialization will be configured according to the config associated
with this EnvironBuilder's ``app``.
"""
kwargs
.
setdefault
(
"app"
,
self
.
app
)
return
json_dumps
(
obj
,
**
kwargs
)
def
make_test_environ_builder
(
*
args
,
**
kwargs
):
"""Create a :class:`flask.testing.EnvironBuilder`.
.. deprecated: 1.1
Will be removed in 2.0. Construct
``flask.testing.EnvironBuilder`` directly instead.
"""
warnings
.
warn
(
DeprecationWarning
(
'"make_test_environ_builder()" is deprecated and will be'
' removed in 2.0. Construct "flask.testing.EnvironBuilder"'
" directly instead."
)
)
return
EnvironBuilder
(
*
args
,
**
kwargs
)
class
FlaskClient
(
Client
):
"""Works like a regular Werkzeug test client but has some knowledge about
how Flask works to defer the cleanup of the request context stack to the
end of a ``with`` body when used in a ``with`` statement. For general
information about how to use this class refer to
:class:`werkzeug.test.Client`.
.. versionchanged:: 0.12
`app.test_client()` includes preset default environment, which can be
set after instantiation of the `app.test_client()` object in
`client.environ_base`.
Basic usage is outlined in the :ref:`testing` chapter.
"""
preserve_context
=
False
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
FlaskClient
,
self
).
__init__
(
*
args
,
**
kwargs
)
self
.
environ_base
=
{
"REMOTE_ADDR"
:
"127.0.0.1"
,
"HTTP_USER_AGENT"
:
"werkzeug/"
+
werkzeug
.
__version__
,
}
@
contextmanager
def
session_transaction
(
self
,
*
args
,
**
kwargs
):
"""When used in combination with a ``with`` statement this opens a
session transaction. This can be used to modify the session that
the test client uses. Once the ``with`` block is left the session is
stored back.
::
with client.session_transaction() as session:
session['value'] = 42
Internally this is implemented by going through a temporary test
request context and since session handling could depend on
request variables this function accepts the same arguments as
:meth:`~flask.Flask.test_request_context` which are directly
passed through.
"""
if
self
.
cookie_jar
is
None
:
raise
RuntimeError
(
"Session transactions only make sense with cookies enabled."
)
app
=
self
.
application
environ_overrides
=
kwargs
.
setdefault
(
"environ_overrides"
,
{})
self
.
cookie_jar
.
inject_wsgi
(
environ_overrides
)
outer_reqctx
=
_request_ctx_stack
.
top
with
app
.
test_request_context
(
*
args
,
**
kwargs
)
as
c
:
session_interface
=
app
.
session_interface
sess
=
session_interface
.
open_session
(
app
,
c
.
request
)
if
sess
is
None
:
raise
RuntimeError
(
"Session backend did not open a session. Check the configuration"
)
# Since we have to open a new request context for the session
# handling we want to make sure that we hide out own context
# from the caller. By pushing the original request context
# (or None) on top of this and popping it we get exactly that
# behavior. It's important to not use the push and pop
# methods of the actual request context object since that would
# mean that cleanup handlers are called
_request_ctx_stack
.
push
(
outer_reqctx
)
try
:
yield
sess
finally
:
_request_ctx_stack
.
pop
()
resp
=
app
.
response_class
()
if
not
session_interface
.
is_null_session
(
sess
):
session_interface
.
save_session
(
app
,
sess
,
resp
)
headers
=
resp
.
get_wsgi_headers
(
c
.
request
.
environ
)
self
.
cookie_jar
.
extract_wsgi
(
c
.
request
.
environ
,
headers
)
def
open
(
self
,
*
args
,
**
kwargs
):
as_tuple
=
kwargs
.
pop
(
"as_tuple"
,
False
)
buffered
=
kwargs
.
pop
(
"buffered"
,
False
)
follow_redirects
=
kwargs
.
pop
(
"follow_redirects"
,
False
)
if
(
not
kwargs
and
len
(
args
)
==
1
and
isinstance
(
args
[
0
],
(
werkzeug
.
test
.
EnvironBuilder
,
dict
))
):
environ
=
self
.
environ_base
.
copy
()
if
isinstance
(
args
[
0
],
werkzeug
.
test
.
EnvironBuilder
):
environ
.
update
(
args
[
0
].
get_environ
())
else
:
environ
.
update
(
args
[
0
])
environ
[
"flask._preserve_context"
]
=
self
.
preserve_context
else
:
kwargs
.
setdefault
(
"environ_overrides"
,
{})[
"flask._preserve_context"
]
=
self
.
preserve_context
kwargs
.
setdefault
(
"environ_base"
,
self
.
environ_base
)
builder
=
EnvironBuilder
(
self
.
application
,
*
args
,
**
kwargs
)
try
:
environ
=
builder
.
get_environ
()
finally
:
builder
.
close
()
return
Client
.
open
(
self
,
environ
,
as_tuple
=
as_tuple
,
buffered
=
buffered
,
follow_redirects
=
follow_redirects
,
)
def
__enter__
(
self
):
if
self
.
preserve_context
:
raise
RuntimeError
(
"Cannot nest client invocations"
)
self
.
preserve_context
=
True
return
self
def
__exit__
(
self
,
exc_type
,
exc_value
,
tb
):
self
.
preserve_context
=
False
# Normally the request context is preserved until the next
# request in the same thread comes. When the client exits we
# want to clean up earlier. Pop request contexts until the stack
# is empty or a non-preserved one is found.
while
True
:
top
=
_request_ctx_stack
.
top
if
top
is
not
None
and
top
.
preserved
:
top
.
pop
()
else
:
break
class
FlaskCliRunner
(
CliRunner
):
"""A :class:`~click.testing.CliRunner` for testing a Flask app's
CLI commands. Typically created using
:meth:`~flask.Flask.test_cli_runner`. See :ref:`testing-cli`.
"""
def
__init__
(
self
,
app
,
**
kwargs
):
self
.
app
=
app
super
(
FlaskCliRunner
,
self
).
__init__
(
**
kwargs
)
def
invoke
(
self
,
cli
=
None
,
args
=
None
,
**
kwargs
):
"""Invokes a CLI command in an isolated environment. See
:meth:`CliRunner.invoke <click.testing.CliRunner.invoke>` for
full method documentation. See :ref:`testing-cli` for examples.
If the ``obj`` argument is not given, passes an instance of
:class:`~flask.cli.ScriptInfo` that knows how to load the Flask
app being tested.
:param cli: Command object to invoke. Default is the app's
:attr:`~flask.app.Flask.cli` group.
:param args: List of strings to invoke the command with.
:return: a :class:`~click.testing.Result` object.
"""
if
cli
is
None
:
cli
=
self
.
app
.
cli
if
"obj"
not
in
kwargs
:
kwargs
[
"obj"
]
=
ScriptInfo
(
create_app
=
lambda
:
self
.
app
)
return
super
(
FlaskCliRunner
,
self
).
invoke
(
cli
,
args
,
**
kwargs
)
env/lib/python3.5/site-packages/flask/views.py
0 → 100644
View file @
ff4a13ed
# -*- coding: utf-8 -*-
"""
flask.views
~~~~~~~~~~~
This module provides class-based views inspired by the ones in Django.
:copyright: 2010 Pallets
:license: BSD-3-Clause
"""
from
._compat
import
with_metaclass
from
.globals
import
request
http_method_funcs
=
frozenset
(
[
"get"
,
"post"
,
"head"
,
"options"
,
"delete"
,
"put"
,
"trace"
,
"patch"
]
)
class
View
(
object
):
"""Alternative way to use view functions. A subclass has to implement
:meth:`dispatch_request` which is called with the view arguments from
the URL routing system. If :attr:`methods` is provided the methods
do not have to be passed to the :meth:`~flask.Flask.add_url_rule`
method explicitly::
class MyView(View):
methods = ['GET']
def dispatch_request(self, name):
return 'Hello %s!' % name
app.add_url_rule('/hello/<name>', view_func=MyView.as_view('myview'))
When you want to decorate a pluggable view you will have to either do that
when the view function is created (by wrapping the return value of
:meth:`as_view`) or you can use the :attr:`decorators` attribute::
class SecretView(View):
methods = ['GET']
decorators = [superuser_required]
def dispatch_request(self):
...
The decorators stored in the decorators list are applied one after another
when the view function is created. Note that you can *not* use the class
based decorators since those would decorate the view class and not the
generated view function!
"""
#: A list of methods this view can handle.
methods
=
None
#: Setting this disables or force-enables the automatic options handling.
provide_automatic_options
=
None
#: The canonical way to decorate class-based views is to decorate the
#: return value of as_view(). However since this moves parts of the
#: logic from the class declaration to the place where it's hooked
#: into the routing system.
#:
#: You can place one or more decorators in this list and whenever the
#: view function is created the result is automatically decorated.
#:
#: .. versionadded:: 0.8
decorators
=
()
def
dispatch_request
(
self
):
"""Subclasses have to override this method to implement the
actual view function code. This method is called with all
the arguments from the URL rule.
"""
raise
NotImplementedError
()
@
classmethod
def
as_view
(
cls
,
name
,
*
class_args
,
**
class_kwargs
):
"""Converts the class into an actual view function that can be used
with the routing system. Internally this generates a function on the
fly which will instantiate the :class:`View` on each request and call
the :meth:`dispatch_request` method on it.
The arguments passed to :meth:`as_view` are forwarded to the
constructor of the class.
"""
def
view
(
*
args
,
**
kwargs
):
self
=
view
.
view_class
(
*
class_args
,
**
class_kwargs
)
return
self
.
dispatch_request
(
*
args
,
**
kwargs
)
if
cls
.
decorators
:
view
.
__name__
=
name
view
.
__module__
=
cls
.
__module__
for
decorator
in
cls
.
decorators
:
view
=
decorator
(
view
)
# We attach the view class to the view function for two reasons:
# first of all it allows us to easily figure out what class-based
# view this thing came from, secondly it's also used for instantiating
# the view class so you can actually replace it with something else
# for testing purposes and debugging.
view
.
view_class
=
cls
view
.
__name__
=
name
view
.
__doc__
=
cls
.
__doc__
view
.
__module__
=
cls
.
__module__
view
.
methods
=
cls
.
methods
view
.
provide_automatic_options
=
cls
.
provide_automatic_options
return
view
class
MethodViewType
(
type
):
"""Metaclass for :class:`MethodView` that determines what methods the view
defines.
"""
def
__init__
(
cls
,
name
,
bases
,
d
):
super
(
MethodViewType
,
cls
).
__init__
(
name
,
bases
,
d
)
if
"methods"
not
in
d
:
methods
=
set
()
for
base
in
bases
:
if
getattr
(
base
,
"methods"
,
None
):
methods
.
update
(
base
.
methods
)
for
key
in
http_method_funcs
:
if
hasattr
(
cls
,
key
):
methods
.
add
(
key
.
upper
())
# If we have no method at all in there we don't want to add a
# method list. This is for instance the case for the base class
# or another subclass of a base method view that does not introduce
# new methods.
if
methods
:
cls
.
methods
=
methods
class
MethodView
(
with_metaclass
(
MethodViewType
,
View
)):
"""A class-based view that dispatches request methods to the corresponding
class methods. For example, if you implement a ``get`` method, it will be
used to handle ``GET`` requests. ::
class CounterAPI(MethodView):
def get(self):
return session.get('counter', 0)
def post(self):
session['counter'] = session.get('counter', 0) + 1
return 'OK'
app.add_url_rule('/counter', view_func=CounterAPI.as_view('counter'))
"""
def
dispatch_request
(
self
,
*
args
,
**
kwargs
):
meth
=
getattr
(
self
,
request
.
method
.
lower
(),
None
)
# If the request method is HEAD and we don't have a handler for it
# retry with GET.
if
meth
is
None
and
request
.
method
==
"HEAD"
:
meth
=
getattr
(
self
,
"get"
,
None
)
assert
meth
is
not
None
,
"Unimplemented method %r"
%
request
.
method
return
meth
(
*
args
,
**
kwargs
)
env/lib/python3.5/site-packages/flask/wrappers.py
0 → 100644
View file @
ff4a13ed
# -*- coding: utf-8 -*-
"""
flask.wrappers
~~~~~~~~~~~~~~
Implements the WSGI wrappers (request and response).
:copyright: 2010 Pallets
:license: BSD-3-Clause
"""
from
werkzeug.exceptions
import
BadRequest
from
werkzeug.wrappers
import
Request
as
RequestBase
from
werkzeug.wrappers
import
Response
as
ResponseBase
from
werkzeug.wrappers.json
import
JSONMixin
as
_JSONMixin
from
.
import
json
from
.globals
import
current_app
class
JSONMixin
(
_JSONMixin
):
json_module
=
json
def
on_json_loading_failed
(
self
,
e
):
if
current_app
and
current_app
.
debug
:
raise
BadRequest
(
"Failed to decode JSON object: {0}"
.
format
(
e
))
raise
BadRequest
()
class
Request
(
RequestBase
,
JSONMixin
):
"""The request object used by default in Flask. Remembers the
matched endpoint and view arguments.
It is what ends up as :class:`~flask.request`. If you want to replace
the request object used you can subclass this and set
:attr:`~flask.Flask.request_class` to your subclass.
The request object is a :class:`~werkzeug.wrappers.Request` subclass and
provides all of the attributes Werkzeug defines plus a few Flask
specific ones.
"""
#: The internal URL rule that matched the request. This can be
#: useful to inspect which methods are allowed for the URL from
#: a before/after handler (``request.url_rule.methods``) etc.
#: Though if the request's method was invalid for the URL rule,
#: the valid list is available in ``routing_exception.valid_methods``
#: instead (an attribute of the Werkzeug exception
#: :exc:`~werkzeug.exceptions.MethodNotAllowed`)
#: because the request was never internally bound.
#:
#: .. versionadded:: 0.6
url_rule
=
None
#: A dict of view arguments that matched the request. If an exception
#: happened when matching, this will be ``None``.
view_args
=
None
#: If matching the URL failed, this is the exception that will be
#: raised / was raised as part of the request handling. This is
#: usually a :exc:`~werkzeug.exceptions.NotFound` exception or
#: something similar.
routing_exception
=
None
@
property
def
max_content_length
(
self
):
"""Read-only view of the ``MAX_CONTENT_LENGTH`` config key."""
if
current_app
:
return
current_app
.
config
[
"MAX_CONTENT_LENGTH"
]
@
property
def
endpoint
(
self
):
"""The endpoint that matched the request. This in combination with
:attr:`view_args` can be used to reconstruct the same or a
modified URL. If an exception happened when matching, this will
be ``None``.
"""
if
self
.
url_rule
is
not
None
:
return
self
.
url_rule
.
endpoint
@
property
def
blueprint
(
self
):
"""The name of the current blueprint"""
if
self
.
url_rule
and
"."
in
self
.
url_rule
.
endpoint
:
return
self
.
url_rule
.
endpoint
.
rsplit
(
"."
,
1
)[
0
]
def
_load_form_data
(
self
):
RequestBase
.
_load_form_data
(
self
)
# In debug mode we're replacing the files multidict with an ad-hoc
# subclass that raises a different error for key errors.
if
(
current_app
and
current_app
.
debug
and
self
.
mimetype
!=
"multipart/form-data"
and
not
self
.
files
):
from
.debughelpers
import
attach_enctype_error_multidict
attach_enctype_error_multidict
(
self
)
class
Response
(
ResponseBase
,
JSONMixin
):
"""The response object that is used by default in Flask. Works like the
response object from Werkzeug but is set to have an HTML mimetype by
default. Quite often you don't have to create this object yourself because
:meth:`~flask.Flask.make_response` will take care of that for you.
If you want to replace the response object used you can subclass this and
set :attr:`~flask.Flask.response_class` to your subclass.
.. versionchanged:: 1.0
JSON support is added to the response, like the request. This is useful
when testing to get the test client response data as JSON.
.. versionchanged:: 1.0
Added :attr:`max_cookie_size`.
"""
default_mimetype
=
"text/html"
def
_get_data_for_json
(
self
,
cache
):
return
self
.
get_data
()
@
property
def
max_cookie_size
(
self
):
"""Read-only view of the :data:`MAX_COOKIE_SIZE` config key.
See :attr:`~werkzeug.wrappers.BaseResponse.max_cookie_size` in
Werkzeug's docs.
"""
if
current_app
:
return
current_app
.
config
[
"MAX_COOKIE_SIZE"
]
# return Werkzeug's default when not in an app context
return
super
(
Response
,
self
).
max_cookie_size
env/lib/python3.5/site-packages/itsdangerous-1.1.0.dist-info/INSTALLER
0 → 100644
View file @
ff4a13ed
pip
env/lib/python3.5/site-packages/itsdangerous-1.1.0.dist-info/LICENSE.rst
0 → 100644
View file @
ff4a13ed
`BSD 3-Clause <https://opensource.org/licenses/BSD-3-Clause>`_
Copyright © 2011 by the Pallets team.
Some rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
We kindly ask you to use these themes in an unmodified manner only with
Pallets and Pallets-related projects, not for unrelated projects. If you
like the visual style and want to use it for your own projects, please
consider making some larger changes to the themes (such as changing font
faces, sizes, colors or margins).
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
----
The initial implementation of itsdangerous was inspired by Django's
signing module.
Copyright © Django Software Foundation and individual contributors.
All rights reserved.
env/lib/python3.5/site-packages/itsdangerous-1.1.0.dist-info/METADATA
0 → 100644
View file @
ff4a13ed
Metadata-Version: 2.1
Name: itsdangerous
Version: 1.1.0
Summary: Various helpers to pass data to untrusted environments and back.
Home-page: https://palletsprojects.com/p/itsdangerous/
Author: Armin Ronacher
Author-email: armin.ronacher@active-4.com
Maintainer: Pallets Team
Maintainer-email: contact@palletsprojects.com
License: BSD
Project-URL: Documentation, https://itsdangerous.palletsprojects.com/
Project-URL: Code, https://github.com/pallets/itsdangerous
Project-URL: Issue tracker, https://github.com/pallets/itsdangerous/issues
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
itsdangerous
============
... so better sign this
Various helpers to pass data to untrusted environments and to get it
back safe and sound. Data is cryptographically signed to ensure that a
token has not been tampered with.
It's possible to customize how data is serialized. Data is compressed as
needed. A timestamp can be added and verified automatically while
loading a token.
Installing
----------
Install and update using `pip`_:
.. code-block:: text
pip install -U itsdangerous
.. _pip: https://pip.pypa.io/en/stable/quickstart/
A Simple Example
----------------
Here's how you could generate a token for transmitting a user's id and
name between web requests.
.. code-block:: python
from itsdangerous import URLSafeSerializer
auth_s = URLSafeSerializer("secret key", "auth")
token = auth_s.dumps({"id": 5, "name": "itsdangerous"})
print(token)
# eyJpZCI6NSwibmFtZSI6Iml0c2Rhbmdlcm91cyJ9.6YP6T0BaO67XP--9UzTrmurXSmg
data = auth_s.loads(token)
print(data["name"])
# itsdangerous
Donate
------
The Pallets organization develops and supports itsdangerous and other
popular packages. In order to grow the community of contributors and
users, and allow the maintainers to devote more time to the projects,
`please donate today`_.
.. _please donate today: https://palletsprojects.com/donate
Links
-----
* Website: https://palletsprojects.com/p/itsdangerous/
* Documentation: https://itsdangerous.palletsprojects.com/
* License: `BSD <https://github.com/pallets/itsdangerous/blob/master/LICENSE.rst>`_
* Releases: https://pypi.org/project/itsdangerous/
* Code: https://github.com/pallets/itsdangerous
* Issue tracker: https://github.com/pallets/itsdangerous/issues
* Test status: https://travis-ci.org/pallets/itsdangerous
* Test coverage: https://codecov.io/gh/pallets/itsdangerous
env/lib/python3.5/site-packages/itsdangerous-1.1.0.dist-info/RECORD
0 → 100644
View file @
ff4a13ed
itsdangerous-1.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
itsdangerous-1.1.0.dist-info/LICENSE.rst,sha256=_rKL-jSNgWsOfbrt3xhJnufoAHxngT241qs3xl4EbNQ,2120
itsdangerous-1.1.0.dist-info/METADATA,sha256=yyKjL2WOg_WybH2Yt-7NIvGpV3B93IsMc2HbToWc7Sk,3062
itsdangerous-1.1.0.dist-info/RECORD,,
itsdangerous-1.1.0.dist-info/WHEEL,sha256=CihQvCnsGZQBGAHLEUMf0IdA4fRduS_NBUTMgCTtvPM,110
itsdangerous-1.1.0.dist-info/top_level.txt,sha256=gKN1OKLk81i7fbWWildJA88EQ9NhnGMSvZqhfz9ICjk,13
itsdangerous/__init__.py,sha256=Dr-SkfFdOyiR_WjiqIXnlFpYRMW0XvPBNV5muzE5N_A,708
itsdangerous/__pycache__/__init__.cpython-35.pyc,,
itsdangerous/__pycache__/_compat.cpython-35.pyc,,
itsdangerous/__pycache__/_json.cpython-35.pyc,,
itsdangerous/__pycache__/encoding.cpython-35.pyc,,
itsdangerous/__pycache__/exc.cpython-35.pyc,,
itsdangerous/__pycache__/jws.cpython-35.pyc,,
itsdangerous/__pycache__/serializer.cpython-35.pyc,,
itsdangerous/__pycache__/signer.cpython-35.pyc,,
itsdangerous/__pycache__/timed.cpython-35.pyc,,
itsdangerous/__pycache__/url_safe.cpython-35.pyc,,
itsdangerous/_compat.py,sha256=oAAMcQAjwQXQpIbuHT3o-aL56ztm_7Fe-4lD7IteF6A,1133
itsdangerous/_json.py,sha256=W7BLL4RPnSOjNdo2gfKT3BeARMCIikY6O75rwWV0XoE,431
itsdangerous/encoding.py,sha256=KhY85PsH3bGHe5JANN4LMZ_3b0IwUWRRnnw1wvLlaIg,1224
itsdangerous/exc.py,sha256=KFxg7K2XMliMQAxL4jkRNgE8e73z2jcRaLrzwqVObnI,2959
itsdangerous/jws.py,sha256=6Lh9W-Lu8D9s7bRazs0Zb35eyAZm3pzLeZqHmRELeII,7470
itsdangerous/serializer.py,sha256=bT-dfjKec9zcKa8Qo8n7mHW_8M-XCTPMOFq1TQI_Fv4,8653
itsdangerous/signer.py,sha256=OOZbK8XomBjQfOFEul8osesn7fc80MXB0L1r7E86_GQ,6345
itsdangerous/timed.py,sha256=on5Q5lX7LT_LaETOhzF1ZmrRbia8P98263R8FiRyM6Y,5635
itsdangerous/url_safe.py,sha256=xnFTaukIPmW6Qwn6uNQLgzdau8RuAKnp5N7ukuXykj0,2275
env/lib/python3.5/site-packages/itsdangerous-1.1.0.dist-info/WHEEL
0 → 100644
View file @
ff4a13ed
Wheel-Version: 1.0
Generator: bdist_wheel (0.32.2)
Root-Is-Purelib: true
Tag: py2-none-any
Tag: py3-none-any
env/lib/python3.5/site-packages/itsdangerous-1.1.0.dist-info/top_level.txt
0 → 100644
View file @
ff4a13ed
itsdangerous
env/lib/python3.5/site-packages/itsdangerous/__init__.py
0 → 100644
View file @
ff4a13ed
from
._json
import
json
from
.encoding
import
base64_decode
from
.encoding
import
base64_encode
from
.encoding
import
want_bytes
from
.exc
import
BadData
from
.exc
import
BadHeader
from
.exc
import
BadPayload
from
.exc
import
BadSignature
from
.exc
import
BadTimeSignature
from
.exc
import
SignatureExpired
from
.jws
import
JSONWebSignatureSerializer
from
.jws
import
TimedJSONWebSignatureSerializer
from
.serializer
import
Serializer
from
.signer
import
HMACAlgorithm
from
.signer
import
NoneAlgorithm
from
.signer
import
Signer
from
.timed
import
TimedSerializer
from
.timed
import
TimestampSigner
from
.url_safe
import
URLSafeSerializer
from
.url_safe
import
URLSafeTimedSerializer
__version__
=
"1.1.0"
env/lib/python3.5/site-packages/itsdangerous/__pycache__/__init__.cpython-35.pyc
0 → 100644
View file @
ff4a13ed
File added
env/lib/python3.5/site-packages/itsdangerous/__pycache__/_compat.cpython-35.pyc
0 → 100644
View file @
ff4a13ed
File added
env/lib/python3.5/site-packages/itsdangerous/__pycache__/_json.cpython-35.pyc
0 → 100644
View file @
ff4a13ed
File added
env/lib/python3.5/site-packages/itsdangerous/__pycache__/encoding.cpython-35.pyc
0 → 100644
View file @
ff4a13ed
File added
env/lib/python3.5/site-packages/itsdangerous/__pycache__/exc.cpython-35.pyc
0 → 100644
View file @
ff4a13ed
File added
Prev
1
…
9
10
11
12
13
14
15
16
17
…
20
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment