issue_comments
10 rows where author_association = "OWNER", issue = 1493471221 and user = 9599 sorted by updated_at descending
This data as json, CSV (advanced)
Suggested facets: created_at (date), updated_at (date)
issue 1
- `.json` errors should be returned as JSON · 10 ✖
id | html_url | issue_url | node_id | user | created_at | updated_at ▲ | author_association | body | reactions | issue | performed_via_github_app |
---|---|---|---|---|---|---|---|---|---|---|---|
1352411327 | https://github.com/simonw/datasette/issues/1949#issuecomment-1352411327 | https://api.github.com/repos/simonw/datasette/issues/1949 | IC_kwDOBm6k_c5QnCi_ | simonw 9599 | 2022-12-15T00:46:27Z | 2022-12-15T00:46:27Z | OWNER | I got this far: ```diff diff --git a/datasette/handle_exception.py b/datasette/handle_exception.py index 8b7e83e3..31d41e00 100644 --- a/datasette/handle_exception.py +++ b/datasette/handle_exception.py @@ -54,7 +54,17 @@ def handle_exception(datasette, request, exception): headers = {} if datasette.cors: add_cors_headers(headers) - if request.path.split("?")[0].endswith(".json"): + # Return JSON error under certain conditions + should_return_json = ( + # URL ends in .json + request.path.split("?")[0].endswith(".json") + or + # Hints from incoming request headers + request.headers.get("content-type") == "application/json" + or "application/json" in request.headers.get("accept", "") + ) + breakpoint() + if should_return_json: return Response.json(info, status=status, headers=headers) else: template = datasette.jinja_env.select_template(templates) diff --git a/tests/test_api_write.py b/tests/test_api_write.py index f27d143f..982543a6 100644 --- a/tests/test_api_write.py +++ b/tests/test_api_write.py @@ -1140,6 +1140,38 @@ async def test_create_table_permissions( assert data["errors"] == expected_errors +@pytest.mark.asyncio +@pytest.mark.parametrize( + "headers,expect_json", + ( + ({}, False), + ({"Accept": "text/html"}, True), + ({"Accept": "application/json"}, True), + ({"Content-Type": "application/json"}, True), + ({"Accept": "application/json, text/plain, /"}, True), + ({"Content-Type": "application/json"}, True), + ({"accept": "application/json, text/plain, /"}, True), + ({"content-type": "application/json"}, True), + ), +) +async def test_permission_errors_html_and_json(ds_write, headers, expect_json): + request_headers = {"Authorization": "Bearer bad_token"} + request_headers.update(headers) + response = await ds_write.client.post( + "/data/-/create", + json={}, + headers=request_headers, + ) + assert response.status_code == 403 + if expect_json: + data = response.json() + assert data["ok"] is False + assert data["errors"] == ["Permission denied"] + else: + assert response.headers["Content-Type"] == "text/html; charset=utf-8" + assert "Permission denied" in response.text + + @pytest.mark.asyncio @pytest.mark.parametrize( "input,expected_rows_after", ``` Then decided I would punt this until the next milestone. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`.json` errors should be returned as JSON 1493471221 | |
1352378370 | https://github.com/simonw/datasette/issues/1949#issuecomment-1352378370 | https://api.github.com/repos/simonw/datasette/issues/1949 | IC_kwDOBm6k_c5Qm6gC | simonw 9599 | 2022-12-15T00:02:08Z | 2022-12-15T00:04:54Z | OWNER | I fixed this issue to help research this further: - https://github.com/simonw/datasette-ripgrep/issues/26 Now this search works: https://ripgrep.datasette.io/-/ripgrep?pattern=return+_error&literal=on&glob=datasette%2F** I wish I had this feature! - https://github.com/simonw/datasette-ripgrep/issues/24 Looks like I have both |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`.json` errors should be returned as JSON 1493471221 | |
1352356356 | https://github.com/simonw/datasette/issues/1949#issuecomment-1352356356 | https://api.github.com/repos/simonw/datasette/issues/1949 | IC_kwDOBm6k_c5Qm1IE | simonw 9599 | 2022-12-14T23:27:25Z | 2022-12-14T23:28:16Z | OWNER | Also weird: errors returned by that mechanism look like this:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`.json` errors should be returned as JSON 1493471221 | |
1352354927 | https://github.com/simonw/datasette/issues/1949#issuecomment-1352354927 | https://api.github.com/repos/simonw/datasette/issues/1949 | IC_kwDOBm6k_c5Qm0xv | simonw 9599 | 2022-12-14T23:25:06Z | 2022-12-14T23:25:14Z | OWNER | Looks like the code I've written for permission checking on Which uses this: Having two different patterns to return errors is bad, I should fix that. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`.json` errors should be returned as JSON 1493471221 | |
1352340518 | https://github.com/simonw/datasette/issues/1949#issuecomment-1352340518 | https://api.github.com/repos/simonw/datasette/issues/1949 | IC_kwDOBm6k_c5QmxQm | simonw 9599 | 2022-12-14T23:07:01Z | 2022-12-14T23:07:01Z | OWNER | Easiest fix would be to look for Not bullet-proof, so people might occasionally make JSON requests and get back an HTML error - but the documentation can tell people that they need to send those headers if they want to reliably get back JSON error messages. I'm happy with this as a solution. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`.json` errors should be returned as JSON 1493471221 | |
1352338620 | https://github.com/simonw/datasette/issues/1949#issuecomment-1352338620 | https://api.github.com/repos/simonw/datasette/issues/1949 | IC_kwDOBm6k_c5Qmwy8 | simonw 9599 | 2022-12-14T23:05:17Z | 2022-12-14T23:05:17Z | OWNER | Sniffing for a |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`.json` errors should be returned as JSON 1493471221 | |
1352335503 | https://github.com/simonw/datasette/issues/1949#issuecomment-1352335503 | https://api.github.com/repos/simonw/datasette/issues/1949 | IC_kwDOBm6k_c5QmwCP | simonw 9599 | 2022-12-14T23:03:28Z | 2022-12-14T23:03:28Z | OWNER | This raises a more complicated issue At some point I'm likely to want to add an HTML interface for creating tables and inserting and updating rows. The obvious URLs for that are the same as for the JSON API: Those endpoints are currently POST only - and can return JSON all the time. If they start accepting form POSTs too they'll need to be able to accept form-encoded data and return HTML instead. That's OK - they can detect incoming JSON thanks to the I think it can still work though: I'll only set |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`.json` errors should be returned as JSON 1493471221 | |
1352331314 | https://github.com/simonw/datasette/issues/1949#issuecomment-1352331314 | https://api.github.com/repos/simonw/datasette/issues/1949 | IC_kwDOBm6k_c5QmvAy | simonw 9599 | 2022-12-14T22:59:36Z | 2022-12-14T22:59:36Z | OWNER | I'm going to prototype that up to see what it looks like. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`.json` errors should be returned as JSON 1493471221 | |
1352330825 | https://github.com/simonw/datasette/issues/1949#issuecomment-1352330825 | https://api.github.com/repos/simonw/datasette/issues/1949 | IC_kwDOBm6k_c5Qmu5J | simonw 9599 | 2022-12-14T22:58:51Z | 2022-12-14T22:59:27Z | OWNER | I need a way for those JSON endpoints to communicate back to the Since it gets the It's a bit of a cludge though! |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`.json` errors should be returned as JSON 1493471221 | |
1352329027 | https://github.com/simonw/datasette/issues/1949#issuecomment-1352329027 | https://api.github.com/repos/simonw/datasette/issues/1949 | IC_kwDOBm6k_c5QmudD | simonw 9599 | 2022-12-14T22:56:24Z | 2022-12-14T22:57:19Z | OWNER | Most But that code triggers when the URL ends with |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`.json` errors should be returned as JSON 1493471221 |
Advanced export
JSON shape: default, array, newline-delimited, object
CREATE TABLE [issue_comments] ( [html_url] TEXT, [issue_url] TEXT, [id] INTEGER PRIMARY KEY, [node_id] TEXT, [user] INTEGER REFERENCES [users]([id]), [created_at] TEXT, [updated_at] TEXT, [author_association] TEXT, [body] TEXT, [reactions] TEXT, [issue] INTEGER REFERENCES [issues]([id]) , [performed_via_github_app] TEXT); CREATE INDEX [idx_issue_comments_issue] ON [issue_comments] ([issue]); CREATE INDEX [idx_issue_comments_user] ON [issue_comments] ([user]);
user 1