Skip to content

Commit

Permalink
feat(generic JSON): handle array-only responses
Browse files Browse the repository at this point in the history
  • Loading branch information
betodealmeida committed Jul 30, 2024
1 parent e7851f4 commit b079712
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Changelog
Next
====

- Handle array-only responses in the generic JSON adapter (#???)

Version 1.2.21 - 2024-07-12
===========================

Expand Down
7 changes: 6 additions & 1 deletion src/shillelagh/adapters/api/generic_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,14 @@ def get_data( # pylint: disable=unused-argument, too-many-arguments
raise ProgrammingError(f'Error: {payload["error"]["message"]}')

for i, row in enumerate(jsonpath.findall(self.path, payload)):
if isinstance(row, list):
row = {f"col_{i}": value for i, value in enumerate(row)}
elif row is None:
row = {}

row = {
k: v
for k, v in (row or {}).items()
for k, v in row.items()
if requested_columns is None or k in requested_columns
}
row["rowid"] = i
Expand Down
44 changes: 44 additions & 0 deletions tests/adapters/api/generic_json_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,3 +283,47 @@ def test_single_row(requests_mock: Mocker) -> None:
sql = f'SELECT * FROM "{url}"'
rows = list(cursor.execute(sql))
assert rows == [("Solve a Rubik's cube", "recreational", 1, 0, "", "4151544", 0.1)]


def test_generic_json_array(requests_mock: Mocker) -> None:
"""
Test a query where the response has only arrays.
"""
# for datassette and other probing adapters
requests_mock.get(
"https://api.github.com/repos/apache/superset/-/versions.json",
status_code=404,
)

url = URL("https://api.github.com/repos/apache/superset/stats/punch_card")
requests_mock.head(str(url), headers={"content-type": "application/json"})
requests_mock.get(
str(url),
json=[
[0, 0, 15],
[0, 1, 8],
[0, 2, 6],
[0, 3, 3],
[0, 4, 2],
None,
],
)

connection = connect(
":memory:",
adapter_kwargs={"genericjsonapi": {"cache_expiration": -1}},
)
cursor = connection.cursor()

sql = f'SELECT * FROM "{url}"'
rows = list(cursor.execute(sql))
assert rows == [
(0, 0, 15),
(0, 1, 8),
(0, 2, 6),
(0, 3, 3),
(0, 4, 2),
(None, None, None),
]
assert cursor.description
assert {t[0] for t in cursor.description} == {"col_0", "col_1", "col_2"}

0 comments on commit b079712

Please sign in to comment.