mirror of https://github.com/pallets/flask.git
Implemented instance paths
This commit is contained in:
parent
63876614b6
commit
153ecbc920
5
CHANGES
5
CHANGES
|
@ -26,6 +26,11 @@ Relase date to be decided, codename to be chosen.
|
|||
- Malformed JSON data will now trigger a bad request HTTP exception instead
|
||||
of a value error which usually would result in a 500 internal server
|
||||
error if not handled. This is a backwards incompatible change.
|
||||
- Applications now not only have a root path where the resources and modules
|
||||
are located but also an instane path which is the designated place to
|
||||
drop files that are modified at runtime (uploads etc.). Also this is
|
||||
conceptionally only instance depending and outside version control so it's
|
||||
the perfect place to put configuration files etc.
|
||||
|
||||
Version 0.7.3
|
||||
-------------
|
||||
|
|
79
flask/app.py
79
flask/app.py
|
@ -11,6 +11,7 @@
|
|||
|
||||
from __future__ import with_statement
|
||||
|
||||
import os
|
||||
import sys
|
||||
from threading import Lock
|
||||
from datetime import timedelta
|
||||
|
@ -103,14 +104,33 @@ class Flask(_PackageBoundObject):
|
|||
pick up SQL queries in `yourapplication.app` and not
|
||||
`yourapplication.views.frontend`)
|
||||
|
||||
.. versionadded:: 0.5
|
||||
The `static_path` parameter was added.
|
||||
.. versionadded:: 0.7
|
||||
The `static_url_path`, `static_folder`, and `template_folder`
|
||||
parameters were added.
|
||||
|
||||
.. versionadded:: 0.8
|
||||
The `instance_path` and `instance_relative_config` parameters were
|
||||
added.
|
||||
|
||||
:param import_name: the name of the application package
|
||||
:param static_path: can be used to specify a different path for the
|
||||
static files on the web. Defaults to ``/static``.
|
||||
This does not affect the folder the files are served
|
||||
*from*.
|
||||
:param static_url_path: can be used to specify a different path for the
|
||||
static files on the web. Defaults to the name
|
||||
of the `static_folder` folder.
|
||||
:param static_folder: the folder with static files that should be served
|
||||
at `static_url_path`. Defaults to the ``'static'``
|
||||
folder in the root path of the application.
|
||||
:param template_folder: the folder that contains the templates that should
|
||||
be used by the application. Defaults to
|
||||
``'templates'`` folder in the root path of the
|
||||
application.
|
||||
:param instance_path: An alternative instance path for the application.
|
||||
By default the folder ``'instance'`` next to the
|
||||
package or module is assumed to be the instance
|
||||
path.
|
||||
:param instance_relative_config: if set to `True` relative filenames
|
||||
for loading the config are assumed to
|
||||
be relative to the instance path instead
|
||||
of the application root.
|
||||
"""
|
||||
|
||||
#: The class that is used for request objects. See :class:`~flask.Request`
|
||||
|
@ -238,7 +258,8 @@ class Flask(_PackageBoundObject):
|
|||
session_interface = SecureCookieSessionInterface()
|
||||
|
||||
def __init__(self, import_name, static_path=None, static_url_path=None,
|
||||
static_folder='static', template_folder='templates'):
|
||||
static_folder='static', template_folder='templates',
|
||||
instance_path=None, instance_relative_config=False):
|
||||
_PackageBoundObject.__init__(self, import_name,
|
||||
template_folder=template_folder)
|
||||
if static_path is not None:
|
||||
|
@ -251,11 +272,21 @@ class Flask(_PackageBoundObject):
|
|||
self.static_url_path = static_url_path
|
||||
if static_folder is not None:
|
||||
self.static_folder = static_folder
|
||||
if instance_path is None:
|
||||
instance_path = self.auto_find_instance_path()
|
||||
elif not os.path.isabs(instance_path):
|
||||
raise ValueError('If an instance path is provided it must be '
|
||||
'absolute. A relative path was given instead.')
|
||||
|
||||
#: Holds the path to the instance folder.
|
||||
#:
|
||||
#: .. versionadded:: 0.8
|
||||
self.instance_path = instance_path
|
||||
|
||||
#: The configuration dictionary as :class:`Config`. This behaves
|
||||
#: exactly like a regular dictionary but supports additional methods
|
||||
#: to load a config from files.
|
||||
self.config = Config(self.root_path, self.default_config)
|
||||
self.config = self.make_config(instance_relative_config)
|
||||
|
||||
# Prepare the deferred setup of the logger.
|
||||
self._logger = None
|
||||
|
@ -491,6 +522,38 @@ class Flask(_PackageBoundObject):
|
|||
"""
|
||||
return self._got_first_request
|
||||
|
||||
def make_config(self, instance_relative=False):
|
||||
"""Used to create the config attribute by the Flask constructor.
|
||||
The `instance_relative` parameter is passed in from the constructor
|
||||
of Flask (there named `instance_relative_config`) and indicates if
|
||||
the config should be relative to the instance path or the root path
|
||||
of the application.
|
||||
|
||||
.. versionadded:: 0.8
|
||||
"""
|
||||
root_path = self.root_path
|
||||
if instance_relative:
|
||||
root_path = self.instance_path
|
||||
return Config(root_path, self.default_config)
|
||||
|
||||
def auto_find_instance_path(self):
|
||||
"""Tries to locate the instance path if it was not provided to the
|
||||
constructor of the application class. It will basically calculate
|
||||
the path to a folder named ``instance`` next to your main file or
|
||||
the package.
|
||||
|
||||
.. versionadded:: 0.8
|
||||
"""
|
||||
root_mod = sys.modules[self.import_name.split('.')[0]]
|
||||
instance_path = None
|
||||
if hasattr(root_mod, '__path__'):
|
||||
package_dir = os.path.dirname(root_mod.__file__)
|
||||
instance_path = os.path.join(package_dir, os.path.pardir)
|
||||
else:
|
||||
instance_path = os.path.dirname(root_mod.__file__)
|
||||
basedir = os.path.normpath(os.path.abspath(instance_path))
|
||||
return os.path.join(basedir, 'instance')
|
||||
|
||||
def create_jinja_environment(self):
|
||||
"""Creates the Jinja2 environment based on :attr:`jinja_options`
|
||||
and :meth:`select_jinja_autoescape`. Since 0.7 this also adds
|
||||
|
|
|
@ -1005,6 +1005,24 @@ class BasicFunctionalityTestCase(unittest.TestCase):
|
|||
rv = c.post('/foo', data={}, follow_redirects=True)
|
||||
self.assertEqual(rv.data, 'success')
|
||||
|
||||
def test_basic_instance_paths(self):
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
app = flask.Flask(__name__)
|
||||
self.assertEqual(app.instance_path, os.path.join(here, 'instance'))
|
||||
|
||||
app = flask.Flask(__name__, instance_path=here)
|
||||
self.assertEqual(app.instance_path, here)
|
||||
|
||||
try:
|
||||
flask.Flask(__name__, instance_path='instance')
|
||||
except ValueError, e:
|
||||
self.assert_('must be absolute' in str(e))
|
||||
else:
|
||||
self.fail('Expected value error')
|
||||
|
||||
from blueprintapp import app
|
||||
self.assertEqual(app.instance_path, os.path.join(here, 'instance'))
|
||||
|
||||
|
||||
class JSONTestCase(unittest.TestCase):
|
||||
|
||||
|
|
Loading…
Reference in New Issue