mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
New plugin hook: extra_serve_options()
This commit is contained in:
parent
9ef0cf6d69
commit
894c424b90
6 changed files with 78 additions and 2 deletions
|
|
@ -151,6 +151,7 @@ class Datasette:
|
|||
memory=False,
|
||||
config=None,
|
||||
version_note=None,
|
||||
plugin_extra_options=None,
|
||||
):
|
||||
immutables = immutables or []
|
||||
self.files = tuple(files) + tuple(immutables)
|
||||
|
|
@ -159,6 +160,7 @@ class Datasette:
|
|||
self.files = [MEMORY]
|
||||
elif memory:
|
||||
self.files = (MEMORY,) + self.files
|
||||
self.plugin_extra_options = plugin_extra_options or {}
|
||||
self.databases = {}
|
||||
self.inspect_data = inspect_data
|
||||
for file in self.files:
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ def package(
|
|||
install,
|
||||
spatialite,
|
||||
version_note,
|
||||
**extra_metadata
|
||||
**extra_metadata,
|
||||
):
|
||||
"Package specified SQLite files into a new datasette Docker container"
|
||||
if not shutil.which("docker"):
|
||||
|
|
@ -220,6 +220,13 @@ def package(
|
|||
call(args)
|
||||
|
||||
|
||||
def extra_serve_options(serve):
|
||||
for options in pm.hook.extra_serve_options():
|
||||
for option in reversed(options):
|
||||
serve = option(serve)
|
||||
return serve
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.argument("files", type=click.Path(exists=True), nargs=-1)
|
||||
@click.option(
|
||||
|
|
@ -286,6 +293,7 @@ def package(
|
|||
)
|
||||
@click.option("--version-note", help="Additional note to show on /-/versions")
|
||||
@click.option("--help-config", is_flag=True, help="Show available config options")
|
||||
@extra_serve_options
|
||||
def serve(
|
||||
files,
|
||||
immutable,
|
||||
|
|
@ -304,6 +312,7 @@ def serve(
|
|||
config,
|
||||
version_note,
|
||||
help_config,
|
||||
**plugin_extra_options,
|
||||
):
|
||||
"""Serve up specified SQLite database files with a web UI"""
|
||||
if help_config:
|
||||
|
|
@ -350,6 +359,7 @@ def serve(
|
|||
config=dict(config),
|
||||
memory=memory,
|
||||
version_note=version_note,
|
||||
plugin_extra_options=plugin_extra_options,
|
||||
)
|
||||
# Run async sanity checks - but only if we're not under pytest
|
||||
asyncio.get_event_loop().run_until_complete(ds.run_sanity_checks())
|
||||
|
|
|
|||
|
|
@ -58,3 +58,8 @@ def register_output_renderer(datasette):
|
|||
@hookspec
|
||||
def register_facet_classes():
|
||||
"Register Facet subclasses"
|
||||
|
||||
|
||||
@hookspec
|
||||
def extra_serve_options():
|
||||
"Return list of extra click.option decorators to be applied to 'datasette serve'"
|
||||
|
|
|
|||
|
|
@ -812,3 +812,45 @@ This example plugin adds a ``x-databases`` HTTP header listing the currently att
|
|||
await app(scope, recieve, wrapped_send)
|
||||
return add_x_databases_header
|
||||
return wrap_with_databases_header
|
||||
|
||||
.. _plugin_hook_extra_serve_options:
|
||||
|
||||
extra_serve_options()
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Add extra Click options to the ``datasette serve`` command. Options you add here will be displayed in ``datasette serve --help`` and their values will be available to your plugin anywhere it can access the ``datasette`` object by reading from ``datasette.plugin_extra_options``.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from datasette import hookimpl
|
||||
import click
|
||||
|
||||
@hookimpl
|
||||
def extra_serve_options():
|
||||
return [
|
||||
click.option(
|
||||
"--my-plugin-paths",
|
||||
type=click.Path(exists=True, file_okay=False, dir_okay=True),
|
||||
help="Directories to use with my-plugin",
|
||||
multiple=True,
|
||||
),
|
||||
click.option(
|
||||
"--my-plugin-enable",
|
||||
is_flag=True,
|
||||
help="Enable functionality from my-plugin",
|
||||
),
|
||||
]
|
||||
|
||||
Your other plugin hooks can then access these settings like so:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from datasette import hookimpl
|
||||
|
||||
@hookimpl
|
||||
def extra_template_vars(datasette):
|
||||
return {
|
||||
"my_plugin_paths": datasette.plugin_extra_options.get("my_plugin_paths") or []
|
||||
}
|
||||
|
||||
Be careful not to define an option which clashes with a Datasette default option, or with options provided by another plugin. For this reason we recommend using a common prefix for your plugin, as shown above.
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ def make_app_client(
|
|||
inspect_data=None,
|
||||
static_mounts=None,
|
||||
template_dir=None,
|
||||
plugin_extra_options=None,
|
||||
):
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
filepath = os.path.join(tmpdir, filename)
|
||||
|
|
@ -151,6 +152,7 @@ def make_app_client(
|
|||
inspect_data=inspect_data,
|
||||
static_mounts=static_mounts,
|
||||
template_dir=template_dir,
|
||||
plugin_extra_options=plugin_extra_options,
|
||||
)
|
||||
ds.sqlite_functions.append(("sleep", 1, lambda n: time.sleep(float(n))))
|
||||
client = TestClient(ds.app())
|
||||
|
|
@ -386,7 +388,8 @@ def extra_template_vars(template, database, table, view_name, request, datasette
|
|||
return {
|
||||
"extra_template_vars": json.dumps({
|
||||
"template": template,
|
||||
"scope_path": request.scope["path"]
|
||||
"scope_path": request.scope["path"],
|
||||
"plugin_extra_options": datasette.plugin_extra_options,
|
||||
}, default=lambda b: b.decode("utf8"))
|
||||
}
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@ def test_plugins_extra_template_vars(restore_working_directory):
|
|||
assert {
|
||||
"template": "show_json.html",
|
||||
"scope_path": "/-/metadata",
|
||||
"plugin_extra_options": {},
|
||||
} == extra_template_vars
|
||||
extra_template_vars_from_awaitable = json.loads(
|
||||
Soup(response.body, "html.parser")
|
||||
|
|
@ -214,3 +215,16 @@ def test_plugins_extra_template_vars(restore_working_directory):
|
|||
"awaitable": True,
|
||||
"scope_path": "/-/metadata",
|
||||
} == extra_template_vars_from_awaitable
|
||||
|
||||
|
||||
def test_plugin_extra_options_available_on_datasette(restore_working_directory):
|
||||
for client in make_app_client(
|
||||
template_dir=str(pathlib.Path(__file__).parent / "test_templates"),
|
||||
plugin_extra_options={"foo": "bar"},
|
||||
):
|
||||
response = client.get("/-/metadata")
|
||||
assert response.status == 200
|
||||
extra_template_vars = json.loads(
|
||||
Soup(response.body, "html.parser").select("pre.extra_template_vars")[0].text
|
||||
)
|
||||
assert {"foo": "bar"} == extra_template_vars["plugin_extra_options"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue