mirror of
https://github.com/simonw/datasette.git
synced 2026-07-08 16:44:34 +02:00
Remove params input alias from the query create and update APIs
The alias existed so API payloads could mirror the params key used by queries defined in datasette.yaml, but it was undocumented and untested, and the create endpoint is not part of the stable API. The API now only accepts parameters - sending params is a 400 Invalid keys error. The documented params key for queries in configuration is unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GrHZSypDfMnym1tM5XJAFZ
This commit is contained in:
parent
b23fc4ec48
commit
b83b12dd7a
3 changed files with 45 additions and 5 deletions
|
|
@ -33,7 +33,6 @@ _query_fields = {
|
|||
"hide_sql",
|
||||
"fragment",
|
||||
"parameters",
|
||||
"params",
|
||||
"is_private",
|
||||
"on_success_message",
|
||||
"on_success_redirect",
|
||||
|
|
@ -540,7 +539,7 @@ async def _prepare_query_create(datasette, request, db, data):
|
|||
raise QueryValidationError("Writable query fields require writable SQL")
|
||||
|
||||
parameters = _coerce_query_parameters(
|
||||
data.get("parameters", data.get("params")),
|
||||
data.get("parameters"),
|
||||
derived,
|
||||
)
|
||||
return {
|
||||
|
|
@ -585,9 +584,9 @@ async def _prepare_query_update(datasette, request, db, existing: StoredQuery, u
|
|||
actor=request.actor,
|
||||
)
|
||||
|
||||
if "parameters" in update or "params" in update:
|
||||
if "parameters" in update:
|
||||
parameters = _coerce_query_parameters(
|
||||
update.get("parameters", update.get("params")),
|
||||
update.get("parameters"),
|
||||
derived,
|
||||
)
|
||||
elif "sql" in update:
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ JSON API: breaking changes
|
|||
- Unknown ``?_extra=`` names now return a ``400`` error for JSON and other data formats, instead of being silently ignored. HTML pages continue to ignore unknown names.
|
||||
- Table JSON responses now include ``next_url`` alongside ``next`` by default - both are ``null`` on the final page. The now-redundant ``?_extra=next_url`` parameter has been removed.
|
||||
- The stored query list JSON no longer includes ``has_more`` - ``"next": null`` is the end-of-results signal across the whole API. This change also uncovered and fixed a bug where the query list ``next_url`` pointed at the HTML page and was a relative path; it is now an absolute URL that preserves the requested format.
|
||||
- Stored query JSON objects no longer duplicate the list of parameter names as both ``params`` and ``parameters`` - only ``parameters`` remains in the output. ``params`` is still accepted as an input alias when creating or updating queries.
|
||||
- Stored query JSON objects no longer duplicate the list of parameter names as both ``params`` and ``parameters`` - only ``parameters`` remains. The query create and update APIs no longer accept ``params`` as an input alias either; ``params`` is still the documented key for :ref:`queries defined in configuration <queries_named_parameters>`.
|
||||
- Page size parameters are now consistent across the API: the stored query lists accept ``?_size=max`` and return a ``400`` error for values over the maximum instead of silently clamping them, and the ``/-/allowed`` and ``/-/rules`` permission debug endpoints renamed their ``page`` and ``page_size`` parameters to ``_page`` and ``_size``, matching the underscore grammar used by every other Datasette system parameter.
|
||||
- ``/-/threads`` now requires the ``permissions-debug`` permission, since it exposes runtime internals such as file paths. It previously only required ``view-instance``.
|
||||
- Trusted stored queries - those defined in configuration - can no longer be deleted through the JSON API or web interface, matching the existing restriction on editing them.
|
||||
|
|
|
|||
|
|
@ -1125,6 +1125,47 @@ async def test_query_update_api_rejects_config_only_fields():
|
|||
assert query.on_success_message_sql is None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_query_api_rejects_params_alias():
|
||||
# "params" is a datasette.yaml configuration key, not an API input -
|
||||
# the API only accepts "parameters"
|
||||
ds = Datasette(memory=True, default_deny=True)
|
||||
ds.root_enabled = True
|
||||
db = ds.add_memory_database("query_params_alias", name="data")
|
||||
await db.execute_write("create table dogs (id integer primary key, name text)")
|
||||
await ds.invoke_startup()
|
||||
|
||||
store_response = await ds.client.post(
|
||||
"/data/-/queries/store",
|
||||
actor={"id": "root"},
|
||||
json={
|
||||
"query": {
|
||||
"name": "by_name",
|
||||
"sql": "select * from dogs where name = :name",
|
||||
"params": ["name"],
|
||||
}
|
||||
},
|
||||
)
|
||||
assert store_response.status_code == 400
|
||||
assert store_response.json()["errors"] == ["Invalid keys: params"]
|
||||
assert await ds.get_query("data", "by_name") is None
|
||||
|
||||
await ds.add_query(
|
||||
"data",
|
||||
"editable",
|
||||
"select * from dogs where name = :name",
|
||||
source="user",
|
||||
owner_id="root",
|
||||
)
|
||||
update_response = await ds.client.post(
|
||||
"/data/editable/-/update",
|
||||
actor={"id": "root"},
|
||||
json={"update": {"params": ["name"]}},
|
||||
)
|
||||
assert update_response.status_code == 400
|
||||
assert update_response.json()["errors"] == ["Invalid keys: params"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_query_update_api_rejects_trusted_queries_but_internal_update_allowed():
|
||||
ds = Datasette(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue