home / github / issue_comments

Menu
  • Search all tables
  • GraphQL API

issue_comments: 1690792514

This data as json

html_url issue_url id node_id user created_at updated_at author_association body reactions issue performed_via_github_app
https://github.com/simonw/datasette/issues/2143#issuecomment-1690792514 https://api.github.com/repos/simonw/datasette/issues/2143 1690792514 IC_kwDOBm6k_c5kx3JC 9599 2023-08-24T00:00:16Z 2023-08-24T00:02:55Z OWNER

I've been thinking about what it might look like to allow command-line arguments to be used to define any of the configuration options in datasette.yml, as alternative and more convenient syntax.

Here's what I've come up with: datasette \ -s settings.sql_time_limit_ms 1000 \ -s plugins.datasette-auth-tokens.manage_tokens true \ -s plugins.datasette-auth-tokens.manage_tokens_database tokens \ -s plugins.datasette-ripgrep.path "/home/simon/code-to-search" \ -s databases.mydatabase.tables.example_table.sort created \ mydatabase.db tokens.db Which would be equivalent to datasette.yml containing this: yaml plugins: datasette-auth-tokens: manage_tokens: true manage_tokens_database: tokens datasette-ripgrep: path: /home/simon/code-to-search databases: mydatabase: tables: example_table: sort: created settings: sql_time_limit_ms: 1000 Here's a prototype implementation of this: ```python import json from typing import Any, List, Tuple

def _handle_pair(key: str, value: str) -> dict: """ Turn a key-value pair into a nested dictionary. foo, bar => {'foo': 'bar'} foo.bar, baz => {'foo': {'bar': 'baz'}} foo.bar, [1, 2, 3] => {'foo': {'bar': [1, 2, 3]}} foo.bar, "baz" => {'foo': {'bar': 'baz'}} foo.bar, '{"baz": "qux"}' => {'foo': {'bar': "{'baz': 'qux'}"}} """ try: value = json.loads(value) except json.JSONDecodeError: # If it doesn't parse as JSON, treat it as a string pass

keys = key.split('.')
result = current_dict = {}

for k in keys[:-1]:
    current_dict[k] = {}
    current_dict = current_dict[k]

current_dict[keys[-1]] = value
return result

def _combine(base: dict, update: dict) -> dict: """ Recursively merge two dictionaries. """ for key, value in update.items(): if isinstance(value, dict) and key in base and isinstance(base[key], dict): base[key] = _combine(base[key], value) else: base[key] = value return base

def handle_pairs(pairs: List[Tuple[str, Any]]) -> dict: """ Parse a list of key-value pairs into a nested dictionary. """ result = {} for key, value in pairs: parsed_pair = _handle_pair(key, value) result = _combine(result, parsed_pair) return result Exercised like this:python print(json.dumps(handle_pairs([ ("settings.sql_time_limit_ms", "1000"), ("plugins.datasette-auth-tokens.manage_tokens", "true"), ("plugins.datasette-auth-tokens.manage_tokens_database", "tokens"), ("plugins.datasette-ripgrep.path", "/home/simon/code-to-search"), ("databases.mydatabase.tables.example_table.sort", "created"), ]), indent=4)) Output:json { "settings": { "sql_time_limit_ms": 1000 }, "plugins": { "datasette-auth-tokens": { "manage_tokens": true, "manage_tokens_database": "tokens" }, "datasette-ripgrep": { "path": "/home/simon/code-to-search" } }, "databases": { "mydatabase": { "tables": { "example_table": { "sort": "created" } } } } } `` Note that-sisn't currently an option fordatasette serve`.

--setting key value IS an existing option, but it isn't completely compatible with this because it maps directly just to settings.

Although... we could keep compatibility by saying that if you call --setting known_setting value and that known_setting is in this list then we treat it as if you said -s settings.known_setting value instead:

https://github.com/simonw/datasette/blob/bdf59eb7db42559e538a637bacfe86d39e5d17ca/datasette/app.py#L114-L204

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
1855885427  
Powered by Datasette · Queries took 1.008ms · About: github-to-sqlite