{"id": 684961449, "node_id": "MDU6SXNzdWU2ODQ5NjE0NDk=", "number": 949, "title": "Try out CodeMirror SQL hints", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 5, "created_at": "2020-08-24T20:58:21Z", "updated_at": "2023-11-03T05:28:58Z", "closed_at": "2020-11-01T03:29:48Z", "author_association": "OWNER", "pull_request": null, "body": "> It would also be interesting to try out the SQL hint mode, which can autocomplete against tables and columns. This demo shows how to configure that: https://codemirror.net/mode/sql/\r\n> \r\n> Some missing documentation: https://stackoverflow.com/questions/20023381/codemirror-how-add-tables-to-sql-hint\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/948#issuecomment-679355426_", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/949/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 410384988, "node_id": "MDU6SXNzdWU0MTAzODQ5ODg=", "number": 411, "title": "How to pass named parameter into spatialite MakePoint() function", "user": {"value": 1055831, "label": "dazzag24"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2019-02-14T16:30:22Z", "updated_at": "2023-10-25T13:23:04Z", "closed_at": "2019-05-05T12:25:04Z", "author_association": "NONE", "pull_request": null, "body": "Hi,\r\ndatasette version: \"0.26.2\"\r\nextensions: \r\n spatialite: \"4.4.0-RC0\"\r\nsqlite version: \"3.22.0\"\r\n\r\nI have a table of airports with latitude and longitude columns. I've added spatialite (with KNN support). After creating the db using csvs-to-sqlit, I run these commands to setup the spatialite tables:\r\n\r\n```\r\nconn.execute('SELECT InitSpatialMetadata(1)')\r\n\r\nconn.execute(\"SELECT AddGeometryColumn('airports', 'point_geom', 4326, 'POINT', 2);\")\r\n\r\nconn.execute('''UPDATE airports SET point_geom = GeomFromText('POINT('||\"longitude\"||' '||\"latitude\"||')',4326);''')\r\n\r\nconn.execute(\"SELECT CreateSpatialIndex('airports', 'point_geom');\")\r\n```\r\n\r\nI'm attempting to create a canned query and have this in my metadata.json file:\r\n```\r\n\"find_airports_nearest_to_point\":{\r\n \"sql\":\"SELECT a.pos AS rank, b.id, b.name, b.country, b.latitude AS latitude, b.longitude AS longitude, a.distance / 1000.0 AS dist_km FROM KNN AS a JOIN airports AS b ON (b.rowid = a.fid) WHERE f_table_name = \\\"airports\\\" AND ref_geometry = MakePoint( :Long , :Lat ) AND max_items = 10;\"}\r\n```\r\nwhich doesn't seem to perform the templating of the name parameters correctly and I get no results. \r\n\r\nHave also tired:\r\n```\r\nMakePoint( || :Long || , || :Lat || )\r\n```\r\nwhich returns this error:\r\n```\r\nnear \"||\": syntax error\r\n```\r\n\r\nHowever I cannot seem to find the correct combination of named parameter syntax (:Lat) or sqlite concatenation operator to make it work. Any ideas if using named parameters inside functions is supported?\r\n\r\nThanks\r\nDarren", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/411/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1910269679, "node_id": "I_kwDOBm6k_c5x3Gbv", "number": 2196, "title": "Discord invite link returns 401", "user": {"value": 1892194, "label": "Olshansk"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2023-09-24T15:16:54Z", "updated_at": "2023-10-13T00:07:08Z", "closed_at": "2023-10-12T21:54:54Z", "author_association": "NONE", "pull_request": null, "body": "I found the link to the datasette discord channel via [this query](https://github.com/search?q=repo%3Asimonw%2Fdatasette%20discord&type=code).\r\n\r\nThe following video should be self explanatory:\r\n\r\nhttps://github.com/simonw/datasette/assets/1892194/8cd33e88-bcaa-41f3-9818-ab4d589c3f02\r\n\r\n\r\nLink for reference: https://discord.com/invite/ktd74dm5mw", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2196/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1930008379, "node_id": "I_kwDOBm6k_c5zCZc7", "number": 2197, "title": "click-default-group-wheel dependency conflict", "user": {"value": 1176293, "label": "ar-jan"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2023-10-06T11:49:20Z", "updated_at": "2023-10-12T21:53:17Z", "closed_at": "2023-10-12T21:53:17Z", "author_association": "NONE", "pull_request": null, "body": "I upgraded my dependencies, then ran into this problem running `datasette inspect`:\r\n\r\n> env/lib/python3.9/site-packages/datasette/cli.py\", line 6, in \r\n> from click_default_group import DefaultGroup\r\n> ModuleNotFoundError: No module named 'click_default_group'\r\n\r\nTurns out the released version of datasette still depends on `click-default-group-wheel`, so `click-default-group` doesn't get installed/recognized:\r\n\r\n```\r\n$ virtualenv venv\r\n$ source venv/bin/activate\r\n$ pip install datasette\r\n$ pip list | grep click-default-group\r\nclick-default-group 1.2.4\r\nclick-default-group-wheel 1.2.3\r\n$ python -c \"from click_default_group import DefaultGroup\"\r\nTraceback (most recent call last):\r\n File \"\", line 1, in \r\nModuleNotFoundError: No module named 'click_default_group'\r\n$ pip install --force-reinstall click-default-group\r\n...\r\nERROR: pip's dependency resolver does not currently take into account all the packages that are installed.\r\nThis behaviour is the source of the following dependency conflicts.\r\ndatasette 0.64.4 requires click-default-group-wheel>=1.2.2, which is not installed.\r\nSuccessfully installed click-8.1.7 click-default-group-1.2.4\r\n```", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2197/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1901416155, "node_id": "I_kwDOBm6k_c5xVU7b", "number": 2189, "title": "Server hang on parallel execution of queries to named in-memory databases", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 31, "created_at": "2023-09-18T17:23:18Z", "updated_at": "2023-09-21T22:26:21Z", "closed_at": "2023-09-21T22:26:21Z", "author_association": "OWNER", "pull_request": null, "body": "I've started to encounter a bug where queries to tables inside named in-memory databases sometimes trigger server hangs.\r\n\r\nI'm still trying to figure out what's going on here - on one occasion I managed to Ctrl+C the server and saw an exception that mentioned a thread lock, but usually hitting Ctrl+C does nothing and I have to `kill -9` the PID instead.\r\n\r\nThis is all running on my M2 Mac.\r\n\r\nI've seen the bug in the Datasette 1.0 alphas and in Datasette 0.64.3 - but reverting to 0.61 appeared to fix it.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2189/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1662951875, "node_id": "I_kwDOBm6k_c5jHqHD", "number": 2057, "title": "DeprecationWarning: pkg_resources is deprecated as an API", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 25, "created_at": "2023-04-11T17:41:20Z", "updated_at": "2023-09-21T22:09:10Z", "closed_at": "2023-09-21T22:09:10Z", "author_association": "OWNER", "pull_request": null, "body": "Got this running tests against Python 3.11.\r\n\r\n```\r\n../../../.local/share/virtualenvs/datasette-big-local-6Yn-280V/lib/python3.11/site-packages/datasette/app.py:14: in \r\n import pkg_resources\r\n../../../.local/share/virtualenvs/datasette-big-local-6Yn-280V/lib/python3.11/site-packages/pkg_resources/__init__.py:121: in \r\n warnings.warn(\"pkg_resources is deprecated as an API\", DeprecationWarning)\r\nE DeprecationWarning: pkg_resources is deprecated as an API\r\n```\r\n\r\nI ran with `pytest -Werror --pdb -x` to get the debugger for that warning, but it turned out searching the code worked better. It's used in these two places:\r\n\r\nhttps://github.com/simonw/datasette/blob/5890a20c374fb0812d88c9b0ef26a838bfa06c76/datasette/plugins.py#L43-L50\r\n\r\nhttps://github.com/simonw/datasette/blob/5890a20c374fb0812d88c9b0ef26a838bfa06c76/datasette/app.py#L1037", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2057/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1907695234, "node_id": "I_kwDOBm6k_c5xtR6C", "number": 2194, "title": "Deploy failing with \"plugins/alternative_route.py: Not a directory\"", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 8, "created_at": "2023-09-21T20:17:49Z", "updated_at": "2023-09-21T22:08:19Z", "closed_at": "2023-09-21T22:08:19Z", "author_association": "OWNER", "pull_request": null, "body": "https://github.com/simonw/datasette/actions/runs/6266449018/job/17017460074\r\n\r\n\"CleanShot\r\n\r\nThis is a bit of a mystery, I don't think I've changed anything recently that could have broken this.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2194/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1907655261, "node_id": "I_kwDOBm6k_c5xtIJd", "number": 2193, "title": "\"Test DATASETTE_LOAD_PLUGINS\" test shows errors but did not fail the CI run", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 6, "created_at": "2023-09-21T19:49:34Z", "updated_at": "2023-09-21T21:56:43Z", "closed_at": "2023-09-21T21:56:43Z", "author_association": "OWNER", "pull_request": null, "body": "> That passed on 3.8 but should have failed: https://github.com/simonw/datasette/actions/runs/6266341481/job/17017099801 - the \"Test DATASETTE_LOAD_PLUGINS\" test shows errors but did not fail the CI run.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/2057#issuecomment-1730201226_\r\n ", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2193/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1886791100, "node_id": "I_kwDOBm6k_c5wdiW8", "number": 2180, "title": "Plugin hook: `actors_from_ids()`", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 6, "created_at": "2023-09-08T01:16:41Z", "updated_at": "2023-09-10T17:44:14Z", "closed_at": "2023-09-08T04:28:03Z", "author_association": "OWNER", "pull_request": null, "body": "In building Datasette Cloud we realized that a bunch of the features we are building need a way of resolving an actor ID to the actual actor, in order to display something more interesting than just an integer ID.\r\n\r\nSocial plugins in particular need this - comments by X, CSV uploaded by X, that kind of thing.\r\n\r\nI think the solution is a new plugin hook: `actors_from_ids(datasette, ids)` which can return a list of actor dictionaries.\r\n\r\nThe default implementation can return `[{\"id\": \"...\"}]` for the IDs passed to it.\r\n\r\nPluggy has a `firstresult=True` option which is relevant here, since this is the first plugin hook we will have implemented where only one plugin should provide an answer.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2180/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1874255116, "node_id": "I_kwDOBm6k_c5vtt0M", "number": 2164, "title": "Ability to only load a specific list of plugins", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2023-08-30T19:33:41Z", "updated_at": "2023-09-08T04:35:46Z", "closed_at": "2023-08-30T22:12:27Z", "author_association": "OWNER", "pull_request": null, "body": "I'm going to try and get this working through an environment variable, so that you can start Datasette and it will only load a subset of plugins including those that use the `register_commands()` hook.\r\n\r\nInitial research on this:\r\n- https://github.com/pytest-dev/pluggy/issues/422", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2164/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1886350562, "node_id": "I_kwDOBm6k_c5wb2zi", "number": 2178, "title": "Don't show foreign key links to tables the user cannot access", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 5, "created_at": "2023-09-07T17:56:41Z", "updated_at": "2023-09-07T23:28:27Z", "closed_at": "2023-09-07T23:28:27Z", "author_association": "OWNER", "pull_request": null, "body": "Spotted this problem while working on this plugin:\r\n- https://github.com/simonw/datasette-public\r\n\r\nIt's possible to make a table public to any users - but then you may end up with situations like this:\r\n\r\n\"CleanShot\r\n\r\nThat table is public, but the foreign key links go to tables that are NOT public.\r\n\r\nWe're also leaking the names of the values in those private tables here, which we shouldn't do. So this is a tiny bit of an information leak.\r\n\r\nSince this only affects people who have configured a table to be public that has foreign keys to a table that is private I don't think this is worth issuing a vulnerability report about - I very much doubt anyone is running Datasette configured in a way that could result in problems because of this.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2178/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1886649402, "node_id": "I_kwDOBm6k_c5wc_w6", "number": 2179, "title": "Flaky test: test_hidden_sqlite_stat1_table", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 0, "created_at": "2023-09-07T22:48:43Z", "updated_at": "2023-09-07T22:51:19Z", "closed_at": "2023-09-07T22:51:19Z", "author_association": "OWNER", "pull_request": null, "body": "This test here: https://github.com/simonw/datasette/blob/fbcb103c0cb6668018ace539a01a6a1f156e8d6a/tests/test_api.py#L1011-L1020\r\n\r\nIt failed for me like this:\r\n\r\n`E AssertionError: assert [('normal', False), ('sqlite_stat1', True), ('sqlite_stat4', True)] in ([('normal', False), ('sqlite_stat1', True)],)`\r\n\r\nLooks like some builds of SQLite include a `sqlite_stat4` table.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2179/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 336464733, "node_id": "MDU6SXNzdWUzMzY0NjQ3MzM=", "number": 328, "title": "Installation instructions, including how to use the docker image", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 4, "created_at": "2018-06-28T03:59:33Z", "updated_at": "2023-09-05T14:10:39Z", "closed_at": "2018-06-28T04:02:10Z", "author_association": "OWNER", "pull_request": null, "body": "", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/328/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1292370469, "node_id": "I_kwDOBm6k_c5NCAIl", "number": 1765, "title": "Document plugins providing new plugin hook-", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-07-03T17:05:14Z", "updated_at": "2023-08-31T23:08:24Z", "closed_at": "2023-08-31T23:06:31Z", "author_association": "OWNER", "pull_request": null, "body": "I've used this pattern twice now: https://til.simonwillison.net/datasette/register-new-plugin-hooks - in `datasette-graphql` and `datasette-low-disk-space-hook`. I should describe the pattern on https://docs.datasette.io/en/stable/writing_plugins.html", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1765/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1876407598, "node_id": "I_kwDOBm6k_c5v17Uu", "number": 2169, "title": "execute-sql on a database should imply view-database/view-permission", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 0, "created_at": "2023-08-31T22:45:56Z", "updated_at": "2023-08-31T22:46:28Z", "closed_at": "2023-08-31T22:46:28Z", "author_association": "OWNER", "pull_request": null, "body": "I noticed that a token with `execute-sql` permission alone did not work, because it was not allowed to view the instance of the database.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2169/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 742041667, "node_id": "MDU6SXNzdWU3NDIwNDE2Njc=", "number": 1092, "title": "Make cascading permission checks available to plugins", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2020-11-13T01:02:55Z", "updated_at": "2023-08-30T22:17:42Z", "closed_at": "2023-08-30T22:17:41Z", "author_association": "OWNER", "pull_request": null, "body": "The `BaseView` class has a method for cascading permission checks, but it's not easily accessible to plugins.\r\n\r\nhttps://github.com/simonw/datasette/blob/5eb8e9bf250b26e30b017d39a392c33973997656/datasette/views/base.py#L75-L99\r\n\r\nThis leaves plugins like `datasette-graphql` having to implement their own versions of this logic, which is bad: https://github.com/simonw/datasette-graphql/issues/65\r\n\r\n> First check `view-database` - if that says `False` then disallow access, if it says `True` then allow access. If it says `None` check `view-instance`.\r\n\r\nThis should become a supported API that plugins are encouraged to use.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1092/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 787098146, "node_id": "MDU6SXNzdWU3ODcwOTgxNDY=", "number": 1190, "title": "`datasette publish upload` mechanism for uploading databases to an existing Datasette instance", "user": {"value": 1024355, "label": "tomershvueli"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2021-01-15T18:18:42Z", "updated_at": "2023-08-30T22:16:39Z", "closed_at": "2023-08-30T22:16:38Z", "author_association": "NONE", "pull_request": null, "body": "If I have a self-hosted instance of Datasette up and running, I'd like to be able to the use the CLI to publish databases to that instance, not only Google or Heroku. Ideally there'd be a `url` parameter or something similar to which one could point the publish command to their instance. ", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1190/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1872043170, "node_id": "I_kwDOBm6k_c5vlRyi", "number": 2163, "title": "Rename core_X to catalog_X in the internals", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2023-08-29T16:45:00Z", "updated_at": "2023-08-29T17:01:31Z", "closed_at": "2023-08-29T17:01:31Z", "author_association": "OWNER", "pull_request": null, "body": "Discussed with Alex this morning. We think the American spelling is fine here (it's shorter than `catalogue`) and that it's a slightly less lazy name than `core_`.\r\n\r\nFollows:\r\n- https://github.com/simonw/datasette/issues/2157", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2163/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1805076818, "node_id": "I_kwDOBm6k_c5rl0lS", "number": 2102, "title": "API tokens with view-table but not view-database/view-instance cannot access the table", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": {"value": 9599, "label": "simonw"}, "milestone": null, "comments": 20, "created_at": "2023-07-14T15:34:27Z", "updated_at": "2023-08-29T16:32:36Z", "closed_at": "2023-08-29T16:32:35Z", "author_association": "OWNER", "pull_request": null, "body": "> Spotted a problem while working on this: if you grant a token access to view table for a specific table but don't also grant view database and view instance permissions, that token is useless.\r\n>\r\n> This was a deliberate design decision in Datasette - it's documented on https://docs.datasette.io/en/1.0a2/authentication.html#access-permissions-in-metadata\r\n>\r\n>> If a user cannot access a specific database, they will not be able to access tables, views or queries within that database. If a user cannot access the instance they will not be able to access any of the databases, tables, views or queries.\r\n>\r\n> I'm now second-guessing if this was a good decision.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette-auth-tokens/issues/7#issuecomment-1636031702_\r\n ", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2102/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1865232341, "node_id": "I_kwDOBm6k_c5vLS_V", "number": 2153, "title": "Datasette --get --actor option", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 5, "created_at": "2023-08-24T14:00:03Z", "updated_at": "2023-08-28T20:19:15Z", "closed_at": "2023-08-28T20:15:53Z", "author_association": "OWNER", "pull_request": null, "body": "I experimented with a prototype of this here:\r\n- https://github.com/simonw/datasette/issues/2102#issuecomment-1691037971_\r\n\r\nWhich lets me run requests as if they belonged to a specific actor like this:\r\n\r\n```bash\r\ndatasette fixtures.db --get '/fixtures/facetable.json' --actor '{\r\n \"_r\": {\r\n \"r\": {\r\n \"fixtures\": {\r\n \"facetable\": [\r\n \"vt\"\r\n ]\r\n }\r\n }\r\n },\r\n \"a\": \"user\"\r\n}'\r\n```\r\n\r\nReally useful for testing actors an `_r` options. Is this worth adding as a feature?", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2153/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 685806511, "node_id": "MDU6SXNzdWU2ODU4MDY1MTE=", "number": 950, "title": "Private/secret databases: database files that are only visible to plugins", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 6, "created_at": "2020-08-25T20:46:17Z", "updated_at": "2023-08-24T22:26:09Z", "closed_at": "2023-08-24T22:26:08Z", "author_association": "OWNER", "pull_request": null, "body": "In thinking about the best way to implement https://github.com/simonw/datasette-auth-passwords/issues/6 (SQL-backed user accounts for `datasette-auth-passwords`) I realized that there are a few different use-cases where a plugin might want to store data that isn't visible to regular Datasette users:\r\n\r\n- Storing password hashes\r\n- Storing API tokens\r\n- Storing secrets that are used for data import integrations (secrets for talking to the Twitter API for example)\r\n\r\nIdea: allow one or more private database files to be attached to Datasette, something like this:\r\n\r\n datasette github.db linkedin.db -s secrets.db -m metadata.yml\r\n\r\nThe `secrets.db` file would not be visible using any of the Datasette's usual interface or API routes - but plugins would be able to run queries against it.\r\n\r\nSo `datasette-auth-passwords` might then be configured like this:\r\n\r\n```yaml\r\nplugins:\r\n datasette-auth-passwords:\r\n database: secrets\r\n sql: \"select password_hash from passwords where username = :username\"\r\n```\r\nThe plugin could even refuse to operate against a database that hadn't been loaded as a secret database.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/950/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1863810783, "node_id": "I_kwDOBm6k_c5vF37f", "number": 2150, "title": "form label { width: 15% } is a bad default", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 4, "created_at": "2023-08-23T18:22:27Z", "updated_at": "2023-08-23T18:37:18Z", "closed_at": "2023-08-23T18:35:48Z", "author_association": "OWNER", "pull_request": null, "body": "See:\r\n- https://github.com/simonw/datasette-configure-fts/issues/14\r\n- https://github.com/simonw/datasette-auth-tokens/issues/12", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2150/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1781022369, "node_id": "I_kwDOBm6k_c5qKD6h", "number": 2091, "title": "Drop support for Python 3.7", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2023-06-29T15:06:38Z", "updated_at": "2023-08-23T18:18:18Z", "closed_at": "2023-08-23T18:18:18Z", "author_association": "OWNER", "pull_request": null, "body": "It's EOL now, as of 2023-06-27 (two days ago): https://devguide.python.org/versions/\r\n\r\n", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2091/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1795051447, "node_id": "I_kwDOBm6k_c5q_k-3", "number": 2097, "title": "Drop Python 3.7", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 0, "created_at": "2023-07-08T18:39:44Z", "updated_at": "2023-08-23T18:18:00Z", "closed_at": "2023-08-23T18:18:00Z", "author_association": "OWNER", "pull_request": null, "body": "> I'm going to drop Python 3.7.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1153#issuecomment-1627455892_\r\n\r\nIt's not supported any more: https://devguide.python.org/versions/", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2097/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 449886319, "node_id": "MDU6SXNzdWU0NDk4ODYzMTk=", "number": 493, "title": "Rename metadata.json to config.json", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 7, "created_at": "2019-05-29T15:48:03Z", "updated_at": "2023-08-23T01:29:21Z", "closed_at": "2023-08-23T01:29:20Z", "author_association": "OWNER", "pull_request": null, "body": "It is increasingly being useful configuration options, when it started out as purely metadata.\r\n\r\nCould cause confusion with the `--config` mechanism though - maybe that should be called \"settings\" instead?", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/493/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 324720095, "node_id": "MDU6SXNzdWUzMjQ3MjAwOTU=", "number": 275, "title": "\"config\" section in metadata.json (root, database and table level)", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2018-05-20T16:02:28Z", "updated_at": "2023-08-23T01:28:37Z", "closed_at": "2023-08-23T01:28:37Z", "author_association": "OWNER", "pull_request": null, "body": "Split off from #274 \r\n\r\nMetadata should an optional `\"config\"` section at root, table or database level.\r\n\r\nThe TableView and RowView and DatabaseView and BaseView classes could all have a `.config(\"key\")` method which knows how to resolve the hierarchy of configs.\r\n\r\nThis will allow individual tables (or databases) to set their own config settings for things like `sql_time_limit_ms`", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/275/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1847201263, "node_id": "I_kwDOBm6k_c5uGg3v", "number": 2140, "title": "Remove all remaining documentation instances of '$ '", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2023-08-11T17:42:13Z", "updated_at": "2023-08-11T17:52:25Z", "closed_at": "2023-08-11T17:45:00Z", "author_association": "OWNER", "pull_request": null, "body": "For example this: https://github.com/simonw/datasette/blob/4535568f2ce907af646304d0ebce2500ebd55677/docs/authentication.rst?plain=1#L33-L35\r\n\r\nThe problem with that `$ ` prefix is that it prevents users from copying and pasting the raw command.\r\n\r\n\"image\"\r\n\r\nhttps://docs.datasette.io/en/stable/authentication.html#using-the-root-actor", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2140/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1838266862, "node_id": "I_kwDOBm6k_c5tkbnu", "number": 2126, "title": "Permissions in metadata.yml / metadata.json", "user": {"value": 36199671, "label": "ctsrc"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2023-08-06T16:24:10Z", "updated_at": "2023-08-11T05:52:30Z", "closed_at": "2023-08-11T05:52:29Z", "author_association": "NONE", "pull_request": null, "body": "https://docs.datasette.io/en/latest/authentication.html#other-permissions-in-metadata says the following:\r\n\r\n> For all other permissions, you can use one or more \"permissions\" blocks in your metadata.\r\n\r\n> To grant access to the permissions debug tool to all signed in users you can grant permissions-debug to any actor with an id matching the wildcard * by adding this a the root of your metadata:\r\n\r\n```yaml\r\npermissions:\r\n debug-menu:\r\n id: '*'\r\n```\r\n\r\nI tried this.\r\n\r\nMy `metadata.yml` file looks like:\r\n\r\n```yaml\r\npermissions:\r\n debug-menu:\r\n id: '*'\r\n permissions-debug:\r\n id: '*'\r\nplugins:\r\n datasette-auth-passwords:\r\n myuser_password_hash:\r\n $env: \"PASSWORD_HASH_MYUSER\"\r\n```\r\n\r\nAnd then I run\r\n\r\n```zsh\r\ndatasette -m metadata.yml tiddlywiki.db --root\r\n```\r\n\r\nAnd I open a session for the \"root\" user of datasette with the link given.\r\n\r\nI open a private browser session and log in as \"myuser\" from http://127.0.0.1:8001/-/login\r\n\r\nThen I check http://127.0.0.1:8001/-/actor which confirms that I am logged in as the \"myuser\" actor\r\n\r\n```json\r\n{\r\n \"actor\": {\r\n \"id\": \"myuser\"\r\n }\r\n}\r\n```\r\n\r\nIn the session where I am logged in as \"myuser\" I then try to go to http://127.0.0.1:8001/-/permissions\r\n\r\nBut all I get there as the logged in user \"myuser\" is\r\n\r\n> Forbidden\r\n>\r\n> Permission denied\r\n\r\nAnd then if I check the http://127.0.0.1:8001/-/permissions as the datasette \"root\" user from another browser session, I see:\r\n\r\n> permissions-debug checked at 2023-08-06T16:22:58.997841 \u2717 (used default)\r\n>\r\n> Actor: {\"id\": \"myuser\"}\r\n\r\nIt seems that in spite of having tried to give the `permissions-debug` permission to the \"myuser\" user in my `metadata.yml` file, datasette does not agree that \"myuser\" has permission `permissions-debug`..\r\n\r\nWhat do I need to do differently so that my \"myuser\" user is able to access http://127.0.0.1:8001/-/permissions ?", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2126/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1823393475, "node_id": "I_kwDOBm6k_c5srsbD", "number": 2119, "title": "database color shows only on index page, not other pages", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 3, "created_at": "2023-07-27T00:19:39Z", "updated_at": "2023-08-11T05:25:45Z", "closed_at": "2023-08-11T05:16:24Z", "author_association": "OWNER", "pull_request": null, "body": "I think this has been a bug for a long time.\r\n\r\nhttps://latest.datasette.io/ currently shows:\r\n\r\n\"image\"\r\n\r\nThose colors are based on a hash of the database name. But when you click through to https://latest.datasette.io/fixtures\r\n\r\n\"image\"\r\n\r\nIt's red on all sub-pages too.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2119/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1846076261, "node_id": "I_kwDOBm6k_c5uCONl", "number": 2139, "title": "border-color: ##ff0000 bug - two hashes", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 8755003, "label": "Datasette 1.0a-next"}, "comments": 2, "created_at": "2023-08-11T01:22:58Z", "updated_at": "2023-08-11T05:16:24Z", "closed_at": "2023-08-11T05:16:24Z", "author_association": "OWNER", "pull_request": null, "body": "Spotted this on https://latest.datasette.io/extra_database\r\n\r\n```html\r\n
\r\n```", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2139/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1843391585, "node_id": "I_kwDOBm6k_c5t3-xh", "number": 2134, "title": "Add writable canned query demo to latest.datasette.io", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 5, "created_at": "2023-08-09T14:31:30Z", "updated_at": "2023-08-10T01:22:46Z", "closed_at": "2023-08-10T01:05:56Z", "author_association": "OWNER", "pull_request": null, "body": "This would be useful while working on:\r\n- #2114", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2134/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1844213115, "node_id": "I_kwDOBm6k_c5t7HV7", "number": 2138, "title": "on_success_message_sql option for writable canned queries", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 8755003, "label": "Datasette 1.0a-next"}, "comments": 2, "created_at": "2023-08-10T00:20:14Z", "updated_at": "2023-08-10T00:39:40Z", "closed_at": "2023-08-10T00:34:26Z", "author_association": "OWNER", "pull_request": null, "body": "> Or... how about if the `on_success_message` option could define a SQL query to be executed to generate that message? Maybe `on_success_message_sql`.\r\n\r\n- https://github.com/simonw/datasette/issues/2134", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2138/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1841501975, "node_id": "I_kwDOBm6k_c5twxcX", "number": 2133, "title": "[feature request]`datasette install plugins.json` options", "user": {"value": 54462, "label": "HaveF"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 9, "created_at": "2023-08-08T15:06:50Z", "updated_at": "2023-08-10T00:31:24Z", "closed_at": "2023-08-09T22:04:46Z", "author_association": "NONE", "pull_request": null, "body": "Hi, simon \u2764\ufe0f \r\n\r\n`datasette plugins --all > plugins.json` could generate all plugins info. On another machine, it would be great to install all plugins just by `datasette install plugins.json`", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2133/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 627794879, "node_id": "MDU6SXNzdWU2Mjc3OTQ4Nzk=", "number": 782, "title": "Redesign default .json format", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 8755003, "label": "Datasette 1.0a-next"}, "comments": 55, "created_at": "2020-05-30T18:47:07Z", "updated_at": "2023-08-10T00:07:17Z", "closed_at": "2023-08-10T00:07:17Z", "author_association": "OWNER", "pull_request": null, "body": "The default JSON just isn't right. I find myself using `?_shape=array` for almost everything I build against the API.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/782/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1843600087, "node_id": "I_kwDOBm6k_c5t4xrX", "number": 2135, "title": "Release notes for 1.0a3", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 9700784, "label": "Datasette 1.0a3"}, "comments": 3, "created_at": "2023-08-09T16:09:26Z", "updated_at": "2023-08-09T19:17:07Z", "closed_at": "2023-08-09T19:17:06Z", "author_association": "OWNER", "pull_request": null, "body": "118 commits! https://github.com/simonw/datasette/compare/1.0a2...26be9f0445b753fb84c802c356b0791a72269f25", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2135/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1843710170, "node_id": "I_kwDOBm6k_c5t5Mja", "number": 2136, "title": "Query view shouldn't return `columns`", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 9700784, "label": "Datasette 1.0a3"}, "comments": 4, "created_at": "2023-08-09T17:23:57Z", "updated_at": "2023-08-09T19:03:04Z", "closed_at": "2023-08-09T19:03:04Z", "author_association": "OWNER", "pull_request": null, "body": "I just noticed that https://latest.datasette.io/fixtures/roadside_attraction_characteristics.json?_labels=on&_size=1 returns:\r\n```json\r\n{\r\n \"ok\": true,\r\n \"next\": \"1\",\r\n \"rows\": [\r\n {\r\n \"rowid\": 1,\r\n \"attraction_id\": {\r\n \"value\": 1,\r\n \"label\": \"The Mystery Spot\"\r\n },\r\n \"characteristic_id\": {\r\n \"value\": 2,\r\n \"label\": \"Paranormal\"\r\n }\r\n }\r\n ],\r\n \"truncated\": false\r\n}\r\n```\r\nBut https://latest.datasette.io/fixtures.json?sql=select+rowid%2C+attraction_id%2C+characteristic_id+from+roadside_attraction_characteristics+order+by+rowid+limit+1 returns:\r\n```json\r\n{\r\n \"rows\": [\r\n {\r\n \"rowid\": 1,\r\n \"attraction_id\": 1,\r\n \"characteristic_id\": 2\r\n }\r\n ],\r\n \"columns\": [\r\n \"rowid\",\r\n \"attraction_id\",\r\n \"characteristic_id\"\r\n ],\r\n \"ok\": true,\r\n \"truncated\": false\r\n}\r\n```\r\nThe `columns` key in the query response is inconsistent with the table response.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2136/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1560662739, "node_id": "I_kwDOBm6k_c5dBdLT", "number": 2007, "title": "`render_cell()` hook should take an optional `request` argument", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2023-01-28T03:13:00Z", "updated_at": "2023-08-09T17:15:03Z", "closed_at": "2023-01-28T03:34:26Z", "author_association": "OWNER", "pull_request": null, "body": "From Discord: https://discordapp.com/channels/823971286308356157/996877076982415491/1068227071156965486", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2007/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1822940263, "node_id": "I_kwDOBm6k_c5sp9xn", "number": 2114, "title": "Implement canned queries against new query JSON work", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 9700784, "label": "Datasette 1.0a3"}, "comments": 3, "created_at": "2023-07-26T18:24:50Z", "updated_at": "2023-08-09T15:26:58Z", "closed_at": "2023-08-09T15:26:57Z", "author_association": "OWNER", "pull_request": null, "body": "- #2109 ", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2114/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1841343173, "node_id": "I_kwDOBm6k_c5twKrF", "number": 2132, "title": "Get form fields on query page working again ", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 9700784, "label": "Datasette 1.0a3"}, "comments": 1, "created_at": "2023-08-08T13:39:05Z", "updated_at": "2023-08-08T13:45:10Z", "closed_at": "2023-08-08T13:45:09Z", "author_association": "OWNER", "pull_request": null, "body": "Caused by:\r\n- #2112\r\n\r\nhttps://latest.datasette.io/fixtures?sql=select+pk1%2C+pk2%2C+pk3%2C+content+from+compound_three_primary_keys+where+%22pk1%22+%3D+%3Ap0+order+by+pk1%2C+pk2%2C+pk3+limit+101&p0=b\r\n\r\n\"image\"\r\n\r\nThe `:p0` form field is missing. Submitting the form results in this error:\r\n\r\n\"image\"\r\n", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2132/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1822982933, "node_id": "I_kwDOBm6k_c5sqIMV", "number": 2117, "title": "Figure out what to do about `DatabaseView.name`", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 9700784, "label": "Datasette 1.0a3"}, "comments": 1, "created_at": "2023-07-26T18:58:06Z", "updated_at": "2023-08-08T02:02:07Z", "closed_at": "2023-08-08T02:02:07Z", "author_association": "OWNER", "pull_request": null, "body": "In the old code:\r\n\r\nhttps://github.com/simonw/datasette/blob/08181823990a71ffa5a1b57b37259198eaa43e06/datasette/views/database.py#L34-L35\r\n\r\nThis `name` class attribute was later used by some of the plugin hooks, passed as `view_name`: https://github.com/simonw/datasette/blob/18dd88ee4d78fe9d760e9da96028ae06d938a85c/datasette/hookspecs.py#L50-L54\r\n\r\nFigure out how that should work once I've refactored those classes to view functions instead.\r\n\r\nRefs:\r\n- #2109 ", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2117/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1822940964, "node_id": "I_kwDOBm6k_c5sp98k", "number": 2115, "title": "Ensure all tests pass against new query view JSON", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 9700784, "label": "Datasette 1.0a3"}, "comments": 0, "created_at": "2023-07-26T18:25:20Z", "updated_at": "2023-08-08T02:01:39Z", "closed_at": "2023-08-08T02:01:38Z", "author_association": "OWNER", "pull_request": null, "body": "- #2109 ", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2115/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1822938661, "node_id": "I_kwDOBm6k_c5sp9Yl", "number": 2112, "title": "Build HTML version of /content?sql=...", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 9700784, "label": "Datasette 1.0a3"}, "comments": 5, "created_at": "2023-07-26T18:23:34Z", "updated_at": "2023-08-08T02:01:09Z", "closed_at": "2023-08-08T02:01:01Z", "author_association": "OWNER", "pull_request": null, "body": "This will help make the hook as robust as possible.\r\n- #2109 ", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2112/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1822937426, "node_id": "I_kwDOBm6k_c5sp9FS", "number": 2111, "title": "Implement new /content.json?sql=...", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 9700784, "label": "Datasette 1.0a3"}, "comments": 4, "created_at": "2023-07-26T18:22:39Z", "updated_at": "2023-08-08T02:00:37Z", "closed_at": "2023-08-08T02:00:22Z", "author_association": "OWNER", "pull_request": null, "body": "This will be the base that the remaining work builds on top of. Refs:\r\n- #2109 ", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2111/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1840329615, "node_id": "I_kwDOBm6k_c5tsTOP", "number": 2130, "title": "Render plugin mechanism needs `error` and `truncated` fields", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 9700784, "label": "Datasette 1.0a3"}, "comments": 2, "created_at": "2023-08-07T23:19:19Z", "updated_at": "2023-08-08T01:51:54Z", "closed_at": "2023-08-08T01:47:42Z", "author_association": "OWNER", "pull_request": null, "body": "While working on:\r\n- https://github.com/simonw/datasette/pull/2118\r\n\r\nIt became clear that the `render` callback function documented here: https://docs.datasette.io/en/0.64.3/plugin_hooks.html#register-output-renderer-datasette\r\n\r\nNeeds to grow the ability to be told if an error occurred (an `error` string) and if the results were truncated (a `truncated` boolean).", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2130/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1822934563, "node_id": "I_kwDOBm6k_c5sp8Yj", "number": 2109, "title": "Plan for getting the new JSON format query views working", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 9700784, "label": "Datasette 1.0a3"}, "comments": 5, "created_at": "2023-07-26T18:20:18Z", "updated_at": "2023-07-27T00:24:47Z", "closed_at": "2023-07-26T18:25:34Z", "author_association": "OWNER", "pull_request": null, "body": "I've been stuck on this for too long. I'm breaking it down into a full milestone:\r\n\r\nhttps://github.com/simonw/datasette/milestone/29", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2109/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1822936521, "node_id": "I_kwDOBm6k_c5sp83J", "number": 2110, "title": "Merge database index page and query view", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 9700784, "label": "Datasette 1.0a3"}, "comments": 1, "created_at": "2023-07-26T18:21:57Z", "updated_at": "2023-07-26T19:53:25Z", "closed_at": "2023-07-26T19:53:25Z", "author_association": "OWNER", "pull_request": null, "body": "Refs:\r\n- #2109\r\n\r\nThe idea here is that hitting `/content` without a `?sql=` will show an empty result set AND default to including a bunch of extras about the list of tables in the database.\r\n\r\nThen I won't have to think about `/content` and `/content?sql=` as separate pages any more.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2110/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1822949756, "node_id": "I_kwDOBm6k_c5sqAF8", "number": 2116, "title": "Turn DatabaseDownload into an async view function", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 9700784, "label": "Datasette 1.0a3"}, "comments": 3, "created_at": "2023-07-26T18:31:59Z", "updated_at": "2023-07-26T18:44:00Z", "closed_at": "2023-07-26T18:44:00Z", "author_association": "OWNER", "pull_request": null, "body": "A minor refactor, but it is a good starting point for this new branch. Refs:\r\n- #2109", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2116/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1816857442, "node_id": "I_kwDOBm6k_c5sSwti", "number": 2106, "title": "`datasette install -e` option", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2023-07-22T18:33:42Z", "updated_at": "2023-07-26T18:28:33Z", "closed_at": "2023-07-22T18:42:54Z", "author_association": "OWNER", "pull_request": null, "body": "As seen in LLM and now in `sqlite-utils` too:\r\n- https://github.com/simonw/sqlite-utils/issues/570\r\n\r\nUseful for developing plugins, see tutorial at https://llm.datasette.io/en/stable/plugins/tutorial-model-plugin.html", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2106/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 771202454, "node_id": "MDU6SXNzdWU3NzEyMDI0NTQ=", "number": 1153, "title": "Use YAML examples in documentation by default, not JSON", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 22, "created_at": "2020-12-18T22:20:15Z", "updated_at": "2023-07-08T20:09:48Z", "closed_at": "2023-07-08T20:08:13Z", "author_association": "OWNER", "pull_request": null, "body": "YAML configuration is much better for multi-line strings, and I'm increasingly adding configuration options to Datasette that benefit from that - fragments of HTML in `description_html` or SQL queries used to configure things like https://github.com/simonw/datasette-atom for example.\r\n\r\nRather than confusing things by showing both in the documentation, I should switch all of the default examples to use YAML instead.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1153/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1355148385, "node_id": "I_kwDOBm6k_c5Qxexh", "number": 1796, "title": "Research an upgrade to CodeMirror 6", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 4, "created_at": "2022-08-30T04:27:46Z", "updated_at": "2023-07-03T04:58:21Z", "closed_at": "2023-07-03T04:58:21Z", "author_association": "OWNER", "pull_request": null, "body": "There are still a bunch of bugs in CodeMirror 5 that affect various mobile browsers - see Datasette Discord report here: https://discord.com/channels/823971286308356157/823971286941302908/1013878624992108645\r\n\r\nhttps://user-images.githubusercontent.com/9599/187349269-7b7c0c8c-3894-4810-82f0-de7c1eb940b3.mp4\r\n\r\n", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1796/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1781047747, "node_id": "I_kwDOBm6k_c5qKKHD", "number": 2092, "title": "test_homepage intermittent failure", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2023-06-29T15:20:37Z", "updated_at": "2023-06-29T15:26:28Z", "closed_at": "2023-06-29T15:24:13Z", "author_association": "OWNER", "pull_request": null, "body": "e.g. in https://github.com/simonw/datasette/actions/runs/5413590227/jobs/9839373852\r\n\r\n```\r\n=================================== FAILURES ===================================\r\n________________________________ test_homepage _________________________________\r\n[gw0] linux -- Python 3.7.17 /opt/hostedtoolcache/Python/3.7.17/x64/bin/python\r\n\r\nds_client = \r\n\r\n @pytest.mark.asyncio\r\n async def test_homepage(ds_client):\r\n response = await ds_client.get(\"/.json\")\r\n assert response.status_code == 200\r\n assert \"application/json; charset=utf-8\" == response.headers[\"content-type\"]\r\n data = response.json()\r\n assert data.keys() == {\"fixtures\": 0}.keys()\r\n d = data[\"fixtures\"]\r\n assert d[\"name\"] == \"fixtures\"\r\n assert d[\"tables_count\"] == 24\r\n assert len(d[\"tables_and_views_truncated\"]) == 5\r\n assert d[\"tables_and_views_more\"] is True\r\n # 4 hidden FTS tables + no_primary_key (hidden in metadata)\r\n assert d[\"hidden_tables_count\"] == 6\r\n # 201 in no_primary_key, plus 6 in other hidden tables:\r\n> assert d[\"hidden_table_rows_sum\"] == 207, data\r\nE AssertionError: {'fixtures': {'color': '9403e5', 'hash': None, 'hidden_table_rows_sum': 0, 'hidden_tables_count': 6, ...}}\r\nE assert 0 == 207\r\n```\r\nMy guess is that this is a timing error, where very occasionally the \"count rows but stop counting if it exceeds a time limit\" thing fails.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2092/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1780973290, "node_id": "I_kwDOBm6k_c5qJ37q", "number": 2089, "title": "codespell test failure", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 5, "created_at": "2023-06-29T14:40:10Z", "updated_at": "2023-06-29T14:48:11Z", "closed_at": "2023-06-29T14:48:10Z", "author_association": "OWNER", "pull_request": null, "body": "https://github.com/simonw/datasette/actions/runs/5413443676/jobs/9838999356\r\n```\r\n codespell docs/*.rst --ignore-words docs/codespell-ignore-words.txt\r\n codespell datasette -S datasette/static --ignore-words docs/codespell-ignore-words.txt\r\n shell: /usr/bin/bash -e {0}\r\n env:\r\n pythonLocation: /opt/hostedtoolcache/Python/3.9.17/x64\r\n LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.9.17/x64/lib\r\ndocs/metadata.rst:192: displaing ==> displaying\r\n```\r\nThis failure is legit, it found a spelling mistake: https://github.com/simonw/datasette/blob/ede62036180993dbd9d4e5d280fc21c183cda1c3/docs/metadata.rst#L192", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2089/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1726236847, "node_id": "I_kwDOBm6k_c5m5Eiv", "number": 2078, "title": "Resolve the difference between `wrap_view()` and `BaseView`", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 16, "created_at": "2023-05-25T17:44:32Z", "updated_at": "2023-05-26T00:18:46Z", "closed_at": "2023-05-26T00:18:46Z", "author_association": "OWNER", "pull_request": null, "body": "There are two patterns for implementing views in Datasette at the moment. I want to combine those.\r\n\r\nPart of:\r\n- #2053", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2078/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1726531350, "node_id": "I_kwDOBm6k_c5m6McW", "number": 2079, "title": "Datasette should serve Access-Control-Max-Age", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 8, "created_at": "2023-05-25T21:50:50Z", "updated_at": "2023-05-25T22:56:28Z", "closed_at": "2023-05-25T22:08:35Z", "author_association": "OWNER", "pull_request": null, "body": "Currently the CORS headers served are:\r\n\r\nhttps://github.com/simonw/datasette/blob/9584879534ff0556e04e4c420262972884cac87b/datasette/utils/__init__.py#L1139-L1143\r\n\r\nServing `Access-Control-Max-Age: 600` would allow browsers to cache that for 10 minutes, avoiding additional CORS pre-flight OPTIONS requests during that time.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2079/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1702354223, "node_id": "I_kwDOBm6k_c5ld90v", "number": 2070, "title": "Mechanism for deploying a preview of a branch using Vercel", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2023-05-09T16:21:45Z", "updated_at": "2023-05-09T16:25:00Z", "closed_at": "2023-05-09T16:24:31Z", "author_association": "OWNER", "pull_request": null, "body": "I prototyped that here: https://github.com/simonw/one-off-actions/blob/main/.github/workflows/deploy-datasette-branch-preview.yml\r\n\r\nIt deployed the `json-extras-query` branch here: https://datasette-preview-json-extras-query.vercel.app/", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2070/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1686033652, "node_id": "I_kwDOBm6k_c5kftT0", "number": 2065, "title": "Datasette cannot be installed with Rye", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 4, "created_at": "2023-04-27T03:35:42Z", "updated_at": "2023-04-27T05:09:36Z", "closed_at": "2023-04-27T05:09:36Z", "author_association": "OWNER", "pull_request": null, "body": "https://github.com/mitsuhiko/rye\r\n\r\nI tried this:\r\n\r\n rye install datasette\r\n\r\nBut now:\r\n\r\n```\r\n% ~/.rye/shims/datasette\r\nTraceback (most recent call last):\r\n File \"/Users/simon/.rye/shims/datasette\", line 5, in \r\n from datasette.cli import cli\r\n File \"/Users/simon/.rye/tools/datasette/lib/python3.11/site-packages/datasette/cli.py\", line 17, in \r\n from .app import (\r\n File \"/Users/simon/.rye/tools/datasette/lib/python3.11/site-packages/datasette/app.py\", line 14, in \r\n import pkg_resources\r\nModuleNotFoundError: No module named 'pkg_resources'\r\n```\r\nI think that's because `setuptools` is not included in Rye.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2065/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1686042269, "node_id": "I_kwDOBm6k_c5kfvad", "number": 2066, "title": "Failing test: httpx.InvalidURL: URL too long", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 10, "created_at": "2023-04-27T03:48:47Z", "updated_at": "2023-04-27T04:27:50Z", "closed_at": "2023-04-27T04:27:50Z", "author_association": "OWNER", "pull_request": null, "body": "https://github.com/simonw/datasette/actions/runs/4815723640/jobs/8574667731\r\n```\r\n def urlparse(url: str = \"\", **kwargs: typing.Optional[str]) -> ParseResult:\r\n # Initial basic checks on allowable URLs.\r\n # ---------------------------------------\r\n \r\n # Hard limit the maximum allowable URL length.\r\n if len(url) > MAX_URL_LENGTH:\r\n> raise InvalidURL(\"URL too long\")\r\nE httpx.InvalidURL: URL too long\r\n\r\n/opt/hostedtoolcache/Python/3.7.16/x64/lib/python3.7/site-packages/httpx/_urlparse.py:155: InvalidURL\r\n=========================== short test summary info ============================\r\nFAILED tests/test_csv.py::test_max_csv_mb - httpx.InvalidURL: URL too long\r\n```", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2066/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1109808154, "node_id": "I_kwDOBm6k_c5CJlQa", "number": 1608, "title": "Documentation should clarify /stable/ vs /latest/", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 15, "created_at": "2022-01-20T22:02:59Z", "updated_at": "2023-03-26T23:41:12Z", "closed_at": "2022-01-20T22:53:17Z", "author_association": "OWNER", "pull_request": null, "body": "It's not currently clear what the difference between https://docs.datasette.io/en/latest/ and https://docs.datasette.io/en/stable/ is - I should fix that.\r\n\r\nOn Twitter: https://twitter.com/simonw/status/1484285006243528705", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1608/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1633077183, "node_id": "I_kwDOBm6k_c5hVse_", "number": 2041, "title": "Remove obsolete table POST code", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 8755003, "label": "Datasette 1.0a-next"}, "comments": 2, "created_at": "2023-03-21T01:01:40Z", "updated_at": "2023-03-21T01:17:44Z", "closed_at": "2023-03-21T01:17:43Z", "author_association": "OWNER", "pull_request": null, "body": "Spotted this in:\r\n- #1999\r\n\r\n`POST /db/table` currently executes obsolete code for inserting a row - I replaced that with `/db/table/-/insert` in \r\nhttps://github.com/simonw/datasette/commit/6e788b49edf4f842c0817f006eb9d865778eea5e but forgot to remove the old code.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2041/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1615891776, "node_id": "I_kwDOBm6k_c5gUI1A", "number": 2037, "title": "Test failure: FAILED tests/test_cli.py::test_install_requirements - FileNotFoundError", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2023-03-08T20:30:06Z", "updated_at": "2023-03-09T22:33:39Z", "closed_at": "2023-03-09T22:33:39Z", "author_association": "OWNER", "pull_request": null, "body": "> FAILED tests/test_cli.py::test_install_requirements - FileNotFoundError: [Errno 2] No such file or directory\r\n\r\nFrom https://github.com/simonw/datasette/actions/runs/4348548218/jobs/7597208191\r\n\r\n```\r\n=================================== FAILURES ===================================\r\n__________________________ test_install_requirements ___________________________\r\n\r\nrun_module = \r\n\r\n @mock.patch(\"datasette.cli.run_module\")\r\n def test_install_requirements(run_module):\r\n runner = CliRunner()\r\n> with runner.isolated_filesystem():\r\n\r\n/home/runner/work/datasette/datasette/tests/test_cli.py:184: \r\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \r\n/opt/hostedtoolcache/Python/3.9.16/x64/lib/python3.9/contextlib.py:119: in __enter__\r\n return next(self.gen)\r\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \r\n\r\nself = , temp_dir = None\r\n\r\n @contextlib.contextmanager\r\n def isolated_filesystem(\r\n self, temp_dir: t.Optional[t.Union[str, os.PathLike]] = None\r\n ) -> t.Iterator[str]:\r\n \"\"\"A context manager that creates a temporary directory and\r\n changes the current working directory to it. This isolates tests\r\n that affect the contents of the CWD to prevent them from\r\n interfering with each other.\r\n \r\n :param temp_dir: Create the temporary directory under this\r\n directory. If given, the created directory is not removed\r\n when exiting.\r\n \r\n .. versionchanged:: 8.0\r\n Added the ``temp_dir`` parameter.\r\n \"\"\"\r\n> cwd = os.getcwd()\r\nE FileNotFoundError: [Errno 2] No such file or directory\r\n\r\n/opt/hostedtoolcache/Python/3.9.16/x64/lib/python3.9/site-packages/click/testing.py:466: FileNotFoundError\r\n```\r\nNot sure why it only affected the \"[Calculate test coverage](https://github.com/simonw/datasette/actions/workflows/test-coverage.yml)\" one.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2037/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1615862295, "node_id": "I_kwDOBm6k_c5gUBoX", "number": 2036, "title": "`publish cloudrun` reuses image tags, which can lead to very surprising deploy problems", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 6, "created_at": "2023-03-08T20:11:44Z", "updated_at": "2023-03-08T20:57:34Z", "closed_at": "2023-03-08T20:57:34Z", "author_association": "OWNER", "pull_request": null, "body": "See this issue:\r\n- https://github.com/simonw/datasette.io/issues/141", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2036/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1612296210, "node_id": "I_kwDOBm6k_c5gGbAS", "number": 2033, "title": "`datasette install -r requirements.txt`", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2023-03-06T22:17:17Z", "updated_at": "2023-03-06T22:54:52Z", "closed_at": "2023-03-06T22:27:34Z", "author_association": "OWNER", "pull_request": null, "body": "Would be useful for cases where you want to install a whole set of plugins in one go, e.g. when running tutorials in GitHub Codespaces.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2033/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1594383280, "node_id": "I_kwDOBm6k_c5fCFuw", "number": 2030, "title": "How to use Datasette with apache webserver on GCP?", "user": {"value": 19700859, "label": "gk7279"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2023-02-22T03:08:49Z", "updated_at": "2023-02-22T21:54:39Z", "closed_at": "2023-02-22T21:54:39Z", "author_association": "NONE", "pull_request": null, "body": "Hi Simon and Datasette team-\r\n\r\nI have installed apache2 webserver inside GCP VM using apt.\r\n\r\nI can see my \"Hello World\" index.html if I use the external IP of this GCP in a browser.\r\n\r\nHowever, when I try to run datasette with different combinations of -h and -p, I am still unable to access the webpage.\r\n\r\nI cannot invest Docker on this VM.\r\n\r\nAny pointers to use datasette with already existing apache2 webserver on GCP is appreciated.\r\n\r\nThanks.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2030/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1579695809, "node_id": "I_kwDOBm6k_c5eKD7B", "number": 2023, "title": "Error: Invalid setting 'hash_urls' in settings.json in 0.64.1", "user": {"value": 80409402, "label": "mlaparie"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2023-02-10T13:35:01Z", "updated_at": "2023-02-10T15:40:00Z", "closed_at": "2023-02-10T15:39:59Z", "author_association": "NONE", "pull_request": null, "body": "On a Debian machine, using datasette 0.64.1 installed with `pip3`, I am getting a `datasette[114272]: Error: Invalid setting 'hash_urls' in settings.json` in `journalctl -xe`. The same settings work on 0.54.1 on another Debian server.\r\n\r\nThis is my `settings.json`:\r\n\r\n```json\r\n{\r\n \"default_page_size\": 200,\r\n \"max_returned_rows\": 8000,\r\n \"num_sql_threads\": 3,\r\n \"sql_time_limit_ms\": 1000,\r\n \"default_facet_size\": 30,\r\n \"facet_time_limit_ms\": 200,\r\n \"facet_suggest_time_limit_ms\": 50,\r\n \"hash_urls\": false,\r\n \"allow_facet\": true,\r\n \"allow_download\": true,\r\n \"suggest_facets\": true,\r\n \"default_cache_ttl\": 5,\r\n \"default_cache_ttl_hashed\": 31536000,\r\n \"cache_size_kb\": 0,\r\n \"allow_csv_stream\": true,\r\n \"max_csv_mb\": 100,\r\n \"truncate_cells_html\": 2048,\r\n \"force_https_urls\": false,\r\n \"template_debug\": false,\r\n \"base_url\": \"/pclim/db/\"\r\n}\r\n```\r\n\r\nThis looks ok to me. Would you have any ideas?", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2023/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1578609658, "node_id": "I_kwDOBm6k_c5eF6v6", "number": 2022, "title": "Error 500 - not clear the cause", "user": {"value": 1667631, "label": "DavidPratten"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2023-02-09T20:57:17Z", "updated_at": "2023-02-09T21:13:50Z", "closed_at": "2023-02-09T21:13:50Z", "author_association": "NONE", "pull_request": null, "body": "On the database that I have sent via linkedIn, datasette works great, but the following URL gives a 500 error.\r\n\r\nhttp://127.0.0.1:8001/literature/authors_papers?authorId=100550354\r\n\r\nThe cause of the error is not apparent.\r\n\r\nIs this expected behaviour?\r\n\r\nDavid", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/2022/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1034535001, "node_id": "I_kwDOBm6k_c49qcBZ", "number": 1497, "title": "Publish to Docker Hub failing with \"libcrypt.so.1: cannot open shared object file\"", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 18, "created_at": "2021-10-24T22:57:07Z", "updated_at": "2023-01-18T17:13:45Z", "closed_at": "2021-10-24T23:36:55Z", "author_association": "OWNER", "pull_request": null, "body": "This means the Datasette 0.59.1 release has not been published to Docker Hub.\r\n\r\nHere's where that failed: https://github.com/simonw/datasette/runs/3991043374?check_suite_focus=true\r\n\r\n```\r\nPreparing to unpack .../libc6_2.32-4_amd64.deb ...\r\ndebconf: unable to initialize frontend: Dialog\r\ndebconf: (TERM is not set, so the dialog frontend is not usable.)\r\ndebconf: falling back to frontend: Readline\r\ndebconf: unable to initialize frontend: Readline\r\ndebconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.28.1 /usr/local/share/perl/5.28.1 /usr/lib/x86_64-linux-gnu/perl5/5.28 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.28 /usr/share/perl/5.28 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7.)\r\ndebconf: falling back to frontend: Teletype\r\nChecking for services that may need to be restarted...\r\nChecking init scripts...\r\nUnpacking libc6:amd64 (2.32-4) over (2.28-10) ...\r\nSetting up libc6:amd64 (2.32-4) ...\r\n/usr/bin/perl: error while loading shared libraries: libcrypt.so.1: cannot open shared object file: No such file or directory\r\ndpkg: error processing package libc6:amd64 (--configure):\r\n installed libc6:amd64 package post-installation script subprocess returned error exit status 127\r\nErrors were encountered while processing:\r\n libc6:amd64\r\nE: Sub-process /usr/bin/dpkg returned an error code (1)\r\nThe command '/bin/sh -c apt-get update && apt-get -y --no-install-recommends install software-properties-common && add-apt-repository \"deb http://httpredir.debian.org/debian sid main\" && apt-get update && apt-get -t sid install -y --no-install-recommends libsqlite3-mod-spatialite && apt-get remove -y software-properties-common && apt clean && rm -rf /var/lib/apt && rm -rf /var/lib/dpkg/info/*' returned a non-zero code: 100\r\n```\r\nSame problem when I attempted to publish using the \"Push specific Docker tag\" workflow: https://github.com/simonw/datasette/runs/3991059912?check_suite_focus=true", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1497/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1529452371, "node_id": "I_kwDOBm6k_c5bKZdT", "number": 1987, "title": "installpython3.com is now a spam website", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 4, "created_at": "2023-01-11T17:55:12Z", "updated_at": "2023-01-11T18:29:26Z", "closed_at": "2023-01-11T18:29:25Z", "author_association": "OWNER", "pull_request": null, "body": "Need to stop linking to it from the docs.\r\n\r\nI'll link to https://www.python.org/about/gettingstarted/ instead.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1987/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1528448642, "node_id": "I_kwDOBm6k_c5bGkaC", "number": 1985, "title": "Don't let Datasette(path) without a list cause weird errors", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2023-01-11T05:17:44Z", "updated_at": "2023-01-11T18:25:04Z", "closed_at": "2023-01-11T18:25:04Z", "author_association": "OWNER", "pull_request": null, "body": "I got a confusing `sqlite3.OperationalError: disk I/O error` error in my tests, it turned out it was because this:\r\n```python\r\nds = Datasette(path)\r\n```\r\nShould have been this:\r\n```python\r\nds = Datasette([path])\r\n```\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette-faiss/issues/1#issuecomment-1378252673_\r\n ", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1985/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1515185383, "node_id": "I_kwDOBm6k_c5aT-Tn", "number": 1971, "title": "Upgrade for Sphinx 6.0 (once Furo has support for it)", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2022-12-31T19:04:35Z", "updated_at": "2023-01-10T02:02:34Z", "closed_at": "2023-01-10T02:02:34Z", "author_association": "OWNER", "pull_request": null, "body": "A deployment of #1967 to ReadTheDocs just failed like this: https://readthedocs.org/projects/datasette/builds/19045460/\r\n\r\n```\r\nRunning Sphinx v6.0.0\r\nmaking output directory... done\r\nbuilding [mo]: targets for 0 po files that are out of date\r\nbuilding [html]: targets for 28 source files that are out of date\r\nupdating environment: [new config] 28 added, 0 changed, 0 removed\r\nreading sources... [ 3%] authentication\r\nreading sources... [ 7%] binary_data\r\nreading sources... [ 10%] changelog\r\n\r\nTraceback (most recent call last):\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/statemachine.py\", line 299, in next_line\r\n self.line = self.input_lines[self.line_offset]\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/statemachine.py\", line 1136, in __getitem__\r\n return self.data[i]\r\nIndexError: list index out of range\r\n\r\nDuring handling of the above exception, another exception occurred:\r\n\r\nTraceback (most recent call last):\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/statemachine.py\", line 226, in run\r\n self.next_line()\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/statemachine.py\", line 302, in next_line\r\n raise EOFError\r\nEOFError\r\n\r\nDuring handling of the above exception, another exception occurred:\r\n\r\nTraceback (most recent call last):\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/sphinx/cmd/build.py\", line 281, in build_main\r\n app.build(args.force_all, args.filenames)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/sphinx/application.py\", line 344, in build\r\n self.builder.build_update()\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/sphinx/builders/__init__.py\", line 310, in build_update\r\n self.build(to_build,\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/sphinx/builders/__init__.py\", line 326, in build\r\n updated_docnames = set(self.read())\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/sphinx/builders/__init__.py\", line 433, in read\r\n self._read_serial(docnames)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/sphinx/builders/__init__.py\", line 454, in _read_serial\r\n self.read_doc(docname)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/sphinx/builders/__init__.py\", line 510, in read_doc\r\n publisher.publish()\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/core.py\", line 224, in publish\r\n self.document = self.reader.read(self.source, self.parser,\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/sphinx/io.py\", line 103, in read\r\n self.parse()\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/readers/__init__.py\", line 76, in parse\r\n self.parser.parse(self.input, document)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/sphinx/parsers.py\", line 78, in parse\r\n self.statemachine.run(inputlines, document, inliner=self.inliner)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 169, in run\r\n results = StateMachineWS.run(self, input_lines, input_offset,\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/statemachine.py\", line 233, in run\r\n context, next_state, result = self.check_line(\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/statemachine.py\", line 445, in check_line\r\n return method(match, context, next_state)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 3024, in text\r\n self.section(title.lstrip(), source, style, lineno + 1, messages)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 325, in section\r\n self.new_subsection(title, lineno, messages)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 391, in new_subsection\r\n newabsoffset = self.nested_parse(\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 279, in nested_parse\r\n state_machine.run(block, input_offset, memo=self.memo,\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 195, in run\r\n results = StateMachineWS.run(self, input_lines, input_offset)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/statemachine.py\", line 233, in run\r\n context, next_state, result = self.check_line(\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/statemachine.py\", line 445, in check_line\r\n return method(match, context, next_state)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 2785, in underline\r\n self.section(title, source, style, lineno - 1, messages)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 325, in section\r\n self.new_subsection(title, lineno, messages)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 391, in new_subsection\r\n newabsoffset = self.nested_parse(\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 279, in nested_parse\r\n state_machine.run(block, input_offset, memo=self.memo,\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 195, in run\r\n results = StateMachineWS.run(self, input_lines, input_offset)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/statemachine.py\", line 233, in run\r\n context, next_state, result = self.check_line(\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/statemachine.py\", line 445, in check_line\r\n return method(match, context, next_state)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 1273, in bullet\r\n i, blank_finish = self.list_item(match.end())\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 1295, in list_item\r\n self.nested_parse(indented, input_offset=line_offset,\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 279, in nested_parse\r\n state_machine.run(block, input_offset, memo=self.memo,\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 195, in run\r\n results = StateMachineWS.run(self, input_lines, input_offset)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/statemachine.py\", line 239, in run\r\n result = state.eof(context)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 2725, in eof\r\n self.blank(None, context, None)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 2716, in blank\r\n paragraph, literalnext = self.paragraph(\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 416, in paragraph\r\n textnodes, messages = self.inline_text(text, lineno)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 425, in inline_text\r\n nodes, messages = self.inliner.parse(text, lineno,\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 649, in parse\r\n before, inlines, remaining, sysmessages = method(self, match,\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 792, in interpreted_or_phrase_ref\r\n nodelist, messages = self.interpreted(rawsource, escaped, role,\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/docutils/parsers/rst/states.py\", line 889, in interpreted\r\n nodes, messages2 = role_fn(role, rawsource, text, lineno, self)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/sphinx/ext/extlinks.py\", line 101, in role\r\n title = caption % part\r\nTypeError: not all arguments converted during string formatting\r\n\r\nException occurred:\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/latest/lib/python3.9/site-packages/sphinx/ext/extlinks.py\", line 101, in role\r\n title = caption % part\r\nTypeError: not all arguments converted during string formatting\r\nThe full traceback has been saved in /tmp/sphinx-err-kq7ylgqo.log, if you want to report the issue to the developers.\r\nPlease also report this if it was a user error, so that a better error message can be provided next time.\r\nA bug report can be filed in the tracker at . Thanks! \r\n```", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1971/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 710650633, "node_id": "MDU6SXNzdWU3MTA2NTA2MzM=", "number": 979, "title": "Default table view JSON should include CREATE TABLE", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2020-09-28T23:54:58Z", "updated_at": "2023-01-09T15:32:39Z", "closed_at": "2023-01-09T15:32:22Z", "author_association": "OWNER", "pull_request": null, "body": "https://latest.datasette.io/fixtures/facetable.json doesn't currently include the CREATE TABLE statement for the page, even though it's available on the HTML version at https://latest.datasette.io/fixtures/facetable", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/979/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1522778923, "node_id": "I_kwDOBm6k_c5aw8Mr", "number": 1978, "title": "Document datasette.urls.row and row_blob", "user": {"value": 25778, "label": "eyeseast"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2023-01-06T15:45:51Z", "updated_at": "2023-01-09T14:30:00Z", "closed_at": "2023-01-09T14:30:00Z", "author_association": "CONTRIBUTOR", "pull_request": null, "body": "These are in the codebase but not in documentation. I think everything else in this class is documented.\r\n\r\n```python\r\nclass Urls:\r\n ...\r\n def row(self, database, table, row_path, format=None):\r\n path = f\"{self.table(database, table)}/{row_path}\"\r\n if format is not None:\r\n path = path_with_format(path=path, format=format)\r\n return PrefixedUrlString(path)\r\n\r\n def row_blob(self, database, table, row_path, column):\r\n return self.table(database, table) + \"/{}.blob?_blob_column={}\".format(\r\n row_path, urllib.parse.quote_plus(column)\r\n )\r\n```\r\n", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1978/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "not_planned"} {"id": 1524076587, "node_id": "I_kwDOBm6k_c5a15Ar", "number": 1979, "title": "More useful error message if enable_load_extension is not available", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 5, "created_at": "2023-01-07T19:13:19Z", "updated_at": "2023-01-08T00:21:23Z", "closed_at": "2023-01-08T00:21:23Z", "author_association": "OWNER", "pull_request": null, "body": "I get this from:\r\n\r\n datasette --load-extension spatialite --get /-/versions.json\r\n\r\n```\r\n File \"/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/datasette/app.py\", line 614, in _prepare_connection\r\n conn.enable_load_extension(True)\r\nAttributeError: 'sqlite3.Connection' object has no attribute 'enable_load_extension'\r\n```\r\nIt would be useful if Datasette caught this error and output something more friendly.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1979/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 957310278, "node_id": "MDU6SXNzdWU5NTczMTAyNzg=", "number": 1409, "title": "`default_allow_sql` setting (a re-imagining of the old `allow_sql` setting)", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 10, "created_at": "2021-07-31T19:48:56Z", "updated_at": "2023-01-07T18:06:01Z", "closed_at": "2023-01-05T00:51:31Z", "author_association": "OWNER", "pull_request": null, "body": "In 49d6d2f7b0f6cb02e25022e1c9403811f1fa0a7c as part of #813 I removed the `allow_sql` setting - on the basis that users could disable the ability to execute custom SQL queries using the new permission system instead.\r\n\r\nI don't think this was the right decision. Disabling custom SQL is an important security capability, and explaining how to do it using permissions is significantly more complex than letting people know they can add `--setting allow_sql off`.\r\n\r\nSo I want to bring that setting back - maybe with a different, better name - and have it modify the default for that option if the permissions system doesn't have an opinion.\r\n\r\nThat way people can still use the setting but then use permissions to allow specific signed-in users access to execute SQL.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1409/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1515182998, "node_id": "I_kwDOBm6k_c5aT9uW", "number": 1970, "title": "Path \"None\" in _internal database table", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2022-12-31T18:51:05Z", "updated_at": "2022-12-31T19:22:58Z", "closed_at": "2022-12-31T18:52:49Z", "author_association": "OWNER", "pull_request": null, "body": "See https://latest.datasette.io/_internal/databases (after https://latest.datasette.io/login-as-root)\r\n\r\n\"image\"\r\n", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1970/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1501900064, "node_id": "I_kwDOBm6k_c5ZhS0g", "number": 1966, "title": "Broken link to live demo in Getting started docs", "user": {"value": 7551922, "label": "lbellomo"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-12-18T13:17:00Z", "updated_at": "2022-12-31T19:15:19Z", "closed_at": "2022-12-31T19:15:10Z", "author_association": "NONE", "pull_request": null, "body": "The link in [Play with a live demo in Getting started](https://github.com/simonw/datasette/blob/main/docs/getting_started.rst#play-with-a-live-demo) to [https://fivethirtyeight.datasettes.com/fivethirtyeight](https://fivethirtyeight.datasettes.com/fivethirtyeight) is broken and the datasette is no longer working (maybe due to the end of the free tier).", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1966/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1515186569, "node_id": "I_kwDOBm6k_c5aT-mJ", "number": 1972, "title": "Fix Sphinx warning about extlink extension", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 0, "created_at": "2022-12-31T19:12:04Z", "updated_at": "2022-12-31T19:13:26Z", "closed_at": "2022-12-31T19:13:26Z", "author_association": "OWNER", "pull_request": null, "body": "```\r\n[sphinx-autobuild] > sphinx-build -b html /Users/simon/Dropbox/Development/datasette/docs /Users/simon/Dropbox/Development/datasette/docs/_build\r\nRunning Sphinx v5.3.0\r\nloading pickled environment... done\r\nWARNING: extlinks: Sphinx-6.0 will require a caption string to contain exactly one '%s' and all other '%' need to be escaped as '%%'.\r\n```\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1971#issuecomment-1368266904_\r\n ", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1972/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1496652622, "node_id": "I_kwDOBm6k_c5ZNRtO", "number": 1955, "title": "invoke_startup() is not run in some conditions, e.g. gunicorn/uvicorn workers, breaking lots of things", "user": {"value": 32839123, "label": "Rik-de-Kort"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 36, "created_at": "2022-12-14T13:39:56Z", "updated_at": "2022-12-19T04:34:16Z", "closed_at": "2022-12-18T02:45:18Z", "author_association": "NONE", "pull_request": null, "body": "In the past (pre-september 14, #1809) I had a running deployment of Datasette on Azure WebApps by emulating the call in cli.py to Gunicorn: `gunicorn -w 2 -k uvicorn.workers.UvicornWorker app:app`.\r\n\r\nMy most recent deployment, however, fails loudly by shouting that `Datasette.invoke_startup()` was not called. It does not seem to be possible to call `invoke_startup` when running using a uvicorn command directly like this (I've reproduced this locally using `uvicorn`). Two candidates that I have tried:\r\n* Uvicorn has a `--factory` option, but the app factory has to be synchronous, so no `await invoke_startup` there\r\n* `asyncio.get_event_loop().run_until_complete` is also not an option because `uvicorn` already has the event loop running.\r\n\r\nOne additional option is:\r\n* Use Gunicorn's [server hooks](https://docs.gunicorn.org/en/stable/settings.html#server-hooks) to call `invoke_startup`. These are also synchronous, but I might be able to get ahead of the event loop starting here.\r\n\r\nIn my current deployment setup, it does not appear to be possible to use `datasette serve` directly, so I'm stuck either\r\n* Trying to rework my complete deployment setup, for instance, using Azure functions as described [here](https://github.com/simonw/azure-functions-datasette))\r\n* Or dig into the ASGI spec and write a wrapper for the sole purpose of launching Datasette using a direct Uvicorn invocation.\r\n\r\nQuestions for the maintainers:\r\n* Is this intended behaviour/will not support/etc.? If so, I'd be happy to add a PR with a couple lines in the documentation.\r\n* if this is not intended behaviour, what is a good way to fix it? I could have a go at the ASGI spec thing (I think the Azure Functions thing is related) and provide a PR with the wrapper here, but I'm all ears!\r\n\r\nAlmost forgot, minimal reproducer:\r\n```python\r\nfrom datasette import Datasette\r\n\r\nds = Datasette(files=['./global-power-plants.db'])]\r\napp = ds.app()\r\n```\r\n\r\nSave as app.py in the same folder as global-power-plants.db, and then try running\r\n`uvicorn app:app`.\r\n\r\nOpening the resulting Datasette instance in the browser will show the error message.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1955/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1306984363, "node_id": "I_kwDOBm6k_c5N5v-r", "number": 1771, "title": "minor a11y: `", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1939/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1434094365, "node_id": "I_kwDOBm6k_c5Veosd", "number": 1881, "title": "Tool for simulating permission checks against actors", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 9, "created_at": "2022-11-03T04:43:20Z", "updated_at": "2022-12-09T01:38:21Z", "closed_at": "2022-11-04T00:13:05Z", "author_association": "OWNER", "pull_request": null, "body": "In working on this issue:\r\n- #1855\r\n\r\nI realized that if I'm going to make actors more complicated (the proposed `_r` key for additional restricted permissions) I really need an interactive tool for simulating these checks, similar to the https://latest.datasette.io/-/allow-debug tool.", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1881/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1432013704, "node_id": "I_kwDOBm6k_c5VWsuI", "number": 1878, "title": "/db/table/-/upsert API", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 8711695, "label": " Datasette 1.0a2"}, "comments": 8, "created_at": "2022-11-01T20:01:18Z", "updated_at": "2022-12-08T01:12:18Z", "closed_at": "2022-12-08T01:12:17Z", "author_association": "OWNER", "pull_request": null, "body": "Equivalent to `sqlite-utils upsert`: https://sqlite-utils.datasette.io/en/stable/python-api.html#upserting-data", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1878/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1473659191, "node_id": "I_kwDOBm6k_c5X1kE3", "number": 1929, "title": "Incorrect link from the API explorer to the JSON API documentation", "user": {"value": 3556, "label": "davidbgk"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 4, "created_at": "2022-12-03T02:08:58Z", "updated_at": "2022-12-06T19:36:23Z", "closed_at": "2022-12-06T19:34:20Z", "author_association": "CONTRIBUTOR", "pull_request": null, "body": "I installed `datasette==1.0a1`.\r\n\r\nWhen I go to http://127.0.0.1:8001/-/api I have a link: `Use this tool to try out the [Datasette API](https://docs.datasette.io/en/1.0a1/json_api.html).` but that documentation page does not exist.\r\n\r\nI'm not sure where it has to be fixed, should it link to the stable page https://docs.datasette.io/en/stable/json_api.html , the latest one https://docs.datasette.io/en/latest/json_api.html#the-json-write-api or would it be more appropriated to deploy documentation for the `1.0a1` version?", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1929/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1473481262, "node_id": "I_kwDOBm6k_c5X04ou", "number": 1928, "title": "Hacker News Datasette write demo", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 7, "created_at": "2022-12-02T21:17:41Z", "updated_at": "2022-12-02T23:47:11Z", "closed_at": "2022-12-02T21:43:19Z", "author_association": "OWNER", "pull_request": null, "body": "Idea is to have my existing scraper at https://github.com/simonw/scrape-hacker-news-by-domain also write to my private Datasette Cloud account, then create an atom feed from it.\r\n\r\n", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1928/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1471969984, "node_id": "I_kwDOBm6k_c5XvHrA", "number": 1926, "title": "Release notes for 1.0a1 (and release it)", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7867486, "label": "Datasette 1.0a1"}, "comments": 1, "created_at": "2022-12-01T21:18:12Z", "updated_at": "2022-12-01T22:06:13Z", "closed_at": "2022-12-01T22:06:12Z", "author_association": "OWNER", "pull_request": null, "body": "Mainly CORS support and a few small bug fixes.\r\n\r\nChanges: https://github.com/simonw/datasette/compare/1.0a0...99da46f7258225fc6fd8e94ddc20859ccccc4109", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1926/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1214859703, "node_id": "I_kwDOBm6k_c5IaUm3", "number": 1719, "title": "Refactor `RowView` and remove `RowTableShared`", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2022-04-25T18:06:24Z", "updated_at": "2022-12-01T21:15:19Z", "closed_at": "2022-04-25T18:33:44Z", "author_association": "OWNER", "pull_request": null, "body": "> The `RowTableShared` class is making this a whole lot more complicated.\r\n> \r\n> I'm going to split the `RowView` view out into an entirely separate `views/row.py` module.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1715#issuecomment-1108875068_", "repo": {"value": 107914493, "label": "datasette"}, "type": "issue", "active_lock_reason": null, "performed_via_github_app": null, "reactions": "{\"url\": \"https://api.github.com/repos/simonw/datasette/issues/1719/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"}