import flask from flask.ext import shelve app = flask.Flask(__name__) app.config['SHELVE_FILENAME'] = 'shelve.db' shelve.init_app(app) @app.route('/') def index(): db = shelve.get_shelve('c') db['foo'] = 'bar' return str(db['other_key']) if __name__ == '__main__': app.run()
Flask-Shelve automatically handles file locking for concurent access, and allows multiple concurrent readers, and a single exclusive writer.
Install with pip:
pip install Flask-Shelve
or download the latest version from github:
git clone git://github.com/jamesls/flask-shelve.git cd flask-shelve python setup.py develop
Flask-Shelve uses the following configuration values:
In general, you typically need to supply just the SHELVE_FILENAME option, the remaining config options have reasonable defaults.
To enable the Flask-Shelve extension, use the init_app function:
import flask from flask.ext.shelve import init_app app = flask.Flask(__name__) app.config['SHELVE_FILENAME'] = 'shelve.db' init_app(app)
In a view function, you can invoke the get_shelve() function, with a mode argument of ‘c’, ‘n’, ‘w’, or ‘r’. The returned value is a shelve.Shelf() instance, which exposes a dict like interface:
from flask.ext.shelve import get_shelve, init_app from myapp import app init_app(app) @app.route('/') def index(): db = get_shelve('c') db['foo'] = 'bar' return str(db['other_key']) if __name__ == '__main__': app.run()
The view function does not need to worry about aquiring/releasing read/write locks, nor does it need to worry about closing the shelve instance, Flask-Shelve takes care of this for you.
Flask-Shelve does not rely on any locking mechanism provided by the underlying dbm, instead it implements its own locking:
In practice, this means that any thread or process has a view function that has called shelve.get_db with a mode of ‘c’, ‘n’, or ‘w’ will block until all views that have the db currently opened return. Note that this is across all threads and processes for any given shelve file.
Performance is terrible, mostly due to the locking needed for concurrent access discussed above. This may change in the future, but there are much better options if you need something with higher performance (a separate server running a SQL/NoSQL db). The main reasons for using this extension are: