Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial documentation for plugins, closes #213
- Loading branch information
Showing
4 changed files
with
161 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ Contents | |
sql_queries | ||
metadata | ||
custom_templates | ||
plugins | ||
changelog | ||
|
||
.. _Zeit Now: https://zeit.co/now | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
Plugins | ||
======= | ||
|
||
Datasette's plugin system is currently under active development. It allows | ||
additional features to be implemented as Python code (or, soon, JavaScript) | ||
which can be wrapped up in a separate Python package. | ||
|
||
You can follow the development of plugins in `issue #14 <https://github.com/simonw/datasette/issues/14>`_. | ||
|
||
Using plugins | ||
------------- | ||
|
||
If a plugin has been packaged for distribution using setuptools you can use | ||
the plugin by installing it alongside Datasette in the same virtual | ||
environment or Docker container. | ||
|
||
You can also define one-off per-project plugins by saving them as | ||
``plugin_name.py`` functions in a ``plugins/`` folder and then passing that | ||
folder to ``datasette serve``. | ||
|
||
Writing plugins | ||
--------------- | ||
|
||
The easiest way to write a plugin is to create a ``my_plugin.py`` file and | ||
drop it into your ``plugins/`` directory. Here is an example plugin, which | ||
adds a new custom SQL function called ``hello_world()`` which takes no | ||
arguments and returns the string ``Hello world!``. | ||
|
||
.. code-block:: python | ||
from datasette import hookimpl | ||
@hookimpl | ||
def prepare_connection(conn): | ||
conn.create_function('hello_world', 0, lambda: 'Hello world!') | ||
If you save this in ``plugins/my_plugin.py`` you can then start Datasette like | ||
this:: | ||
|
||
datasette serve mydb.db --plugins-dir=plugins/ | ||
|
||
Now you can navigate to http://localhost:8001/mydb and run this SQL:: | ||
|
||
select hello_world(); | ||
|
||
To see the output of your plugin. | ||
|
||
Packaging a plugin | ||
------------------ | ||
|
||
Plugins can be packaged using Python setuptools. You can see an example of a | ||
packaged plugin at https://github.com/simonw/datasette-plugin-demos | ||
|
||
The example consists of two files: a ``setup.py`` file that defines the plugin: | ||
|
||
.. code-block:: python | ||
from setuptools import setup | ||
VERSION = '0.1' | ||
setup( | ||
name='datasette-plugin-demos', | ||
description='Examples of plugins for Datasette', | ||
author='Simon Willison', | ||
url='https://github.com/simonw/datasette-plugin-demos', | ||
license='Apache License, Version 2.0', | ||
version=VERSION, | ||
py_modules=['datasette_plugin_demos'], | ||
entry_points={ | ||
'datasette': [ | ||
'plugin_demos = datasette_plugin_demos' | ||
] | ||
}, | ||
install_requires=['datasette'] | ||
) | ||
And a Python module file, ``datasette_plugin_demos.py``, that implements the | ||
plugin: | ||
|
||
.. code-block:: python | ||
from datasette import hookimpl | ||
import random | ||
@hookimpl | ||
def prepare_jinja2_environment(env): | ||
env.filters['uppercase'] = lambda u: u.upper() | ||
@hookimpl | ||
def prepare_connection(conn): | ||
conn.create_function('random_integer', 2, random.randint) | ||
Having built a plugin in this way you can turn it into an installable package | ||
using the following command:: | ||
|
||
python3 setup.py sdist | ||
|
||
This will create a ``.tar.gz`` file in the ``dist/`` directory. | ||
|
||
You can then install your new plugin into a Datasette virtual environment or | ||
Docker container using ``pip``:: | ||
|
||
pip install datasette-plugin-demos-0.1.tar.gz | ||
|
||
To learn how to upload your plugin to `PyPI <https://pypi.org/>`_ for use by | ||
other people, read the PyPA guide to `Packaging and distributing projects | ||
<https://packaging.python.org/tutorials/distributing-packages/>`_. | ||
|
||
|
||
Plugin hooks | ||
------------ | ||
|
||
Datasette will eventually have many more plugin hooks. You can track and | ||
contribute to their development in `issue #14 | ||
<https://github.com/simonw/datasette/issues/14>`_. | ||
|
||
prepare_connection(conn) | ||
~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
This hook is called when a new SQLite database connection is created. You can | ||
use it to `register custom SQL functions <https://docs.python.org/2/library/sqlite3.html#sqlite3.Connection.create_function>`_, | ||
aggregates and collations. For example: | ||
|
||
.. code-block:: python | ||
from datasette import hookimpl | ||
import random | ||
@hookimpl | ||
def prepare_connection(conn): | ||
conn.create_function('random_integer', 2, random.randint) | ||
This registers a SQL function called ``random_integer`` which takes two | ||
arguments and can be called like this:: | ||
|
||
select random_integer(1, 10); | ||
|
||
prepare_jinja2_environment(env) | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
This hook is called with the Jinja2 environment that is used to evaluate | ||
Datasette HTML templates. You can use it to do things like `register custom | ||
template filters <http://jinja.pocoo.org/docs/2.10/api/#custom-filters>`_, for | ||
example: | ||
|
||
.. code-block:: python | ||
from datasette import hookimpl | ||
@hookimpl | ||
def prepare_jinja2_environment(env): | ||
env.filters['uppercase'] = lambda u: u.upper() |