mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
This change updates the `-s/--setting` option to `datasette serve` to allow it to be used to set arbitrarily complex nested settings in a way that is compatible with the new `-c datasette.yml` work happening in: - #2143 It will enable things like this: ``` datasette data.db --setting plugins.datasette-ripgrep.path "/home/simon/code" ``` For the moment though it just affects [settings](https://docs.datasette.io/en/1.0a4/settings.html) - so you can do this: ``` datasette data.db --setting settings.sql_time_limit_ms 3500 ``` I've also implemented a backwards compatibility mechanism, so if you use it this way (the old way): ``` datasette data.db --setting sql_time_limit_ms 3500 ``` It will notice that the setting you passed is one of Datasette's core settings, and will treat that as if you said `settings.sql_time_limit_ms` instead.
This commit is contained in:
parent
527cec66b0
commit
d9aad1fd04
3 changed files with 46 additions and 47 deletions
|
|
@ -31,6 +31,7 @@ from .utils import (
|
||||||
ConnectionProblem,
|
ConnectionProblem,
|
||||||
SpatialiteConnectionProblem,
|
SpatialiteConnectionProblem,
|
||||||
initial_path_for_datasette,
|
initial_path_for_datasette,
|
||||||
|
pairs_to_nested_config,
|
||||||
temporary_docker_directory,
|
temporary_docker_directory,
|
||||||
value_as_boolean,
|
value_as_boolean,
|
||||||
SpatialiteNotFound,
|
SpatialiteNotFound,
|
||||||
|
|
@ -56,35 +57,27 @@ class Setting(CompositeParamType):
|
||||||
|
|
||||||
def convert(self, config, param, ctx):
|
def convert(self, config, param, ctx):
|
||||||
name, value = config
|
name, value = config
|
||||||
if name not in DEFAULT_SETTINGS:
|
if name in DEFAULT_SETTINGS:
|
||||||
msg = (
|
# For backwards compatibility with how this worked prior to
|
||||||
OBSOLETE_SETTINGS.get(name)
|
# Datasette 1.0, we turn bare setting names into setting.name
|
||||||
or f"{name} is not a valid option (--help-settings to see all)"
|
# Type checking for those older settings
|
||||||
)
|
default = DEFAULT_SETTINGS[name]
|
||||||
self.fail(
|
name = "settings.{}".format(name)
|
||||||
msg,
|
if isinstance(default, bool):
|
||||||
param,
|
try:
|
||||||
ctx,
|
return name, "true" if value_as_boolean(value) else "false"
|
||||||
)
|
except ValueAsBooleanError:
|
||||||
return
|
self.fail(f'"{name}" should be on/off/true/false/1/0', param, ctx)
|
||||||
# Type checking
|
elif isinstance(default, int):
|
||||||
default = DEFAULT_SETTINGS[name]
|
if not value.isdigit():
|
||||||
if isinstance(default, bool):
|
self.fail(f'"{name}" should be an integer', param, ctx)
|
||||||
try:
|
return name, value
|
||||||
return name, value_as_boolean(value)
|
elif isinstance(default, str):
|
||||||
except ValueAsBooleanError:
|
return name, value
|
||||||
self.fail(f'"{name}" should be on/off/true/false/1/0', param, ctx)
|
else:
|
||||||
return
|
# Should never happen:
|
||||||
elif isinstance(default, int):
|
self.fail("Invalid option")
|
||||||
if not value.isdigit():
|
return name, value
|
||||||
self.fail(f'"{name}" should be an integer', param, ctx)
|
|
||||||
return
|
|
||||||
return name, int(value)
|
|
||||||
elif isinstance(default, str):
|
|
||||||
return name, value
|
|
||||||
else:
|
|
||||||
# Should never happen:
|
|
||||||
self.fail("Invalid option")
|
|
||||||
|
|
||||||
|
|
||||||
def sqlite_extensions(fn):
|
def sqlite_extensions(fn):
|
||||||
|
|
@ -425,7 +418,7 @@ def uninstall(packages, yes):
|
||||||
"--setting",
|
"--setting",
|
||||||
"settings",
|
"settings",
|
||||||
type=Setting(),
|
type=Setting(),
|
||||||
help="Setting, see docs.datasette.io/en/stable/settings.html",
|
help="nested.key, value setting to use in Datasette configuration",
|
||||||
multiple=True,
|
multiple=True,
|
||||||
)
|
)
|
||||||
@click.option(
|
@click.option(
|
||||||
|
|
@ -547,6 +540,13 @@ def serve(
|
||||||
if config:
|
if config:
|
||||||
config_data = parse_metadata(config.read())
|
config_data = parse_metadata(config.read())
|
||||||
|
|
||||||
|
config_data = config_data or {}
|
||||||
|
|
||||||
|
# Merge in settings from -s/--setting
|
||||||
|
if settings:
|
||||||
|
settings_updates = pairs_to_nested_config(settings)
|
||||||
|
config_data.update(settings_updates)
|
||||||
|
|
||||||
kwargs = dict(
|
kwargs = dict(
|
||||||
immutables=immutable,
|
immutables=immutable,
|
||||||
cache_headers=not reload,
|
cache_headers=not reload,
|
||||||
|
|
@ -558,7 +558,7 @@ def serve(
|
||||||
template_dir=template_dir,
|
template_dir=template_dir,
|
||||||
plugins_dir=plugins_dir,
|
plugins_dir=plugins_dir,
|
||||||
static_mounts=static,
|
static_mounts=static,
|
||||||
settings=dict(settings),
|
settings=None, # These are passed in config= now
|
||||||
memory=memory,
|
memory=memory,
|
||||||
secret=secret,
|
secret=secret,
|
||||||
version_note=version_note,
|
version_note=version_note,
|
||||||
|
|
|
||||||
|
|
@ -113,8 +113,8 @@ Once started you can access it at ``http://localhost:8001``
|
||||||
/MOUNT/...
|
/MOUNT/...
|
||||||
--memory Make /_memory database available
|
--memory Make /_memory database available
|
||||||
-c, --config FILENAME Path to JSON/YAML Datasette configuration file
|
-c, --config FILENAME Path to JSON/YAML Datasette configuration file
|
||||||
--setting SETTING... Setting, see
|
-s, --setting SETTING... nested.key, value setting to use in Datasette
|
||||||
docs.datasette.io/en/stable/settings.html
|
configuration
|
||||||
--secret TEXT Secret used for signing secure values, such as
|
--secret TEXT Secret used for signing secure values, such as
|
||||||
signed cookies
|
signed cookies
|
||||||
--root Output URL that sets a cookie authenticating
|
--root Output URL that sets a cookie authenticating
|
||||||
|
|
|
||||||
|
|
@ -220,20 +220,27 @@ def test_serve_invalid_ports(invalid_port):
|
||||||
assert "Invalid value for '-p'" in result.stderr
|
assert "Invalid value for '-p'" in result.stderr
|
||||||
|
|
||||||
|
|
||||||
def test_setting():
|
@pytest.mark.parametrize(
|
||||||
|
"args",
|
||||||
|
(
|
||||||
|
["--setting", "default_page_size", "5"],
|
||||||
|
["--setting", "settings.default_page_size", "5"],
|
||||||
|
["-s", "settings.default_page_size", "5"],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
def test_setting(args):
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
result = runner.invoke(
|
result = runner.invoke(cli, ["--get", "/-/settings.json"] + args)
|
||||||
cli, ["--setting", "default_page_size", "5", "--get", "/-/settings.json"]
|
|
||||||
)
|
|
||||||
assert result.exit_code == 0, result.output
|
assert result.exit_code == 0, result.output
|
||||||
assert json.loads(result.output)["default_page_size"] == 5
|
settings = json.loads(result.output)
|
||||||
|
assert settings["default_page_size"] == 5
|
||||||
|
|
||||||
|
|
||||||
def test_setting_type_validation():
|
def test_setting_type_validation():
|
||||||
runner = CliRunner(mix_stderr=False)
|
runner = CliRunner(mix_stderr=False)
|
||||||
result = runner.invoke(cli, ["--setting", "default_page_size", "dog"])
|
result = runner.invoke(cli, ["--setting", "default_page_size", "dog"])
|
||||||
assert result.exit_code == 2
|
assert result.exit_code == 2
|
||||||
assert '"default_page_size" should be an integer' in result.stderr
|
assert '"settings.default_page_size" should be an integer' in result.stderr
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("default_allow_sql", (True, False))
|
@pytest.mark.parametrize("default_allow_sql", (True, False))
|
||||||
|
|
@ -360,11 +367,3 @@ def test_help_settings():
|
||||||
result = runner.invoke(cli, ["--help-settings"])
|
result = runner.invoke(cli, ["--help-settings"])
|
||||||
for setting in SETTINGS:
|
for setting in SETTINGS:
|
||||||
assert setting.name in result.output
|
assert setting.name in result.output
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("setting", ("hash_urls", "default_cache_ttl_hashed"))
|
|
||||||
def test_help_error_on_hash_urls_setting(setting):
|
|
||||||
runner = CliRunner()
|
|
||||||
result = runner.invoke(cli, ["--setting", setting, 1])
|
|
||||||
assert result.exit_code == 2
|
|
||||||
assert "The hash_urls setting has been removed" in result.output
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue