Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

get_metadata() plugin hook should support async await_me_maybe pattern #2331

Open
Tracked by #2333
simonw opened this issue Apr 24, 2024 · 2 comments
Open
Tracked by #2333

get_metadata() plugin hook should support async await_me_maybe pattern #2331

simonw opened this issue Apr 24, 2024 · 2 comments

Comments

@simonw
Copy link
Owner

simonw commented Apr 24, 2024

https://docs.datasette.io/en/1.0a13/plugin_hooks.html#get-metadata-datasette-key-database-table currently says:

CleanShot 2024-04-24 at 10 21 24@2x

Refs:

We can fix that with await_me_maybe() which wasn't a pattern we were using back when that hook was added.

@simonw
Copy link
Owner Author

simonw commented Apr 25, 2024

Here's where it's called:

datasette/datasette/app.py

Lines 649 to 695 in 8f9509f

def metadata(self, key=None, database=None, table=None, fallback=True):
"""
Looks up metadata, cascading backwards from specified level.
Returns None if metadata value is not found.
"""
assert not (
database is None and table is not None
), "Cannot call metadata() with table= specified but not database="
metadata = {}
for hook_dbs in pm.hook.get_metadata(
datasette=self, key=key, database=database, table=table
):
metadata = self._metadata_recursive_update(metadata, hook_dbs)
# security precaution!! don't allow anything in the local config
# to be overwritten. this is a temporary measure, not sure if this
# is a good idea long term or maybe if it should just be a concern
# of the plugin's implemtnation
metadata = self._metadata_recursive_update(metadata, self._metadata_local)
databases = metadata.get("databases") or {}
search_list = []
if database is not None:
search_list.append(databases.get(database) or {})
if table is not None:
table_metadata = ((databases.get(database) or {}).get("tables") or {}).get(
table
) or {}
search_list.insert(0, table_metadata)
search_list.append(metadata)
if not fallback:
# No fallback allowed, so just use the first one in the list
search_list = search_list[:1]
if key is not None:
for item in search_list:
if key in item:
return item[key]
return None
else:
# Return the merged list
m = {}
for item in search_list:
m.update(item)
return m

@simonw
Copy link
Owner Author

simonw commented Apr 25, 2024

And here's that `_metadata_recursive_update() method:

datasette/datasette/app.py

Lines 638 to 647 in 8f9509f

def _metadata_recursive_update(self, orig, updated):
if not isinstance(orig, dict) or not isinstance(updated, dict):
return orig
for key, upd_value in updated.items():
if isinstance(upd_value, dict) and isinstance(orig.get(key), dict):
orig[key] = self._metadata_recursive_update(orig[key], upd_value)
else:
orig[key] = upd_value
return orig

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant