DATASETTE_LOAD_PLUGINS environment variable for loading specific plugins

Closes #2164

* Load only specified plugins for DATASETTE_LOAD_PLUGINS=datasette-one,datasette-two
* Load no plugins if DATASETTE_LOAD_PLUGINS=''
* Automated tests in a Bash script for DATASETTE_LOAD_PLUGINS
pull/2173/head
Simon Willison 2023-08-30 15:12:24 -07:00 zatwierdzone przez GitHub
rodzic 30b28c8367
commit 6bfe104d47
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
4 zmienionych plików z 109 dodań i 1 usunięć

Wyświetl plik

@ -50,3 +50,7 @@ jobs:
run: |
# This fails on syntax errors, or a diff was applied
blacken-docs -l 60 docs/*.rst
- name: Test DATASETTE_LOAD_PLUGINS
run: |
pip install datasette-init datasette-json-html
tests/test-datasette-load-plugins.sh

Wyświetl plik

@ -1,4 +1,5 @@
import importlib
import os
import pluggy
import pkg_resources
import sys
@ -22,10 +23,30 @@ DEFAULT_PLUGINS = (
pm = pluggy.PluginManager("datasette")
pm.add_hookspecs(hookspecs)
if not hasattr(sys, "_called_from_test"):
DATASETTE_LOAD_PLUGINS = os.environ.get("DATASETTE_LOAD_PLUGINS", None)
if not hasattr(sys, "_called_from_test") and DATASETTE_LOAD_PLUGINS is None:
# Only load plugins if not running tests
pm.load_setuptools_entrypoints("datasette")
# Load any plugins specified in DATASETTE_LOAD_PLUGINS")
if DATASETTE_LOAD_PLUGINS is not None:
for package_name in [
name for name in DATASETTE_LOAD_PLUGINS.split(",") if name.strip()
]:
try:
distribution = pkg_resources.get_distribution(package_name)
entry_map = distribution.get_entry_map()
if "datasette" in entry_map:
for plugin_name, entry_point in entry_map["datasette"].items():
mod = entry_point.load()
pm.register(mod, name=entry_point.name)
# Ensure name can be found in plugin_to_distinfo later:
pm._plugin_distinfo.append((mod, distribution))
except pkg_resources.DistributionNotFound:
sys.stderr.write("Plugin {} could not be found\n".format(package_name))
# Load default plugins
for plugin in DEFAULT_PLUGINS:
mod = importlib.import_module(plugin)

Wyświetl plik

@ -81,6 +81,60 @@ You can use the name of a package on PyPI or any of the other valid arguments to
datasette publish cloudrun mydb.db \
--install=https://url-to-my-package.zip
.. _plugins_datasette_load_plugins:
Controlling which plugins are loaded
------------------------------------
Datasette defaults to loading every plugin that is installed in the same virtual environment as Datasette itself.
You can set the ``DATASETTE_LOAD_PLUGINS`` environment variable to a comma-separated list of plugin names to load a controlled subset of plugins instead.
For example, to load just the ``datasette-vega`` and ``datasette-cluster-map`` plugins, set ``DATASETTE_LOAD_PLUGINS`` to ``datasette-vega,datasette-cluster-map``:
.. code-block:: bash
export DATASETTE_LOAD_PLUGINS='datasette-vega,datasette-cluster-map'
datasette mydb.db
Or:
.. code-block:: bash
DATASETTE_LOAD_PLUGINS='datasette-vega,datasette-cluster-map' \
datasette mydb.db
To disable the loading of all additional plugins, set ``DATASETTE_LOAD_PLUGINS`` to an empty string:
.. code-block:: bash
export DATASETTE_LOAD_PLUGINS=''
datasette mydb.db
A quick way to test this setting is to use it with the ``datasette plugins`` command:
.. code-block:: bash
DATASETTE_LOAD_PLUGINS='datasette-vega' datasette plugins
This should output the following:
.. code-block:: json
[
{
"name": "datasette-vega",
"static": true,
"templates": false,
"version": "0.6.2",
"hooks": [
"extra_css_urls",
"extra_js_urls"
]
}
]
.. _plugins_installed:
Seeing what plugins are installed

Wyświetl plik

@ -0,0 +1,29 @@
#!/bin/bash
# This should only run in environemnts where both
# datasette-init and datasette-json-html are installed
PLUGINS=$(datasette plugins)
echo "$PLUGINS" | jq 'any(.[]; .name == "datasette-json-html")' | \
grep -q true || ( \
echo "Test failed: datasette-json-html not found" && \
exit 1 \
)
# With the DATASETTE_LOAD_PLUGINS we should not see that
PLUGINS2=$(DATASETTE_LOAD_PLUGINS=datasette-init datasette plugins)
echo "$PLUGINS2" | jq 'any(.[]; .name == "datasette-json-html")' | \
grep -q false || ( \
echo "Test failed: datasette-json-html should not have been loaded" && \
exit 1 \
)
echo "$PLUGINS2" | jq 'any(.[]; .name == "datasette-init")' | \
grep -q true || ( \
echo "Test failed: datasette-init should have been loaded" && \
exit 1 \
)
# With DATASETTE_LOAD_PLUGINS='' we should see no plugins
PLUGINS3=$(DATASETTE_LOAD_PLUGINS='' datasette plugins)
echo "$PLUGINS3"| \
grep -q '\[\]' || ( \
echo "Test failed: datasette plugins should have returned []" && \
exit 1 \
)