Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load plugins from a --plugins-dir=plugins/ directory #211

Closed
simonw opened this issue Apr 16, 2018 · 6 comments
Closed

Load plugins from a --plugins-dir=plugins/ directory #211

simonw opened this issue Apr 16, 2018 · 6 comments
Labels

Comments

@simonw
Copy link
Owner

simonw commented Apr 16, 2018

In #14 and 33c7c53 I've added working support for setuptools entry_points plugins. These can be installed from PyPI using pip install ....

I imagine some projects will benefit from being able to add plugins without first publishing them to PyPI. Datasette already supports loading custom templates like so:

datasette serve --template-dir=mytemplates/ mydb.db

I propose an additional option, --plugins-dir= which specifies a directory full of blah.py files which will be loaded into Datasette when the application server starts.

datasette serve --plugins-dir=myplugins/ mydb.db

This will also need to be supported by datasette publish as those Python files should be copied up as part of the deployment.

@simonw
Copy link
Owner Author

simonw commented Apr 16, 2018

The easiest way to implement this in Python 2 would be execfile(...) - but that was removed in Python 3. According to https://stackoverflow.com/a/437857/6083 2to3 replaces that with this, which ensures the filename is associated with the code for debugging purposes:

with open("somefile.py") as f:
    code = compile(f.read(), "somefile.py", 'exec')
    exec(code, global_vars, local_vars)

Implementing it this way would force this kind of plugin to be self-contained in a single file. I think that's OK: if you want a more complex plugin you can use the standard pluggy-powered setuptools mechanism to build it.

simonw added a commit that referenced this issue Apr 16, 2018
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=plugins/
    datasette publish now/heroku mydb.db --plugins=plugins/
    datasette package mydb.db --plugins=plugins/
@simonw
Copy link
Owner Author

simonw commented Apr 16, 2018

This needs unit tests. I also need to manually test the datasette package and datesette publish commands.

@simonw
Copy link
Owner Author

simonw commented Apr 16, 2018

Here's the result of running:

datasette publish now fivethirtyeight.db \
    --plugins-dir=plugins/ --title="FiveThirtyEight" --branch=plugins-dir

https://datasette-phjtvzwwzl.now.sh/fivethirtyeight-2628db9?sql=select+convert_units%28100%2C+%27m%27%2C+%27ft%27%29

Where plugins/pint_plugin.py contains the following:

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)

@simonw
Copy link
Owner Author

simonw commented Apr 16, 2018

This worked as well:

datasette package fivethirtyeight.db \
    --plugins-dir=plugins/ --title="FiveThirtyEight" --branch=plugins-dir

@simonw
Copy link
Owner Author

simonw commented Apr 16, 2018

Added unit tests in 33c6bca

@simonw
Copy link
Owner Author

simonw commented Apr 16, 2018

Here's the result of running this:

datasette publish heroku fivethirtyeight.db \
    --plugins-dir=plugins/ --title="FiveThirtyEight" --branch=plugins-dir

https://intense-river-24599.herokuapp.com/fivethirtyeight-2628db9?sql=select+convert_units%28100%2C+%27m%27%2C+%27ft%27%29

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant