Compare commits

...

3 commits

Author SHA1 Message Date
Simon Willison
d75e57060d
Removed plugin_demo.py 2018-04-15 17:49:58 -07:00
Simon Willison
db02933f1e
Import version datasette.version to avoid dependency error
Running `from datasette import __version__` in `setup.py` was throwing
an error `ModuleNotFoundError: No module named 'pluggy'`

See https://packaging.python.org/guides/single-sourcing-package-version/

Refs #14
2018-04-15 17:47:05 -07:00
Simon Willison
f2720b0c6b
First working prototype of plugins, refs #14
Uses pluggy: https://pluggy.readthedocs.io/

Two example plugins - an uppercase template filter and a convert_units() SQL function.
2018-04-15 16:17:36 -07:00
4 changed files with 29 additions and 2 deletions

View file

@ -1 +1,3 @@
from datasette.version import __version_info__, __version__ # noqa
from .hookspecs import hookimpl # noqa
from .hookspecs import hookspec # noqa

View file

@ -17,6 +17,7 @@ import jinja2
import hashlib
import time
import pint
import pluggy
import traceback
from .utils import (
Filters,
@ -38,6 +39,7 @@ from .utils import (
urlsafe_components,
validate_sql_select,
)
from . import hookspecs
from .version import __version__
app_root = Path(__file__).parent.parent
@ -49,6 +51,11 @@ connections = threading.local()
ureg = pint.UnitRegistry()
pm = pluggy.PluginManager('datasette')
pm.add_hookspecs(hookspecs)
pm.load_setuptools_entrypoints('datasette')
class DatasetteError(Exception):
def __init__(self, message, title=None, error_dict=None, status=500, template=None):
self.message = message
@ -1100,6 +1107,7 @@ class Datasette:
conn.enable_load_extension(True)
for extension in self.sqlite_extensions:
conn.execute("SELECT load_extension('{}')".format(extension))
pm.hook.prepare_connection(conn=conn)
def inspect(self):
if not self._inspect:
@ -1226,6 +1234,7 @@ class Datasette:
self.jinja_env.filters['quote_plus'] = lambda u: urllib.parse.quote_plus(u)
self.jinja_env.filters['escape_sqlite'] = escape_sqlite
self.jinja_env.filters['to_css_class'] = to_css_class
pm.hook.prepare_jinja2_environment(env=self.jinja_env)
app.add_route(IndexView.as_view(self), '/<as_json:(\.jsono?)?$>')
# TODO: /favicon.ico and /-/static/ deserve far-future cache expires
app.add_route(favicon, '/favicon.ico')

15
datasette/hookspecs.py Normal file
View file

@ -0,0 +1,15 @@
from pluggy import HookimplMarker
from pluggy import HookspecMarker
hookspec = HookspecMarker('datasette')
hookimpl = HookimplMarker('datasette')
@hookspec
def prepare_connection(conn):
"Modify SQLite connection in some way e.g. register custom SQL functions"
@hookspec
def prepare_jinja2_environment(env):
"Modify Jinja2 template environment e.g. register custom template tags"

View file

@ -1,5 +1,5 @@
from setuptools import setup, find_packages
from datasette import __version__
from datasette.version import __version__
import os
@ -28,7 +28,8 @@ setup(
'Sanic==0.7.0',
'Jinja2==2.10',
'hupper==1.0',
'pint==0.8.1'
'pint==0.8.1',
'pluggy>=0.1.0,<1.0',
],
entry_points='''
[console_scripts]