Centralize JSON extra parsing

This commit is contained in:
Simon Willison 2026-06-08 20:45:01 -07:00
commit 03f1ffdf8f
4 changed files with 21 additions and 6 deletions

6
datasette/extras.py Normal file
View file

@ -0,0 +1,6 @@
def extra_names_from_request(request):
extra_bits = request.args.getlist("_extra")
extras = set()
for bit in extra_bits:
extras.update(part for part in bit.split(",") if part)
return extras

View file

@ -1,4 +1,5 @@
import json
from datasette.extras import extra_names_from_request
from datasette.utils import (
value_as_boolean,
remove_infinites,
@ -108,7 +109,7 @@ def json_renderer(request, args, data, error, truncated=None):
# Don't include "columns" in output
# https://github.com/simonw/datasette/issues/2136
if isinstance(data, dict) and "columns" not in request.args.getlist("_extra"):
if isinstance(data, dict) and "columns" not in extra_names_from_request(request):
data.pop("columns", None)
# Handle _nl option for _shape=array

View file

@ -6,6 +6,7 @@ import urllib
from asyncinject import Registry
import markupsafe
from datasette.extras import extra_names_from_request
from datasette.plugins import pm
from datasette.database import QueryInterrupted
from datasette.events import (
@ -850,11 +851,7 @@ class TableDropView(BaseView):
def _get_extras(request):
extra_bits = request.args.getlist("_extra")
extras = set()
for bit in extra_bits:
extras.update(bit.split(","))
return extras
return extra_names_from_request(request)
async def _columns_to_select(table_columns, pks, request):

View file

@ -1376,6 +1376,17 @@ async def test_table_extras(ds_client, extra, expected_json):
assert response.json() == expected_json
@pytest.mark.asyncio
async def test_table_extra_columns_can_be_comma_separated(ds_client):
response = await ds_client.get(
"/fixtures/primary_key_multiple_columns.json?_extra=columns,count"
)
assert response.status_code == 200
data = response.json()
assert data["columns"] == ["id", "content", "content2"]
assert data["count"] == 1
@pytest.mark.asyncio
async def test_extra_render_cell():
"""Test that _extra=render_cell returns rendered HTML from render_cell plugin hook"""