mirror of https://github.com/pallets/flask.git
Merge branch 'master' of https://github.com/mitsuhiko/flask
Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
This commit is contained in:
commit
b51e368cc7
|
@ -7,6 +7,7 @@ python:
|
||||||
- "pypy"
|
- "pypy"
|
||||||
- "3.3"
|
- "3.3"
|
||||||
- "3.4"
|
- "3.4"
|
||||||
|
- "3.5"
|
||||||
|
|
||||||
env:
|
env:
|
||||||
- REQUIREMENTS=lowest
|
- REQUIREMENTS=lowest
|
||||||
|
@ -20,6 +21,8 @@ matrix:
|
||||||
env: REQUIREMENTS=lowest
|
env: REQUIREMENTS=lowest
|
||||||
- python: "3.4"
|
- python: "3.4"
|
||||||
env: REQUIREMENTS=lowest
|
env: REQUIREMENTS=lowest
|
||||||
|
- python: "3.5"
|
||||||
|
env: REQUIREMENTS=lowest
|
||||||
|
|
||||||
|
|
||||||
install:
|
install:
|
||||||
|
|
2
CHANGES
2
CHANGES
|
@ -112,7 +112,7 @@ Version 0.10.1
|
||||||
Version 0.10
|
Version 0.10
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Released on June 13nd 2013, codename Limoncello.
|
Released on June 13th 2013, codename Limoncello.
|
||||||
|
|
||||||
- Changed default cookie serialization format from pickle to JSON to
|
- Changed default cookie serialization format from pickle to JSON to
|
||||||
limit the impact an attacker can do if the secret key leaks. See
|
limit the impact an attacker can do if the secret key leaks. See
|
||||||
|
|
|
@ -130,7 +130,8 @@ The following configuration values are used internally by Flask:
|
||||||
``SEND_FILE_MAX_AGE_DEFAULT`` Default cache control max age to use with
|
``SEND_FILE_MAX_AGE_DEFAULT`` Default cache control max age to use with
|
||||||
:meth:`~flask.Flask.send_static_file` (the
|
:meth:`~flask.Flask.send_static_file` (the
|
||||||
default static file handler) and
|
default static file handler) and
|
||||||
:func:`~flask.send_file`, in
|
:func:`~flask.send_file`, as
|
||||||
|
:class:`datetime.timedelta` or as seconds.
|
||||||
seconds. Override this value on a per-file
|
seconds. Override this value on a per-file
|
||||||
basis using the
|
basis using the
|
||||||
:meth:`~flask.Flask.get_send_file_max_age`
|
:meth:`~flask.Flask.get_send_file_max_age`
|
||||||
|
|
|
@ -24,7 +24,7 @@ Hosted options
|
||||||
- `Deploying Flask on Webfaction <http://flask.pocoo.org/snippets/65/>`_
|
- `Deploying Flask on Webfaction <http://flask.pocoo.org/snippets/65/>`_
|
||||||
- `Deploying Flask on Google App Engine <https://github.com/kamalgill/flask-appengine-template>`_
|
- `Deploying Flask on Google App Engine <https://github.com/kamalgill/flask-appengine-template>`_
|
||||||
- `Sharing your Localhost Server with Localtunnel <http://flask.pocoo.org/snippets/89/>`_
|
- `Sharing your Localhost Server with Localtunnel <http://flask.pocoo.org/snippets/89/>`_
|
||||||
|
- `Deploying on Azure (IIS) <https://azure.microsoft.com/documentation/articles/web-sites-python-configure/>`_
|
||||||
|
|
||||||
Self-hosted options
|
Self-hosted options
|
||||||
-------------------
|
-------------------
|
||||||
|
|
|
@ -193,5 +193,11 @@ Add the following lines to the top of your ``.wsgi`` file::
|
||||||
activate_this = '/path/to/env/bin/activate_this.py'
|
activate_this = '/path/to/env/bin/activate_this.py'
|
||||||
execfile(activate_this, dict(__file__=activate_this))
|
execfile(activate_this, dict(__file__=activate_this))
|
||||||
|
|
||||||
|
For Python 3 add the following lines to the top of your ``.wsgi`` file::
|
||||||
|
|
||||||
|
activate_this = '/path/to/env/bin/activate_this.py'
|
||||||
|
with open(activate_this) as file_:
|
||||||
|
exec(file_.read(), dict(__file__=activate_this))
|
||||||
|
|
||||||
This sets up the load paths according to the settings of the virtual
|
This sets up the load paths according to the settings of the virtual
|
||||||
environment. Keep in mind that the path has to be absolute.
|
environment. Keep in mind that the path has to be absolute.
|
||||||
|
|
|
@ -122,7 +122,7 @@ requirements. Here some examples::
|
||||||
'BrokenPackage>=0.7,<=1.0'
|
'BrokenPackage>=0.7,<=1.0'
|
||||||
]
|
]
|
||||||
|
|
||||||
As mentioned earlier that dependencies are pulled from PyPI. What if you
|
As mentioned earlier, dependencies are pulled from PyPI. What if you
|
||||||
want to depend on a package that cannot be found on PyPI and won't be
|
want to depend on a package that cannot be found on PyPI and won't be
|
||||||
because it is an internal package you don't want to share with anyone?
|
because it is an internal package you don't want to share with anyone?
|
||||||
Just still do as if there was a PyPI entry for it and provide a list of
|
Just still do as if there was a PyPI entry for it and provide a list of
|
||||||
|
|
|
@ -33,7 +33,7 @@ SQLAlchemy. It allows you to define tables and models in one go, similar
|
||||||
to how Django works. In addition to the following text I recommend the
|
to how Django works. In addition to the following text I recommend the
|
||||||
official documentation on the `declarative`_ extension.
|
official documentation on the `declarative`_ extension.
|
||||||
|
|
||||||
Here the example :file:`database.py` module for your application::
|
Here's the example :file:`database.py` module for your application::
|
||||||
|
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
from sqlalchemy.orm import scoped_session, sessionmaker
|
from sqlalchemy.orm import scoped_session, sessionmaker
|
||||||
|
|
12
flask/app.py
12
flask/app.py
|
@ -246,6 +246,16 @@ class Flask(_PackageBoundObject):
|
||||||
permanent_session_lifetime = ConfigAttribute('PERMANENT_SESSION_LIFETIME',
|
permanent_session_lifetime = ConfigAttribute('PERMANENT_SESSION_LIFETIME',
|
||||||
get_converter=_make_timedelta)
|
get_converter=_make_timedelta)
|
||||||
|
|
||||||
|
#: A :class:`~datetime.timedelta` which is used as default cache_timeout
|
||||||
|
#: for the :func:`send_file` functions. The default is 12 hours.
|
||||||
|
#:
|
||||||
|
#: This attribute can also be configured from the config with the
|
||||||
|
#: ``SEND_FILE_MAX_AGE_DEFAULT`` configuration key. This configuration
|
||||||
|
#: variable can also be set with an integer value used as seconds.
|
||||||
|
#: Defaults to ``timedelta(hours=12)``
|
||||||
|
send_file_max_age_default = ConfigAttribute('SEND_FILE_MAX_AGE_DEFAULT',
|
||||||
|
get_converter=_make_timedelta)
|
||||||
|
|
||||||
#: Enable this if you want to use the X-Sendfile feature. Keep in
|
#: Enable this if you want to use the X-Sendfile feature. Keep in
|
||||||
#: mind that the server has to support this. This only affects files
|
#: mind that the server has to support this. This only affects files
|
||||||
#: sent with the :func:`send_file` method.
|
#: sent with the :func:`send_file` method.
|
||||||
|
@ -297,7 +307,7 @@ class Flask(_PackageBoundObject):
|
||||||
'SESSION_COOKIE_SECURE': False,
|
'SESSION_COOKIE_SECURE': False,
|
||||||
'SESSION_REFRESH_EACH_REQUEST': True,
|
'SESSION_REFRESH_EACH_REQUEST': True,
|
||||||
'MAX_CONTENT_LENGTH': None,
|
'MAX_CONTENT_LENGTH': None,
|
||||||
'SEND_FILE_MAX_AGE_DEFAULT': 12 * 60 * 60, # 12 hours
|
'SEND_FILE_MAX_AGE_DEFAULT': timedelta(hours=12),
|
||||||
'TRAP_BAD_REQUEST_ERRORS': False,
|
'TRAP_BAD_REQUEST_ERRORS': False,
|
||||||
'TRAP_HTTP_EXCEPTIONS': False,
|
'TRAP_HTTP_EXCEPTIONS': False,
|
||||||
'EXPLAIN_TEMPLATE_LOADING': False,
|
'EXPLAIN_TEMPLATE_LOADING': False,
|
||||||
|
|
|
@ -14,6 +14,7 @@ import sys
|
||||||
import pkgutil
|
import pkgutil
|
||||||
import posixpath
|
import posixpath
|
||||||
import mimetypes
|
import mimetypes
|
||||||
|
from datetime import timedelta
|
||||||
from time import time
|
from time import time
|
||||||
from zlib import adler32
|
from zlib import adler32
|
||||||
from threading import RLock
|
from threading import RLock
|
||||||
|
@ -856,7 +857,7 @@ class _PackageBoundObject(object):
|
||||||
|
|
||||||
.. versionadded:: 0.9
|
.. versionadded:: 0.9
|
||||||
"""
|
"""
|
||||||
return current_app.config['SEND_FILE_MAX_AGE_DEFAULT']
|
return total_seconds(current_app.send_file_max_age_default)
|
||||||
|
|
||||||
def send_static_file(self, filename):
|
def send_static_file(self, filename):
|
||||||
"""Function used internally to send static files from the static
|
"""Function used internally to send static files from the static
|
||||||
|
@ -898,3 +899,14 @@ class _PackageBoundObject(object):
|
||||||
if mode not in ('r', 'rb'):
|
if mode not in ('r', 'rb'):
|
||||||
raise ValueError('Resources can only be opened for reading')
|
raise ValueError('Resources can only be opened for reading')
|
||||||
return open(os.path.join(self.root_path, resource), mode)
|
return open(os.path.join(self.root_path, resource), mode)
|
||||||
|
|
||||||
|
|
||||||
|
def total_seconds(td):
|
||||||
|
"""Returns the total seconds from a timedelta object.
|
||||||
|
|
||||||
|
:param timedelta td: the timedelta to be converted in seconds
|
||||||
|
|
||||||
|
:returns: number of seconds
|
||||||
|
:rtype: int
|
||||||
|
"""
|
||||||
|
return td.days * 60 * 60 * 24 + td.seconds
|
||||||
|
|
|
@ -17,14 +17,11 @@ from werkzeug.http import http_date, parse_date
|
||||||
from werkzeug.datastructures import CallbackDict
|
from werkzeug.datastructures import CallbackDict
|
||||||
from . import Markup, json
|
from . import Markup, json
|
||||||
from ._compat import iteritems, text_type
|
from ._compat import iteritems, text_type
|
||||||
|
from .helpers import total_seconds
|
||||||
|
|
||||||
from itsdangerous import URLSafeTimedSerializer, BadSignature
|
from itsdangerous import URLSafeTimedSerializer, BadSignature
|
||||||
|
|
||||||
|
|
||||||
def total_seconds(td):
|
|
||||||
return td.days * 60 * 60 * 24 + td.seconds
|
|
||||||
|
|
||||||
|
|
||||||
class SessionMixin(object):
|
class SessionMixin(object):
|
||||||
"""Expands a basic dictionary with an accessors that are expected
|
"""Expands a basic dictionary with an accessors that are expected
|
||||||
by Flask extensions and users for the session.
|
by Flask extensions and users for the session.
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
from datetime import timedelta
|
||||||
import flask
|
import flask
|
||||||
|
|
||||||
|
|
||||||
|
@ -168,6 +169,14 @@ def test_session_lifetime():
|
||||||
assert app.permanent_session_lifetime.seconds == 42
|
assert app.permanent_session_lifetime.seconds == 42
|
||||||
|
|
||||||
|
|
||||||
|
def test_send_file_max_age():
|
||||||
|
app = flask.Flask(__name__)
|
||||||
|
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 3600
|
||||||
|
assert app.send_file_max_age_default.seconds == 3600
|
||||||
|
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = timedelta(hours=2)
|
||||||
|
assert app.send_file_max_age_default.seconds == 7200
|
||||||
|
|
||||||
|
|
||||||
def test_get_namespace():
|
def test_get_namespace():
|
||||||
app = flask.Flask(__name__)
|
app = flask.Flask(__name__)
|
||||||
app.config['FOO_OPTION_1'] = 'foo option 1'
|
app.config['FOO_OPTION_1'] = 'foo option 1'
|
||||||
|
|
Loading…
Reference in New Issue