{"html_url": "https://github.com/simonw/sqlite-utils/pull/118#issuecomment-655018966", "issue_url": "https://api.github.com/repos/simonw/sqlite-utils/issues/118", "id": 655018966, "node_id": "MDEyOklzc3VlQ29tbWVudDY1NTAxODk2Ng==", "user": {"value": 79913, "label": "tsibley"}, "created_at": "2020-07-07T17:41:06Z", "updated_at": "2020-07-07T17:41:06Z", "author_association": "CONTRIBUTOR", "body": "Hmm, while tests pass, this may not work as intended on larger datasets. Looking into it.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 651844316, "label": "Add insert --truncate option"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/784#issuecomment-654424704", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/784", "id": 654424704, "node_id": "MDEyOklzc3VlQ29tbWVudDY1NDQyNDcwNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-06T19:31:53Z", "updated_at": "2020-07-06T19:31:53Z", "author_association": "OWNER", "body": "Documentation: https://datasette.readthedocs.io/en/stable/authentication.html#using-the-root-actor", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 628003707, "label": "Ability to sign in to Datasette as a root account"}, "performed_via_github_app": null} {"html_url": "https://github.com/dogsheep/github-to-sqlite/issues/41#issuecomment-653966670", "issue_url": "https://api.github.com/repos/dogsheep/github-to-sqlite/issues/41", "id": 653966670, "node_id": "MDEyOklzc3VlQ29tbWVudDY1Mzk2NjY3MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-06T01:07:02Z", "updated_at": "2020-07-06T01:07:02Z", "author_association": "MEMBER", "body": "OK that fix worked.https://github.com/dogsheep/github-to-sqlite/runs/839764768?check_suite_focus=true", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 651159727, "label": "Demo is failing to deploy"}, "performed_via_github_app": null} {"html_url": "https://github.com/dogsheep/github-to-sqlite/issues/41#issuecomment-653962708", "issue_url": "https://api.github.com/repos/dogsheep/github-to-sqlite/issues/41", "id": 653962708, "node_id": "MDEyOklzc3VlQ29tbWVudDY1Mzk2MjcwOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-06T00:43:10Z", "updated_at": "2020-07-06T00:43:10Z", "author_association": "MEMBER", "body": "I bet it's datasette-search-all.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 651159727, "label": "Demo is failing to deploy"}, "performed_via_github_app": null} {"html_url": "https://github.com/dogsheep/github-to-sqlite/issues/41#issuecomment-653962669", "issue_url": "https://api.github.com/repos/dogsheep/github-to-sqlite/issues/41", "id": 653962669, "node_id": "MDEyOklzc3VlQ29tbWVudDY1Mzk2MjY2OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-06T00:42:57Z", "updated_at": "2020-07-06T00:42:57Z", "author_association": "MEMBER", "body": "https://github-to-sqlite.dogsheep.net/-/plugins\r\n\r\n```json\r\n[\r\n {\r\n \"name\": \"datasette-json-html\",\r\n \"static\": false,\r\n \"templates\": false,\r\n \"version\": \"0.6\",\r\n \"hooks\": [\r\n \"prepare_connection\",\r\n \"render_cell\"\r\n ]\r\n },\r\n {\r\n \"name\": \"datasette-render-markdown\",\r\n \"static\": false,\r\n \"templates\": false,\r\n \"version\": \"1.1.2\",\r\n \"hooks\": [\r\n \"extra_template_vars\",\r\n \"render_cell\"\r\n ]\r\n },\r\n {\r\n \"name\": \"datasette-pretty-json\",\r\n \"static\": false,\r\n \"templates\": false,\r\n \"version\": \"0.2\",\r\n \"hooks\": [\r\n \"render_cell\"\r\n ]\r\n },\r\n {\r\n \"name\": \"datasette-search-all\",\r\n \"static\": false,\r\n \"templates\": true,\r\n \"version\": \"0.2.1\",\r\n \"hooks\": [\r\n \"asgi_wrapper\",\r\n \"extra_template_vars\"\r\n ]\r\n },\r\n {\r\n \"name\": \"datasette-vega\",\r\n \"static\": true,\r\n \"templates\": false,\r\n \"version\": \"0.6.2\",\r\n \"hooks\": [\r\n \"extra_css_urls\",\r\n \"extra_js_urls\"\r\n ]\r\n }\r\n]\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 651159727, "label": "Demo is failing to deploy"}, "performed_via_github_app": null} {"html_url": "https://github.com/dogsheep/github-to-sqlite/issues/41#issuecomment-653962530", "issue_url": "https://api.github.com/repos/dogsheep/github-to-sqlite/issues/41", "id": 653962530, "node_id": "MDEyOklzc3VlQ29tbWVudDY1Mzk2MjUzMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-06T00:42:13Z", "updated_at": "2020-07-06T00:42:13Z", "author_association": "MEMBER", "body": "So it looks like it's the ASGI lifespan change I made in https://github.com/simonw/datasette/commit/16f592247a2a0e140ada487e9972645406dcae69 - It must be incompatible with one of the plugins.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 651159727, "label": "Demo is failing to deploy"}, "performed_via_github_app": null} {"html_url": "https://github.com/dogsheep/github-to-sqlite/issues/41#issuecomment-653962418", "issue_url": "https://api.github.com/repos/dogsheep/github-to-sqlite/issues/41", "id": 653962418, "node_id": "MDEyOklzc3VlQ29tbWVudDY1Mzk2MjQxOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-06T00:41:38Z", "updated_at": "2020-07-06T00:41:38Z", "author_association": "MEMBER", "body": "https://console.cloud.google.com/run/detail/us-central1/github-to-sqlite/logs?project=datasette-222320 has some clues.\r\n\r\n\"github-to-sqlite_\u2013_Service_details_\u2013_Cloud_Run_\u2013_datasette_\u2013_Google_Cloud_Platform\"\r\n\"github-to-sqlite_\u2013_Service_details_\u2013_Cloud_Run_\u2013_datasette_\u2013_Google_Cloud_Platform\"\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 651159727, "label": "Demo is failing to deploy"}, "performed_via_github_app": null} {"html_url": "https://github.com/dogsheep/github-to-sqlite/issues/41#issuecomment-653960989", "issue_url": "https://api.github.com/repos/dogsheep/github-to-sqlite/issues/41", "id": 653960989, "node_id": "MDEyOklzc3VlQ29tbWVudDY1Mzk2MDk4OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-06T00:32:34Z", "updated_at": "2020-07-06T00:32:34Z", "author_association": "MEMBER", "body": "Same error.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 651159727, "label": "Demo is failing to deploy"}, "performed_via_github_app": null} {"html_url": "https://github.com/dogsheep/github-to-sqlite/issues/41#issuecomment-653947916", "issue_url": "https://api.github.com/repos/dogsheep/github-to-sqlite/issues/41", "id": 653947916, "node_id": "MDEyOklzc3VlQ29tbWVudDY1Mzk0NzkxNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-05T22:40:47Z", "updated_at": "2020-07-05T22:40:47Z", "author_association": "MEMBER", "body": "Might be that it's not got enough RAM. I'll try deploying to a larger instance.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 651159727, "label": "Demo is failing to deploy"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/890#issuecomment-653314465", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/890", "id": 653314465, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MzMxNDQ2NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-03T03:07:41Z", "updated_at": "2020-07-03T03:07:41Z", "author_association": "OWNER", "body": "This is an excellent fix. Thanks!\r\n\r\nNot sure why codecov is complaining. I'm going to merge it as-is.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 650305298, "label": "Load only python files from plugins-dir."}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/890#issuecomment-653309545", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/890", "id": 653309545, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MzMwOTU0NQ==", "user": {"value": 22429695, "label": "codecov[bot]"}, "created_at": "2020-07-03T02:52:25Z", "updated_at": "2020-07-03T03:03:00Z", "author_association": "NONE", "body": "# [Codecov](https://codecov.io/gh/simonw/datasette/pull/890?src=pr&el=h1) Report\n> Merging [#890](https://codecov.io/gh/simonw/datasette/pull/890?src=pr&el=desc) into [master](https://codecov.io/gh/simonw/datasette/commit/57879dc8b346a435804a9e45ffaacbf2a0228bc6&el=desc) will **decrease** coverage by `0.01%`.\n> The diff coverage is `80.00%`.\n\n[![Impacted file tree graph](https://codecov.io/gh/simonw/datasette/pull/890/graphs/tree.svg?width=650&height=150&src=pr&token=eSahVY7kw1)](https://codecov.io/gh/simonw/datasette/pull/890?src=pr&el=tree)\n\n```diff\n@@ Coverage Diff @@\n## master #890 +/- ##\n==========================================\n- Coverage 83.42% 83.40% -0.02% \n==========================================\n Files 27 27 \n Lines 3632 3634 +2 \n==========================================\n+ Hits 3030 3031 +1 \n- Misses 602 603 +1 \n```\n\n\n| [Impacted Files](https://codecov.io/gh/simonw/datasette/pull/890?src=pr&el=tree) | Coverage \u0394 | |\n|---|---|---|\n| [datasette/app.py](https://codecov.io/gh/simonw/datasette/pull/890/diff?src=pr&el=tree#diff-ZGF0YXNldHRlL2FwcC5weQ==) | `95.99% <80.00%> (-0.17%)` | :arrow_down: |\n\n------\n\n[Continue to review full report at Codecov](https://codecov.io/gh/simonw/datasette/pull/890?src=pr&el=continue).\n> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)\n> `\u0394 = absolute (impact)`, `\u00f8 = not affected`, `? = missing data`\n> Powered by [Codecov](https://codecov.io/gh/simonw/datasette/pull/890?src=pr&el=footer). Last update [57879dc...745af3b](https://codecov.io/gh/simonw/datasette/pull/890?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 650305298, "label": "Load only python files from plugins-dir."}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/848#issuecomment-643711117", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/848", "id": 643711117, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzcxMTExNw==", "user": {"value": 22429695, "label": "codecov[bot]"}, "created_at": "2020-06-14T03:05:55Z", "updated_at": "2020-07-03T02:44:09Z", "author_association": "NONE", "body": "# [Codecov](https://codecov.io/gh/simonw/datasette/pull/848?src=pr&el=h1) Report\n> Merging [#848](https://codecov.io/gh/simonw/datasette/pull/848?src=pr&el=desc) into [master](https://codecov.io/gh/simonw/datasette/commit/57879dc8b346a435804a9e45ffaacbf2a0228bc6&el=desc) will **decrease** coverage by `0.60%`.\n> The diff coverage is `0.00%`.\n\n[![Impacted file tree graph](https://codecov.io/gh/simonw/datasette/pull/848/graphs/tree.svg?width=650&height=150&src=pr&token=eSahVY7kw1)](https://codecov.io/gh/simonw/datasette/pull/848?src=pr&el=tree)\n\n```diff\n@@ Coverage Diff @@\n## master #848 +/- ##\n==========================================\n- Coverage 83.42% 82.82% -0.61% \n==========================================\n Files 27 26 -1 \n Lines 3632 3540 -92 \n==========================================\n- Hits 3030 2932 -98 \n- Misses 602 608 +6 \n```\n\n\n| [Impacted Files](https://codecov.io/gh/simonw/datasette/pull/848?src=pr&el=tree) | Coverage \u0394 | |\n|---|---|---|\n| [datasette/cli.py](https://codecov.io/gh/simonw/datasette/pull/848/diff?src=pr&el=tree#diff-ZGF0YXNldHRlL2NsaS5weQ==) | `71.34% <0.00%> (-0.89%)` | :arrow_down: |\n| [datasette/views/special.py](https://codecov.io/gh/simonw/datasette/pull/848/diff?src=pr&el=tree#diff-ZGF0YXNldHRlL3ZpZXdzL3NwZWNpYWwucHk=) | `77.77% <0.00%> (-3.40%)` | :arrow_down: |\n| [datasette/app.py](https://codecov.io/gh/simonw/datasette/pull/848/diff?src=pr&el=tree#diff-ZGF0YXNldHRlL2FwcC5weQ==) | `94.58% <0.00%> (-1.58%)` | :arrow_down: |\n| [datasette/utils/asgi.py](https://codecov.io/gh/simonw/datasette/pull/848/diff?src=pr&el=tree#diff-ZGF0YXNldHRlL3V0aWxzL2FzZ2kucHk=) | `90.90% <0.00%> (-0.42%)` | :arrow_down: |\n| [datasette/utils/\\_\\_init\\_\\_.py](https://codecov.io/gh/simonw/datasette/pull/848/diff?src=pr&el=tree#diff-ZGF0YXNldHRlL3V0aWxzL19faW5pdF9fLnB5) | `93.84% <0.00%> (-0.09%)` | :arrow_down: |\n| [datasette/plugins.py](https://codecov.io/gh/simonw/datasette/pull/848/diff?src=pr&el=tree#diff-ZGF0YXNldHRlL3BsdWdpbnMucHk=) | `82.35% <0.00%> (\u00f8)` | |\n| [datasette/hookspecs.py](https://codecov.io/gh/simonw/datasette/pull/848/diff?src=pr&el=tree#diff-ZGF0YXNldHRlL2hvb2tzcGVjcy5weQ==) | `100.00% <0.00%> (\u00f8)` | |\n| [datasette/default\\_permissions.py](https://codecov.io/gh/simonw/datasette/pull/848/diff?src=pr&el=tree#diff-ZGF0YXNldHRlL2RlZmF1bHRfcGVybWlzc2lvbnMucHk=) | `100.00% <0.00%> (\u00f8)` | |\n| [datasette/default\\_magic\\_parameters.py](https://codecov.io/gh/simonw/datasette/pull/848/diff?src=pr&el=tree#diff-ZGF0YXNldHRlL2RlZmF1bHRfbWFnaWNfcGFyYW1ldGVycy5weQ==) | | |\n| [datasette/views/base.py](https://codecov.io/gh/simonw/datasette/pull/848/diff?src=pr&el=tree#diff-ZGF0YXNldHRlL3ZpZXdzL2Jhc2UucHk=) | `93.40% <0.00%> (+<0.01%)` | :arrow_up: |\n| ... and [2 more](https://codecov.io/gh/simonw/datasette/pull/848/diff?src=pr&el=tree-more) | |\n\n------\n\n[Continue to review full report at Codecov](https://codecov.io/gh/simonw/datasette/pull/848?src=pr&el=continue).\n> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)\n> `\u0394 = absolute (impact)`, `\u00f8 = not affected`, `? = missing data`\n> Powered by [Codecov](https://codecov.io/gh/simonw/datasette/pull/848?src=pr&el=footer). Last update [57879dc...0d100d1](https://codecov.io/gh/simonw/datasette/pull/848?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638270441, "label": "Reload support for config_dir mode."}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/889#issuecomment-653002499", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/889", "id": 653002499, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MzAwMjQ5OQ==", "user": {"value": 49260, "label": "amjith"}, "created_at": "2020-07-02T13:22:13Z", "updated_at": "2020-07-02T13:22:13Z", "author_association": "CONTRIBUTOR", "body": "I was able to narrow this down to the fact that lifespan protocol is turned on. \r\n\r\nI see the workaround you've used here: https://github.com/simonw/datasette-debug-asgi/commit/72d568d32a3159c763ce908c0b269736935c6987\r\n\r\nIf so, maybe it's time to update some of the asg_wrapper [plugins](https://datasette.readthedocs.io/en/stable/plugin_hooks.html#asgi-wrapper-datasette). ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 649907676, "label": "asgi_wrapper plugin hook is crashing at startup"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/889#issuecomment-652990131", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/889", "id": 652990131, "node_id": "MDEyOklzc3VlQ29tbWVudDY1Mjk5MDEzMQ==", "user": {"value": 49260, "label": "amjith"}, "created_at": "2020-07-02T12:58:11Z", "updated_at": "2020-07-02T13:00:18Z", "author_association": "CONTRIBUTOR", "body": "FWIW, this error does NOT happen in datasette 0.45a4.\r\n\r\nIt only started on 0.45a5", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 649907676, "label": "asgi_wrapper plugin hook is crashing at startup"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/886#issuecomment-652732460", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/886", "id": 652732460, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjczMjQ2MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-02T01:52:02Z", "updated_at": "2020-07-02T01:52:02Z", "author_association": "OWNER", "body": "In investigating this I'm not convinced 500 errors are being correctly raised by errors in canned writable queries.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 649429772, "label": "Reconsider how _actor_X magic parameter deals with missing values"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/886#issuecomment-652731459", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/886", "id": 652731459, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjczMTQ1OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-02T01:48:08Z", "updated_at": "2020-07-02T01:48:08Z", "author_association": "OWNER", "body": "A common error with this (and other) magic parameters is for the database query to result in the following:\r\n\r\n You did not supply a value for binding 3.\r\n\r\nThis is a pretty crufty error. I'm inclined to say that ANY missing or invalid magic parameter should be treated as a `None` value instead.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 649429772, "label": "Reconsider how _actor_X magic parameter deals with missing values"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/887#issuecomment-652711822", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/887", "id": 652711822, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjcxMTgyMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-02T00:31:33Z", "updated_at": "2020-07-02T00:31:33Z", "author_association": "OWNER", "body": "If a canned query has a title defined that will be used instead: https://latest.datasette.io/fixtures/neighborhood_search\r\n\r\n\"fixtures__select_neighborhood__facet_cities_name__state_from_facetable_join_facet_cities_on_facetable_city_id___facet_cities_id_where_neighborhood_like_________text________order_by_neighborhood_\"\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 649437530, "label": "Canned query page should show the name of the canned query"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/887#issuecomment-652711562", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/887", "id": 652711562, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjcxMTU2Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-02T00:30:43Z", "updated_at": "2020-07-02T00:30:43Z", "author_association": "OWNER", "body": "Demo has updated: https://latest.datasette.io/fixtures/magic_parameters\r\n\r\n\"fixtures__select___header_user_agent_as_user_agent____now_datetime_utc_as_datetime\"\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 649437530, "label": "Canned query page should show the name of the canned query"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/883#issuecomment-652710178", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/883", "id": 652710178, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjcxMDE3OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-02T00:25:44Z", "updated_at": "2020-07-02T00:25:44Z", "author_association": "OWNER", "body": "This is a great idea.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 648749062, "label": "Skip counting hidden tables"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/887#issuecomment-652709199", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/887", "id": 652709199, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjcwOTE5OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-02T00:21:54Z", "updated_at": "2020-07-02T00:21:54Z", "author_association": "OWNER", "body": "Example in the live demo: https://latest.datasette.io/fixtures/magic_parameters\r\n\r\n\"fixtures__select___header_user_agent_as_user_agent____now_datetime_utc_as_datetime\"\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 649437530, "label": "Canned query page should show the name of the canned query"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/885#issuecomment-652681996", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/885", "id": 652681996, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjY4MTk5Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-01T22:44:47Z", "updated_at": "2020-07-01T22:44:47Z", "author_association": "OWNER", "body": "https://simonwillison.net/2020/Jul/1/datasette-045/", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 649373451, "label": "Blog entry about the release"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/882#issuecomment-652663177", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/882", "id": 652663177, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjY2MzE3Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-01T21:48:08Z", "updated_at": "2020-07-01T21:48:08Z", "author_association": "OWNER", "body": "https://datasette.readthedocs.io/en/latest/changelog.html#v0-45", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 648673556, "label": "Release notes for 0.45"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/880#issuecomment-652646487", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/880", "id": 652646487, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjY0NjQ4Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-01T21:05:48Z", "updated_at": "2020-07-01T21:05:48Z", "author_association": "OWNER", "body": "I've been testing the WIP using this in the console:\r\n```javascript\r\nfetch('/data/add_name.json', {\r\n method: 'POST',\r\n body: 'name=XXXfetch',\r\n credentials: 'omit',\r\n headers: {'Content-Type': 'application/x-www-form-urlencoded'}\r\n})\r\n.then(response => console.log(response))\r\n```\r\nAgainst a canned query configured like this:\r\n```yaml\r\ndatabases:\r\n data:\r\n queries:\r\n add_name:\r\n sql: insert into names (name) values (:name)\r\n write: true\r\n```\r\nI haven't got it to work yet. Latest error is this one:\r\n```\r\nINFO: Uvicorn running on http://127.0.0.1:8001 (Press CTRL+C to quit)\r\nTraceback (most recent call last):\r\n File \"/Users/simon/Dropbox/Development/datasette/datasette/app.py\", line 975, in route_path\r\n await response.asgi_send(send)\r\nAttributeError: 'tuple' object has no attribute 'asgi_send'\r\nINFO: 127.0.0.1:49938 - \"POST /data/add_name.json HTTP/1.1\" 500 Internal Server Error\r\n```\r\nIt looks like I'm going to have to rethink how the `BaseView` code around tables, formats and hashes is structured in order to fix this. That's a big refactoring! I'm moving this to a new milestone for Datasette 0.46.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 648637666, "label": "POST to /db/canned-query that returns JSON should be supported (for API clients)"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/882#issuecomment-652604569", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/882", "id": 652604569, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjYwNDU2OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-01T19:27:17Z", "updated_at": "2020-07-01T19:27:17Z", "author_association": "OWNER", "body": "Don't forget to update the news in the README.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 648673556, "label": "Release notes for 0.45"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/877#issuecomment-652597975", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/877", "id": 652597975, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjU5Nzk3NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-01T19:12:15Z", "updated_at": "2020-07-01T19:12:15Z", "author_association": "OWNER", "body": "The latest release of https://github.com/simonw/datasette-auth-tokens (0.2) now supports SQL configuration of tokens.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 648421105, "label": "Consider dropping explicit CSRF protection entirely?"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/877#issuecomment-652520496", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/877", "id": 652520496, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjUyMDQ5Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-01T16:26:52Z", "updated_at": "2020-07-01T16:26:52Z", "author_association": "OWNER", "body": "Tokens get verified by plugins. So far there's only one: https://github.com/simonw/datasette-auth-tokens - which has you hard-coding plugins in a configuration file. I have a issue there to add support for database-backed tokens too: https://github.com/simonw/datasette-auth-tokens/issues/1", "reactions": "{\"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 648421105, "label": "Consider dropping explicit CSRF protection entirely?"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/883#issuecomment-652394742", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/883", "id": 652394742, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjM5NDc0Mg==", "user": {"value": 3243482, "label": "abdusco"}, "created_at": "2020-07-01T12:41:13Z", "updated_at": "2020-07-01T12:41:13Z", "author_association": "CONTRIBUTOR", "body": "Well tests need to be updated.\r\n \r\nI need to get tests working on Windows.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 648749062, "label": "Skip counting hidden tables"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/883#issuecomment-652311990", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/883", "id": 652311990, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjMxMTk5MA==", "user": {"value": 22429695, "label": "codecov[bot]"}, "created_at": "2020-07-01T09:40:40Z", "updated_at": "2020-07-01T09:40:40Z", "author_association": "NONE", "body": "# [Codecov](https://codecov.io/gh/simonw/datasette/pull/883?src=pr&el=h1) Report\n> Merging [#883](https://codecov.io/gh/simonw/datasette/pull/883?src=pr&el=desc) into [master](https://codecov.io/gh/simonw/datasette/commit/676bb64c877d73f8ff496cef4632f5a8a5a9283c&el=desc) will **not change** coverage.\n> The diff coverage is `n/a`.\n\n[![Impacted file tree graph](https://codecov.io/gh/simonw/datasette/pull/883/graphs/tree.svg?width=650&height=150&src=pr&token=eSahVY7kw1)](https://codecov.io/gh/simonw/datasette/pull/883?src=pr&el=tree)\n\n```diff\n@@ Coverage Diff @@\n## master #883 +/- ##\n=======================================\n Coverage 83.42% 83.42% \n=======================================\n Files 27 27 \n Lines 3632 3632 \n=======================================\n Hits 3030 3030 \n Misses 602 602 \n```\n\n\n\n------\n\n[Continue to review full report at Codecov](https://codecov.io/gh/simonw/datasette/pull/883?src=pr&el=continue).\n> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)\n> `\u0394 = absolute (impact)`, `\u00f8 = not affected`, `? = missing data`\n> Powered by [Codecov](https://codecov.io/gh/simonw/datasette/pull/883?src=pr&el=footer). Last update [676bb64...251884f](https://codecov.io/gh/simonw/datasette/pull/883?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 648749062, "label": "Skip counting hidden tables"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/883#issuecomment-652297139", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/883", "id": 652297139, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjI5NzEzOQ==", "user": {"value": 3243482, "label": "abdusco"}, "created_at": "2020-07-01T09:11:29Z", "updated_at": "2020-07-01T09:11:29Z", "author_association": "CONTRIBUTOR", "body": "Turns out we should include hidden tables in the result dict, or we're breaking tests. I've committed a refactor https://github.com/simonw/datasette/pull/883/commits/4f06e1bf6fbe4b73be770b87f610bf7c0e6e3ea7", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 648749062, "label": "Skip counting hidden tables"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/877#issuecomment-652255960", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/877", "id": 652255960, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjI1NTk2MA==", "user": {"value": 3243482, "label": "abdusco"}, "created_at": "2020-07-01T07:52:25Z", "updated_at": "2020-07-01T08:10:00Z", "author_association": "CONTRIBUTOR", "body": "I am calling the API from another origin, so injecting CSRF token into templates wouldn't work.\r\n\r\nEDIT:\r\n\r\nI'll try the new version, it sounds promising", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 648421105, "label": "Consider dropping explicit CSRF protection entirely?"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/877#issuecomment-652261382", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/877", "id": 652261382, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjI2MTM4Mg==", "user": {"value": 3243482, "label": "abdusco"}, "created_at": "2020-07-01T08:03:17Z", "updated_at": "2020-07-01T08:03:23Z", "author_association": "CONTRIBUTOR", "body": "Bearer tokens sound interesting. Where do tokens come from? An auth provider of my choosing? How do they get verified?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 648421105, "label": "Consider dropping explicit CSRF protection entirely?"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/877#issuecomment-652182990", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/877", "id": 652182990, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjE4Mjk5MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-01T04:29:38Z", "updated_at": "2020-07-01T04:42:59Z", "author_association": "OWNER", "body": "Have you tried the method described here? https://datasette.readthedocs.io/en/latest/internals.html#csrf-protection - I'm happy to bulk out that section of the documentation if that doesn't help solve your problem.\r\n\r\nI just closed #835 which should make CSRF protection easier to work with - it won't interfere with requests without cookies or requests with `Authentication: Bearer token` tokens. See also https://github.com/simonw/asgi-csrf/issues/11\r\n\r\nYou can try out `pip install datasette==0.45a5` to get those features. Hopefully releasing a full 0.45 tomorrow.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 648421105, "label": "Consider dropping explicit CSRF protection entirely?"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/877#issuecomment-652166115", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/877", "id": 652166115, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjE2NjExNQ==", "user": {"value": 3243482, "label": "abdusco"}, "created_at": "2020-07-01T03:28:07Z", "updated_at": "2020-07-01T03:28:07Z", "author_association": "CONTRIBUTOR", "body": "Does this mean custom routes get to expose endpoints accepting POST requests? I've tried earlier to add some POST endpoints, but requests were being rejected by Datasette due to CSRF", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 648421105, "label": "Consider dropping explicit CSRF protection entirely?"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/812#issuecomment-652165709", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/812", "id": 652165709, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjE2NTcwOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-01T03:26:35Z", "updated_at": "2020-07-01T03:26:35Z", "author_association": "OWNER", "body": "This case may not be covered without extra work:\r\nhttps://github.com/simonw/datasette/blob/3ec5b1abf6afa2d22a3378092809a1a8c0249d26/datasette/views/database.py#L122-L123", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634112607, "label": "Ability to customize what happens when a view permission fails"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/812#issuecomment-652163450", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/812", "id": 652163450, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjE2MzQ1MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-01T03:18:51Z", "updated_at": "2020-07-01T03:20:28Z", "author_association": "OWNER", "body": "This can be a plugin hook:\r\n\r\n```python\r\n@hookspec\r\ndef forbidden(datasette, request, message, send):\r\n \"Custom response for a 403 forbidden error\"\r\n```\r\nIf the hook returns a `Response` object, it will be returned to the user. Plugins are likely to want to return a redirect response.\r\n\r\nMaybe the hook can instead use the `send` argument to respond to the request and return `True` which means \"I've responded to this\"?\r\n\r\nI'm going to leave `send` off for the moment - I can add that in the future if it turns out it would have been a good idea.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 634112607, "label": "Ability to customize what happens when a view permission fails"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/880#issuecomment-652162722", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/880", "id": 652162722, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjE2MjcyMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-01T03:16:07Z", "updated_at": "2020-07-01T03:16:07Z", "author_association": "OWNER", "body": "The response from this will never be a 302 - it will always be a 200 if the response worked or a 400 for bad parameters or a 500 for errors. The body returned will always be in JSON format.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 648637666, "label": "POST to /db/canned-query that returns JSON should be supported (for API clients)"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/859#issuecomment-652160909", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/859", "id": 652160909, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjE2MDkwOQ==", "user": {"value": 3243482, "label": "abdusco"}, "created_at": "2020-07-01T03:09:32Z", "updated_at": "2020-07-01T03:10:21Z", "author_association": "CONTRIBUTOR", "body": "I've just realized Datasette tries to count hidden tables too. There are 5 visible tables, 25 hidden tables, which I haven't realize earlier to consider their effect. I've turned off counting for hidden tables to see if it has any effect.\r\n\r\nWhat's the point of counting FTS tables?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 642572841, "label": "Database page loads too slowly with many large tables (due to table counts)"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/835#issuecomment-652159398", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/835", "id": 652159398, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjE1OTM5OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-07-01T03:03:51Z", "updated_at": "2020-07-01T03:03:51Z", "author_association": "OWNER", "body": "I'm going to add some tests for this.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637363686, "label": "Mechanism for skipping CSRF checks on API posts"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/876#issuecomment-652106227", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/876", "id": 652106227, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjEwNjIyNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-30T23:49:55Z", "updated_at": "2020-06-30T23:50:04Z", "author_association": "OWNER", "body": "Done: https://latest.datasette.io/-/patterns\r\n\r\n\"Datasette__Pattern_Portfolio\"", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 647879783, "label": "Add log out link to the pattern portfolio"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/879#issuecomment-652105722", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/879", "id": 652105722, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjEwNTcyMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-30T23:48:06Z", "updated_at": "2020-06-30T23:48:06Z", "author_association": "OWNER", "body": "Updated documentation: https://datasette.readthedocs.io/en/latest/pages.html", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 648569227, "label": "Database page documentation still talks about hashes in URLs"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/832#issuecomment-652103895", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/832", "id": 652103895, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MjEwMzg5NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-30T23:41:22Z", "updated_at": "2020-06-30T23:41:22Z", "author_association": "OWNER", "body": "I don't think this needs any additional documentation - the new behaviour matches how the permissions are documented here: https://datasette.readthedocs.io/en/0.44/authentication.html#built-in-permissions", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636722501, "label": "Having view-table permission but NOT view-database should still grant access to /db/table"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/832#issuecomment-651999516", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/832", "id": 651999516, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MTk5OTUxNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-30T19:33:49Z", "updated_at": "2020-06-30T21:34:59Z", "author_association": "OWNER", "body": "Tests needed for this:\r\n\r\n- If a user has view table but NOT view database / view instance, can they view the table page?\r\n- If a user has view canned query but NOT view database / view instance, can they view the canned query page?\r\n- If a user has view database but NOT view instance, can they view the database page?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636722501, "label": "Having view-table permission but NOT view-database should still grant access to /db/table"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/832#issuecomment-651995453", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/832", "id": 651995453, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MTk5NTQ1Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-30T19:25:13Z", "updated_at": "2020-06-30T19:25:26Z", "author_association": "OWNER", "body": "I'm going to put the new `check_permissions()` method on `BaseView` as well. If I want that method to be available to plugins I can do so by turning that `BaseView` class into a documented API that plugins are encouraged to use themselves.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636722501, "label": "Having view-table permission but NOT view-database should still grant access to /db/table"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/832#issuecomment-651994978", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/832", "id": 651994978, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MTk5NDk3OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-30T19:24:12Z", "updated_at": "2020-06-30T19:24:12Z", "author_association": "OWNER", "body": "Hah... but check_permission` is a method on `BaseView`. Here are the various permission methods at the moment:\r\n\r\nhttps://github.com/simonw/datasette/blob/6c2634583627bfab750c115cb13850252821d637/datasette/default_permissions.py#L5-L14\r\n\r\nAnd on BaseView:\r\n\r\nhttps://github.com/simonw/datasette/blob/a8a5f813722f72703a7aae41135ccc40635cc02f/datasette/views/base.py#L65-L70", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636722501, "label": "Having view-table permission but NOT view-database should still grant access to /db/table"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/832#issuecomment-651993977", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/832", "id": 651993977, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MTk5Mzk3Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-30T19:22:06Z", "updated_at": "2020-06-30T19:22:06Z", "author_association": "OWNER", "body": "`permission_allowed` is already the name of the pugin hook. It's actually a bit confusing that it's also the name of a method on `datasette.`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636722501, "label": "Having view-table permission but NOT view-database should still grant access to /db/table"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/832#issuecomment-651993537", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/832", "id": 651993537, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MTk5MzUzNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-30T19:21:15Z", "updated_at": "2020-06-30T19:21:15Z", "author_association": "OWNER", "body": "I could rename `permission_allowed()` to `check_permission()` and have a complementary `check_permissions()` method.\r\n\r\nThis is a breaking change but we're pre-1.0 so I think that's OK. I could even set up a temporary `permission_allowed()` alias which prints a deprecation warning to the console, then remove that at 1.0.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636722501, "label": "Having view-table permission but NOT view-database should still grant access to /db/table"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/832#issuecomment-651992737", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/832", "id": 651992737, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MTk5MjczNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-30T19:19:33Z", "updated_at": "2020-06-30T19:20:02Z", "author_association": "OWNER", "body": "I already have this method on Datasette:\r\n```python\r\nasync def permission_allowed(self, actor, action, resource=None, default=False):\r\n```\r\nWhat would be a good method name that complements that and indicates \"check a list of permissions in order\"? Should it even run against the request or should you have to hand it `request.actor`?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 636722501, "label": "Having view-table permission but NOT view-database should still grant access to /db/table"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/877#issuecomment-651984989", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/877", "id": 651984989, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MTk4NDk4OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-30T19:03:25Z", "updated_at": "2020-06-30T19:03:25Z", "author_association": "OWNER", "body": "Relevant: #835", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 648421105, "label": "Consider dropping explicit CSRF protection entirely?"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/877#issuecomment-651984355", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/877", "id": 651984355, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MTk4NDM1NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-30T19:02:15Z", "updated_at": "2020-06-30T19:02:15Z", "author_association": "OWNER", "body": "https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#login-csrf\r\n\r\n> Login CSRF can be mitigated by creating pre-sessions (sessions before a user is authenticated) and including tokens in login form.\r\n\r\nSounds like regular CSRF protection to me.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 648421105, "label": "Consider dropping explicit CSRF protection entirely?"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/805#issuecomment-651302221", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/805", "id": 651302221, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MTMwMjIyMQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T19:02:45Z", "updated_at": "2020-06-29T19:05:26Z", "author_association": "OWNER", "body": "No I prefer the idea that logged out users can still perform some writes, in a not-likely-to-attract-abuse way.\r\n\r\nSo a root-user-can-configure-polls, logged-out-users-can-vote-in-them demo would be good.\r\n\r\nOr... crazy idea: a collaborative drawing program? A grid of cells of emoji, anyone can add an emoji to a cell. Would involve a bit of JavaScript. I could use https://github.com/joeattardi/emoji-button for this.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632724154, "label": "Writable canned queries live demo on Glitch"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/805#issuecomment-651301202", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/805", "id": 651301202, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MTMwMTIwMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T19:00:37Z", "updated_at": "2020-06-29T19:00:37Z", "author_association": "OWNER", "body": "How about a blog? Pre-configured canned queries that are only available to `\"root\"`, plus datasette-template-sql and default templates for the index page and blog entry pages.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632724154, "label": "Writable canned queries live demo on Glitch"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/875#issuecomment-651293559", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/875", "id": 651293559, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MTI5MzU1OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T18:43:50Z", "updated_at": "2020-06-29T18:43:50Z", "author_association": "OWNER", "body": "\"_memory_\"\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 647103735, "label": "\"Logged in as: XXX - logout\" navigation item"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/873#issuecomment-651203178", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/873", "id": 651203178, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MTIwMzE3OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T15:44:38Z", "updated_at": "2020-06-29T15:44:54Z", "author_association": "OWNER", "body": "I'm having real trouble figuring out how to gain access to the port that was used to start the server. I'm treating this as a very low priority - it only affects the exact `-p 0 --root` combination which isn't going to affect many people at all.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 647095487, "label": "\"datasette -p 0 --root\" gives the wrong URL"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/873#issuecomment-651193594", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/873", "id": 651193594, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MTE5MzU5NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T15:27:46Z", "updated_at": "2020-06-29T15:27:46Z", "author_association": "OWNER", "body": "Uninstalling `datasette-debug-asgi` caused the server to startup correctly again.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 647095487, "label": "\"datasette -p 0 --root\" gives the wrong URL"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/873#issuecomment-651193131", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/873", "id": 651193131, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MTE5MzEzMQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T15:27:00Z", "updated_at": "2020-06-29T15:27:00Z", "author_association": "OWNER", "body": "Aha! Yes it's not being called, and the reason is this: https://github.com/encode/starlette/issues/486\r\n\r\nShort version: by default an exception raised during that phase is silently swallowed! You can avoid the swallowing by adding `lifespan=\"on\"` to the call to `uvicorn.run()`.\r\n\r\nWhen I did that here:\r\n\r\n`uvicorn.run(ds.app(), host=host, port=port, log_level=\"info\", lifespan=\"on\")`\r\n\r\nThe server failed to start with this error:\r\n\r\n```\r\nINFO: Started server process [68849]\r\nINFO: Waiting for application startup.\r\nERROR: Exception in 'lifespan' protocol\r\nTraceback (most recent call last):\r\n File \".../uvicorn/lifespan/on.py\", line 48, in main\r\n await app(scope, self.receive, self.send)\r\n File \".../uvicorn/middleware/proxy_headers.py\", line 45, in __call__\r\n return await self.app(scope, receive, send)\r\n File \".../datasette_debug_asgi.py\", line 9, in wrapped_app\r\n if scope[\"path\"] == \"/-/asgi-scope\":\r\nKeyError: 'path'\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 647095487, "label": "\"datasette -p 0 --root\" gives the wrong URL"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/873#issuecomment-650910137", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/873", "id": 650910137, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDkxMDEzNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T05:16:32Z", "updated_at": "2020-06-29T05:16:32Z", "author_association": "OWNER", "body": "I'm not convinced that function is ever actually being called - I added a `print()` statement to it and it's not executing. I don't think the tests cover it.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 647095487, "label": "\"datasette -p 0 --root\" gives the wrong URL"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/873#issuecomment-650909476", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/873", "id": 650909476, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDkwOTQ3Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T05:14:08Z", "updated_at": "2020-06-29T05:14:08Z", "author_association": "OWNER", "body": "I already have a `AsgiLifespan` class:\r\nhttps://github.com/simonw/datasette/blob/35aee82c60b2c9a0185b934db5528c8bd11830f2/datasette/app.py#L896-L905\r\n\r\nIt runs this function: https://github.com/simonw/datasette/blob/35aee82c60b2c9a0185b934db5528c8bd11830f2/datasette/app.py#L890-L894\r\n\r\nCould that startup function also output the `--root` login URL, if needed?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 647095487, "label": "\"datasette -p 0 --root\" gives the wrong URL"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/873#issuecomment-650909136", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/873", "id": 650909136, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDkwOTEzNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T05:12:58Z", "updated_at": "2020-06-29T05:12:58Z", "author_association": "OWNER", "body": "On startup Datasette currently outputs:\r\n```\r\nINFO: Waiting for application startup.\r\nINFO: ASGI 'lifespan' protocol appears unsupported.\r\nINFO: Application startup complete.\r\n```\r\nSo the ASGI lifespan protocol is almost certainly the right way to solve this.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 647095487, "label": "\"datasette -p 0 --root\" gives the wrong URL"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/873#issuecomment-650908854", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/873", "id": 650908854, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDkwODg1NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T05:12:04Z", "updated_at": "2020-06-29T05:12:04Z", "author_association": "OWNER", "body": "Can I detect the port the server is running on from within the regular Datasette ASGI code? If so I could use that ability and maybe output the magic `--root` link a second after the server starts up somehow.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 647095487, "label": "\"datasette -p 0 --root\" gives the wrong URL"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/873#issuecomment-650908534", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/873", "id": 650908534, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDkwODUzNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T05:11:06Z", "updated_at": "2020-06-29T05:11:06Z", "author_association": "OWNER", "body": "Uvicorn's lifespan stuff isn't easy to figure out, but this test suite holds some clues: https://github.com/encode/uvicorn/blob/master/tests/test_lifespan.py", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 647095487, "label": "\"datasette -p 0 --root\" gives the wrong URL"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/873#issuecomment-650907323", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/873", "id": 650907323, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDkwNzMyMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T05:07:16Z", "updated_at": "2020-06-29T05:07:16Z", "author_association": "OWNER", "body": "This line is interesting: is this a hook I can attach to somehow?\r\n```python\r\n await self.lifespan.startup()\r\n```\r\nFrom https://github.com/encode/uvicorn/blob/a75fe1381f6b1f78901691c71894f3cf487b5d30/uvicorn/main.py#L475", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 647095487, "label": "\"datasette -p 0 --root\" gives the wrong URL"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/873#issuecomment-650906533", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/873", "id": 650906533, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDkwNjUzMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T05:04:44Z", "updated_at": "2020-06-29T05:04:44Z", "author_association": "OWNER", "body": "The challenge is... can we run our own custom code after that line has executed that has access to `server` and can hence access `server.servers[0].sockets[0].getsockname()[1]` to find the port?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 647095487, "label": "\"datasette -p 0 --root\" gives the wrong URL"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/873#issuecomment-650906318", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/873", "id": 650906318, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDkwNjMxOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T05:04:04Z", "updated_at": "2020-06-29T05:04:12Z", "author_association": "OWNER", "body": "Within uvicorn it does this:\r\n```python\r\n if port == 0:\r\n port = server.sockets[0].getsockname()[1]\r\n```\r\nThat `server` variable is later stashed here:\r\n```\r\nself.servers = [server]\r\n```\r\nWhere `self` is the instance of `class Server` - which is the class that Uvicorn instantiates and calls `.run()` on when we do `uvicorn.run()` here: https://github.com/simonw/datasette/blob/35aee82c60b2c9a0185b934db5528c8bd11830f2/datasette/cli.py#L409", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 647095487, "label": "\"datasette -p 0 --root\" gives the wrong URL"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/873#issuecomment-650905399", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/873", "id": 650905399, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDkwNTM5OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T05:01:03Z", "updated_at": "2020-06-29T05:01:03Z", "author_association": "OWNER", "body": "This is a bit tricky to fix. This change to uvicorn is relevant: https://github.com/encode/uvicorn/commit/a75fe1381f6b1f78901691c71894f3cf487b5d30", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 647095487, "label": "\"datasette -p 0 --root\" gives the wrong URL"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/875#issuecomment-650899265", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/875", "id": 650899265, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDg5OTI2NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T04:34:32Z", "updated_at": "2020-06-29T04:34:32Z", "author_association": "OWNER", "body": "From https://github.com/simonw/datasette/issues/840#issuecomment-643454625\r\n> Another problem: what to display in the \"you are logged in as\", since we don't dictate an actor design.\r\n> \r\n> I'm going to use a includes template for this that can easily be over-ridden by administrators or by plugins.\r\n> \r\n> The default will look for the first available of the following keys:\r\n> \r\n> * display\r\n> * name\r\n> * username\r\n> * login\r\n> * id", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 647103735, "label": "\"Logged in as: XXX - logout\" navigation item"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/875#issuecomment-650898808", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/875", "id": 650898808, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDg5ODgwOA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T04:32:31Z", "updated_at": "2020-06-29T04:33:30Z", "author_association": "OWNER", "body": "I could borrow the implementation for this from `datasette-auth-github`\r\nhttps://github.com/simonw/datasette-auth-github/blob/182298b034ecb647971b65057d1d3e7b7fbbb482/datasette_auth_github/templates/base.html\r\n```html+jinja\r\n{% extends \"default:base.html\" %}\r\n\r\n{% block extra_head %}\r\n\r\n{% endblock %}\r\n\r\n{% block nav %}\r\n {{ super() }}\r\n {% if auth and auth.username %}\r\n

\r\n {{ auth.username }} · Log out\r\n

\r\n {% endif %}\r\n{% endblock %}\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 647103735, "label": "\"Logged in as: XXX - logout\" navigation item"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/840#issuecomment-650895874", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/840", "id": 650895874, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDg5NTg3NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T04:18:59Z", "updated_at": "2020-06-29T04:19:11Z", "author_association": "OWNER", "body": "Now just need the \"Logged in as: XXX <logout>\" navigation item.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637966833, "label": "Log out mechanism for clearing ds_actor cookie"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/840#issuecomment-650891502", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/840", "id": 650891502, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDg5MTUwMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T03:58:08Z", "updated_at": "2020-06-29T03:58:08Z", "author_association": "OWNER", "body": "Step one: a \"logout\" page at `/-/logout` - which shows you a single CSRF-protected \"logout\" button if you do a GET against it and logs you out if you do a POST against it.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637966833, "label": "Log out mechanism for clearing ds_actor cookie"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/805#issuecomment-650891257", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/805", "id": 650891257, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDg5MTI1Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T03:56:48Z", "updated_at": "2020-06-29T03:56:48Z", "author_association": "OWNER", "body": "Using `datasette-glitch` and the new https://github.com/simonw/datasette-write - currently running on `datasette==0.45a4` - works on Glitch. The console shows a login link which gives you a cookie which allows you access to the `/-/write` interface.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632724154, "label": "Writable canned queries live demo on Glitch"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/864#issuecomment-650847013", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/864", "id": 650847013, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDg0NzAxMw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T00:41:55Z", "updated_at": "2020-06-29T00:41:55Z", "author_association": "OWNER", "body": "To test this I'll need a plugin test that renders a custom template. Here's an example I can imitate: https://github.com/simonw/datasette/blob/7ac4936cec87f5a591e5d2680f0acefc3d35a705/tests/test_plugins.py#L588-L596", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 644309017, "label": "datasette.add_message() doesn't work inside plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/864#issuecomment-650846625", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/864", "id": 650846625, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDg0NjYyNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T00:39:47Z", "updated_at": "2020-06-29T00:39:47Z", "author_association": "OWNER", "body": "I think the fix is to move the `\"show_messages\"` variable to here:\r\n\r\nhttps://github.com/simonw/datasette/blob/7ac4936cec87f5a591e5d2680f0acefc3d35a705/datasette/app.py#L735-L748", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 644309017, "label": "datasette.add_message() doesn't work inside plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/864#issuecomment-650846473", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/864", "id": 650846473, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDg0NjQ3Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T00:39:04Z", "updated_at": "2020-06-29T00:39:04Z", "author_association": "OWNER", "body": "Re-opening: plugins may get to set messages but they don't display them, even if they render a template that extends `base.html`. For example, this code in a plugin:\r\n```python\r\n return Response.html(\r\n await datasette.render_template(\r\n \"write.html\",\r\n {\"databases\": databases, \"sql\": request.args.get(\"sql\") or \"\"},\r\n request=request,\r\n )\r\n )\r\n```\r\nThis won't display messages. The reason is that the messages are made available to the template context in the `BaseView.render()` method here:\r\nhttps://github.com/simonw/datasette/blob/7ac4936cec87f5a591e5d2680f0acefc3d35a705/datasette/views/base.py#L87-L95", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 644309017, "label": "datasette.add_message() doesn't work inside plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/864#issuecomment-650842514", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/864", "id": 650842514, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDg0MjUxNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T00:12:59Z", "updated_at": "2020-06-29T00:12:59Z", "author_association": "OWNER", "body": "> I've made enough progress on this to be able to solve the messages issue in #864. I may still complete this overall goal (registering internal views with `register_routes()`) as part of Datasette 0.45 but it would be OK if it slipped to a later release.\r\nhttps://github.com/simonw/datasette/issues/870#issuecomment-650842381", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 644309017, "label": "datasette.add_message() doesn't work inside plugins"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/870#issuecomment-650842381", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/870", "id": 650842381, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDg0MjM4MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-29T00:12:07Z", "updated_at": "2020-06-29T00:12:07Z", "author_association": "OWNER", "body": "I've made enough progress on this to be able to solve the messages issue in #864. I may still complete this overall goal (registering internal views with `register_routes()`) as part of Datasette 0.45 but it would be OK if it slipped to a later release.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 646737558, "label": "Refactor default views to use register_routes"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/870#issuecomment-650838972", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/870", "id": 650838972, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDgzODk3Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-28T23:46:40Z", "updated_at": "2020-06-28T23:46:40Z", "author_association": "OWNER", "body": "I'm going to create the single `Request()` instance in the `DatasetteRouter` class - at the beginning of the `route_path` method: https://github.com/simonw/datasette/blob/3bc2461c77ecba3e1a95301dd440a9bef56b1283/datasette/app.py#L905-L925", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 646737558, "label": "Refactor default views to use register_routes"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/870#issuecomment-650838691", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/870", "id": 650838691, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDgzODY5MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-28T23:44:12Z", "updated_at": "2020-06-28T23:44:25Z", "author_association": "OWNER", "body": "This code is interesting:\r\n\r\nhttps://github.com/simonw/datasette/blob/3bc2461c77ecba3e1a95301dd440a9bef56b1283/datasette/app.py#L948-L955\r\n\r\nI want to change the signature of that `return await view(new_scope, receive, send)` method to instead take `(request, send)` - so I can have a single shared request object that's created just once per HTTP request.\r\n\r\nThe problem is the scope modification: I have code that modifies the scope, but how should that impact a shared `Request` instance? Should its `.scope` be replaced with alternative scopes as it travels through the codebase?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 646737558, "label": "Refactor default views to use register_routes"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/870#issuecomment-650834666", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/870", "id": 650834666, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDgzNDY2Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-28T23:07:19Z", "updated_at": "2020-06-28T23:07:19Z", "author_association": "OWNER", "body": "So now the problem is simpler: I need to get `BaseView` to a state where it can accept a shared `request` object and it can be used in conjunction with `register_routes()`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 646737558, "label": "Refactor default views to use register_routes"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/870#issuecomment-650834251", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/870", "id": 650834251, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDgzNDI1MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-28T23:03:28Z", "updated_at": "2020-06-28T23:03:28Z", "author_association": "OWNER", "body": "I'm going to ditch that `AsgiView` class too, by combining it into `BaseView`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 646737558, "label": "Refactor default views to use register_routes"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/870#issuecomment-650820068", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/870", "id": 650820068, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDgyMDA2OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-28T20:52:09Z", "updated_at": "2020-06-28T20:53:00Z", "author_association": "OWNER", "body": "Maybe I could add a `as_request_view` method as an alternative to `as_asgi`:\r\n\r\nhttps://github.com/simonw/datasette/blob/a8bcafc1775c8a8655b365ae22a3d64f6361c74a/datasette/utils/asgi.py#L150-L174\r\n\r\nOr I could teach the `Router` to spot the `dispatch_request` method and call it directly.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 646737558, "label": "Refactor default views to use register_routes"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/847#issuecomment-650819895", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/847", "id": 650819895, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDgxOTg5NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-28T20:50:21Z", "updated_at": "2020-06-28T20:50:21Z", "author_association": "OWNER", "body": "I'm happy enough with https://codecov.io/gh/simonw/datasette that I'm not going to spend any more time on this.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638259643, "label": "Take advantage of .coverage being a SQLite database"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/870#issuecomment-650818309", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/870", "id": 650818309, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDgxODMwOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-28T20:36:28Z", "updated_at": "2020-06-28T20:36:52Z", "author_association": "OWNER", "body": "Since `AsgiRouter` is only used as the super-class of the `DatasetteRouter` class maybe I should get rid of `AsgiRouter` entirely - no point in having a Datasette-specific subclass of it if the parent class isn't ever used by anything else.\r\n\r\nI could also rename it to just `Router` which is a nicer name than `DatasetteRouter`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 646737558, "label": "Refactor default views to use register_routes"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/870#issuecomment-650818086", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/870", "id": 650818086, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDgxODA4Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-28T20:34:33Z", "updated_at": "2020-06-28T20:34:33Z", "author_association": "OWNER", "body": "The key to all of this may be the `DatasetteRouter` class. It deals with `scope` right now but if it internally dealt with `request` that could be enough to fix #864 by adding logic needed by the `.add_message()` mechanism.\r\n\r\nhttps://github.com/simonw/datasette/blob/0991ea75cc7b265389aa8362414a305ba532d31a/datasette/app.py#L904-L938", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 646737558, "label": "Refactor default views to use register_routes"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/870#issuecomment-650815278", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/870", "id": 650815278, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDgxNTI3OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-28T20:09:07Z", "updated_at": "2020-06-28T20:11:21Z", "author_association": "OWNER", "body": "There's a lot of complex logic in the `DataView` class, which handles conditionally returning content as `.json` or as HTML or as `.csv`.\r\n\r\nThat view subclasses `AsgiView` which is itself request-aware, so maybe I don't need to reconsider how those classes work - just figure out how to hook them up with `register_routes`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 646737558, "label": "Refactor default views to use register_routes"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/871#issuecomment-650812444", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/871", "id": 650812444, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDgxMjQ0NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-28T19:43:27Z", "updated_at": "2020-06-28T19:43:27Z", "author_association": "OWNER", "body": "Currently:\r\n\r\n> `_timestamp_epoch`\r\n> \r\n> The number of seconds since the Unix epoch.\r\n> \r\n> `_timestamp_date_utc`\r\n> \r\n> The date in UTC, e.g. `2020-06-01`\r\n> \r\n> `_timestamp_datetime_utc`\r\n> \r\n> The ISO 8601 datetime in UTC, e.g. `2020-06-24T18:01:07Z`\r\n\r\nI'm going to rename them to:\r\n\r\n- `_now_epoch`\r\n- `_now_date_utc`\r\n- `_now_datetime_utc`", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 646840273, "label": "Rename the _timestamp magic parameters to _now"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/834#issuecomment-650811919", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/834", "id": 650811919, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDgxMTkxOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-28T19:38:50Z", "updated_at": "2020-06-28T19:38:50Z", "author_association": "OWNER", "body": "I have two plugins in progress that use this hook now:\r\n\r\n- https://github.com/simonw/datasette-init creates tables and views on startup\r\n- https://github.com/simonw/datasette-glitch outputs the login-as-root secret link on Glitch", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637342551, "label": "startup() plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/805#issuecomment-650784162", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/805", "id": 650784162, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDc4NDE2Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-28T15:48:32Z", "updated_at": "2020-06-28T15:48:32Z", "author_association": "OWNER", "body": "https://github.com/simonw/datasette-glitch is my new plugin that outputs the root login link on Glitch when the server starts.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632724154, "label": "Writable canned queries live demo on Glitch"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/834#issuecomment-643657067", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/834", "id": 643657067, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MzY1NzA2Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-13T17:59:42Z", "updated_at": "2020-06-28T04:01:52Z", "author_association": "OWNER", "body": "Documentation: https://datasette.readthedocs.io/en/latest/plugin_hooks.html#startup-datasette", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637342551, "label": "startup() plugin hook"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/842#issuecomment-650684635", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/842", "id": 650684635, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDY4NDYzNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-28T03:30:31Z", "updated_at": "2020-06-28T03:30:31Z", "author_association": "OWNER", "body": "Live demo: https://latest.datasette.io/fixtures/magic_parameters", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638212085, "label": "Magic parameters for canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/805#issuecomment-650681496", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/805", "id": 650681496, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDY4MTQ5Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-28T03:11:51Z", "updated_at": "2020-06-28T03:11:51Z", "author_association": "OWNER", "body": "I can use magic parameters from #842 in this.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 632724154, "label": "Writable canned queries live demo on Glitch"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/842#issuecomment-650679100", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/842", "id": 650679100, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDY3OTEwMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-28T03:00:44Z", "updated_at": "2020-06-28T03:00:44Z", "author_association": "OWNER", "body": "I'm going to add some canned queries to the `metadata.json` used by the live demo that illustrate this feature.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638212085, "label": "Magic parameters for canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/842#issuecomment-650678951", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/842", "id": 650678951, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDY3ODk1MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-28T02:59:52Z", "updated_at": "2020-06-28T02:59:52Z", "author_association": "OWNER", "body": "Documentation: https://datasette.readthedocs.io/en/latest/sql_queries.html#magic-parameters\r\n\r\nPlugin hook documentation: https://datasette.readthedocs.io/en/latest/plugin_hooks.html#plugin-hook-register-magic-parameters", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638212085, "label": "Magic parameters for canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/869#issuecomment-650600176", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/869", "id": 650600176, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDYwMDE3Ng==", "user": {"value": 22429695, "label": "codecov[bot]"}, "created_at": "2020-06-27T18:41:31Z", "updated_at": "2020-06-28T02:54:21Z", "author_association": "NONE", "body": "# [Codecov](https://codecov.io/gh/simonw/datasette/pull/869?src=pr&el=h1) Report\n> Merging [#869](https://codecov.io/gh/simonw/datasette/pull/869?src=pr&el=desc) into [master](https://codecov.io/gh/simonw/datasette/commit/1bb33dab49fd25f77b9f8e7ab7ee23b3d64c123c&el=desc) will **increase** coverage by `0.23%`.\n> The diff coverage is `90.62%`.\n\n[![Impacted file tree graph](https://codecov.io/gh/simonw/datasette/pull/869/graphs/tree.svg?width=650&height=150&src=pr&token=eSahVY7kw1)](https://codecov.io/gh/simonw/datasette/pull/869?src=pr&el=tree)\n\n```diff\n@@ Coverage Diff @@\n## master #869 +/- ##\n==========================================\n+ Coverage 82.99% 83.23% +0.23% \n==========================================\n Files 26 27 +1 \n Lines 3547 3609 +62 \n==========================================\n+ Hits 2944 3004 +60 \n- Misses 603 605 +2 \n```\n\n\n| [Impacted Files](https://codecov.io/gh/simonw/datasette/pull/869?src=pr&el=tree) | Coverage \u0394 | |\n|---|---|---|\n| [datasette/plugins.py](https://codecov.io/gh/simonw/datasette/pull/869/diff?src=pr&el=tree#diff-ZGF0YXNldHRlL3BsdWdpbnMucHk=) | `82.35% <\u00f8> (\u00f8)` | |\n| [datasette/views/database.py](https://codecov.io/gh/simonw/datasette/pull/869/diff?src=pr&el=tree#diff-ZGF0YXNldHRlL3ZpZXdzL2RhdGFiYXNlLnB5) | `96.45% <86.36%> (-1.88%)` | :arrow_down: |\n| [datasette/default\\_magic\\_parameters.py](https://codecov.io/gh/simonw/datasette/pull/869/diff?src=pr&el=tree#diff-ZGF0YXNldHRlL2RlZmF1bHRfbWFnaWNfcGFyYW1ldGVycy5weQ==) | `91.17% <91.17%> (\u00f8)` | |\n| [datasette/app.py](https://codecov.io/gh/simonw/datasette/pull/869/diff?src=pr&el=tree#diff-ZGF0YXNldHRlL2FwcC5weQ==) | `96.07% <100.00%> (+0.81%)` | :arrow_up: |\n| [datasette/hookspecs.py](https://codecov.io/gh/simonw/datasette/pull/869/diff?src=pr&el=tree#diff-ZGF0YXNldHRlL2hvb2tzcGVjcy5weQ==) | `100.00% <100.00%> (\u00f8)` | |\n| [datasette/utils/\\_\\_init\\_\\_.py](https://codecov.io/gh/simonw/datasette/pull/869/diff?src=pr&el=tree#diff-ZGF0YXNldHRlL3V0aWxzL19faW5pdF9fLnB5) | `93.87% <100.00%> (+0.02%)` | :arrow_up: |\n\n------\n\n[Continue to review full report at Codecov](https://codecov.io/gh/simonw/datasette/pull/869?src=pr&el=continue).\n> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)\n> `\u0394 = absolute (impact)`, `\u00f8 = not affected`, `? = missing data`\n> Powered by [Codecov](https://codecov.io/gh/simonw/datasette/pull/869?src=pr&el=footer). Last update [1bb33da...9e693a7](https://codecov.io/gh/simonw/datasette/pull/869?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 646734280, "label": "Magic parameters for canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/842#issuecomment-650648434", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/842", "id": 650648434, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDY0ODQzNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-27T23:27:35Z", "updated_at": "2020-06-27T23:37:38Z", "author_association": "OWNER", "body": "I'm going to rename `_request_X` to `_header_X` as that better reflects what it now does.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638212085, "label": "Magic parameters for canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/868#issuecomment-650600606", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/868", "id": 650600606, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDYwMDYwNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-27T18:44:28Z", "updated_at": "2020-06-27T18:44:28Z", "author_association": "OWNER", "body": "This is really exciting! Thanks so much for looking into this.\r\n\r\nI'm interested in moving CI for this repo over to GitHub Actions, so I'd be fine with you getting this to work as an Action rather than through Travis. If you can get it working in Travis though I'll happily land that and figure out how to convert that to GitHub Actions later on.", "reactions": "{\"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 646448486, "label": "initial windows ci setup"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/835#issuecomment-650598710", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/835", "id": 650598710, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDU5ODcxMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-27T18:32:22Z", "updated_at": "2020-06-27T18:32:22Z", "author_association": "OWNER", "body": "Skipping CSRF on `Authorization: Bearer xxx` headers also makes sense for JWT applications, which tend to send JWTs using that form of header.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 637363686, "label": "Mechanism for skipping CSRF checks on API posts"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/842#issuecomment-650593122", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/842", "id": 650593122, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDU5MzEyMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-27T18:03:02Z", "updated_at": "2020-06-27T18:03:10Z", "author_association": "OWNER", "body": "> Security thought: make sure it's not possible to accidentally open up a security hole where an attacker can send a GET request that causes the magic parameter `_cookie_ds_actor` to be resolved and returned as JSON data that the attacker can see.\r\n\r\nThis is an open security hole in https://github.com/simonw/datasette/commit/94c1315f0030fd58ce46a9294052c5c9d9d181c7 - it's useful for testing, but I need to remove it before I land that branch.\r\n\r\nhttps://github.com/simonw/datasette/blob/94c1315f0030fd58ce46a9294052c5c9d9d181c7/datasette/views/database.py#L231-L237\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638212085, "label": "Magic parameters for canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/842#issuecomment-650458857", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/842", "id": 650458857, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDQ1ODg1Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-27T00:11:04Z", "updated_at": "2020-06-27T00:11:04Z", "author_association": "OWNER", "body": "Security thought: make sure it's not possible to accidentally open up a security hole where an attacker can send a GET request that causes the magic parameter `_cookie_ds_actor` to be resolved and returned as JSON data that the attacker can see.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638212085, "label": "Magic parameters for canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/842#issuecomment-650455793", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/842", "id": 650455793, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDQ1NTc5Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-26T23:57:30Z", "updated_at": "2020-06-27T00:00:16Z", "author_association": "OWNER", "body": "Maybe I should ship a default `_scope_headers_...` parameter instead, which reads from a dictionary of `scope[\"headers\"]` - https://asgi-scope.now.sh/ shows what those look like.\r\n\r\n```\r\n{'client': ('148.64.98.14', 0),\r\n 'headers': [[b'host', b'asgi-scope.now.sh'],\r\n [b'x-forwarded-for', b'148.64.98.14'],\r\n [b'x-vercel-id', b'sw72x-1593215573008-024e4e603806'],\r\n [b'x-forwarded-host', b'asgi-scope.now.sh'],\r\n [b'accept',\r\n b'text/html,application/xhtml+xml,application/xml;q=0.9,image/'\r\n b'webp,*/*;q=0.8'],\r\n [b'x-real-ip', b'148.64.98.14'],\r\n [b'x-vercel-deployment-url', b'asgi-scope-9eyeojbek.now.sh'],\r\n [b'upgrade-insecure-requests', b'1'],\r\n [b'x-vercel-trace', b'sfo1'],\r\n [b'x-forwarded-proto', b'https'],\r\n [b'accept-language', b'en-US,en;q=0.5'],\r\n [b'user-agent',\r\n b'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:77.0) Gecko'\r\n b'/20100101 Firefox/77.0'],\r\n [b'x-vercel-forwarded-for', b'148.64.98.14'],\r\n [b'accept-encoding', b'gzip, deflate, br'],\r\n [b'dnt', b'1'],\r\n [b'te', b'trailers']],\r\n 'http_version': '1.1',\r\n 'method': 'GET',\r\n 'path': '/',\r\n 'query_string': b'',\r\n 'raw_path': b'/',\r\n 'root_path': '',\r\n 'scheme': 'https',\r\n 'server': ('asgi-scope.now.sh', 80),\r\n 'type': 'http'}\r\n```\r\n\r\nI'm going to have `_request_X` actually mean \"find the first value for X in `scope[\"headers\"`]\" - with underscores converted to hyphens.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638212085, "label": "Magic parameters for canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/842#issuecomment-650455353", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/842", "id": 650455353, "node_id": "MDEyOklzc3VlQ29tbWVudDY1MDQ1NTM1Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-26T23:55:40Z", "updated_at": "2020-06-26T23:55:40Z", "author_association": "OWNER", "body": "`_request_ip` is actually quite hard to implement - should it take into account things like the `x-forwarded-for` header?\r\n\r\nIt probably should - but that means it now needs a bunch of extra configuration to tell it which of those headers can be trusted in the current environment.\r\n\r\nAs such I think I'll leave that for a plugin.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 638212085, "label": "Magic parameters for canned queries"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/867#issuecomment-649931714", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/867", "id": 649931714, "node_id": "MDEyOklzc3VlQ29tbWVudDY0OTkzMTcxNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-06-26T03:12:51Z", "updated_at": "2020-06-26T03:12:51Z", "author_association": "OWNER", "body": "Here's the relevant code:\r\nhttps://github.com/simonw/datasette/blob/1bb33dab49fd25f77b9f8e7ab7ee23b3d64c123c/datasette/app.py#L1057-L1070\r\nAnd the relevant test code:\r\nhttps://github.com/simonw/datasette/blob/1bb33dab49fd25f77b9f8e7ab7ee23b3d64c123c/tests/test_plugins.py#L567-L573\r\n\r\nhttps://github.com/simonw/datasette/blob/1bb33dab49fd25f77b9f8e7ab7ee23b3d64c123c/tests/plugins/my_plugin.py#L162-L196", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 645975649, "label": "register_routes() should support non-async view functions too"}, "performed_via_github_app": null}