Permalink
Browse files

Documented instance root

  • Loading branch information...
1 parent 153ecbc commit 187cb80dcc1b087f1a7b7d4d67afbd531ad01cd2 @mitsuhiko mitsuhiko committed Aug 10, 2011
Showing with 78 additions and 3 deletions.
  1. +2 −1 CHANGES
  2. +61 −0 docs/config.rst
  3. +11 −0 flask/app.py
  4. +4 −2 flask/helpers.py
View
@@ -30,7 +30,8 @@ Relase date to be decided, codename to be chosen.
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.
+ the perfect place to put configuration files etc. For more information
+ see :ref:`instance-folders`.
Version 0.7.3
-------------
View
@@ -267,3 +267,64 @@ your configuration files. However here a list of good recommendations:
:ref:`fabric-deployment` pattern.
.. _fabric: http://fabfile.org/
+
+
+.. _instance-folders:
+
+Instance Folders
+----------------
+
+.. versionadded:: 0.8
+
+Flask 0.8 introduces instance folders. Flask for a long time made it
+possible to refer to paths relative to the application's folder directly
+(via :attr:`Flask.root_path`). This was also how many developers loaded
+configurations stored next to the application. Unfortunately however this
+only works well if applications are not packages in which case the root
+path refers to the contents of the package.
+
+With Flask 0.8 a new attribute was introduced:
+:attr:`Flask.instance_path`. It refers to a new concept called the
+“instance folder”. The instance folder is designed to not be under
+version control and be deployment specific. It's the perfect place to
+drop things that either change at runtime or configuration files.
+
+To make it easier to put this folder into an ignore list for your version
+control system it's called ``instance`` and placed directly next to your
+package or module by default. This path can be overridden by specifying
+the `instance_path` parameter to your application::
+
+ app = Flask(__name__, instance_path='/path/to/instance')
+
+Please keep in mind that this path *must* be absolute when provided.
+
+Since the config object provided loading of configuration files from
+relative filenames we made it possible to change the loading via filenames
+to be relative to the instance path if wanted. The behavior of relative
+paths in config files can be flipped between “relative to the application
+root” (the default) to “relative to instance folder” via the
+`instance_relative_config` switch to the application constructor::
+
+ app = Flask(__name__, instance_relative_config=True)
+
+Here is a full example of how to configure Flask to preload the config
+from a module and then override the config from a file in the config
+folder if it exists::
+
+ app = Flask(__name__, instance_relative_config=True)
+ app.config.from_object('yourapplication.default_settings')
+ app.config.from_pyfile('application.cfg', silent=True)
+
+The path to the instance folder can be found via the
+:attr:`Flask.instance_path`. Flask also provides a shortcut to open a
+file from the instnace folder with :meth:`Flask.open_instance_resource`.
+
+Example usage for both::
+
+ filename = os.path.join(app.instance_root, 'application.cfg')
+ with open(filename) as f:
+ config = f.read()
+
+ # or via open_instance_resource:
+ with app.open_instance_resource('application.cfg') as f:
+ config = f.read()
View
@@ -554,6 +554,17 @@ def auto_find_instance_path(self):
basedir = os.path.normpath(os.path.abspath(instance_path))
return os.path.join(basedir, 'instance')
+ def open_instance_resource(self, resource, mode='rb'):
+ """Opens a resource from the application's instance folder
+ (:attr:`instance_path`). Otherwise works like
+ :meth:`open_resource`. Instance resources can also be opened for
+ writing.
+
+ :param resource: the name of the resource. To access resources within
+ subfolders use forward slashes as separator.
+ """
+ return open(os.path.join(self.instance_path, resource), mode)
+
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
View
@@ -565,7 +565,7 @@ def send_static_file(self, filename):
raise RuntimeError('No static folder for this object')
return send_from_directory(self.static_folder, filename)
- def open_resource(self, resource):
+ def open_resource(self, resource, mode='rb'):
"""Opens a resource from the application's resource folder. To see
how this works, consider the following folder structure::
@@ -587,4 +587,6 @@ def open_resource(self, resource):
:param resource: the name of the resource. To access resources within
subfolders use forward slashes as separator.
"""
- return open(os.path.join(self.root_path, resource), 'rb')
+ if mode not in ('r', 'rb'):
+ raise ValueError('Resources can only be opened for reading')
+ return open(os.path.join(self.root_path, resource), mode)

0 comments on commit 187cb80

Please sign in to comment.