flatisfy/flatisfy/web/dbplugin.py

78 lines
2.5 KiB
Python

# coding: utf-8
"""
This module contains a Bottle plugin to pass the database argument to any route
which needs it.
This module is heavily based on code from
[Bottle-SQLAlchemy](https://github.com/iurisilvio/bottle-sqlalchemy) which is
licensed under MIT license.
"""
from __future__ import absolute_import, division, print_function, unicode_literals
import inspect
import bottle
class DatabasePlugin(object):
"""
A Bottle plugin to automatically pass an SQLAlchemy database session object
to the routes specifying they need it.
"""
name = "database"
api = 2
KEYWORD = "db"
def __init__(self, get_session):
"""
:param create_session: SQLAlchemy session maker created with the
'sessionmaker' function. Will create its own if undefined.
"""
self.get_session = get_session
def setup(self, app): # pylint: disable=locally-disabled,no-self-use
"""
Make sure that other installed plugins don't affect the same
keyword argument and check if metadata is available.
"""
for other in app.plugins:
if not isinstance(other, DatabasePlugin):
continue
else:
raise bottle.PluginError("Found another conflicting Database plugin.")
def apply(self, callback, route):
"""
Method called on route invocation. Should apply some transformations to
the route prior to returing it.
We check the presence of ``self.KEYWORD`` in the route signature and
replace the route callback by a partial invocation where we replaced
this argument by a valid SQLAlchemy session.
"""
# Check whether the route needs a valid db session or not.
try:
callback_args = inspect.signature(route.callback).parameters
except AttributeError:
# inspect.signature does not exist on older Python
callback_args = inspect.getargspec(route.callback).args
if self.KEYWORD not in callback_args:
# If no need for a db session, call the route callback
return callback
def wrapper(*args, **kwargs):
"""
Wrap the callback in a call to get_session.
"""
with self.get_session() as session:
# Get a db session and pass it to the callback
kwargs[self.KEYWORD] = session
return callback(*args, **kwargs)
return wrapper
Plugin = DatabasePlugin