2018-04-20 14:32:02 +00:00
.. _plugins:
2018-04-16 15:12:09 +00:00
Plugins
=======
2019-05-16 05:18:02 +00:00
Datasette's plugin system allows additional features to be implemented as Python
code (or front-end JavaScript) which can be wrapped up in a separate Python
package. The underlying mechanism uses `pluggy <https://pluggy.readthedocs.io/> `_ .
2018-04-16 15:12:09 +00:00
2021-01-09 22:17:18 +00:00
See the `Datasette plugins directory <https://datasette.io/plugins> `__ for a list of existing plugins, or take a look at the
2019-11-27 19:19:11 +00:00
`datasette-plugin <https://github.com/topics/datasette-plugin> `__ topic on GitHub.
Things you can do with plugins include:
* Add visualizations to Datasette, for example
`datasette-cluster-map <https://github.com/simonw/datasette-cluster-map> `__ and
`datasette-vega <https://github.com/simonw/datasette-vega> `__ .
* Make new custom SQL functions available for use within Datasette, for example
`datasette-haversine <https://github.com/simonw/datasette-haversine> `__ and
`datasette-jellyfish <https://github.com/simonw/datasette-jellyfish> `__ .
2020-06-05 03:10:40 +00:00
* Define custom output formats with custom extensions, for example `datasette-atom <https://github.com/simonw/datasette-atom> `__ and
`datasette-ics <https://github.com/simonw/datasette-ics> `__ .
2019-11-27 19:19:11 +00:00
* Add template functions that can be called within your Jinja custom templates,
for example `datasette-render-markdown <https://github.com/simonw/datasette-render-markdown#markdown-in-templates> `__ .
* Customize how database values are rendered in the Datasette interface, for example
`datasette-render-binary <https://github.com/simonw/datasette-render-binary> `__ and
`datasette-pretty-json <https://github.com/simonw/datasette-pretty-json> `__ .
2020-06-12 00:43:51 +00:00
* Customize how Datasette's authentication and permissions systems work, for example `datasette-auth-tokens <https://github.com/simonw/datasette-auth-tokens> `__ and
`datasette-permissions-sql <https://github.com/simonw/datasette-permissions-sql> `__ .
2019-11-27 19:19:11 +00:00
2020-04-27 16:30:24 +00:00
.. _plugins_installing:
Installing plugins
------------------
2018-04-16 15:12:09 +00:00
2020-06-22 02:37:48 +00:00
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.
2018-04-16 15:12:09 +00:00
2020-08-11 22:31:47 +00:00
You can install plugins using the `` datasette install `` command::
datasette install datasette-vega
You can uninstall plugins with `` datasette uninstall `` ::
datasette uninstall datasette-vega
2020-08-19 17:20:41 +00:00
You can upgrade plugins with `` datasette install --upgrade `` or `` datasette install -U `` ::
datasette install -U datasette-vega
This command can also be used to upgrade Datasette itself to the latest released version::
datasette install -U datasette
These commands are thin wrappers around `` pip install `` and `` pip uninstall `` , which ensure they run `` pip `` in the same virtual environment as Datasette itself.
2020-08-11 22:31:47 +00:00
One-off plugins using --plugins-dir
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2020-06-22 02:37:48 +00:00
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 `` using the `` --plugins-dir `` option::
2018-04-16 15:12:09 +00:00
2020-06-22 02:37:48 +00:00
datasette mydb.db --plugins-dir=plugins/
2018-04-18 15:05:06 +00:00
2020-08-11 22:31:47 +00:00
Deploying plugins using datasette publish
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2020-06-22 02:37:48 +00:00
The `` datasette publish `` and `` datasette package `` commands both take an optional `` --install `` argument. You can use this one or more times to tell Datasette to `` pip install `` specific plugins as part of the process::
2018-04-16 15:12:09 +00:00
2020-06-22 02:37:48 +00:00
datasette publish cloudrun mydb.db --install=datasette-vega
2018-04-16 15:12:09 +00:00
2020-06-22 02:37:48 +00:00
You can use the name of a package on PyPI or any of the other valid arguments to `` pip install `` such as a URL to a `` .zip `` file::
2018-04-16 15:12:09 +00:00
2020-06-22 02:37:48 +00:00
datasette publish cloudrun mydb.db \
--install=https://url-to-my-package.zip
2018-04-16 15:12:09 +00:00
2019-02-01 03:47:05 +00:00
.. _plugins_installed:
2019-01-26 20:01:16 +00:00
Seeing what plugins are installed
---------------------------------
You can see a list of installed plugins by navigating to the `` /-/plugins `` page of your Datasette instance - for example: https://fivethirtyeight.datasettes.com/-/plugins
You can also use the `` datasette plugins `` command::
$ datasette plugins
[
{
"name": "datasette_json_html",
"static": false,
"templates": false,
"version": "0.4.0"
}
]
2022-01-20 05:04:09 +00:00
.. [[[cog
from datasette import cli
from click.testing import CliRunner
import textwrap, json
cog.out("\n")
result = CliRunner().invoke(cli.cli, ["plugins", "--all"])
# cog.out() with text containing newlines was unindenting for some reason
cog.outl("If you run `` datasette plugins --all `` it will include default plugins that ship as part of Datasette::\n")
plugins = [p for p in json.loads(result.output) if p["name"].startswith("datasette.")]
indented = textwrap.indent(json.dumps(plugins, indent=4), " ")
for line in indented.split("\n"):
cog.outl(line)
cog.out("\n\n")
.. ]]]
2019-01-26 20:01:16 +00:00
If you run `` datasette plugins --all `` it will include default plugins that ship as part of Datasette::
[
2022-01-20 05:04:09 +00:00
{
2022-01-20 05:14:04 +00:00
"name": "datasette.actor_auth_cookie",
2022-01-20 05:04:09 +00:00
"static": false,
"templates": false,
"version": null,
"hooks": [
2022-01-20 05:14:04 +00:00
"actor_from_request"
2022-01-20 05:04:09 +00:00
]
},
2019-01-26 20:01:16 +00:00
{
2022-01-20 05:14:04 +00:00
"name": "datasette.blob_renderer",
2019-01-26 20:01:16 +00:00
"static": false,
"templates": false,
2022-01-20 05:04:09 +00:00
"version": null,
"hooks": [
2022-01-20 05:14:04 +00:00
"register_output_renderer"
2022-01-20 05:04:09 +00:00
]
2019-01-26 20:01:16 +00:00
},
{
2022-01-20 05:14:04 +00:00
"name": "datasette.default_magic_parameters",
2022-01-20 05:04:09 +00:00
"static": false,
"templates": false,
"version": null,
"hooks": [
2022-01-20 05:14:04 +00:00
"register_magic_parameters"
2022-01-20 05:04:09 +00:00
]
},
{
2022-01-20 05:14:04 +00:00
"name": "datasette.default_menu_links",
2020-04-04 23:04:33 +00:00
"static": false,
"templates": false,
2022-01-20 05:04:09 +00:00
"version": null,
"hooks": [
2022-01-20 05:14:04 +00:00
"menu_links"
2022-01-20 05:04:09 +00:00
]
2020-04-04 23:04:33 +00:00
},
{
2022-01-20 05:14:04 +00:00
"name": "datasette.default_permissions",
2019-01-26 20:01:16 +00:00
"static": false,
"templates": false,
2022-01-20 05:04:09 +00:00
"version": null,
"hooks": [
2022-10-26 02:55:47 +00:00
"actor_from_request",
2022-10-26 04:26:12 +00:00
"permission_allowed",
2022-10-30 21:53:33 +00:00
"register_commands",
2022-12-13 02:05:54 +00:00
"register_permissions",
2022-10-30 21:53:33 +00:00
"skip_csrf"
2022-01-20 05:04:09 +00:00
]
2019-01-26 20:01:16 +00:00
},
{
2022-01-20 05:14:04 +00:00
"name": "datasette.facets",
2022-01-20 05:04:09 +00:00
"static": false,
"templates": false,
"version": null,
"hooks": [
2022-01-20 05:14:04 +00:00
"register_facet_classes"
2022-01-20 05:04:09 +00:00
]
},
{
2022-01-20 05:14:04 +00:00
"name": "datasette.filters",
2019-01-26 20:01:16 +00:00
"static": false,
"templates": false,
2022-01-20 05:04:09 +00:00
"version": null,
"hooks": [
2022-01-20 05:14:04 +00:00
"filters_from_request"
2022-01-20 05:04:09 +00:00
]
},
2022-07-18 00:57:41 +00:00
{
"name": "datasette.forbidden",
"static": false,
"templates": false,
"version": null,
"hooks": [
"forbidden"
]
},
{
"name": "datasette.handle_exception",
"static": false,
"templates": false,
"version": null,
"hooks": [
"handle_exception"
]
},
2022-01-20 05:04:09 +00:00
{
2022-01-20 05:14:04 +00:00
"name": "datasette.publish.cloudrun",
2022-01-20 05:04:09 +00:00
"static": false,
"templates": false,
"version": null,
"hooks": [
2022-01-20 05:14:04 +00:00
"publish_subcommand"
2022-01-20 05:04:09 +00:00
]
},
{
2022-01-20 05:14:04 +00:00
"name": "datasette.publish.heroku",
2022-01-20 05:04:09 +00:00
"static": false,
"templates": false,
"version": null,
"hooks": [
2022-01-20 05:14:04 +00:00
"publish_subcommand"
2022-01-20 05:04:09 +00:00
]
},
{
2022-01-20 05:14:04 +00:00
"name": "datasette.sql_functions",
2022-01-20 05:04:09 +00:00
"static": false,
"templates": false,
"version": null,
"hooks": [
2022-01-20 05:14:04 +00:00
"prepare_connection"
2022-01-20 05:04:09 +00:00
]
2019-01-26 20:01:16 +00:00
}
]
2022-01-20 05:04:09 +00:00
.. [[[end]]]
2019-01-26 20:01:16 +00:00
You can add the `` --plugins-dir= `` option to include any plugins found in that directory.
2018-09-19 17:48:12 +00:00
.. _plugins_configuration:
2018-08-28 08:35:21 +00:00
Plugin configuration
--------------------
Plugins can have their own configuration, embedded in a :ref: `metadata` file. Configuration options for plugins live within a `` "plugins" `` key in that file, which can be included at the root, database or table level.
2020-11-15 16:43:13 +00:00
Here is an example of some plugin configuration for a specific table:
.. code-block :: json
2018-08-28 08:35:21 +00:00
{
2020-11-15 16:45:26 +00:00
"databases": {
2018-08-28 08:35:21 +00:00
"sf-trees": {
"tables": {
"Street_Tree_List": {
"plugins": {
"datasette-cluster-map": {
"latitude_column": "lat",
"longitude_column": "lng"
}
}
}
}
}
}
}
This tells the `` datasette-cluster-map `` column which latitude and longitude columns should be used for a table called `` Street_Tree_List `` inside a database file called `` sf-trees.db `` .
2019-07-08 02:06:31 +00:00
.. _plugins_configuration_secret:
2019-07-04 05:36:44 +00:00
Secret configuration values
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Any values embedded in `` metadata.json `` will be visible to anyone who views the `` /-/metadata `` page of your Datasette instance. Some plugins may need configuration that should stay secret - API keys for example. There are two ways in which you can store secret configuration values.
2020-11-15 16:43:13 +00:00
**As environment variables** . If your secret lives in an environment variable that is available to the Datasette process, you can indicate that the configuration value should be read from that environment variable like so:
.. code-block :: json
2019-07-04 05:36:44 +00:00
{
"plugins": {
"datasette-auth-github": {
"client_secret": {
"$env": "GITHUB_CLIENT_SECRET"
}
}
}
}
2020-11-15 16:43:13 +00:00
**As values in separate files** . Your secrets can also live in files on disk. To specify a secret should be read from a file, provide the full file path like this:
.. code-block :: json
2019-07-04 05:36:44 +00:00
{
"plugins": {
"datasette-auth-github": {
"client_secret": {
"$file": "/secrets/client-secret"
}
}
}
}
2019-07-08 02:06:31 +00:00
If you are publishing your data using the :ref: `datasette publish <cli_publish>` family of commands, you can use the `` --plugin-secret `` option to set these secrets at publish time. For example, using Heroku you might run the following command::
$ datasette publish heroku my_database.db \
--name my-heroku-app-demo \
--install=datasette-auth-github \
--plugin-secret datasette-auth-github client_id your_client_id \
--plugin-secret datasette-auth-github client_secret your_client_secret
2020-11-15 16:43:13 +00:00
This will set the necessary environment variables and add the following to the deployed `` metadata.json `` :
.. code-block :: json
{
"plugins": {
"datasette-auth-github": {
"client_id": {
"$env": "DATASETTE_AUTH_GITHUB_CLIENT_ID"
},
"client_secret": {
"$env": "DATASETTE_AUTH_GITHUB_CLIENT_SECRET"
}
}
}
}