New --plugins-dir=plugins/ option (#212)

* New --plugins-dir=plugins/ option

New option causing Datasette to load and evaluate all of the Python files in
the specified directory and register any plugins that are defined in those
files.

This new option is available for the following commands:

    datasette serve mydb.db --plugins-dir=plugins/
    datasette publish now/heroku mydb.db --plugins-dir=plugins/
    datasette package mydb.db --plugins-dir=plugins/

* Unit tests for --plugins-dir=plugins/

Closes #211
This commit is contained in:
Simon Willison 2018-04-15 22:22:01 -07:00 committed by GitHub
commit b2955d9065
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 86 additions and 12 deletions

View file

@ -15,12 +15,16 @@ def app_client():
conn = sqlite3.connect(filepath)
conn.executescript(TABLES)
os.chdir(os.path.dirname(filepath))
plugins_dir = os.path.join(tmpdir, 'plugins')
os.mkdir(plugins_dir)
open(os.path.join(plugins_dir, 'my_plugin.py'), 'w').write(PLUGIN)
ds = Datasette(
[filepath],
page_size=50,
max_returned_rows=100,
sql_time_limit_ms=20,
metadata=METADATA,
plugins_dir=plugins_dir,
)
ds.sqlite_functions.append(
('sleep', 1, lambda n: time.sleep(float(n))),
@ -90,6 +94,20 @@ METADATA = {
}
}
PLUGIN = '''
from datasette import hookimpl
import pint
ureg = pint.UnitRegistry()
@hookimpl
def prepare_connection(conn):
def convert_units(amount, from_, to_):
"select convert_units(100, 'm', 'ft');"
return (amount * ureg(from_)).to(to_).to_tuple()[0]
conn.create_function('convert_units', 3, convert_units)
'''
TABLES = '''
CREATE TABLE simple_primary_key (

View file

@ -588,8 +588,10 @@ def test_row_foreign_key_tables(app_client):
def test_unit_filters(app_client):
response = app_client.get('/test_tables/units.json?distance__lt=75km&frequency__gt=1kHz',
gather_request=False)
response = app_client.get(
'/test_tables/units.json?distance__lt=75km&frequency__gt=1kHz',
gather_request=False
)
assert response.status == 200
data = response.json
@ -598,3 +600,11 @@ def test_unit_filters(app_client):
assert len(data['rows']) == 1
assert data['rows'][0][0] == 2
def test_plugins_dir_plugin(app_client):
response = app_client.get(
"/test_tables.json?sql=select+convert_units(100%2C+'m'%2C+'ft')",
gather_request=False
)
assert pytest.approx(328.0839) == response.json['rows'][0][0]

View file

@ -195,6 +195,7 @@ def test_temporary_docker_directory_uses_hard_link():
extra_options=None,
branch=None,
template_dir=None,
plugins_dir=None,
static=[],
) as temp_docker:
hello = os.path.join(temp_docker, 'hello')
@ -218,6 +219,7 @@ def test_temporary_docker_directory_uses_copy_if_hard_link_fails(mock_link):
extra_options=None,
branch=None,
template_dir=None,
plugins_dir=None,
static=[],
) as temp_docker:
hello = os.path.join(temp_docker, 'hello')