2018-04-20 07:32:02 -07:00
.. _plugins:
2018-04-16 08:12:09 -07:00
Plugins
=======
2019-05-15 22:18:02 -07: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 08:12:09 -07:00
2021-01-09 14:17:18 -08: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 11:19:11 -08: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-04 20:10:40 -07: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 11:19:11 -08: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-11 17:43:51 -07: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 11:19:11 -08:00
2020-04-27 09:30:24 -07:00
.. _plugins_installing:
Installing plugins
------------------
2018-04-16 08:12:09 -07:00
2020-06-21 19:37:48 -07: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 08:12:09 -07:00
2020-08-11 15:31:47 -07: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 10:20:41 -07: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 15:31:47 -07:00
One-off plugins using --plugins-dir
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2020-06-21 19:37:48 -07: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 08:12:09 -07:00
2020-06-21 19:37:48 -07:00
datasette mydb.db --plugins-dir=plugins/
2018-04-18 08:05:06 -07:00
2020-08-11 15:31:47 -07:00
Deploying plugins using datasette publish
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2020-06-21 19:37:48 -07: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 08:12:09 -07:00
2020-06-21 19:37:48 -07:00
datasette publish cloudrun mydb.db --install=datasette-vega
2018-04-16 08:12:09 -07:00
2020-06-21 19:37:48 -07: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 08:12:09 -07:00
2020-06-21 19:37:48 -07:00
datasette publish cloudrun mydb.db \
--install=https://url-to-my-package.zip
2018-04-16 08:12:09 -07:00
2019-01-31 19:47:05 -08:00
.. _plugins_installed:
2019-01-26 12:01:16 -08: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-19 21:04:09 -08: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 12:01:16 -08:00
If you run `` datasette plugins --all `` it will include default plugins that ship as part of Datasette::
[
2022-01-19 21:04:09 -08:00
{
2022-01-19 21:14:04 -08:00
"name": "datasette.actor_auth_cookie",
2022-01-19 21:04:09 -08:00
"static": false,
"templates": false,
"version": null,
"hooks": [
2022-01-19 21:14:04 -08:00
"actor_from_request"
2022-01-19 21:04:09 -08:00
]
},
2019-01-26 12:01:16 -08:00
{
2022-01-19 21:14:04 -08:00
"name": "datasette.blob_renderer",
2019-01-26 12:01:16 -08:00
"static": false,
"templates": false,
2022-01-19 21:04:09 -08:00
"version": null,
"hooks": [
2022-01-19 21:14:04 -08:00
"register_output_renderer"
2022-01-19 21:04:09 -08:00
]
2019-01-26 12:01:16 -08:00
},
{
2022-01-19 21:14:04 -08:00
"name": "datasette.default_magic_parameters",
2022-01-19 21:04:09 -08:00
"static": false,
"templates": false,
"version": null,
"hooks": [
2022-01-19 21:14:04 -08:00
"register_magic_parameters"
2022-01-19 21:04:09 -08:00
]
},
{
2022-01-19 21:14:04 -08:00
"name": "datasette.default_menu_links",
2020-04-04 16:04:33 -07:00
"static": false,
"templates": false,
2022-01-19 21:04:09 -08:00
"version": null,
"hooks": [
2022-01-19 21:14:04 -08:00
"menu_links"
2022-01-19 21:04:09 -08:00
]
2020-04-04 16:04:33 -07:00
},
{
2022-01-19 21:14:04 -08:00
"name": "datasette.default_permissions",
2019-01-26 12:01:16 -08:00
"static": false,
"templates": false,
2022-01-19 21:04:09 -08:00
"version": null,
"hooks": [
2022-10-25 19:55:47 -07:00
"actor_from_request",
2022-10-25 21:26:12 -07:00
"permission_allowed",
2022-12-12 18:05:54 -08:00
"register_permissions",
2022-10-30 14:53:33 -07:00
"skip_csrf"
2022-01-19 21:04:09 -08:00
]
2019-01-26 12:01:16 -08:00
},
{
2022-01-19 21:14:04 -08:00
"name": "datasette.facets",
2022-01-19 21:04:09 -08:00
"static": false,
"templates": false,
"version": null,
"hooks": [
2022-01-19 21:14:04 -08:00
"register_facet_classes"
2022-01-19 21:04:09 -08:00
]
},
{
2022-01-19 21:14:04 -08:00
"name": "datasette.filters",
2019-01-26 12:01:16 -08:00
"static": false,
"templates": false,
2022-01-19 21:04:09 -08:00
"version": null,
"hooks": [
2022-01-19 21:14:04 -08:00
"filters_from_request"
2022-01-19 21:04:09 -08:00
]
},
2022-07-17 17:57:41 -07: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-19 21:04:09 -08:00
{
2022-01-19 21:14:04 -08:00
"name": "datasette.publish.cloudrun",
2022-01-19 21:04:09 -08:00
"static": false,
"templates": false,
"version": null,
"hooks": [
2022-01-19 21:14:04 -08:00
"publish_subcommand"
2022-01-19 21:04:09 -08:00
]
},
{
2022-01-19 21:14:04 -08:00
"name": "datasette.publish.heroku",
2022-01-19 21:04:09 -08:00
"static": false,
"templates": false,
"version": null,
"hooks": [
2022-01-19 21:14:04 -08:00
"publish_subcommand"
2022-01-19 21:04:09 -08:00
]
},
{
2022-01-19 21:14:04 -08:00
"name": "datasette.sql_functions",
2022-01-19 21:04:09 -08:00
"static": false,
"templates": false,
"version": null,
"hooks": [
2022-01-19 21:14:04 -08:00
"prepare_connection"
2022-01-19 21:04:09 -08:00
]
2019-01-26 12:01:16 -08:00
}
]
2022-01-19 21:04:09 -08:00
.. [[[end]]]
2019-01-26 12:01:16 -08:00
You can add the `` --plugins-dir= `` option to include any plugins found in that directory.
2018-09-19 19:48:12 +02:00
.. _plugins_configuration:
2018-08-28 01:35:21 -07: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 08:43:13 -08:00
Here is an example of some plugin configuration for a specific table:
.. code-block :: json
2018-08-28 01:35:21 -07:00
{
2020-11-15 08:45:26 -08:00
"databases": {
2018-08-28 01:35:21 -07: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-07 19:06:31 -07:00
.. _plugins_configuration_secret:
2019-07-03 22:36:44 -07: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 08:43:13 -08: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-03 22:36:44 -07:00
{
"plugins": {
"datasette-auth-github": {
"client_secret": {
"$env": "GITHUB_CLIENT_SECRET"
}
}
}
}
2020-11-15 08:43:13 -08: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-03 22:36:44 -07:00
{
"plugins": {
"datasette-auth-github": {
"client_secret": {
"$file": "/secrets/client-secret"
}
}
}
}
2019-07-07 19:06:31 -07: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 08:43:13 -08: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"
}
}
}
}