mirror of
https://github.com/simonw/datasette.git
synced 2026-07-09 00:54:35 +02:00
Homepage JSON returns databases as a list
/.json previously returned databases as an object keyed by database name, unlike /-/databases.json and every other collection in the API. It now returns a list of database objects. The HTML template already consumed the list. This endpoint remains undocumented. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GrHZSypDfMnym1tM5XJAFZ
This commit is contained in:
parent
13dc7a08b7
commit
5cb2bc6909
4 changed files with 17 additions and 13 deletions
|
|
@ -152,7 +152,7 @@ class IndexView(BaseView):
|
|||
json.dumps(
|
||||
{
|
||||
"ok": True,
|
||||
"databases": {db["name"]: db for db in databases},
|
||||
"databases": databases,
|
||||
"metadata": await self.ds.get_instance_metadata(),
|
||||
},
|
||||
cls=CustomJSONEncoder,
|
||||
|
|
|
|||
|
|
@ -201,8 +201,8 @@ Routes: `/(\.(?P<format>jsono?))?$` and `/-/(\.(?P<format>jsono?))?$`
|
|||
- **Parameters:** `_sort=relationships` sorts each database's truncated table
|
||||
list by foreign-key relationship count.
|
||||
- **JSON response** (index.py:147-161) — includes `ok: true` plus:
|
||||
- `databases` — an **object keyed by database name** (not a list). Each
|
||||
value: `name`, `hash` (or null), `color`, `path`,
|
||||
- `databases` — a **list** of database objects (undocumented API, subject
|
||||
to change). Each item: `name`, `hash` (or null), `color`, `path`,
|
||||
`tables_and_views_truncated` (up to 5 items: `name`, `columns`,
|
||||
`primary_keys`, `count` (int or null), `hidden`, `fts_table`,
|
||||
`num_relationships_for_sorting`, `private`; view items are just
|
||||
|
|
|
|||
|
|
@ -156,10 +156,12 @@ Endpoints disagree about the success envelope:
|
|||
|
||||
### 2a. Collection representations disagree (P2)
|
||||
|
||||
- Homepage `/.json` returns `databases` as an **object keyed by name**
|
||||
- ~~Homepage `/.json` returns `databases` as an **object keyed by name**
|
||||
(index.py:147-161); `/-/databases.json` returns an **array**; the database
|
||||
page returns `tables` as an array. Choose arrays-of-objects everywhere
|
||||
(objects-keyed-by-name break when names need ordering or pagination).
|
||||
(objects-keyed-by-name break when names need ordering or pagination).~~
|
||||
✅ **Done** — the homepage returns a list, matching `/-/databases.json`.
|
||||
The homepage JSON remains deliberately undocumented.
|
||||
- ~~Insert/upsert with `return: true` respond with `rows` (plural, list); row
|
||||
update with `return: true` responds with `row` (singular, object)
|
||||
(views/row.py:837-844). Pick one (`rows` everywhere, even for one row,
|
||||
|
|
|
|||
|
|
@ -26,8 +26,9 @@ async def test_homepage(ds_client):
|
|||
"title",
|
||||
]
|
||||
databases = data.get("databases")
|
||||
assert databases.keys() == {"fixtures": 0}.keys()
|
||||
d = databases["fixtures"]
|
||||
assert isinstance(databases, list)
|
||||
assert [d["name"] for d in databases] == ["fixtures"]
|
||||
d = databases[0]
|
||||
assert d["name"] == "fixtures"
|
||||
assert isinstance(d["tables_count"], int)
|
||||
assert isinstance(len(d["tables_and_views_truncated"]), int)
|
||||
|
|
@ -43,7 +44,7 @@ async def test_homepage_sort_by_relationships(ds_client):
|
|||
assert response.status_code == 200
|
||||
tables = [
|
||||
t["name"]
|
||||
for t in response.json()["databases"]["fixtures"]["tables_and_views_truncated"]
|
||||
for t in response.json()["databases"][0]["tables_and_views_truncated"]
|
||||
]
|
||||
assert tables == [
|
||||
"simple_primary_key",
|
||||
|
|
@ -251,8 +252,8 @@ def test_no_files_uses_memory_database(app_client_no_files):
|
|||
assert response.status == 200
|
||||
assert {
|
||||
"ok": True,
|
||||
"databases": {
|
||||
"_memory": {
|
||||
"databases": [
|
||||
{
|
||||
"name": "_memory",
|
||||
"hash": None,
|
||||
"color": "a6c7b9",
|
||||
|
|
@ -267,7 +268,7 @@ def test_no_files_uses_memory_database(app_client_no_files):
|
|||
"views_count": 0,
|
||||
"private": False,
|
||||
},
|
||||
},
|
||||
],
|
||||
"metadata": {},
|
||||
} == response.json
|
||||
# Try that SQL query
|
||||
|
|
@ -852,8 +853,9 @@ async def test_tilde_encoded_database_names(db_name):
|
|||
ds = Datasette()
|
||||
ds.add_memory_database(db_name)
|
||||
response = await ds.client.get("/.json")
|
||||
assert db_name in response.json()["databases"].keys()
|
||||
path = response.json()["databases"][db_name]["path"]
|
||||
databases_by_name = {d["name"]: d for d in response.json()["databases"]}
|
||||
assert db_name in databases_by_name
|
||||
path = databases_by_name[db_name]["path"]
|
||||
# And the JSON for that database
|
||||
response2 = await ds.client.get(path + ".json")
|
||||
assert response2.status_code == 200
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue