{"id": 1055469073, "node_id": "I_kwDOBm6k_c4-6S4R", "number": 1513, "title": "Research: CTEs and union all to calculate facets AND query at the same time", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 12, "created_at": "2021-11-16T22:26:45Z", "updated_at": "2021-11-16T23:41:46Z", "closed_at": "2021-11-16T23:41:46Z", "author_association": "OWNER", "pull_request": null, "body": "Consider this page: https://global-power-plants.datasettes.com/global-power-plants/global-power-plants?_search=plant&_facet=owner&_facet=country_long&_facet=primary_fuel\r\n\r\nDatasette needs to run the main query for the rows on that page, a count query for the total query, then a separate query for each of those three specified facets.\r\n\r\nThis is a `_search=` query, so it needs to execute the FTS code once for the rows, again for the count, and then three more times for each of the facets.\r\n\r\nCould running that query as a CTE and doing the other queries as part of the same large query produce significant speed improvements?", "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/1513/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": 1050163432, "node_id": "I_kwDOBm6k_c4-mDjo", "number": 1503, "title": "`?_nocol=` removes that column from the filter interface", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2021-11-10T18:22:50Z", "updated_at": "2021-11-14T05:08:27Z", "closed_at": "2021-11-14T04:53:07Z", "author_association": "OWNER", "pull_request": null, "body": "e.g. on https://latest.datasette.io/fixtures/sortable?_nocol=sortable\r\n\r\n\"fixtures__sortable__201_rows\"\r\n\r\nThis causes weird behaviour when you e.g. facet by a hidden column, since selecting facets and then re-submitting the form will clear the selected filter.\r\n\r\n![nocol-bug](https://user-images.githubusercontent.com/9599/141171135-aded71d1-a4cb-4b7f-a4ea-26828fa98906.gif)\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/1503/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": 1052826038, "node_id": "I_kwDOBm6k_c4-wNm2", "number": 1506, "title": "Columns beginning with an underscore do not facet correctly", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2021-11-14T02:20:32Z", "updated_at": "2021-11-14T04:45:21Z", "closed_at": "2021-11-14T04:45:21Z", "author_association": "OWNER", "pull_request": null, "body": "Datasette treats columns that start with an underscore as querystring parameters it should ignore!\r\n\r\n\"bchydro__item_versions__99_918_rows\"\r\n\r\nDiscovered in https://github.com/simonw/git-history/issues/14#issuecomment-968192464", "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/1506/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": 1052851176, "node_id": "I_kwDOBm6k_c4-wTvo", "number": 1507, "title": "ReadTheDocs build failed for 0.59.2 release", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 6, "created_at": "2021-11-14T05:24:34Z", "updated_at": "2021-11-14T05:41:55Z", "closed_at": "2021-11-14T05:41:55Z", "author_association": "OWNER", "pull_request": null, "body": "I had to cancel the 0.59.2 release because ReadTheDocs was failing to build the documentation.\r\n\r\nhttps://readthedocs.org/projects/datasette/builds/15268454/\r\n\r\n```\r\n /home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/0.59.2/bin/python -m sphinx -T -b html -d _build/doctrees -D language=en . _build/html\r\nRunning Sphinx v1.8.5\r\nloading translations [en]... done\r\nmaking output directory...\r\nbuilding [mo]: targets for 0 po files that are out of date\r\nbuilding [html]: targets for 27 source files that are out of date\r\nupdating environment: 27 added, 0 changed, 0 removed\r\nreading sources... [ 3%] authentication\r\n\r\nTraceback (most recent call last):\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/0.59.2/lib/python2.7/site-packages/sphinx/cmd/build.py\", line 304, in build_main\r\n app.build(args.force_all, filenames)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/0.59.2/lib/python2.7/site-packages/sphinx/application.py\", line 341, in build\r\n self.builder.build_update()\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/0.59.2/lib/python2.7/site-packages/sphinx/builders/__init__.py\", line 347, in build_update\r\n len(to_build))\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/0.59.2/lib/python2.7/site-packages/sphinx/builders/__init__.py\", line 360, in build\r\n updated_docnames = set(self.read())\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/0.59.2/lib/python2.7/site-packages/sphinx/builders/__init__.py\", line 468, in read\r\n self._read_serial(docnames)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/0.59.2/lib/python2.7/site-packages/sphinx/builders/__init__.py\", line 490, in _read_serial\r\n self.read_doc(docname)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/0.59.2/lib/python2.7/site-packages/sphinx/builders/__init__.py\", line 534, in read_doc\r\n doctree = read_doc(self.app, self.env, self.env.doc2path(docname))\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/0.59.2/lib/python2.7/site-packages/sphinx/io.py\", line 318, in read_doc\r\n pub.publish()\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/0.59.2/lib/python2.7/site-packages/docutils/core.py\", line 219, in publish\r\n self.apply_transforms()\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/0.59.2/lib/python2.7/site-packages/docutils/core.py\", line 200, in apply_transforms\r\n self.document.transformer.apply_transforms()\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/0.59.2/lib/python2.7/site-packages/sphinx/transforms/__init__.py\", line 90, in apply_transforms\r\n Transformer.apply_transforms(self)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/0.59.2/lib/python2.7/site-packages/docutils/transforms/__init__.py\", line 171, in apply_transforms\r\n transform.apply(**kwargs)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/0.59.2/lib/python2.7/site-packages/sphinx/transforms/__init__.py\", line 245, in apply\r\n apply_source_workaround(n)\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/0.59.2/lib/python2.7/site-packages/sphinx/util/nodes.py\", line 94, in apply_source_workaround\r\n for classifier in reversed(node.parent.traverse(nodes.classifier)):\r\nTypeError: argument to reversed() must be a sequence\r\n\r\nException occurred:\r\n File \"/home/docs/checkouts/readthedocs.org/user_builds/datasette/envs/0.59.2/lib/python2.7/site-packages/sphinx/util/nodes.py\", line 94, in apply_source_workaround\r\n for classifier in reversed(node.parent.traverse(nodes.classifier)):\r\nTypeError: argument to reversed() must be a sequence\r\nThe full traceback has been saved in /tmp/sphinx-err-vkl0oE.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/1507/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": 1021550542, "node_id": "I_kwDOBm6k_c4845_O", "number": 1482, "title": "Support Python 3.10", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2021-10-09T00:30:52Z", "updated_at": "2021-10-24T22:21:40Z", "closed_at": "2021-10-24T22:19:55Z", "author_association": "OWNER", "pull_request": null, "body": "I started work on this in #1481 where I found a Python 3.10 bug that needs a workaround in Janus, see:\r\n\r\n- https://github.com/aio-libs/janus/issues/358\r\n\r\nThis is a tracking issue for anything else that shows up.\r\n\r\nThis is also needed for the Homebrew package to upgrade to 3.10:\r\n\r\n- https://github.com/Homebrew/homebrew-core/pull/86932", "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/1482/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": 1021849766, "node_id": "I_kwDOBm6k_c486DCm", "number": 1483, "title": "Running a search on page 2 of results should not preserve ?_next=", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 0, "created_at": "2021-10-10T01:18:12Z", "updated_at": "2021-10-13T21:08:10Z", "closed_at": "2021-10-13T21:08:10Z", "author_association": "OWNER", "pull_request": null, "body": "Reported by @eigenfoo in https://github.com/simonw/datasette/issues/1470", "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/1483/reactions\", \"total_count\": 2, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 1, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1025754125, "node_id": "I_kwDOBm6k_c49I8QN", "number": 1488, "title": "Upgrade to httpx 0.20.0 (request() got an unexpected keyword argument 'allow_redirects')", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 5, "created_at": "2021-10-13T22:37:22Z", "updated_at": "2021-10-14T18:03:45Z", "closed_at": "2021-10-14T18:03:45Z", "author_association": "OWNER", "pull_request": null, "body": "This is caused by a change made to `httpx` in https://github.com/encode/httpx/releases/tag/0.20.0", "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/1488/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": 1033864602, "node_id": "I_kwDOBm6k_c49n4Wa", "number": 1496, "title": "Named parameters docs should include an example of a cast", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2021-10-22T18:56:04Z", "updated_at": "2021-10-22T19:38:23Z", "closed_at": "2021-10-22T19:34:27Z", "author_association": "OWNER", "pull_request": null, "body": "https://docs.datasette.io/en/stable/sql_queries.html#named-parameters\r\n\r\nIt's not obvious that the values from parameters are always SQLite strings, which means that you can't do e.g. integer comparisons on them without casting them first. The documentation here should include an example 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/1496/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": 1057996111, "node_id": "I_kwDOBm6k_c4_D71P", "number": 1517, "title": "Let `register_routes()` over-ride default routes within Datasette", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 2, "created_at": "2021-11-19T00:22:15Z", "updated_at": "2021-11-19T03:20:00Z", "closed_at": "2021-11-19T03:07:27Z", "author_association": "OWNER", "pull_request": null, "body": "See https://github.com/simonw/datasette/issues/878#issuecomment-973554024_ - right now `register_routes()` can't replace default Datasette routes.\r\n\r\nIt would be neat if plugins could do this - especially if there was a neat documented way for them to then re-dispatch to the original route code after making some kind of modification.", "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/1517/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": 1058815557, "node_id": "I_kwDOBm6k_c4_HD5F", "number": 1521, "title": "Docker configuration for exercising Datasette behind Apache mod_proxy", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 10, "created_at": "2021-11-19T18:46:18Z", "updated_at": "2021-11-19T20:32:29Z", "closed_at": "2021-11-19T20:32:29Z", "author_association": "OWNER", "pull_request": null, "body": "> Having a live demo running on Cloud Run that proxies through Apache and uses `base_url` would be incredibly useful for replicating and debugging this kind of thing. I wonder how hard it is to run Apache and `mod_proxy` in the same Docker container as Datasette?\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1519#issuecomment-974310208_", "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/1521/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": 1058896236, "node_id": "I_kwDOBm6k_c4_HXls", "number": 1522, "title": "Deploy a live instance of demos/apache-proxy", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 34, "created_at": "2021-11-19T20:32:55Z", "updated_at": "2021-11-23T03:00:34Z", "closed_at": "2021-11-20T18:51:56Z", "author_association": "OWNER", "pull_request": null, "body": "> I'll get this working on my laptop first, but then I want to get it up and running on Cloud Run - maybe with a GitHub Actions workflow in this repo that re-deploys it on manual execution.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1521#issuecomment-974322178_\r\n\r\nI started by following https://ahmet.im/blog/cloud-run-multiple-processes-easy-way/ - see example in https://github.com/ahmetb/multi-process-container-lazy-solution", "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/1522/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": 1059219106, "node_id": "I_kwDOBm6k_c4_Imai", "number": 1524, "title": "Improve Apache proxy documentation, link to demo", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 4, "created_at": "2021-11-20T20:03:14Z", "updated_at": "2021-11-20T23:34:03Z", "closed_at": "2021-11-20T23:34:03Z", "author_association": "OWNER", "pull_request": null, "body": "> The latest demo is now live at https://datasette-apache-proxy-demo.fly.dev/prefix/fixtures/sortable?_facet=pk2\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1519#issuecomment-974697824_\r\n\r\nI'm going to put out 0.59.3 bugfix release with this, but I'd like to first improve the documentation on https://docs.datasette.io/en/stable/deploying.html#apache-proxy-configuration to highlight the new demo.", "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/1524/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": 1059555791, "node_id": "I_kwDOBm6k_c4_J4nP", "number": 1527, "title": "Columns starting with an underscore behave poorly in filters", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 7, "created_at": "2021-11-22T01:01:36Z", "updated_at": "2022-01-14T00:57:08Z", "closed_at": "2022-01-14T00:57:08Z", "author_association": "OWNER", "pull_request": null, "body": "Similar bug to #1525 (and #1506 before it). Start on https://latest.datasette.io/fixtures/facetable?_facet=_neighborhood - then select a neighborhood - then try to remove that filter using the little \"x\" and submitting the form again.\r\n\r\n![filter-bug](https://user-images.githubusercontent.com/9599/142786754-31d265a2-944d-4ea2-af6f-305d445a2ccb.gif)\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/1527/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": 1059509927, "node_id": "I_kwDOBm6k_c4_Jtan", "number": 1525, "title": "\"Links from other tables\" broken for columns starting with underscore", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2021-11-21T22:55:08Z", "updated_at": "2021-11-30T06:39:01Z", "closed_at": "2021-11-30T06:34:35Z", "author_association": "OWNER", "pull_request": null, "body": "Same bug as #1506, this time it's this link or the row page:\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/1525/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": 1073712378, "node_id": "I_kwDOBm6k_c4__4z6", "number": 1544, "title": "Code that detects the label column for a table is case-sensitive", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2021-12-07T20:01:25Z", "updated_at": "2021-12-07T20:03:43Z", "closed_at": "2021-12-07T20:03:43Z", "author_association": "OWNER", "pull_request": null, "body": "I just noticed that a column called `Name` is not being picked up as the label column for a 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/1544/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": 1065431383, "node_id": "I_kwDOBm6k_c4_gTFX", "number": 1533, "title": "Add `Link: rel=\"alternate\"` header pointing to JSON for a table/query", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 4, "created_at": "2021-11-28T20:43:25Z", "updated_at": "2022-02-02T07:56:51Z", "closed_at": "2022-02-02T07:49:33Z", "author_association": "OWNER", "pull_request": null, "body": "Originally explored in https://github.com/simonw/datasette-notebook/issues/2#issuecomment-980789406 - I wanted an efficient way to scan a list of URLs and figure out which if any of those corresponded to Datasette tables, canned queries or SQL output that could be represented as a table on a page.\r\n\r\nIt looks like a neat way to do that is with ` Link:` header like this:\r\n\r\n`Link: http://127.0.0.1:8058/fixtures/compound_three_primary_keys.json; rel=\"alternate\"; type=\"application/datasette+json\"`\r\n\r\nI can put a ` `context_vars` can solve this but they were introduced in Python 3.7: https://www.python.org/dev/peps/pep-0567/\r\n>\r\n> Python 3.6 support ends in a few days time, and it looks like Glitch has updated to 3.7 now - so maybe I can get away with Datasette needing 3.7 these days?\r\n>\r\n> Tweeted about that here: https://twitter.com/simonw/status/1473761478155010048\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1576#issuecomment-999878907_", "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/1577/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": 1087931918, "node_id": "I_kwDOBm6k_c5A2IYO", "number": 1579, "title": "`.execute_write(... block=True)` should be the default behaviour", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 7, "created_at": "2021-12-23T18:54:28Z", "updated_at": "2022-01-13T22:28:08Z", "closed_at": "2021-12-23T19:18:26Z", "author_association": "OWNER", "pull_request": null, "body": "Every single piece of code I've written against the write APIs has used the `block=True` option to wait for the result.\r\n\r\nWithout that, it instead fires the write into the queue but then continues even before it has finished executing.\r\n\r\n`block=True` should clearly be the default behaviour here!", "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/1579/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": 1077893013, "node_id": "I_kwDOBm6k_c5AP1eV", "number": 1551, "title": "`keep_blank_values=True` when parsing `request.args`", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 3, "created_at": "2021-12-12T19:53:07Z", "updated_at": "2022-01-13T22:26:04Z", "closed_at": "2021-12-12T20:02:01Z", "author_association": "OWNER", "pull_request": null, "body": "This code in `TableView` wouldn't be necessary: https://github.com/simonw/datasette/blob/492f9835aa7e90540dd0c6324282b109f73df71b/datasette/views/table.py#L396-L399\r\n\r\nIf that happened here instead: https://github.com/simonw/datasette/blob/492f9835aa7e90540dd0c6324282b109f73df71b/datasette/utils/asgi.py#L98-L100\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1518#issuecomment-991827468_", "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/1551/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": 1079149656, "node_id": "I_kwDOBm6k_c5AUoRY", "number": 1555, "title": "Optimize all those calls to index_list and foreign_key_list", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 27, "created_at": "2021-12-13T23:50:56Z", "updated_at": "2022-01-13T22:27:32Z", "closed_at": "2021-12-19T20:55:59Z", "author_association": "OWNER", "pull_request": null, "body": "On the first hit to a restarted index I'm seeing this in the SQL traces: https://latest-with-plugins.datasette.io/github/commits?_trace=1\r\n\r\n\"image\"\r\n\r\nI imagine this could be sped up a lot using tricks like this one from the SQLite documentation: https://sqlite.org/pragma.html#pragfunc\r\n\r\n```sql\r\nSELECT DISTINCT m.name || '.' || ii.name AS 'indexed-columns'\r\n FROM sqlite_schema AS m,\r\n pragma_index_list(m.name) AS il,\r\n pragma_index_info(il.name) AS ii\r\n WHERE m.type='table'\r\n ORDER BY 1;\r\n```\r\nhttps://latest-with-plugins.datasette.io/fixtures?sql=SELECT+DISTINCT+m.name+%7C%7C+%27.%27+%7C%7C+ii.name+AS+%27indexed-columns%27%0D%0A++FROM+sqlite_schema+AS+m%2C%0D%0A+++++++pragma_index_list%28m.name%29+AS+il%2C%0D%0A+++++++pragma_index_info%28il.name%29+AS+ii%0D%0A+WHERE+m.type%3D%27table%27%0D%0A+ORDER+BY+1%3B", "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/1555/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": 1081318247, "node_id": "I_kwDOBm6k_c5Ac5tn", "number": 1556, "title": "Show count of facet values always, not just for `?_facet_size=max`", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 1, "created_at": "2021-12-15T17:49:01Z", "updated_at": "2022-01-13T22:26:07Z", "closed_at": "2021-12-15T17:58:06Z", "author_association": "OWNER", "pull_request": null, "body": "> You've caused me to rethink this feature - I no longer think there's value in only showing these numbers if `?_facet_size=max` as opposed to all of the time.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1423#issuecomment-995023410_", "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/1556/reactions\", \"total_count\": 1, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 1, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1082564912, "node_id": "I_kwDOBm6k_c5AhqEw", "number": 1557, "title": "`?_nosuggest=1` parameter for disabling facet suggestions on table view", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 1, "created_at": "2021-12-16T19:21:42Z", "updated_at": "2022-01-13T22:26:48Z", "closed_at": "2021-12-16T19:24:59Z", "author_association": "OWNER", "pull_request": null, "body": "Found I wanted this while I was debugging #625 just to clean up the debug traces, but it makes sense as a partner to `?_nofacet=1` and `?_nocount=1` from #1350 and #1353.", "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/1557/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": 1082746149, "node_id": "I_kwDOBm6k_c5AiWUl", "number": 1560, "title": "Table page title has \"where where\" in it", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 0, "created_at": "2021-12-17T00:05:48Z", "updated_at": "2022-01-13T22:28:35Z", "closed_at": "2022-01-13T22:20:15Z", "author_association": "OWNER", "pull_request": null, "body": "Just noticed this while working on #1518.\r\n\r\n```\r\n% curl -s 'https://latest.datasette.io/fixtures/facetable?_sort=pk&on_earth__exact=1' | grep -C 1 ''\r\n<head>\r\n <title>fixtures: facetable: 14 rows\r\n where where on_earth = 1 sorted by pk\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/1560/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": 1083669410, "node_id": "I_kwDOBm6k_c5Al3ui", "number": 1566, "title": "Release Datasette 0.60", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 6, "created_at": "2021-12-17T22:58:12Z", "updated_at": "2022-01-14T01:59:55Z", "closed_at": "2022-01-14T01:59:55Z", "author_association": "OWNER", "pull_request": null, "body": "Using this as a tracking issue. I'm hoping to get the bulk of the JSON redesign work from the refactor in #1554 in for this release.", "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/1566/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": 1083573206, "node_id": "I_kwDOBm6k_c5AlgPW", "number": 1563, "title": "Datasette(... files=) should not be a required argument", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 2, "created_at": "2021-12-17T19:54:18Z", "updated_at": "2022-01-13T22:27:18Z", "closed_at": "2021-12-18T02:19:40Z", "author_association": "OWNER", "pull_request": null, "body": "```pycon\r\n>>> ds = Datasette(memory=True)\r\nTraceback (most recent call last):\r\n File \"\", line 1, in \r\nTypeError: __init__() missing 1 required positional argument: 'files'\r\n>>> ds = Datasette(memory=True, files=[])\r\n```\r\nI wanted to create an in-memory Datasette for running some tests, no point in forcing me to pass `files=[]` to do that.", "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/1563/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": 1083581011, "node_id": "I_kwDOBm6k_c5AliJT", "number": 1564, "title": "_prepare_connection not called on write connections", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 1, "created_at": "2021-12-17T20:06:47Z", "updated_at": "2022-01-20T21:29:43Z", "closed_at": "2021-12-18T01:58:44Z", "author_association": "OWNER", "pull_request": null, "body": "I was trying to initalize SpatiaLite in a write connection:\r\n```pycon\r\n>>> from datasette.app import Datasette\r\n>>> ds = Datasette(memory=True, files=[], sqlite_extensions=[\"spatialite\"])\r\n>>> db = ds.add_memory_database('geo')\r\n>>> await db.execute_write(\"select InitSpatialMetadata(1)\")\r\nUUID('3f143baa-4e3d-5842-a36f-4fa2f683b72f')\r\nno such function: InitSpatialMetadata\r\n```\r\nIt looks like the code that loads additional modules only works on read-only connections, not on write connections:\r\n\r\nhttps://github.com/simonw/datasette/blob/92a5280d2e75c39424a75ad6226fc74400ae984f/datasette/database.py#L146-L153\r\n\r\nCompared to:\r\n\r\nhttps://github.com/simonw/datasette/blob/92a5280d2e75c39424a75ad6226fc74400ae984f/datasette/database.py#L124-L132", "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/1564/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": 1083921371, "node_id": "I_kwDOBm6k_c5Am1Pb", "number": 1570, "title": "Separate db.execute_write() into three methods", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 2, "created_at": "2021-12-18T18:45:54Z", "updated_at": "2022-01-13T22:27:38Z", "closed_at": "2021-12-18T18:57:25Z", "author_association": "OWNER", "pull_request": null, "body": "> Rather than adding a `executemany=True` parameter, I'm now thinking a better design might be to have three methods:\r\n>\r\n> - `db.execute_write(sql, params=None, block=False)`\r\n> - `db.execute_write_script(sql, block=False)`\r\n> - `db.execute_write_many(sql, params_seq, block=False)`\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1555#issuecomment-997267416_", "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/1570/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": 1083927147, "node_id": "I_kwDOBm6k_c5Am2pr", "number": 1571, "title": "Track number of executions for execute_write_many() in traces", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 0, "created_at": "2021-12-18T19:16:17Z", "updated_at": "2022-01-13T22:27:49Z", "closed_at": "2021-12-19T20:30:40Z", "author_association": "OWNER", "pull_request": null, "body": "Spotted while working on #1555\r\n\r\n\"image\"\r\n\r\nThere's no indication there of how many times `execute_write_many()` executed the SQL.\r\n\r\nSolving this is a tiny bit tricky because `params_seq` is an iterator that we don't want to exhaust before passing it to `conn.executemany()` - so we need to instead wrap it in something that counts how many times it was called.\r\n\r\nBut then we need a way to attach that to the trace here: https://github.com/simonw/datasette/blob/d637ed46762fdbbd8e32b86f258cd9a53c1cfdc7/datasette/database.py#L115-L122\r\n\r\nSo probably need to redesign the `trace()` decorator to allow extra pairs to be attached to it within the `with` statement.\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/1571/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": 1083718998, "node_id": "I_kwDOBm6k_c5AmD1W", "number": 1567, "title": "Remove undocumented sqlite_functions mechanism", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 0, "created_at": "2021-12-18T01:51:10Z", "updated_at": "2022-01-13T22:27:04Z", "closed_at": "2021-12-18T01:54:46Z", "author_association": "OWNER", "pull_request": null, "body": "I added this in 0b8c1b0a6da9cb8ac0d28cc90dd783de87554036 but it's never been documented and the same thing can now be achieved using the `prepare_connection` plugin hook.\r\n\r\nhttps://github.com/simonw/datasette/blob/0c91e59d2bbfc08884cfcf5d1b902a2f4968b7ff/datasette/app.py#L262\r\n\r\nhttps://github.com/simonw/datasette/blob/0c91e59d2bbfc08884cfcf5d1b902a2f4968b7ff/datasette/app.py#L551-L552\r\n\r\nIt's used here in the tests:\r\n\r\nhttps://github.com/simonw/datasette/blob/69244a617b1118dcbd04a8f102173f04680cf08c/tests/fixtures.py#L156", "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/1567/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": 1083726550, "node_id": "I_kwDOBm6k_c5AmFrW", "number": 1568, "title": "Trace should show queries on the write connection too", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 2, "created_at": "2021-12-18T02:34:12Z", "updated_at": "2022-01-13T22:27:23Z", "closed_at": "2021-12-18T02:42:34Z", "author_association": "OWNER", "pull_request": null, "body": "> Here's why - `trace` only applies to read, not write SQL operations: https://github.com/simonw/datasette/blob/7c8f8aa209e4ba7bf83976f8495d67c28fbfca24/datasette/database.py#L209-L211\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1555#issuecomment-997128508_", "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/1568/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": 1083895395, "node_id": "I_kwDOBm6k_c5Amu5j", "number": 1569, "title": "db.execute_write(..., executescript=True) parameter", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 2, "created_at": "2021-12-18T18:20:47Z", "updated_at": "2022-01-13T22:27:27Z", "closed_at": "2021-12-18T18:34:18Z", "author_association": "OWNER", "pull_request": null, "body": "> Idea: teach `execute_write` to accept an optional `executescript=True` parameter, like this:\r\n```diff\r\ndiff --git a/datasette/database.py b/datasette/database.py\r\nindex 468e936..1a424f5 100644\r\n--- a/datasette/database.py\r\n+++ b/datasette/database.py\r\n@@ -94,10 +94,14 @@ class Database:\r\n f\"file:{self.path}{qs}\", uri=True, check_same_thread=False\r\n )\r\n \r\n- async def execute_write(self, sql, params=None, block=False):\r\n+ async def execute_write(self, sql, params=None, executescript=False, block=False):\r\n+ assert not executescript and params, \"Cannot use params with executescript=True\"\r\n def _inner(conn):\r\n with conn:\r\n- return conn.execute(sql, params or [])\r\n+ if executescript:\r\n+ return conn.executescript(sql)\r\n+ else:\r\n+ return conn.execute(sql, params or [])\r\n \r\n with trace(\"sql\", database=self.name, sql=sql.strip(), params=params):\r\n results = await self.execute_write_fn(_inner, block=block)\r\n```\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1555#issuecomment-997248364_", "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/1569/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": 1084007781, "node_id": "I_kwDOBm6k_c5AnKVl", "number": 1572, "title": "\"Query took\" should be \"Queries took\"", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 0, "created_at": "2021-12-19T04:03:00Z", "updated_at": "2022-01-13T22:27:43Z", "closed_at": "2021-12-19T04:03:24Z", "author_association": "OWNER", "pull_request": null, "body": "This is misleading, since usually there have been more than one query executed:\r\n\r\n![CleanShot 2021-12-18 at 20 02 35@2x](https://user-images.githubusercontent.com/9599/146663457-9c4c2900-5cc0-4650-a565-bb1ff0b8a725.png)\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/1572/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": 1084257842, "node_id": "I_kwDOBm6k_c5AoHYy", "number": 1575, "title": "__call__() got an unexpected keyword argument 'specname'", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2021-12-20T01:24:04Z", "updated_at": "2021-12-20T01:48:03Z", "closed_at": "2021-12-20T01:47:57Z", "author_association": "OWNER", "pull_request": null, "body": "> I've installed the alpha version but get an error when starting up Datasette:\r\n\r\n```\r\nTraceback (most recent call last):\r\n File \"/Users/tim/.pyenv/versions/stock-exchange/bin/datasette\", line 5, in \r\n from datasette.cli import cli\r\n File \"/Users/tim/.pyenv/versions/3.8.5/envs/stock-exchange/lib/python3.8/site-packages/datasette/cli.py\", line 15, in \r\n from .app import Datasette, DEFAULT_SETTINGS, SETTINGS, SQLITE_LIMIT_ATTACHED, pm\r\n File \"/Users/tim/.pyenv/versions/3.8.5/envs/stock-exchange/lib/python3.8/site-packages/datasette/app.py\", line 31, in \r\n from .views.database import DatabaseDownload, DatabaseView\r\n File \"/Users/tim/.pyenv/versions/3.8.5/envs/stock-exchange/lib/python3.8/site-packages/datasette/views/database.py\", line 25, in \r\n from datasette.plugins import pm\r\n File \"/Users/tim/.pyenv/versions/3.8.5/envs/stock-exchange/lib/python3.8/site-packages/datasette/plugins.py\", line 29, in \r\n mod = importlib.import_module(plugin)\r\n File \"/Users/tim/.pyenv/versions/3.8.5/lib/python3.8/importlib/__init__.py\", line 127, in import_module\r\n return _bootstrap._gcd_import(name[level:], package, level)\r\n File \"/Users/tim/.pyenv/versions/3.8.5/envs/stock-exchange/lib/python3.8/site-packages/datasette/filters.py\", line 9, in \r\n @hookimpl(specname=\"filters_from_request\")\r\nTypeError: __call__() got an unexpected keyword argument 'specname'\r\n```\r\n\r\n_Originally posted by @wragge in https://github.com/simonw/datasette/issues/1547#issuecomment-997511968_", "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/1575/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": 1087181951, "node_id": "I_kwDOBm6k_c5AzRR_", "number": 1576, "title": "Traces should include SQL executed by subtasks created with `asyncio.gather`", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 12, "created_at": "2021-12-22T20:52:02Z", "updated_at": "2022-02-05T05:21:35Z", "closed_at": "2022-02-05T05:19:53Z", "author_association": "OWNER", "pull_request": null, "body": "I tried running some parallel SQL queries using `asyncio.gather()` but the SQL that was executed didn't show up in the trace rendered by https://datasette.io/plugins/datasette-pretty-traces\r\n\r\nI realized that was because traces are keyed against the current task ID, which changes when a sub-task is run using `asyncio.gather` or similar.\r\n\r\nThe faceting and suggest faceting queries are missing from this trace:\r\n\r\n![image](https://user-images.githubusercontent.com/9599/147153855-2d611f07-922a-4d18-9e6e-4be89e010dc4.png)\r\n\r\n> The reason they aren't showing up in the traces is that traces are stored just for the currently executing `asyncio` task ID: https://github.com/simonw/datasette/blob/ace86566b28280091b3844cf5fbecd20158e9004/datasette/tracer.py#L13-L25\r\n>\r\n> This is so traces for other incoming requests don't end up mixed together. But there's no current mechanism to track async tasks that are effectively \"child tasks\" of the current request, and hence should be tracked the same.\r\n>\r\n> https://stackoverflow.com/a/69349501/6083 suggests that you pass the task ID as an argument to the child tasks that are executed using `asyncio.gather()` to work around this kind of problem.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1518#issuecomment-999870993_", "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/1576/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": 1104691662, "node_id": "I_kwDOBm6k_c5B2EHO", "number": 1600, "title": "plugins --all example should use cog", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-01-15T11:47:49Z", "updated_at": "2022-01-20T05:06:21Z", "closed_at": "2022-01-20T05:04:16Z", "author_association": "OWNER", "pull_request": null, "body": "The example output for `datasette plugins --all`on this page has got out of date: https://docs.datasette.io/en/stable/plugins.html#seeing-what-plugins-are-installed", "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/1600/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": 1097040427, "node_id": "I_kwDOBm6k_c5BY4Ir", "number": 1587, "title": "Add `sqlite_stat1`(-4) tables to hidden table list", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2022-01-08T21:28:20Z", "updated_at": "2022-01-20T04:12:59Z", "closed_at": "2022-01-20T04:12:59Z", "author_association": "OWNER", "pull_request": null, "body": "> Running `ANALYZE` creates a new visible table called `sqlite_stat1`: https://www.sqlite.org/fileformat.html#the_sqlite_stat1_table\r\n>\r\n> This should be added to the default list of hidden tables in Datasette.", "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/1587/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": 1097101917, "node_id": "I_kwDOBm6k_c5BZHJd", "number": 1588, "title": "`explain query plan select` is too strict about whitespace", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 3, "created_at": "2022-01-09T04:22:42Z", "updated_at": "2022-01-13T22:28:19Z", "closed_at": "2022-01-13T20:35:05Z", "author_association": "OWNER", "pull_request": null, "body": "`explain query plan select * from facetable` is allowed: https://latest.datasette.io/fixtures?sql=explain+query+plan+select+*+from+facetable\r\n\r\nBut... `explain query plan select * from facetable` (with two spaces before the `select`) returns a \"Statement must be a SELECT\" error: https://latest.datasette.io/fixtures?sql=explain+query+plan++select+*+from+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/1588/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": 1102359726, "node_id": "I_kwDOBm6k_c5BtKyu", "number": 1594, "title": "Add a CLI reference page to the docs, inspired by sqlite-utils", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 3, "created_at": "2022-01-13T20:55:08Z", "updated_at": "2022-01-13T22:28:22Z", "closed_at": "2022-01-13T21:38:48Z", "author_association": "OWNER", "pull_request": null, "body": "Thought of this while posting this comment: https://github.com/simonw/datasette/issues/1591#issuecomment-1012506595\r\n\r\nI added https://sqlite-utils.datasette.io/en/stable/cli-reference.html to `sqlite-utils` in https://github.com/simonw/sqlite-utils/issues/383 and I _really_ like it - it's a page showing the `--help` output of every CLI command for that tool.\r\n\r\nIt's maintained using `cog`. One of the benefits is that I get a free commit history of changes to `--help` at https://github.com/simonw/sqlite-utils/commits/main/docs/cli-reference.rst", "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/1594/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": 1102484126, "node_id": "I_kwDOBm6k_c5BtpKe", "number": 1595, "title": "Release notes for 0.60", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 7571612, "label": "Datasette 0.60"}, "comments": 4, "created_at": "2022-01-13T22:23:14Z", "updated_at": "2022-01-14T01:37:39Z", "closed_at": "2022-01-14T01:37:39Z", "author_association": "OWNER", "pull_request": null, "body": null, "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/1595/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": 1102612922, "node_id": "I_kwDOBm6k_c5BuIm6", "number": 1597, "title": "\"datasette inspect\" has no help summary", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-01-14T00:02:16Z", "updated_at": "2022-01-14T00:07:36Z", "closed_at": "2022-01-14T00:07:36Z", "author_association": "OWNER", "pull_request": null, "body": "Made obvious by the new CLI reference page added in #1594. https://docs.datasette.io/en/latest/cli-reference.html#datasette-inspect-help\r\n```\r\nCommands:\r\n serve* Serve up specified SQLite database files with a web UI\r\n inspect\r\n install Install Python packages - e.g.\r\n```\r\n```\r\nUsage: datasette inspect [OPTIONS] [FILES]...\r\n\r\nOptions:\r\n --inspect-file TEXT\r\n --load-extension TEXT Path to a SQLite extension to load\r\n --help Show this message and exit.\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/1597/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": 1102637351, "node_id": "I_kwDOBm6k_c5BuOkn", "number": 1598, "title": "Replace update-docs-help.py script with cog", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-01-14T00:33:27Z", "updated_at": "2022-01-14T00:47:57Z", "closed_at": "2022-01-14T00:47:57Z", "author_association": "OWNER", "pull_request": null, "body": "I introduced `cog` in #1594 - I can use this to replace the older `update-docs-help.py` mechanism:\r\n\r\nhttps://github.com/simonw/datasette/blob/76d66d5b2bf10249c0beaac0999b93ac8d757f48/tests/test_docs.py#L36-L53", "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/1598/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": 1121618041, "node_id": "I_kwDOBm6k_c5C2oh5", "number": 1620, "title": "Link: rel=\"alternate\" to JSON for queries too", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 3, "created_at": "2022-02-02T08:02:42Z", "updated_at": "2022-02-02T21:53:02Z", "closed_at": "2022-02-02T21:33:00Z", "author_association": "OWNER", "pull_request": null, "body": "Following:\r\n- #1533\r\n\r\nI implemented it for tables and rows but I should have done queries as well.", "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/1620/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": 1122413719, "node_id": "I_kwDOBm6k_c5C5qyX", "number": 1621, "title": "Test against Python 3.11 dev version", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 0, "created_at": "2022-02-02T21:38:57Z", "updated_at": "2022-03-19T04:04:49Z", "closed_at": "2022-02-02T21:58:54Z", "author_association": "OWNER", "pull_request": null, "body": "To avoid another surprise like we got with 3.10: https://simonwillison.net/2021/Oct/9/finding-and-reporting-a-bug/\r\n\r\nFrom a quick GitHub code search it looks like `3.11-dev` should work: https://cs.github.com/urllib3/urllib3/blob/7bec77e81aa0a194c98381053225813f5347c9d2/.github/workflows/ci.yml#L60", "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/1621/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": 1122416919, "node_id": "I_kwDOBm6k_c5C5rkX", "number": 1623, "title": "/-/patterns returns link: alternate JSON header to 404", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 2, "created_at": "2022-02-02T21:42:49Z", "updated_at": "2022-03-19T04:04:49Z", "closed_at": "2022-02-02T21:48:56Z", "author_association": "OWNER", "pull_request": null, "body": "Bug from:\r\n- #1620\r\n\r\n```\r\n% curl -s -I 'https://latest.datasette.io/-/patterns' | grep link\r\nlink: https://latest.datasette.io/-/patterns.json; rel=\"alternate\"; type=\"application/json+datasette\"\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/1623/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": 1108235694, "node_id": "I_kwDOBm6k_c5CDlWu", "number": 1603, "title": "A proper favicon", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 19, "created_at": "2022-01-19T15:24:55Z", "updated_at": "2022-03-19T04:04:49Z", "closed_at": "2022-01-20T06:07:31Z", "author_association": "OWNER", "pull_request": null, "body": "Tips here: https://adamj.eu/tech/2022/01/18/how-to-add-a-favicon-to-your-django-site/ - I think a PNG served at `/favicon.ico` is the best option, since safari doesn't support SVG yet.\r\n\r\nRelevant code: https://github.com/simonw/datasette/blob/cb29119db9115b1f40de2fb45263ed77e3bfbb3e/datasette/app.py#L182-L183\r\n\r\nI can reuse the icon for https://datasette.io/desktop", "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/1603/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": 1108846067, "node_id": "I_kwDOBm6k_c5CF6Xz", "number": 1606, "title": "Tests failing against Python 3.6", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2022-01-20T04:22:44Z", "updated_at": "2022-01-20T04:36:42Z", "closed_at": "2022-01-20T04:36:42Z", "author_association": "OWNER", "pull_request": null, "body": "https://github.com/simonw/datasette/runs/4877484366\r\n\r\n```\r\nE File \"/opt/hostedtoolcache/Python/3.6.15/x64/lib/python3.6/site-packages/uvicorn/server.py\", line 67, in run\r\nE return asyncio.run(self.serve(sockets=sockets))\r\nE AttributeError: module 'asyncio' has no attribute 'run'\r\n```\r\nI think this may mean `uvicorn` has dropped support for Python 3.6.", "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/1606/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": 1109884720, "node_id": "I_kwDOBm6k_c5CJ38w", "number": 1609, "title": "Ensure \"pip install datasette\" still works with Python 3.6", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 12, "created_at": "2022-01-21T00:08:10Z", "updated_at": "2022-01-24T19:20:09Z", "closed_at": "2022-01-21T02:24:13Z", "author_association": "OWNER", "pull_request": null, "body": "## Original title: Can I keep \"pip install datasette\" working on Python 3.6?\r\n\r\nI dropped support for 3.6 in:\r\n- #1577\r\n\r\nI'm getting reports that `pip3 install datasette` throws an error on that Python, even though I haven't made that new release yet - presumably due to lack of pinning of Uvicorn: https://twitter.com/ldodds/status/1484289475195080706\r\n\r\nIs it possible to get `pip` on that version of Python to install the highest possible version of the packages that are still known to support Python 3.6?\r\n\r\nIf so, how?", "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/1609/reactions\", \"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "draft": null, "state_reason": "completed"} {"id": 1109783030, "node_id": "I_kwDOBm6k_c5CJfH2", "number": 1607, "title": "More detailed information about installed SpatiaLite version", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 2, "created_at": "2022-01-20T21:28:03Z", "updated_at": "2022-02-09T06:42:02Z", "closed_at": "2022-02-09T06:32:28Z", "author_association": "OWNER", "pull_request": null, "body": "https://www.gaia-gis.it/gaia-sins/spatialite-sql-5.0.0.html#version has a whole bunch of interesting functions for things like `freexl_version()` and `geos_version()` and `HasMathSQL()` and suchlike.\r\n\r\nThese could be shown on the `/-/versions` page.", "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/1607/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": 1138008042, "node_id": "I_kwDOBm6k_c5D1J_q", "number": 1636, "title": "\"permissions\" propery in metadata for configuring arbitrary permissions", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 8711695, "label": " Datasette 1.0a2"}, "comments": 14, "created_at": "2022-02-15T00:25:59Z", "updated_at": "2022-12-13T02:40:50Z", "closed_at": "2022-12-13T02:40:50Z", "author_association": "OWNER", "pull_request": null, "body": "The `\"allow\"` block mechanism can already be used to configure various default permissions. When adding permissions to `datasette-tiddlywiki` I realized it would be good to be able to configure arbitrary permissions such as `edit-tiddlywiki` there 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/1636/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": 1126604194, "node_id": "I_kwDOBm6k_c5DJp2i", "number": 1632, "title": "datasette one.db one.db opens database twice, as one and one_2", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 6, "created_at": "2022-02-07T23:14:47Z", "updated_at": "2022-03-19T04:04:49Z", "closed_at": "2022-02-07T23:50:01Z", "author_association": "OWNER", "pull_request": null, "body": "> ```\r\n> % mkdir /tmp/data\r\n> % cp ~/Dropbox/Development/datasette/fixtures.db /tmp/data \r\n> % datasette /tmp/data/*.db /tmp/data/created.db --create -p 8852\r\n> ...\r\n> INFO: Uvicorn running on http://127.0.0.1:8852 (Press CTRL+C to quit)\r\n> ^CINFO: Shutting down\r\n> % datasette /tmp/data/*.db /tmp/data/created.db --create -p 8852\r\n> ...\r\n> INFO: 127.0.0.1:49533 - \"GET / HTTP/1.1\" 200 OK\r\n> ```\r\n> The first time I ran Datasette I got two databases - `fixtures` and `created`\r\n> \r\n> BUT... when I ran Datasette the second time it looked like this:\r\n> \r\n> \"image\"\r\n> \r\n> This is the same result you get if you run:\r\n> \r\n> datasette /tmp/data/fixtures.db /tmp/data/created.db /tmp/data/created.db\r\n> \r\n> This is caused by this Datasette issue:\r\n> - https://github.com/simonw/datasette/issues/509\r\n> \r\n> So... either I teach Datasette to de-duplicate multiple identical file paths passed to the command, or I can't use `/data/*.db` in the `Dockerfile` here and I need to go back to other solutions for the challenge described in this comment: https://github.com/simonw/datasette-publish-fly/pull/12#issuecomment-1031971831\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette-publish-fly/pull/12#issuecomment-1032029874_", "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/1632/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": 1152072027, "node_id": "I_kwDOBm6k_c5Eqzlb", "number": 1642, "title": "Dependency issue with asgiref and uvicorn", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-02-26T18:00:35Z", "updated_at": "2022-03-05T01:11:27Z", "closed_at": "2022-03-05T01:11:17Z", "author_association": "OWNER", "pull_request": null, "body": "```\r\nERROR: After October 2020 you may experience errors when installing or updating packages. This is because pip will change the way that it resolves dependency conflicts.\r\n\r\nWe recommend you use --use-feature=2020-resolver to test your packages with the new resolver before it becomes the default.\r\n\r\ndatasette 0.60.2 requires asgiref<3.5.0,>=3.2.10, but you'll have asgiref 3.5.0 which is incompatible.\r\n```\r\nThat's after I forced an upgrade of `uvicorn` due to this warning:\r\n```\r\nERROR: After October 2020 you may experience errors when installing or updating packages. This is because pip will change the way that it resolves dependency conflicts.\r\n\r\nWe recommend you use --use-feature=2020-resolver to test your packages with the new resolver before it becomes the default.\r\n\r\nuvicorn 0.13.1 requires click==7.*, but you'll have click 8.0.4 which is incompatible.\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/1642/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": 1160407071, "node_id": "I_kwDOBm6k_c5FKmgf", "number": 1647, "title": "Test failures with SQLite 3.37.0+ due to column affinity case", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 5, "created_at": "2022-03-05T17:37:46Z", "updated_at": "2022-03-05T19:56:28Z", "closed_at": "2022-03-05T19:47:04Z", "author_association": "OWNER", "pull_request": null, "body": "These three tests are failing on my local machine:\r\n```\r\nFAILED tests/test_internals_database.py::test_table_column_details[facetable-expected0] - AssertionError: assert [Column(cid=0, name='pk', type='INTEGER', no...\r\nFAILED tests/test_internals_database.py::test_table_column_details[sortable-expected1] - AssertionError: assert [Column(cid=0, name='pk1', type='varchar(30)'...\r\nFAILED tests/test_table_html.py::test_sort_links - AssertionError: assert [{'a_href': None,\\n 'attrs': {'class': ['col-Link'],\\n 'data-column': '...\r\n```\r\nI ran `pytest --lf -vv` and the output had things like this in it:\r\n```\r\nE - Column(cid=1, name='created', type='text', notnull=0, default_value=None, is_pk=0, hidden=0),\r\nE ? ^^^^\r\nE + Column(cid=1, name='created', type='TEXT', notnull=0, default_value=None, is_pk=0, hidden=0),\r\n...\r\nE {'a_href': '/fixtures/sortable?_sort=sortable_with_nulls_2',\r\nE 'attrs': {'class': ['col-sortable_with_nulls_2'],\r\nE 'data-column': 'sortable_with_nulls_2',\r\nE 'data-column-not-null': '0',\r\nE - 'data-column-type': 'real',\r\nE ? ^^^^\r\nE + 'data-column-type': 'REAL',\r\nE ? ^^^^\r\n```\r\nSomething is causing column types to come back in uppercase where previously they were lowercase.", "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/1647/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": 1160750713, "node_id": "I_kwDOBm6k_c5FL6Z5", "number": 1650, "title": "Implement redirects from old % encoding to new dash encoding", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 5, "created_at": "2022-03-06T23:40:02Z", "updated_at": "2022-03-07T19:26:15Z", "closed_at": "2022-03-07T19:26:14Z", "author_association": "OWNER", "pull_request": null, "body": "> One big advantage to this scheme is that redirecting old links to `%2F` pages (e.g. https://fivethirtyeight.datasettes.com/fivethirtyeight/twitter-ratio%2Fsenators) is easy - if you see a `%` in the `raw_path`, redirect to that page with the `%` replaced by `-`.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1439#issuecomment-1060044007_", "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/1650/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": 1161584460, "node_id": "I_kwDOBm6k_c5FPF9M", "number": 1651, "title": "Get rid of the no-longer necessary ?_format=json hack for tables called x.json", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 8, "created_at": "2022-03-07T15:40:42Z", "updated_at": "2022-03-19T04:04:50Z", "closed_at": "2022-03-15T18:25:42Z", "author_association": "OWNER", "pull_request": null, "body": "Tidy up from:\r\n- #1439", "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/1651/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": 1161969891, "node_id": "I_kwDOBm6k_c5FQkDj", "number": 1654, "title": "Adopt a code of conduct", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 5, "created_at": "2022-03-07T22:00:24Z", "updated_at": "2022-03-07T22:19:35Z", "closed_at": "2022-03-07T22:19:35Z", "author_association": "OWNER", "pull_request": null, "body": "This is long overdue, especially given the size of the project now.", "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/1654/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": 1174162781, "node_id": "I_kwDOBm6k_c5F_E1d", "number": 1666, "title": "Refactor URL routing to enable testing", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 3, "created_at": "2022-03-19T03:52:29Z", "updated_at": "2022-03-19T16:32:03Z", "closed_at": "2022-03-19T16:32:03Z", "author_association": "OWNER", "pull_request": null, "body": "I ran into some bugs earlier with URL routing - having more robust testing around this (especially since they are defined using regular expressions) would be really useful.\r\n\r\n- A utility function that resolves a path against a list of reflexes and returns the match\r\n- Make the routes and regular expressions available from a private Datasette method\r\n- Add tests that exercise them\r\n\r\nRelated:\r\n- #1660", "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/1666/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": 1174404647, "node_id": "I_kwDOBm6k_c5F__4n", "number": 1669, "title": "Release 0.61 alpha", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2022-03-20T00:35:35Z", "updated_at": "2022-03-20T01:24:36Z", "closed_at": "2022-03-20T01:24:36Z", "author_association": "OWNER", "pull_request": null, "body": "> I'm going to release this as a 0.61 alpha so I can more easily depend on it from `datasette-hashed-urls`.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1668#issuecomment-1073136896_", "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/1669/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": 1174306154, "node_id": "I_kwDOBm6k_c5F_n1q", "number": 1668, "title": "Introduce concept of a database `route`, separate from its name", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 20, "created_at": "2022-03-19T16:48:28Z", "updated_at": "2022-03-20T16:43:16Z", "closed_at": "2022-03-20T16:43:16Z", "author_association": "OWNER", "pull_request": null, "body": "Some issues came up in the new `datasette-hashed-urls` plugin relating to the way it renames databases on startup to achieve unique URLs that depend on the database SHA-256 content:\r\n\r\n- https://github.com/simonw/datasette-hashed-urls/issues/10\r\n- https://github.com/simonw/datasette-hashed-urls/issues/9\r\n- https://github.com/simonw/datasette-hashed-urls/issues/8\r\n\r\nAll three of these could be addressed by making the \"path\" concept for a database (the `/foo` bit where it is served) work independently of the database's name, which would be used for default display and also as the alias when configuring cross-database aliases.", "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/1668/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": 1174302994, "node_id": "I_kwDOBm6k_c5F_nES", "number": 1667, "title": "Make route matched pattern groups more consistent", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 3, "created_at": "2022-03-19T16:32:35Z", "updated_at": "2022-03-19T20:37:42Z", "closed_at": "2022-03-19T20:37:41Z", "author_association": "OWNER", "pull_request": null, "body": "> ... highlights how inconsistent the way the capturing works is. Especially `as_format` which can be `None` or `\"\"` or `.json` or `json` or not used at all in the case of `TableView`.\r\n\r\nhttps://github.com/simonw/datasette/blob/764738dfcb16cd98b0987d443f59d5baa9d3c332/tests/test_routes.py#L12-L36\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1666#issuecomment-1073039670_\r\n\r\nPart of:\r\n- #1660", "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/1667/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": 1168995756, "node_id": "I_kwDOBm6k_c5FrXWs", "number": 1657, "title": "Tilde encoding: use ~ instead of - for dash-encoding", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 12, "created_at": "2022-03-14T22:55:17Z", "updated_at": "2022-03-15T18:25:11Z", "closed_at": "2022-03-15T18:01:58Z", "author_association": "OWNER", "pull_request": null, "body": "Refs #1439", "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/1657/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": 1169840669, "node_id": "I_kwDOBm6k_c5Fulod", "number": 1658, "title": "Revert main to version that passes tests", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 1, "created_at": "2022-03-15T15:37:02Z", "updated_at": "2022-03-19T04:04:50Z", "closed_at": "2022-03-15T15:42:58Z", "author_association": "OWNER", "pull_request": null, "body": "> I've made a real mess of this. I'm going to revert Datasette`main` back to the last commit that passed the tests and try this again in a branch.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1657#issuecomment-1068125636_", "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/1658/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": 1170144879, "node_id": "I_kwDOBm6k_c5Fvv5v", "number": 1660, "title": "Refactor and simplify Datasette routing and views", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 8, "created_at": "2022-03-15T19:56:56Z", "updated_at": "2022-03-21T19:19:12Z", "closed_at": "2022-03-21T19:19:01Z", "author_association": "OWNER", "pull_request": null, "body": "While working on:\n- https://github.com/simonw/datasette/issues/1657\n- https://github.com/simonw/datasette/issues/1439\n\nIt became very clear that the least maintainable part of Datasette at the moment is the way routing to the database, table and row views work - in particular the subclassing mechanism with BaseView and DataView, but also the complex variety of ways in which the URL routes capture different named regular expression groups.", "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/1660/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": 1170355774, "node_id": "I_kwDOBm6k_c5FwjY-", "number": 1661, "title": "Remove Hashed URL mode", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 10, "created_at": "2022-03-15T23:13:56Z", "updated_at": "2022-03-19T00:37:37Z", "closed_at": "2022-03-19T00:37:36Z", "author_association": "OWNER", "pull_request": null, "body": "It's now handled by a plugin instead:\r\n- #647\r\n- https://github.com/simonw/datasette-hashed-urls/issues/3\r\n\r\nhttps://github.com/simonw/datasette-hashed-urls\r\n\r\nSub-tasks:\r\n\r\n- [x] Remove hashed URL mode implementation\r\n- [x] Update documentation\r\n- [x] Ensure `--setting hash_urls 1` shows a useful 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/1661/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": 1170554975, "node_id": "I_kwDOBm6k_c5FxUBf", "number": 1663, "title": "Document the internals that were used in datasette-hashed-urls", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 2, "created_at": "2022-03-16T05:17:08Z", "updated_at": "2022-03-19T04:04:50Z", "closed_at": "2022-03-17T21:32:38Z", "author_association": "OWNER", "pull_request": null, "body": "The https://github.com/simonw/datasette-hashed-urls used a couple of currently undocumented features:\r\n- `db.hash`\r\n- `Datasette(..., immutables=[...])`", "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/1663/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": 1190828163, "node_id": "I_kwDOBm6k_c5G-piD", "number": 1698, "title": "Add a warning about bots and Cloud Run", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-04-03T05:57:17Z", "updated_at": "2022-04-03T06:10:24Z", "closed_at": "2022-04-03T06:10:24Z", "author_association": "OWNER", "pull_request": null, "body": "Recommend the https://github.com/simonw/datasette-block-robots plugin if you are going to run a large database in Cloud Run (one with a lot of rows).", "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/1698/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": 1189113609, "node_id": "I_kwDOBm6k_c5G4G8J", "number": 1697, "title": "`Request.fake(..., url_vars={})`", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 1, "created_at": "2022-04-01T01:48:40Z", "updated_at": "2022-04-01T02:02:18Z", "closed_at": "2022-04-01T02:02:10Z", "author_association": "OWNER", "pull_request": null, "body": "I just created an alternative `.fake()` method because I wanted to fake the `url_vars` captured in the route as well:\r\n```python\r\nfrom datasette.utils.asgi import Request\r\nclass Request(Request):\r\n\r\n @classmethod\r\n def fake(cls, path_with_query_string, method=\"GET\", scheme=\"http\", url_vars=None):\r\n \"\"\"Useful for constructing Request objects for tests\"\"\"\r\n path, _, query_string = path_with_query_string.partition(\"?\")\r\n scope = {\r\n \"http_version\": \"1.1\",\r\n \"method\": method,\r\n \"path\": path,\r\n \"raw_path\": path_with_query_string.encode(\"latin-1\"),\r\n \"query_string\": query_string.encode(\"latin-1\"),\r\n \"scheme\": scheme,\r\n \"type\": \"http\",\r\n }\r\n if url_vars:\r\n scope[\"url_route\"] = {\r\n \"kwargs\": url_vars\r\n }\r\n return cls(scope, None)\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/1697/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": 1174423568, "node_id": "I_kwDOBm6k_c5GAEgQ", "number": 1670, "title": "Ship Datasette 0.61", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 6, "created_at": "2022-03-20T02:47:54Z", "updated_at": "2022-03-23T18:32:32Z", "closed_at": "2022-03-23T18:32:03Z", "author_association": "OWNER", "pull_request": null, "body": "Let the alpha bake for a while, since #1668 is a big last-minute change.\r\n\r\nAfter shipping, release a new `datasette-hashed-urls` that depends on it, also this:\r\n\r\n- https://github.com/simonw/datasette-hashed-urls/issues/11", "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/1670/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": 1175694248, "node_id": "I_kwDOBm6k_c5GE6uo", "number": 1677, "title": "Remove `check_permission()` from `BaseView`", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 1, "created_at": "2022-03-21T17:18:18Z", "updated_at": "2022-03-21T18:45:04Z", "closed_at": "2022-03-21T18:45:03Z", "author_association": "OWNER", "pull_request": null, "body": "Follow-on from:\r\n- #1675\r\n\r\nRefs:\r\n- #1660", "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/1677/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": 1175648453, "node_id": "I_kwDOBm6k_c5GEvjF", "number": 1675, "title": "Extract out `check_permissions()` from `BaseView", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 7, "created_at": "2022-03-21T16:39:46Z", "updated_at": "2022-03-21T17:14:31Z", "closed_at": "2022-03-21T17:13:21Z", "author_association": "OWNER", "pull_request": null, "body": "> I'm going to refactor this stuff out and document it so it can be easily used by plugins:\r\n\r\nhttps://github.com/simonw/datasette/blob/4a4164b81191dec35e423486a208b05a9edc65e4/datasette/views/base.py#L69-L103\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1660#issuecomment-1074136176_", "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/1675/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": 1175715988, "node_id": "I_kwDOBm6k_c5GFACU", "number": 1678, "title": "Make `check_visibility()` a documented API", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 1, "created_at": "2022-03-21T17:30:34Z", "updated_at": "2022-03-21T19:04:03Z", "closed_at": "2022-03-21T19:01:46Z", "author_association": "OWNER", "pull_request": null, "body": "Spotted this while working on:\r\n- #1677\r\n\r\nhttps://github.com/simonw/datasette/blob/e627510b760198ccedba9e5af47a771e847785c9/datasette/utils/__init__.py#L1005-L1021", "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/1678/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": 1175854982, "node_id": "I_kwDOBm6k_c5GFh-G", "number": 1679, "title": "Research: how much overhead does the n=1 time limit have?", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 11, "created_at": "2022-03-21T19:27:46Z", "updated_at": "2022-03-21T21:55:57Z", "closed_at": "2022-03-21T21:55:56Z", "author_association": "OWNER", "pull_request": null, "body": "https://github.com/simonw/datasette/blob/1a7750eb29fd15dd2eea3b9f6e33028ce441b143/datasette/utils/__init__.py#L181-L200\r\n\r\n```python\r\n@contextmanager\r\ndef sqlite_timelimit(conn, ms):\r\n deadline = time.perf_counter() + (ms / 1000)\r\n # n is the number of SQLite virtual machine instructions that will be\r\n # executed between each check. It's hard to know what to pick here.\r\n # After some experimentation, I've decided to go with 1000 by default and\r\n # 1 for time limits that are less than 50ms\r\n n = 1000\r\n if ms < 50:\r\n n = 1\r\n\r\n def handler():\r\n if time.perf_counter() >= deadline:\r\n return 1\r\n\r\n conn.set_progress_handler(handler, n)\r\n try:\r\n yield\r\n finally:\r\n conn.set_progress_handler(None, n)\r\n```\r\nHow often do I set a time limit of 50 or less? How much slower does it go thanks to this 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/1679/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": 1178521513, "node_id": "I_kwDOBm6k_c5GPs-p", "number": 1682, "title": "SQL queries against databases with different routes are broken", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-03-23T18:42:57Z", "updated_at": "2022-03-23T18:48:16Z", "closed_at": "2022-03-23T18:48:16Z", "author_association": "OWNER", "pull_request": null, "body": "500 error on https://datasette-hashed-urls-preview.vercel.app/fixtures-09f8f95?sql=select+*+from+facetable\r\n\r\nHere's the trace:\r\n```\r\n File \"/Users/simon/.local/share/virtualenvs/datasette-hashed-urls-ssI2fO50/lib/python3.10/site-packages/datasette/views/database.py\", line 54, in data\r\n return await QueryView(self.ds).data(\r\n File \"/Users/simon/.local/share/virtualenvs/datasette-hashed-urls-ssI2fO50/lib/python3.10/site-packages/datasette/views/database.py\", line 232, in data\r\n self.ds.get_database(database), sql\r\n File \"/Users/simon/.local/share/virtualenvs/datasette-hashed-urls-ssI2fO50/lib/python3.10/site-packages/datasette/app.py\", line 401, in get_database\r\n return self.databases[name]\r\nKeyError: 'fixtures-aa7318b'\r\n```\r\nIt looks like this is a Datasette bug, which is frustrating because I just shipped Datasette 0.61 five minutes ago!\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette-hashed-urls/issues/13#issuecomment-1076693667_", "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/1682/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": 1179928510, "node_id": "I_kwDOBm6k_c5GVEe-", "number": 1683, "title": "allow_facet: False should be respected by column cog menu", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 0, "created_at": "2022-03-24T19:05:06Z", "updated_at": "2022-03-24T19:16:36Z", "closed_at": "2022-03-24T19:16:36Z", "author_association": "OWNER", "pull_request": null, "body": "The column cog menu currently shows \"Facet by this\" even if faceting is disabled for the Datasette 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/1683/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": 1182065616, "node_id": "I_kwDOBm6k_c5GdOPQ", "number": 1689, "title": "datasette.add_message() documentation is incorrect", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-03-26T20:49:42Z", "updated_at": "2022-03-26T21:35:57Z", "closed_at": "2022-03-26T20:51:21Z", "author_association": "OWNER", "pull_request": null, "body": "https://docs.datasette.io/en/0.61.1/internals.html#add-message-request-message-message-type-datasette-info says:\r\n\r\n`.add_message(request, message, message_type=datasette.INFO)`\r\n\r\nBut in the code it's:\r\n\r\nhttps://github.com/simonw/datasette/blob/6b99e4a66ba0ed8fca8ee41ceb7206928b60d5d1/datasette/app.py#L582", "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/1689/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": 1182143895, "node_id": "I_kwDOBm6k_c5GdhWX", "number": 1691, "title": "Bug in pytest-httpx example", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 0, "created_at": "2022-03-26T22:45:30Z", "updated_at": "2022-03-26T22:46:09Z", "closed_at": "2022-03-26T22:46:09Z", "author_association": "OWNER", "pull_request": null, "body": "https://docs.datasette.io/en/0.61.1/testing_plugins.html#testing-outbound-http-calls-with-pytest-httpx says:\r\n\r\n```python\r\nasync def test_outbound_http_call(httpx_mock):\r\n httpx_mock.add_response(\r\n url='https://www.example.com/',\r\n data='Hello world',\r\n )\r\n```\r\nThat's wrong - `data=` should be `text=`.\r\n\r\nhttps://github.com/Colin-b/pytest_httpx/blob/v0.20.0/README.md#reply-with-custom-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/1691/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": 1194790504, "node_id": "I_kwDOBm6k_c5HNw5o", "number": 1701, "title": "Use + for spaces instead of ~20", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 3268330, "label": "Datasette 1.0"}, "comments": 0, "created_at": "2022-04-06T15:40:48Z", "updated_at": "2022-04-06T15:55:10Z", "closed_at": "2022-04-06T15:55:05Z", "author_association": "OWNER", "pull_request": null, "body": "Tilde encoding introduced in #1657 means that database files with spaces in the name - e.g. the Apple Mail `Envelope Index` database - end up with URLs like this:\r\n\r\n http://127.0.0.1:8001/Envelope~20Index\r\n\r\nI think this would be prettier:\r\n\r\n http://127.0.0.1:9933/Envelope+Index", "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/1701/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": 1200649889, "node_id": "I_kwDOBm6k_c5HkHah", "number": 1710, "title": "Guide for plugin authors to upgrade their plugins for 1.0", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-04-11T22:58:25Z", "updated_at": "2022-04-11T23:04:01Z", "closed_at": "2022-04-11T23:03:25Z", "author_association": "OWNER", "pull_request": null, "body": "I'll also encourage testing against both Datasette 0.x and Datasette 1.0 using a GitHub Actions matrix.", "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/1710/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": 1202227104, "node_id": "I_kwDOBm6k_c5HqIeg", "number": 1712, "title": "Make \"\" easier to read", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2022-04-12T18:17:07Z", "updated_at": "2022-04-12T19:12:22Z", "closed_at": "2022-04-12T18:44:20Z", "author_association": "OWNER", "pull_request": null, "body": "`Binary: 2,427,344 bytes` would be nicer - even better, include a tooltip showing that size translated using this function: https://github.com/simonw/datasette/blob/138e4d9a53e3982137294ba383303c3a848cfca4/datasette/utils/__init__.py#L837-L846\r\n\r\n![CleanShot 2022-04-12 at 11 15 04@2x](https://user-images.githubusercontent.com/9599/163027324-b0b6092e-6e11-438b-8077-789025d0bb37.png)\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/1712/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": 1223234932, "node_id": "I_kwDOBm6k_c5I6RV0", "number": 1733, "title": "Get Datasette compatible with Pyodide", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 9, "created_at": "2022-05-02T19:01:58Z", "updated_at": "2022-05-04T15:14:01Z", "closed_at": "2022-05-02T20:15:27Z", "author_association": "OWNER", "pull_request": null, "body": "I've already got this working as a prototype. Here are the changes I had to make:\r\n\r\n- Replace the two dependencies that don't publish pure Python wheels to PyPI: `click-default-group` and `python-baseconv`\r\n- Get Datasette to work without threading - which it turns out is exclusively used for database connections\r\n- Make the `uvicorn` dependency optional (only needed when Datasette runs in the CLI)\r\n\r\nTODO:\r\n\r\n- [x] Switch to `click-default-group-wheel`\r\n- [x] https://github.com/simonw/datasette/issues/1734\r\n- [x] Work around `uvicorn` import error\r\n- [x] https://github.com/simonw/datasette/issues/1735\r\n- [x] #1737\r\n\r\nGoal is to be able to do the following directly in https://pyodide.org/en/stable/console.html\r\n\r\n```python\r\nimport micropip\r\nawait micropip.install(\"datasette\")\r\nfrom datasette.app import Datasette\r\nds = Datasette()\r\nawait ds.client.get(\"/.json\")\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/1733/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": 1223241647, "node_id": "I_kwDOBm6k_c5I6S-v", "number": 1734, "title": "Remove python-baseconv dependency", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2022-05-02T19:08:37Z", "updated_at": "2022-05-02T23:25:49Z", "closed_at": "2022-05-02T19:39:20Z", "author_association": "OWNER", "pull_request": null, "body": "> I was going to vendor `baseconv.py`, but then I reconsidered - what if there are plugins out there that expect `import baseconv` to work because they have depended on Datasette?\r\n>\r\n> I used https://cs.github.com/ and as far as I can tell there aren't any!\r\n>\r\n> So I'm going to remove that dependency and work out a smarter way to do this - probably by providing a utility function within Datasette itself.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1733#issuecomment-1115258737_", "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/1734/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": 1223263540, "node_id": "I_kwDOBm6k_c5I6YU0", "number": 1735, "title": "Datasette setting to disable threading (for Pyodide)", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-05-02T19:31:08Z", "updated_at": "2022-05-02T23:25:49Z", "closed_at": "2022-05-02T20:13:52Z", "author_association": "OWNER", "pull_request": null, "body": "> I'm going to add a Datasette setting to disable threading entirely, designed for usage in this particular case.\r\n>\r\n> I thought about adding a new setting, then I noticed this:\r\n>\r\n> datasette mydatabase.db --setting num_sql_threads 10\r\n>\r\n> I'm going to let users set that to `0` to disable threaded execution of SQL queries.\r\n\r\n_Originally posted by @simonw in https://github.com/simonw/datasette/issues/1733#issuecomment-1115278325_", "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/1735/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": 1223459734, "node_id": "I_kwDOBm6k_c5I7IOW", "number": 1737, "title": "Automated test for Pyodide compatibility", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 4, "created_at": "2022-05-02T23:24:25Z", "updated_at": "2022-05-02T23:40:50Z", "closed_at": "2022-05-02T23:40:50Z", "author_association": "OWNER", "pull_request": null, "body": "Refs:\r\n- #1733\r\n\r\nNeed something in the test suite such that if Datasette breaks against Pyodide in the future we hear about it.\r\n\r\nI'm thinking this is an opportunity to use [shot-scraper javascript](https://github.com/simonw/shot-scraper#scraping-pages-using-javascript).", "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/1737/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": 1223527226, "node_id": "I_kwDOBm6k_c5I7Ys6", "number": 1738, "title": "\"Cannot use _sort and _sort_desc at the same time\"", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": {"value": 8303187, "label": "Datasette 0.62"}, "comments": 2, "created_at": "2022-05-03T01:06:24Z", "updated_at": "2022-08-14T16:13:55Z", "closed_at": "2022-08-14T16:13:55Z", "author_association": "OWNER", "pull_request": null, "body": "Triggered this error while playing with the sort desc checkbox and the apply button that are only visible on this page at mobile screen width:\r\n\r\nhttps://latest.datasette.io/fixtures/compound_three_primary_keys?_sort_desc=pk1\r\n\r\nNavigate to that page (with the browser narrow enough to show the box), un-check the box and click Apply:\r\n\r\n![sort-bug](https://user-images.githubusercontent.com/9599/166390804-cb289b29-63dc-4986-b7f9-81cf2ae04914.gif)\r\n\r\nAlso notable: I managed to get to a page with `?_sort_desk=pk1` in the URL three times by clicking around with that button.", "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/1738/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": 1223699280, "node_id": "I_kwDOBm6k_c5I8CtQ", "number": 1739, "title": ".db downloads should be served with an ETag", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 6, "created_at": "2022-05-03T05:11:21Z", "updated_at": "2022-05-04T18:21:18Z", "closed_at": "2022-05-03T14:59:51Z", "author_association": "OWNER", "pull_request": null, "body": "I noticed that my Pyodide Datasette prototype is downloading the same database file every single time rather than browser caching it:\r\n\r\n![image](https://user-images.githubusercontent.com/9599/166407074-dee19587-0667-4424-9e88-d3b5b90fd819.png)\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/1739/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": 1212823665, "node_id": "I_kwDOBm6k_c5ISjhx", "number": 1715, "title": "Refactor TableView to use asyncinject", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 13, "created_at": "2022-04-22T21:43:39Z", "updated_at": "2022-12-01T21:15:18Z", "closed_at": "2022-04-28T22:26:56Z", "author_association": "OWNER", "pull_request": null, "body": "I've been working on a dependency injection mechanism in a separate library:\r\n\r\n- https://github.com/simonw/asyncinject\r\n\r\nI think it's ready to try out with Datasette to see if it's a pattern that will work here.\r\n\r\nI'm going to attempt to refactor `TableView` to use it. There are two overall goals here:\r\n\r\n- Use `asyncinject` to add parallel execution of some aspects of the table page - most notably I want to be able to execute the `count(*)` query, the `select ...` query, the various faceting queries and the facet suggestion queries in parallel - and measure if doing so is good for performance.\r\n- Use it to execute different output formats (possibly with some changes to the existing `register_output_renderer()` plugin hook). I want CSV and JSON to use the same mechanism that plugins use.\r\n\r\nStretch goal is to get this working with streaming data too, see:\r\n\r\n- #1101", "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/1715/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": 1212838949, "node_id": "I_kwDOBm6k_c5ISnQl", "number": 1716, "title": "Configure git blame to ignore Black commit", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-04-22T21:56:37Z", "updated_at": "2022-04-22T22:02:19Z", "closed_at": "2022-04-22T22:02:19Z", "author_association": "OWNER", "pull_request": null, "body": "GitHub can support this in blame views now too:\r\n\r\nhttps://docs.github.com/en/repositories/working-with-files/using-files/viewing-a-file#ignore-commits-in-the-blame-view", "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/1716/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": 1213683988, "node_id": "I_kwDOBm6k_c5IV1kU", "number": 1718, "title": "Code examples in the documentation should be formatted with Black", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 12, "created_at": "2022-04-24T15:22:50Z", "updated_at": "2022-04-24T16:24:14Z", "closed_at": "2022-04-24T16:18:03Z", "author_association": "OWNER", "pull_request": null, "body": "For example on this page: https://docs.datasette.io/en/stable/writing_plugins.html#packaging-a-plugin\r\n\r\nI wonder if there's an easy way for me to enforce this for Sphinx documentation?", "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/1718/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"} {"id": 1215174094, "node_id": "I_kwDOBm6k_c5IbhXO", "number": 1720, "title": "Design plugin hook for extras", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 14, "created_at": "2022-04-26T00:08:10Z", "updated_at": "2022-12-01T21:15:19Z", "closed_at": "2022-04-26T20:20:27Z", "author_association": "OWNER", "pull_request": null, "body": "Refs:\r\n- #262\r\n- #1709\r\n\r\nI realized that this is a really natural plugin hook - and if I design it as a hook I can implement Datasette's core extras as default plugins.", "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/1720/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": 1216508080, "node_id": "I_kwDOBm6k_c5IgnCw", "number": 1723, "title": "Research running SQL in table view in parallel using `asyncio.gather()`", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 5, "created_at": "2022-04-26T21:42:48Z", "updated_at": "2022-04-27T18:53:44Z", "closed_at": "2022-04-26T22:19:09Z", "author_association": "OWNER", "pull_request": null, "body": "Spun off from:\r\n- #1715", "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/1723/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": 1216619276, "node_id": "I_kwDOBm6k_c5IhCMM", "number": 1724, "title": "?_trace=1 doesn't work on Global Power Plants demo", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 3, "created_at": "2022-04-27T00:15:02Z", "updated_at": "2022-04-27T06:15:14Z", "closed_at": "2022-04-27T00:18:30Z", "author_association": "OWNER", "pull_request": null, "body": "https://global-power-plants.datasettes.com/global-power-plants/global-power-plants?_trace=1 is not showing the trace JSON at the bottom of the page.\r\n\r\nConfirmed that `trace_debug` is `true` on https://global-power-plants.datasettes.com/-/settings\r\n\r\nPossibly related:\r\n\r\n- https://github.com/simonw/datasette-total-page-time/issues/1", "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/1724/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": 1239008850, "node_id": "I_kwDOBm6k_c5J2cZS", "number": 1744, "title": "`--nolock` feature for opening locked databases", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 7, "created_at": "2022-05-17T18:25:16Z", "updated_at": "2022-05-17T19:46:38Z", "closed_at": "2022-05-17T19:40:30Z", "author_association": "OWNER", "pull_request": null, "body": "The getting started docs currently suggest you try this to browse your Chrome history:\r\n\r\n datasette ~/Library/Application\\ Support/Google/Chrome/Default/History\r\n\r\nBut if Chrome is running you will likely get this error:\r\n\r\n sqlite3.OperationalError: database is locked\r\n\r\nTurns out there's a workaround for this which I just spotted [on the SQLite forum](https://sqlite.org/forum/forumpost/86a67f6995):\r\n\r\n> You can do this using a [URI filename](https://sqlite.org/uri.html):\r\n> ```\r\n> sqlite3 'file:places.sqlite?mode=ro&nolock=1'\r\n> ```\r\n> That opens the file `places.sqlite` in read-only mode with locking disabled. This isn't safe, in that changes to the database made by other corrections are likely to cause this connection to return incorrect results or crash. Read-only mode should at least mean that you don't corrupt the database in the process.", "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/1744/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": 1239080102, "node_id": "I_kwDOBm6k_c5J2tym", "number": 1745, "title": "Documentation on running cog", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-05-17T19:41:06Z", "updated_at": "2022-05-17T19:45:51Z", "closed_at": "2022-05-17T19:43:45Z", "author_association": "OWNER", "pull_request": null, "body": "Noticed that `cog -r docs/*.rst` isn't documented in https://docs.datasette.io/en/latest/contributing.html#editing-and-building-the-documentation", "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/1745/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": 1243498298, "node_id": "I_kwDOBm6k_c5KHkc6", "number": 1746, "title": "Switch documentation theme to Furo", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 21, "created_at": "2022-05-20T18:42:17Z", "updated_at": "2022-05-20T21:28:29Z", "closed_at": "2022-05-20T21:28:29Z", "author_association": "OWNER", "pull_request": null, "body": "https://github.com/pradyunsg/furo\r\n\r\nI just did this for `shot-scraper` and I really like it: https://shot-scraper.datasette.io/en/latest/\r\n\r\n- https://github.com/simonw/shot-scraper/issues/77", "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/1746/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": 1243512344, "node_id": "I_kwDOBm6k_c5KHn4Y", "number": 1747, "title": "Add tutorials to the getting started guide", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 1, "created_at": "2022-05-20T19:01:52Z", "updated_at": "2022-05-20T19:12:30Z", "closed_at": "2022-05-20T19:05:34Z", "author_association": "OWNER", "pull_request": null, "body": "On https://docs.datasette.io/en/stable/getting_started.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/1747/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": 1243517592, "node_id": "I_kwDOBm6k_c5KHpKY", "number": 1748, "title": "Add copy buttons next to code examples in the documentation", "user": {"value": 9599, "label": "simonw"}, "state": "closed", "locked": 0, "assignee": null, "milestone": null, "comments": 2, "created_at": "2022-05-20T19:09:00Z", "updated_at": "2022-05-20T19:15:00Z", "closed_at": "2022-05-20T19:11:32Z", "author_association": "OWNER", "pull_request": null, "body": "Similar to the ones in `datasette-copyable` which are implemented here: https://github.com/executablebooks/sphinx-copybutton/tree/f84c001a0507f8ec46779d0701b079a265564583", "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/1748/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"}