[{"id": "changelog:id29", "page": "changelog", "ref": "id29", "title": "0.60 (2022-01-13)", "content": "", "breadcrumbs": "[\"Changelog\"]", "references": "[]"}, {"id": "changelog:id3", "page": "changelog", "ref": "id3", "title": "0.65.2 (2025-11-05)", "content": "Fixes an  open redirect  security issue: Datasette instances would redirect to  example.com/foo/bar  if you accessed the path  //example.com/foo/bar . Thanks to  James Jefferies  for the fix. ( #2429 ) \n                 \n                 \n                     Upgraded for compatibility with Python 3.14. \n                 \n                 \n                     Fixed  datasette publish cloudrun  to work with changes to the underlying Cloud Run architecture. ( #2511 ) \n                 \n                 \n                     Minor upgrades to fix warnings, including  pkg_resources  deprecation.", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/jamesjefferies\", \"label\": \"James Jefferies\"}, {\"href\": \"https://github.com/simonw/datasette/issues/2429\", \"label\": \"#2429\"}, {\"href\": \"https://github.com/simonw/datasette/issues/2511\", \"label\": \"#2511\"}]"}, {"id": "changelog:id30", "page": "changelog", "ref": "id30", "title": "0.59.4 (2021-11-29)", "content": "Fixed bug where columns with a leading underscore could not be removed from the interactive filters list. ( #1527 ) \n                 \n                 \n                     Fixed bug where columns with a leading underscore were not correctly linked to by the \"Links from other tables\" interface on the row page. ( #1525 ) \n                 \n                 \n                     Upgraded dependencies  aiofiles ,  black  and  janus .", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/1527\", \"label\": \"#1527\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1525\", \"label\": \"#1525\"}]"}, {"id": "changelog:id31", "page": "changelog", "ref": "id31", "title": "0.59.3 (2021-11-20)", "content": "Fixed numerous bugs when running Datasette  behind a proxy  with a prefix URL path using the  base_url  setting. A live demo of this mode is now available at  datasette-apache-proxy-demo.datasette.io/prefix/ . ( #1519 ,  #838 ) \n                 \n                 \n                     ?column__arraycontains=  and  ?column__arraynotcontains=  table parameters now also work against SQL views. ( #448 ) \n                 \n                 \n                     ?_facet_array=column  no longer returns incorrect counts if columns contain the same value more than once.", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://datasette-apache-proxy-demo.datasette.io/prefix/\", \"label\": \"datasette-apache-proxy-demo.datasette.io/prefix/\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1519\", \"label\": \"#1519\"}, {\"href\": \"https://github.com/simonw/datasette/issues/838\", \"label\": \"#838\"}, {\"href\": \"https://github.com/simonw/datasette/issues/448\", \"label\": \"#448\"}]"}, {"id": "changelog:id32", "page": "changelog", "ref": "id32", "title": "0.59.2 (2021-11-13)", "content": "Column names with a leading underscore now work correctly when used as a facet. ( #1506 ) \n                 \n                 \n                     Applying  ?_nocol=  to a column no longer removes that column from the filtering interface. ( #1503 ) \n                 \n                 \n                     Official Datasette Docker container now uses Debian Bullseye as the base image. ( #1497 ) \n                 \n                 \n                     Datasette is four years old today! Here's the  original release announcement  from 2017.", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/1506\", \"label\": \"#1506\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1503\", \"label\": \"#1503\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1497\", \"label\": \"#1497\"}, {\"href\": \"https://simonwillison.net/2017/Nov/13/datasette/\", \"label\": \"original release announcement\"}]"}, {"id": "changelog:id33", "page": "changelog", "ref": "id33", "title": "0.59.1 (2021-10-24)", "content": "Fix compatibility with Python 3.10. ( #1482 ) \n                 \n                 \n                     Documentation on how to use  Named parameters  with integer and floating point values. ( #1496 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/1482\", \"label\": \"#1482\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1496\", \"label\": \"#1496\"}]"}, {"id": "changelog:id34", "page": "changelog", "ref": "id34", "title": "0.59 (2021-10-14)", "content": "Columns can now have associated metadata descriptions in  metadata.json , see  Column descriptions . ( #942 ) \n                 \n                 \n                     New  register_commands()  plugin hook allows plugins to register additional Datasette CLI commands, e.g.  datasette mycommand file.db . ( #1449 ) \n                 \n                 \n                     Adding  ?_facet_size=max  to a table page now shows the number of unique values in each facet. ( #1423 ) \n                 \n                 \n                     Upgraded dependency  httpx 0.20  - the undocumented  allow_redirects=  parameter to  datasette.client  is now  follow_redirects= , and defaults to  False  where it previously defaulted to  True . ( #1488 ) \n                 \n                 \n                     The  --cors  option now causes Datasette to return the  Access-Control-Allow-Headers: Authorization  header, in addition to  Access-Control-Allow-Origin: * . ( #1467 ) \n                 \n                 \n                     Code that figures out which named parameters a SQL query takes in order to display form fields for them is no longer confused by strings that contain colon characters. ( #1421 ) \n                 \n                 \n                     Renamed  --help-config  option to  --help-settings . ( #1431 ) \n                 \n                 \n                     datasette.databases  property is now a documented API. ( #1443 ) \n                 \n                 \n                     The  base.html  template now wraps everything other than the  <footer>  in a  <div class=\"not-footer\">  element, to help with advanced CSS customization. ( #1446 ) \n                 \n                 \n                     The  render_cell()  plugin hook can now return an awaitable function. This means the hook can execute SQL queries. ( #1425 ) \n                 \n                 \n                     register_routes(datasette)  plugin hook now accepts an optional  datasette  argument. ( #1404 ) \n                 \n                 \n                     New  hide_sql  canned query option for defaulting to hiding the SQL query used by a canned query, see  Additional canned query options . ( #1422 ) \n                 \n                 \n                     New  --cpu  option for  datasette publish cloudrun . ( #1420 ) \n                 \n                 \n                     If  Rich  is installed in the same virtual environment as Datasette, it will be used to provide enhanced display of error tracebacks on the console. ( #1416 ) \n                 \n                 \n                     datasette.utils   parse_metadata(content)  function, used by the new  datasette-remote-metadata plugin , is now a documented API. ( #1405 ) \n                 \n                 \n                     Fixed bug where  ?_next=x&_sort=rowid  could throw an error. ( #1470 ) \n                 \n                 \n                     Column cog menu no longer shows the option to facet by a column that is already selected by the default facets in metadata. ( #1469 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/942\", \"label\": \"#942\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1449\", \"label\": \"#1449\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1423\", \"label\": \"#1423\"}, {\"href\": \"https://github.com/encode/httpx/releases/tag/0.20.0\", \"label\": \"httpx 0.20\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1488\", \"label\": \"#1488\"}, {\"href\": \"https://github.com/simonw/datasette/pull/1467\", \"label\": \"#1467\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1421\", \"label\": \"#1421\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1431\", \"label\": \"#1431\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1443\", \"label\": \"#1443\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1446\", \"label\": \"#1446\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1425\", \"label\": \"#1425\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1404\", \"label\": \"#1404\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1422\", \"label\": \"#1422\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1420\", \"label\": \"#1420\"}, {\"href\": \"https://github.com/willmcgugan/rich\", \"label\": \"Rich\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1416\", \"label\": \"#1416\"}, {\"href\": \"https://datasette.io/plugins/datasette-remote-metadata\", \"label\": \"datasette-remote-metadata plugin\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1405\", \"label\": \"#1405\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1470\", \"label\": \"#1470\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1469\", \"label\": \"#1469\"}]"}, {"id": "changelog:id35", "page": "changelog", "ref": "id35", "title": "0.58.1 (2021-07-16)", "content": "Fix for an intermittent race condition caused by the  refresh_schemas()  internal function. ( #1231 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/1231\", \"label\": \"#1231\"}]"}, {"id": "changelog:id36", "page": "changelog", "ref": "id36", "title": "0.58 (2021-07-14)", "content": "New  datasette --uds /tmp/datasette.sock  option for binding Datasette to a Unix domain socket, see  proxy documentation  ( #1388 ) \n                 \n                 \n                     \"searchmode\": \"raw\"  table metadata option for defaulting a table to executing SQLite full-text search syntax without first escaping it, see  Advanced SQLite search queries . ( #1389 ) \n                 \n                 \n                     New plugin hook:  get_metadata() , for returning custom metadata for an instance, database or table. Thanks, Brandon Roberts! ( #1384 ) \n                 \n                 \n                     New plugin hook:  skip_csrf(datasette, scope) , for opting out of CSRF protection based on the incoming request. ( #1377 ) \n                 \n                 \n                     The  menu_links() ,  table_actions()  and  database_actions()  plugin hooks all gained a new optional  request  argument providing access to the current request. ( #1371 ) \n                 \n                 \n                     Major performance improvement for Datasette faceting. ( #1394 ) \n                 \n                 \n                     Improved documentation for  Running Datasette behind a proxy  to recommend using  ProxyPreservehost On  with Apache. ( #1387 ) \n                 \n                 \n                     POST  requests to endpoints that do not support that HTTP verb now return a 405 error. \n                 \n                 \n                     db.path  can now be provided as a  pathlib.Path  object, useful when writing unit tests for plugins. Thanks, Chris Amico. ( #1365 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/1388\", \"label\": \"#1388\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1389\", \"label\": \"#1389\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1384\", \"label\": \"#1384\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1377\", \"label\": \"#1377\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1371\", \"label\": \"#1371\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1394\", \"label\": \"#1394\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1387\", \"label\": \"#1387\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1365\", \"label\": \"#1365\"}]"}, {"id": "changelog:id37", "page": "changelog", "ref": "id37", "title": "0.57.1 (2021-06-08)", "content": "Fixed visual display glitch with global navigation menu. ( #1367 ) \n                 \n                 \n                     No longer truncates the list of table columns displayed on the  /database  page. ( #1364 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/1367\", \"label\": \"#1367\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1364\", \"label\": \"#1364\"}]"}, {"id": "changelog:id38", "page": "changelog", "ref": "id38", "title": "0.57 (2021-06-05)", "content": "This release fixes a  reflected cross-site scripting  security hole with the  ?_trace=1  feature. You should upgrade to this version, or to Datasette 0.56.1, as soon as possible. ( #1360 ) \n             \n             In addition to the security fix, this release includes  ?_col=  and  ?_nocol=  options for controlling which columns are displayed for a table,  ?_facet_size=  for increasing the number of facet results returned, re-display of your SQL query should an error occur and numerous bug fixes.", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://owasp.org/www-community/attacks/xss/#reflected-xss-attacks\", \"label\": \"reflected cross-site scripting\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1360\", \"label\": \"#1360\"}]"}, {"id": "changelog:id39", "page": "changelog", "ref": "id39", "title": "0.56.1 (2021-06-05)", "content": "This release fixes a  reflected cross-site scripting  security hole with the  ?_trace=1  feature. You should upgrade to this version, or to Datasette 0.57, as soon as possible. ( #1360 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://owasp.org/www-community/attacks/xss/#reflected-xss-attacks\", \"label\": \"reflected cross-site scripting\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1360\", \"label\": \"#1360\"}]"}, {"id": "changelog:id4", "page": "changelog", "ref": "id4", "title": "Other changes", "content": "The internal  catalog_views  table now tracks SQLite views alongside tables in the introspection database. ( #2495 ) \n                     \n                     \n                         Hitting the  /  brings up a search interface for navigating to tables that the current user can view. A new  /-/tables  endpoint supports this functionality. ( #2523 ) \n                     \n                     \n                         Datasette attempts to detect some configuration errors on startup. \n                     \n                     \n                         Datasette now supports Python 3.14 and no longer tests against Python 3.9.", "breadcrumbs": "[\"Changelog\", \"1.0a20 (2025-11-03)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/2495\", \"label\": \"#2495\"}, {\"href\": \"https://github.com/simonw/datasette/issues/2523\", \"label\": \"#2523\"}]"}, {"id": "changelog:id40", "page": "changelog", "ref": "id40", "title": "0.56 (2021-03-28)", "content": "Documentation improvements, bug fixes and support for SpatiaLite 5. \n             \n                 \n                     The SQL editor can now be resized by dragging a handle. ( #1236 ) \n                 \n                 \n                     Fixed a bug with JSON faceting and the  __arraycontains  filter caused by tables with spaces in their names. ( #1239 ) \n                 \n                 \n                     Upgraded  httpx  dependency. ( #1005 ) \n                 \n                 \n                     JSON faceting is now suggested even if a column contains blank strings. ( #1246 ) \n                 \n                 \n                     New  datasette.add_memory_database()  method. ( #1247 ) \n                 \n                 \n                     The  Response.asgi_send()  method is now documented. ( #1266 ) \n                 \n                 \n                     The official Datasette Docker image now bundles SpatiaLite version 5. ( #1278 ) \n                 \n                 \n                     Fixed a  no such table: pragma_database_list  bug when running Datasette against SQLite versions prior to SQLite 3.16.0. ( #1276 ) \n                 \n                 \n                     HTML lists displayed in table cells are now styled correctly. Thanks, Bob Whitelock. ( #1141 ,  #1252 ) \n                 \n                 \n                     Configuration directory mode now correctly serves immutable databases that are listed in  inspect-data.json . Thanks Campbell Allen and Frankie Robertson. ( #1031 ,  #1229 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/1236\", \"label\": \"#1236\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1239\", \"label\": \"#1239\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1005\", \"label\": \"#1005\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1246\", \"label\": \"#1246\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1247\", \"label\": \"#1247\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1266\", \"label\": \"#1266\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1278\", \"label\": \"#1278\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1276\", \"label\": \"#1276\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1141\", \"label\": \"#1141\"}, {\"href\": \"https://github.com/simonw/datasette/pull/1252\", \"label\": \"#1252\"}, {\"href\": \"https://github.com/simonw/datasette/pull/1031\", \"label\": \"#1031\"}, {\"href\": \"https://github.com/simonw/datasette/pull/1229\", \"label\": \"#1229\"}]"}, {"id": "changelog:id41", "page": "changelog", "ref": "id41", "title": "0.55 (2021-02-18)", "content": "Support for cross-database SQL queries and built-in support for serving via HTTPS. \n             \n                 \n                     The new  --crossdb  command-line option causes Datasette to attach up to ten database files to the same  /_memory  database connection. This enables cross-database SQL queries, including the ability to use joins and unions to combine data from tables that exist in different database files. See  Cross-database queries  for details. ( #283 ) \n                 \n                 \n                     --ssl-keyfile  and  --ssl-certfile  options can be used to specify a TLS certificate, allowing Datasette to serve traffic over  https://  without needing to run it behind a separate proxy. ( #1221 ) \n                 \n                 \n                     The  /:memory:  page has been renamed (and redirected) to  /_memory  for consistency with the new  /_internal  database introduced in Datasette 0.54. ( #1205 ) \n                 \n                 \n                     Added plugin testing documentation on  Using pdb for errors thrown inside Datasette . ( #1207 ) \n                 \n                 \n                     The  official Datasette Docker image  now uses Python 3.7.10, applying  the latest security fix  for that Python version. ( #1235 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/283\", \"label\": \"#283\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1221\", \"label\": \"#1221\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1205\", \"label\": \"#1205\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1207\", \"label\": \"#1207\"}, {\"href\": \"https://hub.docker.com/r/datasetteproject/datasette\", \"label\": \"official Datasette Docker image\"}, {\"href\": \"https://www.python.org/downloads/release/python-3710/\", \"label\": \"the latest security fix\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1235\", \"label\": \"#1235\"}]"}, {"id": "changelog:id42", "page": "changelog", "ref": "id42", "title": "0.54.1 (2021-02-02)", "content": "Fixed a bug where  ?_search=  and  ?_sort=  parameters were incorrectly duplicated when the filter form on the table page was re-submitted. ( #1214 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/1214\", \"label\": \"#1214\"}]"}, {"id": "changelog:id43", "page": "changelog", "ref": "id43", "title": "0.54 (2021-01-25)", "content": "The two big new features in this release are the  _internal  SQLite in-memory database storing details of all connected databases and tables, and support for JavaScript modules in plugins and additional scripts. \n             For additional commentary on this release, see  Datasette 0.54, the annotated release notes .", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://simonwillison.net/2021/Jan/25/datasette/\", \"label\": \"Datasette 0.54, the annotated release notes\"}]"}, {"id": "changelog:id44", "page": "changelog", "ref": "id44", "title": "Other changes", "content": "Datasette can now open multiple database files with the same name, e.g. if you run  datasette path/to/one.db path/to/other/one.db . ( #509 ) \n                     \n                     \n                         datasette publish cloudrun  now sets  force_https_urls  for every deployment, fixing some incorrect  http://  links. ( #1178 ) \n                     \n                     \n                         Fixed a bug in the example nginx configuration in  Running Datasette behind a proxy . ( #1091 ) \n                     \n                     \n                         The  Datasette Ecosystem  documentation page has been reduced in size in favour of the  datasette.io   tools  and  plugins  directories. ( #1182 ) \n                     \n                     \n                         The request object now provides a  request.full_path  property, which returns the path including any query string. ( #1184 ) \n                     \n                     \n                         Better error message for disallowed  PRAGMA  clauses in SQL queries. ( #1185 ) \n                     \n                     \n                         datasette publish heroku  now deploys using  python-3.8.7 . \n                     \n                     \n                         New plugin testing documentation on  Testing outbound HTTP calls with pytest-httpx . ( #1198 ) \n                     \n                     \n                         All  ?_*  query string parameters passed to the table page are now persisted in hidden form fields, so parameters such as  ?_size=10  will be correctly passed to the next page when query filters are changed. ( #1194 ) \n                     \n                     \n                         Fixed a bug loading a database file called  test-database (1).sqlite . ( #1181 )", "breadcrumbs": "[\"Changelog\", \"0.54 (2021-01-25)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/509\", \"label\": \"#509\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1178\", \"label\": \"#1178\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1091\", \"label\": \"#1091\"}, {\"href\": \"https://datasette.io/tools\", \"label\": \"tools\"}, {\"href\": \"https://datasette.io/plugins\", \"label\": \"plugins\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1182\", \"label\": \"#1182\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1184\", \"label\": \"#1184\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1185\", \"label\": \"#1185\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1198\", \"label\": \"#1198\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1194\", \"label\": \"#1194\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1181\", \"label\": \"#1181\"}]"}, {"id": "changelog:id45", "page": "changelog", "ref": "id45", "title": "0.53 (2020-12-10)", "content": "Datasette has an official project website now, at  https://datasette.io/ . This release mainly updates the documentation to reflect the new site. \n             \n                 \n                     New  ?column__arraynotcontains=  table filter. ( #1132 ) \n                 \n                 \n                     datasette serve  has a new  --create  option, which will create blank database files if they do not already exist rather than exiting with an error. ( #1135 ) \n                 \n                 \n                     New  ?_header=off  option for CSV export which omits the CSV header row,  documented here . ( #1133 ) \n                 \n                 \n                     \"Powered by Datasette\" link in the footer now links to  https://datasette.io/ . ( #1138 ) \n                 \n                 \n                     Project news no longer lives in the README - it can now be found at  https://datasette.io/news . ( #1137 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://datasette.io/\", \"label\": \"https://datasette.io/\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1132\", \"label\": \"#1132\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1135\", \"label\": \"#1135\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1133\", \"label\": \"#1133\"}, {\"href\": \"https://datasette.io/\", \"label\": \"https://datasette.io/\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1138\", \"label\": \"#1138\"}, {\"href\": \"https://datasette.io/news\", \"label\": \"https://datasette.io/news\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1137\", \"label\": \"#1137\"}]"}, {"id": "changelog:id46", "page": "changelog", "ref": "id46", "title": "0.52.5 (2020-12-09)", "content": "Fix for error caused by combining the  _searchmode=raw  and  ?_search_COLUMN  parameters. ( #1134 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/1134\", \"label\": \"#1134\"}]"}, {"id": "changelog:id47", "page": "changelog", "ref": "id47", "title": "0.52.4 (2020-12-05)", "content": "Show  pysqlite3  version on  /-/versions , if installed. ( #1125 ) \n                 \n                 \n                     Errors output by Datasette (e.g. for invalid SQL queries) now go to  stderr , not  stdout . ( #1131 ) \n                 \n                 \n                     Fix for a startup error on windows caused by unnecessary  from os import EX_CANTCREAT  - thanks, Abdussamet Ko\u00e7ak.  ( #1094 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/coleifer/pysqlite3\", \"label\": \"pysqlite3\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1125\", \"label\": \"#1125\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1131\", \"label\": \"#1131\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1094\", \"label\": \"#1094\"}]"}, {"id": "changelog:id48", "page": "changelog", "ref": "id48", "title": "0.52.3 (2020-12-03)", "content": "Fixed bug where static assets would 404 for Datasette installed on ARM Amazon Linux. ( #1124 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/1124\", \"label\": \"#1124\"}]"}, {"id": "changelog:id49", "page": "changelog", "ref": "id49", "title": "0.52.2 (2020-12-02)", "content": "Generated columns from SQLite 3.31.0 or higher are now correctly displayed. ( #1116 ) \n                 \n                 \n                     Error message if you attempt to open a SpatiaLite database now suggests using  --load-extension=spatialite  if it detects that the extension is available in a common location. ( #1115 ) \n                 \n                 \n                     OPTIONS  requests against the  /database  page no longer raise a 500 error. ( #1100 ) \n                 \n                 \n                     Databases larger than 32MB that are published to Cloud Run can now be downloaded. ( #749 ) \n                 \n                 \n                     Fix for misaligned cog icon on table and database pages. Thanks, Abdussamet Ko\u00e7ak. ( #1121 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/1116\", \"label\": \"#1116\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1115\", \"label\": \"#1115\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1100\", \"label\": \"#1100\"}, {\"href\": \"https://github.com/simonw/datasette/issues/749\", \"label\": \"#749\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1121\", \"label\": \"#1121\"}]"}, {"id": "changelog:id5", "page": "changelog", "ref": "id5", "title": "0.65.1 (2024-11-28)", "content": "Fixed bug with upgraded HTTPX 0.28.0 dependency. ( #2443 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/2443\", \"label\": \"#2443\"}]"}, {"id": "changelog:id50", "page": "changelog", "ref": "id50", "title": "0.52.1 (2020-11-29)", "content": "Documentation on  Testing plugins  now recommends using  datasette.client . ( #1102 ) \n                 \n                 \n                     Fix bug where compound foreign keys produced broken links. ( #1098 ) \n                 \n                 \n                     datasette --load-module=spatialite  now also checks for  /usr/local/lib/mod_spatialite.so . Thanks, Dan Peterson. ( #1114 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/1102\", \"label\": \"#1102\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1098\", \"label\": \"#1098\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1114\", \"label\": \"#1114\"}]"}, {"id": "changelog:id51", "page": "changelog", "ref": "id51", "title": "0.52 (2020-11-28)", "content": "This release includes a number of changes relating to an internal rebranding effort: Datasette's  configuration  mechanism (things like  datasette --config default_page_size:10 ) has been renamed to  settings . \n             \n                 \n                     New  --setting default_page_size 10  option as a replacement for  --config default_page_size:10  (note the lack of a colon). The  --config  option is deprecated but will continue working until Datasette 1.0. ( #992 ) \n                 \n                 \n                     The  /-/config  introspection page is now  /-/settings , and the previous page redirects to the new one. ( #1103 ) \n                 \n                 \n                     The  config.json  file in  Configuration directory mode  is now called  settings.json . ( #1104 ) \n                 \n                 \n                     The undocumented  datasette.config()  internal method has been replaced by a documented  .setting(key)  method. ( #1107 ) \n                 \n             \n             Also in this release: \n             \n                 \n                     New plugin hook:  database_actions(datasette, actor, database, request) , which adds menu items to a new cog menu shown at the top of the database page. ( #1077 ) \n                 \n                 \n                     datasette publish cloudrun  has a new  --apt-get-install  option that can be used to install additional Ubuntu packages as part of the deployment. This is useful for deploying the new  datasette-ripgrep plugin . ( #1110 ) \n                 \n                 \n                     Swept the documentation to remove words that minimize involved difficulty. ( #1089 ) \n                 \n             \n             And some bug fixes: \n             \n                 \n                     Foreign keys linking to rows with blank label columns now display as a hyphen, allowing those links to be clicked. ( #1086 ) \n                 \n                 \n                     Fixed bug where row pages could sometimes 500 if the underlying queries exceeded a time limit. ( #1088 ) \n                 \n                 \n                     Fixed a bug where the table action menu could appear partially obscured by the edge of the page. ( #1084 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/992\", \"label\": \"#992\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1103\", \"label\": \"#1103\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1104\", \"label\": \"#1104\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1107\", \"label\": \"#1107\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1077\", \"label\": \"#1077\"}, {\"href\": \"https://github.com/simonw/datasette-ripgrep\", \"label\": \"datasette-ripgrep plugin\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1110\", \"label\": \"#1110\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1089\", \"label\": \"#1089\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1086\", \"label\": \"#1086\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1088\", \"label\": \"#1088\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1084\", \"label\": \"#1084\"}]"}, {"id": "changelog:id52", "page": "changelog", "ref": "id52", "title": "0.51.1 (2020-10-31)", "content": "Improvements to the new  Binary data  documentation page.", "breadcrumbs": "[\"Changelog\"]", "references": "[]"}, {"id": "changelog:id53", "page": "changelog", "ref": "id53", "title": "0.51 (2020-10-31)", "content": "A new visual design, plugin hooks for adding navigation options, better handling of binary data, URL building utility methods and better support for running Datasette behind a proxy.", "breadcrumbs": "[\"Changelog\"]", "references": "[]"}, {"id": "changelog:id54", "page": "changelog", "ref": "id54", "title": "Smaller changes", "content": "Wide tables shown within Datasette now scroll horizontally ( #998 ). This is achieved using a new  <div class=\"table-wrapper\">  element which may impact the implementation of some plugins (for example  this change to datasette-cluster-map ). \n                     \n                     \n                         New  debug-menu  permission. ( #1068 ) \n                     \n                     \n                         Removed  --debug  option, which didn't do anything. ( #814 ) \n                     \n                     \n                         Link:  HTTP header pagination. ( #1014 ) \n                     \n                     \n                         x  button for clearing filters. ( #1016 ) \n                     \n                     \n                         Edit SQL button on canned queries, ( #1019 ) \n                     \n                     \n                         --load-extension=spatialite  shortcut. ( #1028 ) \n                     \n                     \n                         scale-in animation for column action menu. ( #1039 ) \n                     \n                     \n                         Option to pass a list of templates to  .render_template()  is now documented. ( #1045 ) \n                     \n                     \n                         New  datasette.urls.static_plugins()  method. ( #1033 ) \n                     \n                     \n                         datasette -o  option now opens the most relevant page. ( #976 ) \n                     \n                     \n                         datasette --cors  option now enables access to  /database.db  downloads. ( #1057 ) \n                     \n                     \n                         Database file downloads now implement cascading permissions, so you can download a database if you have  view-database-download  permission even if you do not have permission to access the Datasette instance. ( #1058 ) \n                     \n                     \n                         New documentation on  Designing URLs for your plugin . ( #1053 )", "breadcrumbs": "[\"Changelog\", \"0.51 (2020-10-31)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/998\", \"label\": \"#998\"}, {\"href\": \"https://github.com/simonw/datasette-cluster-map/commit/fcb4abbe7df9071c5ab57defd39147de7145b34e\", \"label\": \"this change to datasette-cluster-map\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1068\", \"label\": \"#1068\"}, {\"href\": \"https://github.com/simonw/datasette/issues/814\", \"label\": \"#814\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1014\", \"label\": \"#1014\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1016\", \"label\": \"#1016\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1019\", \"label\": \"#1019\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1028\", \"label\": \"#1028\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1039\", \"label\": \"#1039\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1045\", \"label\": \"#1045\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1033\", \"label\": \"#1033\"}, {\"href\": \"https://github.com/simonw/datasette/issues/976\", \"label\": \"#976\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1057\", \"label\": \"#1057\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1058\", \"label\": \"#1058\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1053\", \"label\": \"#1053\"}]"}, {"id": "changelog:id55", "page": "changelog", "ref": "id55", "title": "0.50.2 (2020-10-09)", "content": "Fixed another bug introduced in 0.50 where column header links on the table page were broken. ( #1011 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/1011\", \"label\": \"#1011\"}]"}, {"id": "changelog:id56", "page": "changelog", "ref": "id56", "title": "0.50.1 (2020-10-09)", "content": "Fixed a bug introduced in 0.50 where the export as JSON/CSV links on the table, row and query pages were broken. ( #1010 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/1010\", \"label\": \"#1010\"}]"}, {"id": "changelog:id57", "page": "changelog", "ref": "id57", "title": "0.50 (2020-10-09)", "content": "The key new feature in this release is the  column actions  menu on the table page ( #891 ). This can be used to sort a column in ascending or descending order, facet data by that column or filter the table to just rows that have a value for that column. \n             Plugin authors can use the new  datasette.client  object to make internal HTTP requests from their plugins, allowing them to make use of Datasette's JSON API. ( #943 ) \n             New  Deploying Datasette  documentation with guides for deploying Datasette on a Linux server  using systemd  or to hosting providers  that support buildpacks . ( #514 ,  #997 ) \n             Other improvements in this release: \n             \n                 \n                     Publishing to Google Cloud Run  documentation now covers Google Cloud SDK options. Thanks, Geoffrey Hing. ( #995 ) \n                 \n                 \n                     New  datasette -o  option which opens your browser as soon as Datasette starts up. ( #970 ) \n                 \n                 \n                     Datasette now sets  sqlite3.enable_callback_tracebacks(True)  so that errors in custom SQL functions will display tracebacks. ( #891 ) \n                 \n                 \n                     Fixed two rendering bugs with column headers in portrait mobile view. ( #978 ,  #980 ) \n                 \n                 \n                     New  db.table_column_details(table)  introspection method for retrieving full details of the columns in a specific table, see  Database introspection . \n                 \n                 \n                     Fixed a routing bug with custom page wildcard templates. ( #996 ) \n                 \n                 \n                     datasette publish heroku  now deploys using Python 3.8.6. \n                 \n                 \n                     New  datasette publish heroku --tar=  option. ( #969 ) \n                 \n                 \n                     OPTIONS  requests against HTML pages no longer return a 500 error. ( #1001 ) \n                 \n                 \n                     Datasette now supports Python 3.9. \n                 \n             \n             See also  Datasette 0.50: The annotated release notes .", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/891\", \"label\": \"#891\"}, {\"href\": \"https://github.com/simonw/datasette/issues/943\", \"label\": \"#943\"}, {\"href\": \"https://github.com/simonw/datasette/issues/514\", \"label\": \"#514\"}, {\"href\": \"https://github.com/simonw/datasette/issues/997\", \"label\": \"#997\"}, {\"href\": \"https://github.com/simonw/datasette/pull/995\", \"label\": \"#995\"}, {\"href\": \"https://github.com/simonw/datasette/issues/970\", \"label\": \"#970\"}, {\"href\": \"https://github.com/simonw/datasette/issues/891\", \"label\": \"#891\"}, {\"href\": \"https://github.com/simonw/datasette/issues/978\", \"label\": \"#978\"}, {\"href\": \"https://github.com/simonw/datasette/issues/980\", \"label\": \"#980\"}, {\"href\": \"https://github.com/simonw/datasette/issues/996\", \"label\": \"#996\"}, {\"href\": \"https://github.com/simonw/datasette/issues/969\", \"label\": \"#969\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1001\", \"label\": \"#1001\"}, {\"href\": \"https://simonwillison.net/2020/Oct/9/datasette-0-50/\", \"label\": \"Datasette 0.50: The annotated release notes\"}]"}, {"id": "changelog:id58", "page": "changelog", "ref": "id58", "title": "0.49.1 (2020-09-15)", "content": "Fixed a bug with writable canned queries that use magic parameters but accept no non-magic arguments. ( #967 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/967\", \"label\": \"#967\"}]"}, {"id": "changelog:id59", "page": "changelog", "ref": "id59", "title": "0.49 (2020-09-14)", "content": "See also  Datasette 0.49: The annotated release notes . \n             \n                 \n                     Writable canned queries now expose a JSON API, see  JSON API for writable canned queries . ( #880 ) \n                 \n                 \n                     New mechanism for defining page templates with custom path parameters - a template file called  pages/about/{slug}.html  will be used to render any requests to  /about/something . See  Path parameters for pages . ( #944 ) \n                 \n                 \n                     register_output_renderer()  render functions can now return a  Response . ( #953 ) \n                 \n                 \n                     New  --upgrade  option for  datasette install . ( #945 ) \n                 \n                 \n                     New  datasette --pdb  option. ( #962 ) \n                 \n                 \n                     datasette --get  exit code now reflects the internal HTTP status code. ( #947 ) \n                 \n                 \n                     New  raise_404()  template function for returning 404 errors. ( #964 ) \n                 \n                 \n                     datasette publish heroku  now deploys using Python 3.8.5 \n                 \n                 \n                     Upgraded  CodeMirror  to 5.57.0. ( #948 ) \n                 \n                 \n                     Upgraded code style to Black 20.8b1. ( #958 ) \n                 \n                 \n                     Fixed bug where selected facets were not correctly persisted in hidden form fields on the table page. ( #963 ) \n                 \n                 \n                     Renamed the default error template from  500.html  to  error.html . \n                 \n                 \n                     Custom error pages are now documented, see  Custom error pages . ( #965 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://simonwillison.net/2020/Sep/15/datasette-0-49/\", \"label\": \"Datasette 0.49: The annotated release notes\"}, {\"href\": \"https://github.com/simonw/datasette/issues/880\", \"label\": \"#880\"}, {\"href\": \"https://github.com/simonw/datasette/issues/944\", \"label\": \"#944\"}, {\"href\": \"https://github.com/simonw/datasette/issues/953\", \"label\": \"#953\"}, {\"href\": \"https://github.com/simonw/datasette/issues/945\", \"label\": \"#945\"}, {\"href\": \"https://github.com/simonw/datasette/issues/962\", \"label\": \"#962\"}, {\"href\": \"https://github.com/simonw/datasette/issues/947\", \"label\": \"#947\"}, {\"href\": \"https://github.com/simonw/datasette/issues/964\", \"label\": \"#964\"}, {\"href\": \"https://codemirror.net/\", \"label\": \"CodeMirror\"}, {\"href\": \"https://github.com/simonw/datasette/issues/948\", \"label\": \"#948\"}, {\"href\": \"https://github.com/simonw/datasette/issues/958\", \"label\": \"#958\"}, {\"href\": \"https://github.com/simonw/datasette/issues/963\", \"label\": \"#963\"}, {\"href\": \"https://github.com/simonw/datasette/issues/965\", \"label\": \"#965\"}]"}, {"id": "changelog:id6", "page": "changelog", "ref": "id6", "title": "0.65 (2024-10-07)", "content": "Upgrade for compatibility with Python 3.13 (by vendoring Pint dependency). ( #2434 ) \n                 \n                 \n                     Dropped support for Python 3.8.", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/2434\", \"label\": \"#2434\"}]"}, {"id": "changelog:id60", "page": "changelog", "ref": "id60", "title": "0.48 (2020-08-16)", "content": "Datasette documentation now lives at  docs.datasette.io . \n                 \n                 \n                     db.is_mutable  property is now documented and tested, see  Database introspection . \n                 \n                 \n                     The  extra_template_vars ,  extra_css_urls ,  extra_js_urls  and  extra_body_script  plugin hooks now all accept the same arguments. See  extra_template_vars(template, database, table, columns, view_name, request, datasette)  for details. ( #939 ) \n                 \n                 \n                     Those hooks now accept a new  columns  argument detailing the table columns that will be rendered on that page. ( #938 ) \n                 \n                 \n                     Fixed bug where plugins calling  db.execute_write_fn()  could hang Datasette if the connection failed. ( #935 ) \n                 \n                 \n                     Fixed bug with the  ?_nl=on  output option and binary data. ( #914 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://docs.datasette.io/\", \"label\": \"docs.datasette.io\"}, {\"href\": \"https://github.com/simonw/datasette/issues/939\", \"label\": \"#939\"}, {\"href\": \"https://github.com/simonw/datasette/issues/938\", \"label\": \"#938\"}, {\"href\": \"https://github.com/simonw/datasette/issues/935\", \"label\": \"#935\"}, {\"href\": \"https://github.com/simonw/datasette/issues/914\", \"label\": \"#914\"}]"}, {"id": "changelog:id61", "page": "changelog", "ref": "id61", "title": "0.47.3 (2020-08-15)", "content": "The  datasette --get  command-line mechanism now ensures any plugins using the  startup()  hook are correctly executed. ( #934 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/934\", \"label\": \"#934\"}]"}, {"id": "changelog:id62", "page": "changelog", "ref": "id62", "title": "0.47.2 (2020-08-12)", "content": "Fixed an issue with the Docker image  published to Docker Hub . ( #931 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://hub.docker.com/r/datasetteproject/datasette\", \"label\": \"published to Docker Hub\"}, {\"href\": \"https://github.com/simonw/datasette/issues/931\", \"label\": \"#931\"}]"}, {"id": "changelog:id63", "page": "changelog", "ref": "id63", "title": "0.47.1 (2020-08-11)", "content": "Fixed a bug where the  sdist  distribution of Datasette was not correctly including the template files. ( #930 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/930\", \"label\": \"#930\"}]"}, {"id": "changelog:id64", "page": "changelog", "ref": "id64", "title": "0.47 (2020-08-11)", "content": "Datasette now has  a GitHub discussions forum  for conversations about the project that go beyond just bug reports and issues. \n                 \n                 \n                     Datasette can now be installed on macOS using Homebrew! Run  brew install simonw/datasette/datasette . See  Using Homebrew . ( #335 ) \n                 \n                 \n                     Two new commands:  datasette install name-of-plugin  and  datasette uninstall name-of-plugin . These are equivalent to  pip install  and  pip uninstall  but automatically run in the same virtual environment as Datasette, so users don't have to figure out where that virtual environment is - useful for installations created using Homebrew or  pipx . See  Installing plugins . ( #925 ) \n                 \n                 \n                     A new command-line option,  datasette --get , accepts a path to a URL within the Datasette instance. It will run that request through Datasette (without starting a web server) and print out the response. See  datasette --get  for an example. ( #926 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/discussions\", \"label\": \"a GitHub discussions forum\"}, {\"href\": \"https://github.com/simonw/datasette/issues/335\", \"label\": \"#335\"}, {\"href\": \"https://github.com/simonw/datasette/issues/925\", \"label\": \"#925\"}, {\"href\": \"https://github.com/simonw/datasette/issues/926\", \"label\": \"#926\"}]"}, {"id": "changelog:id65", "page": "changelog", "ref": "id65", "title": "0.46 (2020-08-09)", "content": "This release contains a security fix related to authenticated writable canned queries. If you are using this feature you should upgrade as soon as possible. \n             \n             \n                 \n                     Security fix:  CSRF tokens were incorrectly included in read-only canned query forms, which could allow them to be leaked to a sophisticated attacker. See  issue 918  for details. \n                 \n                 \n                     Datasette now supports GraphQL via the new  datasette-graphql  plugin - see  GraphQL in Datasette with the new datasette-graphql plugin . \n                 \n                 \n                     Principle git branch has been renamed from  master  to  main . ( #849 ) \n                 \n                 \n                     New debugging tool:  /-/allow-debug tool  ( demo here ) helps test allow blocks against actors, as described in  Defining permissions with \"allow\" blocks . ( #908 ) \n                 \n                 \n                     New logo for the documentation, and a new project tagline: \"An open source multi-tool for exploring and publishing data\". \n                 \n                 \n                     Whitespace in column values is now respected on display, using  white-space: pre-wrap . ( #896 ) \n                 \n                 \n                     New  await request.post_body()  method for accessing the raw POST body, see  Request object . ( #897 ) \n                 \n                 \n                     Database file downloads now include a  content-length  HTTP header, enabling download progress bars. ( #905 ) \n                 \n                 \n                     File downloads now also correctly set the suggested file name using a  content-disposition  HTTP header. ( #909 ) \n                 \n                 \n                     tests  are now excluded from the Datasette package properly - thanks, abeyerpath. ( #456 ) \n                 \n                 \n                     The Datasette package published to PyPI now includes  sdist  as well as  bdist_wheel . \n                 \n                 \n                     Better titles for canned query pages. ( #887 ) \n                 \n                 \n                     Now only loads Python files from a directory passed using the  --plugins-dir  option - thanks, Amjith Ramanujam. ( #890 ) \n                 \n                 \n                     New documentation section on  Publishing to Vercel .", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/918\", \"label\": \"issue 918\"}, {\"href\": \"https://github.com/simonw/datasette-graphql\", \"label\": \"datasette-graphql\"}, {\"href\": \"https://simonwillison.net/2020/Aug/7/datasette-graphql/\", \"label\": \"GraphQL in Datasette with the new datasette-graphql plugin\"}, {\"href\": \"https://github.com/simonw/datasette/issues/849\", \"label\": \"#849\"}, {\"href\": \"https://latest.datasette.io/-/allow-debug\", \"label\": \"demo here\"}, {\"href\": \"https://github.com/simonw/datasette/issues/908\", \"label\": \"#908\"}, {\"href\": \"https://github.com/simonw/datasette/issues/896\", \"label\": \"#896\"}, {\"href\": \"https://github.com/simonw/datasette/issues/897\", \"label\": \"#897\"}, {\"href\": \"https://github.com/simonw/datasette/issues/905\", \"label\": \"#905\"}, {\"href\": \"https://github.com/simonw/datasette/issues/909\", \"label\": \"#909\"}, {\"href\": \"https://github.com/simonw/datasette/issues/456\", \"label\": \"#456\"}, {\"href\": \"https://github.com/simonw/datasette/issues/887\", \"label\": \"#887\"}, {\"href\": \"https://github.com/simonw/datasette/pull/890\", \"label\": \"#890\"}]"}, {"id": "changelog:id66", "page": "changelog", "ref": "id66", "title": "0.45 (2020-07-01)", "content": "See also  Datasette 0.45: The annotated release notes . \n             Magic parameters for canned queries, a log out feature, improved plugin documentation and four new plugin hooks.", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://simonwillison.net/2020/Jul/1/datasette-045/\", \"label\": \"Datasette 0.45: The annotated release notes\"}]"}, {"id": "changelog:id67", "page": "changelog", "ref": "id67", "title": "Smaller changes", "content": "Cascading view permissions - so if a user has  view-table  they can view the table page even if they do not have  view-database  or  view-instance . ( #832 ) \n                     \n                     \n                         CSRF protection no longer applies to  Authentication: Bearer token  requests or requests without cookies. ( #835 ) \n                     \n                     \n                         datasette.add_message()  now works inside plugins. ( #864 ) \n                     \n                     \n                         Workaround for \"Too many open files\" error in test runs. ( #846 ) \n                     \n                     \n                         Respect existing  scope[\"actor\"]  if already set by ASGI middleware. ( #854 ) \n                     \n                     \n                         New process for shipping  Alpha and beta releases . ( #807 ) \n                     \n                     \n                         {{ csrftoken() }}  now works when plugins render a template using  datasette.render_template(..., request=request) . ( #863 ) \n                     \n                     \n                         Datasette now creates a single  Request object  and uses it throughout the lifetime of the current HTTP request. ( #870 )", "breadcrumbs": "[\"Changelog\", \"0.45 (2020-07-01)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/832\", \"label\": \"#832\"}, {\"href\": \"https://github.com/simonw/datasette/issues/835\", \"label\": \"#835\"}, {\"href\": \"https://github.com/simonw/datasette/issues/864\", \"label\": \"#864\"}, {\"href\": \"https://github.com/simonw/datasette/issues/846\", \"label\": \"#846\"}, {\"href\": \"https://github.com/simonw/datasette/issues/854\", \"label\": \"#854\"}, {\"href\": \"https://github.com/simonw/datasette/issues/807\", \"label\": \"#807\"}, {\"href\": \"https://github.com/simonw/datasette/issues/863\", \"label\": \"#863\"}, {\"href\": \"https://github.com/simonw/datasette/issues/870\", \"label\": \"#870\"}]"}, {"id": "changelog:id68", "page": "changelog", "ref": "id68", "title": "0.44 (2020-06-11)", "content": "See also  Datasette 0.44: The annotated release notes . \n             Authentication and permissions, writable canned queries, flash messages, new plugin hooks and more.", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://simonwillison.net/2020/Jun/12/annotated-release-notes/\", \"label\": \"Datasette 0.44: The annotated release notes\"}]"}, {"id": "changelog:id69", "page": "changelog", "ref": "id69", "title": "Smaller changes", "content": "New internals documentation for  Request object  and  Response class . ( #706 ) \n                     \n                     \n                         request.url  now respects the  force_https_urls  config setting. closes ( #781 ) \n                     \n                     \n                         request.args.getlist()  returns  []  if missing. Removed  request.raw_args  entirely. ( #774 ) \n                     \n                     \n                         New  datasette.get_database()  method. \n                     \n                     \n                         Added  _  prefix to many private, undocumented methods of the Datasette class. ( #576 ) \n                     \n                     \n                         Removed the  db.get_outbound_foreign_keys()  method which duplicated the behaviour of  db.foreign_keys_for_table() . \n                     \n                     \n                         New  await datasette.permission_allowed()  method. \n                     \n                     \n                         /-/actor  debugging endpoint for viewing the currently authenticated actor. \n                     \n                     \n                         New  request.cookies  property. \n                     \n                     \n                         /-/plugins  endpoint now shows a list of hooks implemented by each plugin, e.g.  https://latest.datasette.io/-/plugins?all=1 \n                     \n                     \n                         request.post_vars()  method no longer discards empty values. \n                     \n                     \n                         New \"params\" canned query key for explicitly setting named parameters, see  Canned query parameters . ( #797 ) \n                     \n                     \n                         request.args  is now a  MultiParams  object. \n                     \n                     \n                         Fixed a bug with the  datasette plugins  command. ( #802 ) \n                     \n                     \n                         Nicer pattern for using  make_app_client()  in tests. ( #395 ) \n                     \n                     \n                         New  request.actor  property. \n                     \n                     \n                         Fixed broken CSS on nested 404 pages. ( #777 ) \n                     \n                     \n                         New  request.url_vars  property. ( #822 ) \n                     \n                     \n                         Fixed a bug with the  python tests/fixtures.py  command for outputting Datasette's testing fixtures database and plugins. ( #804 ) \n                     \n                     \n                         datasette publish heroku  now deploys using Python 3.8.3. \n                     \n                     \n                         Added a warning that the  register_facet_classes()  hook is unstable and may change in the future. ( #830 ) \n                     \n                     \n                         The  {\"$env\": \"ENVIRONMENT_VARIBALE\"}  mechanism (see  Secret configuration values ) now works with variables inside nested lists. ( #837 )", "breadcrumbs": "[\"Changelog\", \"0.44 (2020-06-11)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/706\", \"label\": \"#706\"}, {\"href\": \"https://github.com/simonw/datasette/issues/781\", \"label\": \"#781\"}, {\"href\": \"https://github.com/simonw/datasette/issues/774\", \"label\": \"#774\"}, {\"href\": \"https://github.com/simonw/datasette/issues/576\", \"label\": \"#576\"}, {\"href\": \"https://latest.datasette.io/-/plugins?all=1\", \"label\": \"https://latest.datasette.io/-/plugins?all=1\"}, {\"href\": \"https://github.com/simonw/datasette/issues/797\", \"label\": \"#797\"}, {\"href\": \"https://github.com/simonw/datasette/issues/802\", \"label\": \"#802\"}, {\"href\": \"https://github.com/simonw/datasette/issues/395\", \"label\": \"#395\"}, {\"href\": \"https://github.com/simonw/datasette/issues/777\", \"label\": \"#777\"}, {\"href\": \"https://github.com/simonw/datasette/issues/822\", \"label\": \"#822\"}, {\"href\": \"https://github.com/simonw/datasette/issues/804\", \"label\": \"#804\"}, {\"href\": \"https://github.com/simonw/datasette/issues/830\", \"label\": \"#830\"}, {\"href\": \"https://github.com/simonw/datasette/issues/837\", \"label\": \"#837\"}]"}, {"id": "changelog:id7", "page": "changelog", "ref": "id7", "title": "0.64.8 (2024-06-21)", "content": "Security improvement: 404 pages used to reflect content from the URL path, which could be used to display misleading information to Datasette users. 404 errors no longer display additional information from the URL. ( #2359 ) \n                 \n                 \n                     Backported a better fix for correctly extracting named parameters from canned query SQL against SQLite 3.46.0. ( #2353 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/2359\", \"label\": \"#2359\"}, {\"href\": \"https://github.com/simonw/datasette/issues/2353\", \"label\": \"#2353\"}]"}, {"id": "changelog:id70", "page": "changelog", "ref": "id70", "title": "0.43 (2020-05-28)", "content": "The main focus of this release is a major upgrade to the  register_output_renderer(datasette)  plugin hook, which allows plugins to provide new output formats for Datasette such as  datasette-atom  and  datasette-ics . \n             \n                 \n                     Redesign of  register_output_renderer(datasette)  to provide more context to the render callback and support an optional  \"can_render\"  callback that controls if a suggested link to the output format is provided. ( #581 ,  #770 ) \n                 \n                 \n                     Visually distinguish float and integer columns - useful for figuring out why order-by-column might be returning unexpected results. ( #729 ) \n                 \n                 \n                     The  Request object , which is passed to several plugin hooks, is now documented. ( #706 ) \n                 \n                 \n                     New  metadata.json  option for setting a custom default page size for specific tables and views, see  Setting a custom page size . ( #751 ) \n                 \n                 \n                     Canned queries can now be configured with a default URL fragment hash, useful when working with plugins such as  datasette-vega , see  Additional canned query options . ( #706 ) \n                 \n                 \n                     Fixed a bug in  datasette publish  when running on operating systems where the  /tmp  directory lives in a different volume, using a backport of the Python 3.8  shutil.copytree()  function. ( #744 ) \n                 \n                 \n                     Every plugin hook is now covered by the unit tests, and a new unit test checks that each plugin hook has at least one corresponding test. ( #771 ,  #773 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette-atom\", \"label\": \"datasette-atom\"}, {\"href\": \"https://github.com/simonw/datasette-ics\", \"label\": \"datasette-ics\"}, {\"href\": \"https://github.com/simonw/datasette/issues/581\", \"label\": \"#581\"}, {\"href\": \"https://github.com/simonw/datasette/issues/770\", \"label\": \"#770\"}, {\"href\": \"https://github.com/simonw/datasette/issues/729\", \"label\": \"#729\"}, {\"href\": \"https://github.com/simonw/datasette/issues/706\", \"label\": \"#706\"}, {\"href\": \"https://github.com/simonw/datasette/issues/751\", \"label\": \"#751\"}, {\"href\": \"https://github.com/simonw/datasette-vega\", \"label\": \"datasette-vega\"}, {\"href\": \"https://github.com/simonw/datasette/issues/706\", \"label\": \"#706\"}, {\"href\": \"https://github.com/simonw/datasette/issues/744\", \"label\": \"#744\"}, {\"href\": \"https://github.com/simonw/datasette/issues/771\", \"label\": \"#771\"}, {\"href\": \"https://github.com/simonw/datasette/issues/773\", \"label\": \"#773\"}]"}, {"id": "changelog:id71", "page": "changelog", "ref": "id71", "title": "0.42 (2020-05-08)", "content": "A small release which provides improved internal methods for use in plugins, along with documentation. See  #685 . \n             \n                 \n                     Added documentation for  db.execute() , see  await db.execute(sql, ...) . \n                 \n                 \n                     Renamed  db.execute_against_connection_in_thread()  to  db.execute_fn()  and made it a documented method, see  await db.execute_fn(fn) . \n                 \n                 \n                     New  results.first()  and  results.single_value()  methods, plus documentation for the  Results  class - see  Results .", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/685\", \"label\": \"#685\"}]"}, {"id": "changelog:id72", "page": "changelog", "ref": "id72", "title": "0.41 (2020-05-06)", "content": "You can now create  custom pages  within your Datasette instance using a custom template file. For example, adding a template file called  templates/pages/about.html  will result in a new page being served at  /about  on your instance. See the  custom pages documentation  for full details, including how to return custom HTTP headers, redirects and status codes. ( #648 ) \n             Configuration directory mode  ( #731 ) allows you to define a custom Datasette instance as a directory. So instead of running the following: \n             datasette one.db two.db \\\n  --metadata=metadata.json \\\n  --template-dir=templates/ \\\n  --plugins-dir=plugins \\\n  --static css:css \n             You can instead arrange your files in a single directory called  my-project  and run this: \n             datasette my-project/ \n             Also in this release: \n             \n                 \n                     New  NOT LIKE  table filter:  ?colname__notlike=expression . ( #750 ) \n                 \n                 \n                     Datasette now has a  pattern portfolio  at  /-/patterns  - e.g.  https://latest.datasette.io/-/patterns . This is a page that shows every Datasette user interface component in one place, to aid core development and people building custom CSS themes. ( #151 ) \n                 \n                 \n                     SQLite  PRAGMA functions  such as  pragma_table_info(tablename)  are now allowed in Datasette SQL queries. ( #761 ) \n                 \n                 \n                     Datasette pages now consistently return a  content-type  of  text/html; charset=utf-8\" . ( #752 ) \n                 \n                 \n                     Datasette now handles an ASGI  raw_path  value of  None , which should allow compatibility with the  Mangum  adapter for running ASGI apps on AWS Lambda. Thanks, Colin Dellow. ( #719 ) \n                 \n                 \n                     Installation documentation now covers how to  Using pipx . ( #756 ) \n                 \n                 \n                     Improved the documentation for  Full-text search . ( #748 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/648\", \"label\": \"#648\"}, {\"href\": \"https://github.com/simonw/datasette/issues/731\", \"label\": \"#731\"}, {\"href\": \"https://github.com/simonw/datasette/issues/750\", \"label\": \"#750\"}, {\"href\": \"https://latest.datasette.io/-/patterns\", \"label\": \"https://latest.datasette.io/-/patterns\"}, {\"href\": \"https://github.com/simonw/datasette/issues/151\", \"label\": \"#151\"}, {\"href\": \"https://www.sqlite.org/pragma.html#pragfunc\", \"label\": \"PRAGMA functions\"}, {\"href\": \"https://github.com/simonw/datasette/issues/761\", \"label\": \"#761\"}, {\"href\": \"https://github.com/simonw/datasette/issues/752\", \"label\": \"#752\"}, {\"href\": \"https://github.com/erm/mangum\", \"label\": \"Mangum\"}, {\"href\": \"https://github.com/simonw/datasette/pull/719\", \"label\": \"#719\"}, {\"href\": \"https://github.com/simonw/datasette/issues/756\", \"label\": \"#756\"}, {\"href\": \"https://github.com/simonw/datasette/issues/748\", \"label\": \"#748\"}]"}, {"id": "changelog:id73", "page": "changelog", "ref": "id73", "title": "0.40 (2020-04-21)", "content": "Datasette  Metadata  can now be provided as a YAML file as an optional alternative to JSON. ( #713 ) \n                 \n                 \n                     Removed support for  datasette publish now , which used the the now-retired Zeit Now v1 hosting platform. A new plugin,  datasette-publish-now , can be installed to publish data to Zeit ( now Vercel ) Now v2. ( #710 ) \n                 \n                 \n                     Fixed a bug where the  extra_template_vars(request, view_name)  plugin hook was not receiving the correct  view_name . ( #716 ) \n                 \n                 \n                     Variables added to the template context by the  extra_template_vars()  plugin hook are now shown in the  ?_context=1  debugging mode (see  template_debug ). ( #693 ) \n                 \n                 \n                     Fixed a bug where the \"templates considered\" HTML comment was no longer being displayed. ( #689 ) \n                 \n                 \n                     Fixed a  datasette publish  bug where  --plugin-secret  would over-ride plugin configuration in the provided  metadata.json  file. ( #724 ) \n                 \n                 \n                     Added a new CSS class for customizing the canned query page. ( #727 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/713\", \"label\": \"#713\"}, {\"href\": \"https://github.com/simonw/datasette-publish-now\", \"label\": \"datasette-publish-now\"}, {\"href\": \"https://vercel.com/blog/zeit-is-now-vercel\", \"label\": \"now Vercel\"}, {\"href\": \"https://github.com/simonw/datasette/issues/710\", \"label\": \"#710\"}, {\"href\": \"https://github.com/simonw/datasette/issues/716\", \"label\": \"#716\"}, {\"href\": \"https://github.com/simonw/datasette/issues/693\", \"label\": \"#693\"}, {\"href\": \"https://github.com/simonw/datasette/issues/689\", \"label\": \"#689\"}, {\"href\": \"https://github.com/simonw/datasette/issues/724\", \"label\": \"#724\"}, {\"href\": \"https://github.com/simonw/datasette/issues/727\", \"label\": \"#727\"}]"}, {"id": "changelog:id74", "page": "changelog", "ref": "id74", "title": "0.39 (2020-03-24)", "content": "New  base_url  configuration setting for serving up the correct links while running Datasette under a different URL prefix. ( #394 ) \n                 \n                 \n                     New metadata settings  \"sort\"  and  \"sort_desc\"  for setting the default sort order for a table. See  Setting a default sort order . ( #702 ) \n                 \n                 \n                     Sort direction arrow now displays by default on the primary key. This means you only have to click once (not twice) to sort in reverse order. ( #677 ) \n                 \n                 \n                     New  await Request(scope, receive).post_vars()  method for accessing POST form variables. ( #700 ) \n                 \n                 \n                     Plugin hooks  documentation now links to example uses of each plugin. ( #709 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/394\", \"label\": \"#394\"}, {\"href\": \"https://github.com/simonw/datasette/issues/702\", \"label\": \"#702\"}, {\"href\": \"https://github.com/simonw/datasette/issues/677\", \"label\": \"#677\"}, {\"href\": \"https://github.com/simonw/datasette/issues/700\", \"label\": \"#700\"}, {\"href\": \"https://github.com/simonw/datasette/issues/709\", \"label\": \"#709\"}]"}, {"id": "changelog:id75", "page": "changelog", "ref": "id75", "title": "0.38 (2020-03-08)", "content": "The  Docker build  of Datasette now uses SQLite 3.31.1, upgraded from 3.26. ( #695 ) \n                 \n                 \n                     datasette publish cloudrun  now accepts an optional  --memory=2Gi  flag for setting the Cloud Run allocated memory to a value other than the default (256Mi). ( #694 ) \n                 \n                 \n                     Fixed bug where templates that shipped with plugins were sometimes not being correctly loaded. ( #697 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://hub.docker.com/r/datasetteproject/datasette\", \"label\": \"Docker build\"}, {\"href\": \"https://github.com/simonw/datasette/issues/695\", \"label\": \"#695\"}, {\"href\": \"https://github.com/simonw/datasette/issues/694\", \"label\": \"#694\"}, {\"href\": \"https://github.com/simonw/datasette/issues/697\", \"label\": \"#697\"}]"}, {"id": "changelog:id76", "page": "changelog", "ref": "id76", "title": "0.37.1 (2020-03-02)", "content": "Don't attempt to count table rows to display on the index page for databases > 100MB. ( #688 ) \n                 \n                 \n                     Print exceptions if they occur in the write thread rather than silently swallowing them. \n                 \n                 \n                     Handle the possibility of  scope[\"path\"]  being a string rather than bytes \n                 \n                 \n                     Better documentation for the  extra_template_vars(template, database, table, columns, view_name, request, datasette)  plugin hook.", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/688\", \"label\": \"#688\"}]"}, {"id": "changelog:id77", "page": "changelog", "ref": "id77", "title": "0.37 (2020-02-25)", "content": "Plugins now have a supported mechanism for writing to a database, using the new  .execute_write()  and  .execute_write_fn()  methods.  Documentation . ( #682 ) \n                 \n                 \n                     Immutable databases that have had their rows counted using the  inspect  command now use the calculated count more effectively - thanks, Kevin Keogh. ( #666 ) \n                 \n                 \n                     --reload  no longer restarts the server if a database file is modified, unless that database was opened immutable mode with  -i . ( #494 ) \n                 \n                 \n                     New  ?_searchmode=raw  option turns off escaping for FTS queries in  ?_search=  allowing full use of SQLite's  FTS5 query syntax . ( #676 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/682\", \"label\": \"#682\"}, {\"href\": \"https://github.com/simonw/datasette/pull/666\", \"label\": \"#666\"}, {\"href\": \"https://github.com/simonw/datasette/issues/494\", \"label\": \"#494\"}, {\"href\": \"https://www.sqlite.org/fts5.html#full_text_query_syntax\", \"label\": \"FTS5 query syntax\"}, {\"href\": \"https://github.com/simonw/datasette/issues/676\", \"label\": \"#676\"}]"}, {"id": "changelog:id78", "page": "changelog", "ref": "id78", "title": "0.36 (2020-02-21)", "content": "The  datasette  object passed to plugins now has API documentation:  Datasette class . ( #576 ) \n                 \n                 \n                     New methods on  datasette :  .add_database()  and  .remove_database()  -  documentation . ( #671 ) \n                 \n                 \n                     prepare_connection()  plugin hook now takes optional  datasette  and  database  arguments -  prepare_connection(conn, database, datasette) . ( #678 ) \n                 \n                 \n                     Added three new plugins and one new conversion tool to the  The Datasette Ecosystem .", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/576\", \"label\": \"#576\"}, {\"href\": \"https://github.com/simonw/datasette/issues/671\", \"label\": \"#671\"}, {\"href\": \"https://github.com/simonw/datasette/issues/678\", \"label\": \"#678\"}]"}, {"id": "changelog:id79", "page": "changelog", "ref": "id79", "title": "0.35 (2020-02-04)", "content": "Added five new plugins and one new conversion tool to the  The Datasette Ecosystem . \n                 \n                 \n                     The  Datasette  class has a new  render_template()  method which can be used by plugins to render templates using Datasette's pre-configured  Jinja  templating library. \n                 \n                 \n                     You can now execute SQL queries that start with a  -- comment  - thanks, Jay Graves ( #653 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://jinja.palletsprojects.com/\", \"label\": \"Jinja\"}, {\"href\": \"https://github.com/simonw/datasette/pull/653\", \"label\": \"#653\"}]"}, {"id": "changelog:id8", "page": "changelog", "ref": "id8", "title": "0.64.7 (2024-06-12)", "content": "Fixed a bug where canned queries with named parameters threw an error when run against SQLite 3.46.0. ( #2353 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/2353\", \"label\": \"#2353\"}]"}, {"id": "changelog:id80", "page": "changelog", "ref": "id80", "title": "0.34 (2020-01-29)", "content": "_search=  queries are now correctly escaped using a new  escape_fts()  custom SQL function. This means you can now run searches for strings like  park.  without seeing errors. ( #651 ) \n                 \n                 \n                     Google Cloud Run  is no longer in beta, so  datasette publish cloudrun  has been updated to work even if the user has not installed the  gcloud  beta components package. Thanks, Katie McLaughlin ( #660 ) \n                 \n                 \n                     datasette package  now accepts a  --port  option for specifying which port the resulting Docker container should listen on. ( #661 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/651\", \"label\": \"#651\"}, {\"href\": \"https://cloud.google.com/run/\", \"label\": \"Google Cloud Run\"}, {\"href\": \"https://github.com/simonw/datasette/pull/660\", \"label\": \"#660\"}, {\"href\": \"https://github.com/simonw/datasette/issues/661\", \"label\": \"#661\"}]"}, {"id": "changelog:id81", "page": "changelog", "ref": "id81", "title": "0.33 (2019-12-22)", "content": "rowid  is now included in dropdown menus for filtering tables ( #636 ) \n                 \n                 \n                     Columns are now only suggested for faceting if they have at least one value with more than one record ( #638 ) \n                 \n                 \n                     Queries with no results now display \"0 results\" ( #637 ) \n                 \n                 \n                     Improved documentation for the  --static  option ( #641 ) \n                 \n                 \n                     asyncio task information is now included on the  /-/threads  debug page \n                 \n                 \n                     Bumped Uvicorn dependency 0.11 \n                 \n                 \n                     You can now use  --port 0  to listen on an available port \n                 \n                 \n                     New  template_debug  setting for debugging templates, e.g.  https://latest.datasette.io/fixtures/roadside_attractions?_context=1  ( #654 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/636\", \"label\": \"#636\"}, {\"href\": \"https://github.com/simonw/datasette/issues/638\", \"label\": \"#638\"}, {\"href\": \"https://github.com/simonw/datasette/issues/637\", \"label\": \"#637\"}, {\"href\": \"https://github.com/simonw/datasette/issues/641\", \"label\": \"#641\"}, {\"href\": \"https://latest.datasette.io/fixtures/roadside_attractions?_context=1\", \"label\": \"https://latest.datasette.io/fixtures/roadside_attractions?_context=1\"}, {\"href\": \"https://github.com/simonw/datasette/issues/654\", \"label\": \"#654\"}]"}, {"id": "changelog:id82", "page": "changelog", "ref": "id82", "title": "0.32 (2019-11-14)", "content": "Datasette now renders templates using  Jinja async mode . This means plugins can provide custom template functions that perform asynchronous actions, for example the new  datasette-template-sql  plugin which allows custom templates to directly execute SQL queries and render their results. ( #628 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://jinja.palletsprojects.com/en/2.10.x/api/#async-support\", \"label\": \"Jinja async mode\"}, {\"href\": \"https://github.com/simonw/datasette-template-sql\", \"label\": \"datasette-template-sql\"}, {\"href\": \"https://github.com/simonw/datasette/issues/628\", \"label\": \"#628\"}]"}, {"id": "changelog:id83", "page": "changelog", "ref": "id83", "title": "0.31.2 (2019-11-13)", "content": "Fixed a bug where  datasette publish heroku  applications failed to start ( #633 ) \n                 \n                 \n                     Fix for  datasette publish  with just  --source_url  - thanks, Stanley Zheng ( #572 ) \n                 \n                 \n                     Deployments to Heroku now use Python 3.8.0 ( #632 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/633\", \"label\": \"#633\"}, {\"href\": \"https://github.com/simonw/datasette/issues/572\", \"label\": \"#572\"}, {\"href\": \"https://github.com/simonw/datasette/issues/632\", \"label\": \"#632\"}]"}, {"id": "changelog:id84", "page": "changelog", "ref": "id84", "title": "0.31.1 (2019-11-12)", "content": "Deployments created using  datasette publish   now use  python:3.8  base Docker image ( #629 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/pull/629\", \"label\": \"#629\"}]"}, {"id": "changelog:id85", "page": "changelog", "ref": "id85", "title": "0.31 (2019-11-11)", "content": "This version adds compatibility with Python 3.8 and breaks compatibility with Python 3.5. \n             If you are still running Python 3.5 you should stick with  0.30.2 , which you can install like this: \n             pip install datasette==0.30.2 \n             \n                 \n                     Format SQL button now works with read-only SQL queries - thanks, Tobias Kunze ( #602 ) \n                 \n                 \n                     New  ?column__notin=x,y,z  filter for table views ( #614 ) \n                 \n                 \n                     Table view now uses  select col1, col2, col3  instead of  select * \n                 \n                 \n                     Database filenames can now contain spaces - thanks, Tobias Kunze ( #590 ) \n                 \n                 \n                     Removed obsolete  ?_group_count=col  feature ( #504 ) \n                 \n                 \n                     Improved user interface and documentation for  datasette publish cloudrun  ( #608 ) \n                 \n                 \n                     Tables with indexes now show the  CREATE INDEX  statements on the table page ( #618 ) \n                 \n                 \n                     Current version of  uvicorn  is now shown on  /-/versions \n                 \n                 \n                     Python 3.8 is now supported! ( #622 ) \n                 \n                 \n                     Python 3.5 is no longer supported.", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/pull/602\", \"label\": \"#602\"}, {\"href\": \"https://github.com/simonw/datasette/issues/614\", \"label\": \"#614\"}, {\"href\": \"https://github.com/simonw/datasette/pull/590\", \"label\": \"#590\"}, {\"href\": \"https://github.com/simonw/datasette/issues/504\", \"label\": \"#504\"}, {\"href\": \"https://github.com/simonw/datasette/issues/608\", \"label\": \"#608\"}, {\"href\": \"https://github.com/simonw/datasette/issues/618\", \"label\": \"#618\"}, {\"href\": \"https://www.uvicorn.org/\", \"label\": \"uvicorn\"}, {\"href\": \"https://github.com/simonw/datasette/issues/622\", \"label\": \"#622\"}]"}, {"id": "changelog:id86", "page": "changelog", "ref": "id86", "title": "0.30.2 (2019-11-02)", "content": "/-/plugins  page now uses distribution name e.g.  datasette-cluster-map  instead of the name of the underlying Python package ( datasette_cluster_map ) ( #606 ) \n                 \n                 \n                     Array faceting is now only suggested for columns that contain arrays of strings ( #562 ) \n                 \n                 \n                     Better documentation for the  --host  argument ( #574 ) \n                 \n                 \n                     Don't show  None  with a broken link for the label on a nullable foreign key ( #406 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/606\", \"label\": \"#606\"}, {\"href\": \"https://github.com/simonw/datasette/issues/562\", \"label\": \"#562\"}, {\"href\": \"https://github.com/simonw/datasette/issues/574\", \"label\": \"#574\"}, {\"href\": \"https://github.com/simonw/datasette/issues/406\", \"label\": \"#406\"}]"}, {"id": "changelog:id87", "page": "changelog", "ref": "id87", "title": "0.30.1 (2019-10-30)", "content": "Fixed bug where  ?_where=  parameter was not persisted in hidden form fields ( #604 ) \n                 \n                 \n                     Fixed bug with .JSON representation of row pages - thanks, Chris Shaw ( #603 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/604\", \"label\": \"#604\"}, {\"href\": \"https://github.com/simonw/datasette/issues/603\", \"label\": \"#603\"}]"}, {"id": "changelog:id88", "page": "changelog", "ref": "id88", "title": "0.30 (2019-10-18)", "content": "Added  /-/threads  debugging page \n                 \n                 \n                     Allow  EXPLAIN WITH...  ( #583 ) \n                 \n                 \n                     Button to format SQL - thanks, Tobias Kunze ( #136 ) \n                 \n                 \n                     Sort databases on homepage by argument order - thanks, Tobias Kunze ( #585 ) \n                 \n                 \n                     Display metadata footer on custom SQL queries - thanks, Tobias Kunze ( #589 ) \n                 \n                 \n                     Use  --platform=managed  for  publish cloudrun  ( #587 ) \n                 \n                 \n                     Fixed bug returning non-ASCII characters in CSV ( #584 ) \n                 \n                 \n                     Fix for  /foo  v.s.  /foo-bar  bug ( #601 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/583\", \"label\": \"#583\"}, {\"href\": \"https://github.com/simonw/datasette/issues/136\", \"label\": \"#136\"}, {\"href\": \"https://github.com/simonw/datasette/issues/585\", \"label\": \"#585\"}, {\"href\": \"https://github.com/simonw/datasette/pull/589\", \"label\": \"#589\"}, {\"href\": \"https://github.com/simonw/datasette/issues/587\", \"label\": \"#587\"}, {\"href\": \"https://github.com/simonw/datasette/issues/584\", \"label\": \"#584\"}, {\"href\": \"https://github.com/simonw/datasette/issues/601\", \"label\": \"#601\"}]"}, {"id": "changelog:id89", "page": "changelog", "ref": "id89", "title": "0.29.3 (2019-09-02)", "content": "Fixed implementation of CodeMirror on database page ( #560 ) \n                 \n                 \n                     Documentation typo fixes - thanks, Min ho Kim ( #561 ) \n                 \n                 \n                     Mechanism for detecting if a table has FTS enabled now works if the table name used alternative escaping mechanisms ( #570 ) - for compatibility with  a recent change to sqlite-utils .", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/560\", \"label\": \"#560\"}, {\"href\": \"https://github.com/simonw/datasette/pull/561\", \"label\": \"#561\"}, {\"href\": \"https://github.com/simonw/datasette/issues/570\", \"label\": \"#570\"}, {\"href\": \"https://github.com/simonw/sqlite-utils/pull/57\", \"label\": \"a recent change to sqlite-utils\"}]"}, {"id": "changelog:id9", "page": "changelog", "ref": "id9", "title": "Other changes", "content": "The new  DATASETTE_TRACE_PLUGINS=1 environment variable  turns on detailed trace output for every executed plugin hook, useful for debugging and understanding how the plugin system works at a low level. ( #2274 ) \n                     \n                     \n                         Datasette on Python 3.9 or above marks its non-cryptographic uses of the MD5 hash function as  usedforsecurity=False , for compatibility with FIPS systems. ( #2270 ) \n                     \n                     \n                         SQL relating to  Datasette's internal database  now executes inside a transaction, avoiding a potential database locked error. ( #2273 ) \n                     \n                     \n                         The  /-/threads  debug page now identifies the database in the name associated with each dedicated write thread. ( #2265 ) \n                     \n                     \n                         The  /db/-/create  API now fires a  insert-rows  event if rows were inserted after the table was created. ( #2260 )", "breadcrumbs": "[\"Changelog\", \"1.0a9 (2024-02-16)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/2274\", \"label\": \"#2274\"}, {\"href\": \"https://github.com/simonw/datasette/issues/2270\", \"label\": \"#2270\"}, {\"href\": \"https://github.com/simonw/datasette/issues/2273\", \"label\": \"#2273\"}, {\"href\": \"https://github.com/simonw/datasette/issues/2265\", \"label\": \"#2265\"}, {\"href\": \"https://github.com/simonw/datasette/issues/2260\", \"label\": \"#2260\"}]"}, {"id": "changelog:id90", "page": "changelog", "ref": "id90", "title": "0.29.2 (2019-07-13)", "content": "Bumped  Uvicorn  to 0.8.4, fixing a bug where the query string was not included in the server logs. ( #559 ) \n                 \n                 \n                     Fixed bug where the navigation breadcrumbs were not displayed correctly on the page for a custom query. ( #558 ) \n                 \n                 \n                     Fixed bug where custom query names containing unicode characters caused errors.", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://www.uvicorn.org/\", \"label\": \"Uvicorn\"}, {\"href\": \"https://github.com/simonw/datasette/issues/559\", \"label\": \"#559\"}, {\"href\": \"https://github.com/simonw/datasette/issues/558\", \"label\": \"#558\"}]"}, {"id": "changelog:id91", "page": "changelog", "ref": "id91", "title": "0.29.1 (2019-07-11)", "content": "Fixed bug with static mounts using relative paths which could lead to traversal exploits ( #555 ) - thanks Abdussamet Kocak! \n                 \n                 \n                     Datasette can now be run as a module:  python -m datasette  ( #556 ) - thanks, Abdussamet Kocak!", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/555\", \"label\": \"#555\"}, {\"href\": \"https://github.com/simonw/datasette/issues/556\", \"label\": \"#556\"}]"}, {"id": "changelog:id92", "page": "changelog", "ref": "id92", "title": "0.29 (2019-07-07)", "content": "ASGI, new plugin hooks, facet by date and much, much more...", "breadcrumbs": "[\"Changelog\"]", "references": "[]"}, {"id": "changelog:id93", "page": "changelog", "ref": "id93", "title": "0.28 (2019-05-19)", "content": "A  salmagundi  of new features!", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://adamj.eu/tech/2019/01/18/a-salmagundi-of-django-alpha-announcements/\", \"label\": \"salmagundi\"}]"}, {"id": "changelog:id94", "page": "changelog", "ref": "id94", "title": "Small changes", "content": "We now show the size of the database file next to the download link ( #172 ) \n                     \n                     \n                         New  /-/databases  introspection page shows currently connected databases ( #470 ) \n                     \n                     \n                         Binary data is no longer displayed on the table and row pages ( #442  - thanks, Russ Garrett) \n                     \n                     \n                         New show/hide SQL links on custom query pages ( #415 ) \n                     \n                     \n                         The  extra_body_script  plugin hook now accepts an optional  view_name  argument ( #443  - thanks, Russ Garrett) \n                     \n                     \n                         Bumped Jinja2 dependency to 2.10.1 ( #426 ) \n                     \n                     \n                         All table filters are now documented, and documentation is enforced via unit tests ( 2c19a27 ) \n                     \n                     \n                         New project guideline: master should stay shippable at all times! ( 31f36e1 ) \n                     \n                     \n                         Fixed a bug where  sqlite_timelimit()  occasionally failed to clean up after itself ( bac4e01 ) \n                     \n                     \n                         We no longer load additional plugins when executing pytest ( #438 ) \n                     \n                     \n                         Homepage now links to database views if there are less than five tables in a database ( #373 ) \n                     \n                     \n                         The  --cors  option is now respected by error pages ( #453 ) \n                     \n                     \n                         datasette publish heroku  now uses the  --include-vcs-ignore  option, which means it works under Travis CI ( #407 ) \n                     \n                     \n                         datasette publish heroku  now publishes using Python 3.6.8 ( 666c374 ) \n                     \n                     \n                         Renamed  datasette publish now  to  datasette publish nowv1  ( #472 ) \n                     \n                     \n                         datasette publish nowv1  now accepts multiple  --alias  parameters ( 09ef305 ) \n                     \n                     \n                         Removed the  datasette skeleton  command ( #476 ) \n                     \n                     \n                         The  documentation on how to build the documentation  now recommends  sphinx-autobuild", "breadcrumbs": "[\"Changelog\", \"0.28 (2019-05-19)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/172\", \"label\": \"#172\"}, {\"href\": \"https://github.com/simonw/datasette/issues/470\", \"label\": \"#470\"}, {\"href\": \"https://github.com/simonw/datasette/pull/442\", \"label\": \"#442\"}, {\"href\": \"https://github.com/simonw/datasette/issues/415\", \"label\": \"#415\"}, {\"href\": \"https://github.com/simonw/datasette/pull/443\", \"label\": \"#443\"}, {\"href\": \"https://github.com/simonw/datasette/pull/426\", \"label\": \"#426\"}, {\"href\": \"https://github.com/simonw/datasette/commit/2c19a27d15a913e5f3dd443f04067169a6f24634\", \"label\": \"2c19a27\"}, {\"href\": \"https://github.com/simonw/datasette/commit/31f36e1b97ccc3f4387c80698d018a69798b6228\", \"label\": \"31f36e1\"}, {\"href\": \"https://github.com/simonw/datasette/commit/bac4e01f40ae7bd19d1eab1fb9349452c18de8f5\", \"label\": \"bac4e01\"}, {\"href\": \"https://github.com/simonw/datasette/issues/438\", \"label\": \"#438\"}, {\"href\": \"https://github.com/simonw/datasette/issues/373\", \"label\": \"#373\"}, {\"href\": \"https://github.com/simonw/datasette/issues/453\", \"label\": \"#453\"}, {\"href\": \"https://github.com/simonw/datasette/pull/407\", \"label\": \"#407\"}, {\"href\": \"https://github.com/simonw/datasette/commit/666c37415a898949fae0437099d62a35b1e9c430\", \"label\": \"666c374\"}, {\"href\": \"https://github.com/simonw/datasette/issues/472\", \"label\": \"#472\"}, {\"href\": \"https://github.com/simonw/datasette/commit/09ef305c687399384fe38487c075e8669682deb4\", \"label\": \"09ef305\"}, {\"href\": \"https://github.com/simonw/datasette/issues/476\", \"label\": \"#476\"}]"}, {"id": "changelog:id95", "page": "changelog", "ref": "id95", "title": "0.27.1 (2019-05-09)", "content": "Tiny bugfix release: don't install  tests/  in the wrong place. Thanks, Veit Heller.", "breadcrumbs": "[\"Changelog\"]", "references": "[]"}, {"id": "changelog:id96", "page": "changelog", "ref": "id96", "title": "0.27 (2019-01-31)", "content": "New command:  datasette plugins  ( documentation ) shows you the currently installed list of plugins. \n                 \n                 \n                     Datasette can now output  newline-delimited JSON  using the new  ?_shape=array&_nl=on  query string option. \n                 \n                 \n                     Added documentation on  The Datasette Ecosystem . \n                 \n                 \n                     Now using Python 3.7.2 as the base for the official  Datasette Docker image .", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"http://ndjson.org/\", \"label\": \"newline-delimited JSON\"}, {\"href\": \"https://hub.docker.com/r/datasetteproject/datasette/\", \"label\": \"Datasette Docker image\"}]"}, {"id": "changelog:id97", "page": "changelog", "ref": "id97", "title": "0.26.1 (2019-01-10)", "content": "/-/versions  now includes SQLite  compile_options  ( #396 ) \n                 \n                 \n                     datasetteproject/datasette  Docker image now uses SQLite 3.26.0 ( #397 ) \n                 \n                 \n                     Cleaned up some deprecation warnings under Python 3.7", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/396\", \"label\": \"#396\"}, {\"href\": \"https://hub.docker.com/r/datasetteproject/datasette\", \"label\": \"datasetteproject/datasette\"}, {\"href\": \"https://github.com/simonw/datasette/issues/397\", \"label\": \"#397\"}]"}, {"id": "changelog:id98", "page": "changelog", "ref": "id98", "title": "0.26 (2019-01-02)", "content": "datasette serve --reload  now restarts Datasette if a database file changes on disk. \n                 \n                 \n                     datasette publish now  now takes an optional  --alias mysite.now.sh  argument. This will attempt to set an alias after the deploy completes. \n                 \n                 \n                     Fixed a bug where the advanced CSV export form failed to include the currently selected filters ( #393 )", "breadcrumbs": "[\"Changelog\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/393\", \"label\": \"#393\"}]"}, {"id": "changelog:id99", "page": "changelog", "ref": "id99", "title": "0.25.2 (2018-12-16)", "content": "datasette publish heroku  now uses the  python-3.6.7  runtime \n                 \n                 \n                     Added documentation on  how to build the documentation \n                 \n                 \n                     Added documentation covering  our release process \n                 \n                 \n                     Upgraded to pytest 4.0.2", "breadcrumbs": "[\"Changelog\"]", "references": "[]"}, {"id": "changelog:improved-support-for-spatialite", "page": "changelog", "ref": "improved-support-for-spatialite", "title": "Improved support for SpatiaLite", "content": "The  SpatiaLite module \n                    for SQLite adds robust geospatial features to the database. \n                 Getting SpatiaLite working can be tricky, especially if you want to use the most\n                    recent alpha version (with support for K-nearest neighbor). \n                 Datasette now includes  extensive documentation on SpatiaLite , and thanks to  Ravi Kotecha  our GitHub\n                    repo includes a  Dockerfile  that can build\n                    the latest SpatiaLite and configure it for use with Datasette. \n                 The  datasette publish  and  datasette package  commands now accept a new\n                     --spatialite  argument which causes them to install and configure SpatiaLite\n                    as part of the container they deploy.", "breadcrumbs": "[\"Changelog\", \"0.23 (2018-06-18)\"]", "references": "[{\"href\": \"https://www.gaia-gis.it/fossil/libspatialite/index\", \"label\": \"SpatiaLite module\"}, {\"href\": \"https://github.com/r4vi\", \"label\": \"Ravi Kotecha\"}, {\"href\": \"https://github.com/simonw/datasette/blob/master/Dockerfile\", \"label\": \"Dockerfile\"}]"}, {"id": "changelog:javascript-modules", "page": "changelog", "ref": "javascript-modules", "title": "JavaScript modules", "content": "JavaScript modules  were introduced in ECMAScript 2015 and provide native browser support for the  import  and  export  keywords. \n                 To use modules, JavaScript needs to be included in  <script>  tags with a  type=\"module\"  attribute. \n                 Datasette now has the ability to output  <script type=\"module\">  in places where you may wish to take advantage of modules. The  extra_js_urls  option described in  Custom CSS and JavaScript  can now be used with modules, and module support is also available for the  extra_body_script()  plugin hook. ( #1186 ,  #1187 ) \n                 datasette-leaflet-freedraw  is the first example of a Datasette plugin that takes advantage of the new support for JavaScript modules. See  Drawing shapes on a map to query a SpatiaLite database  for more on this plugin.", "breadcrumbs": "[\"Changelog\", \"0.54 (2021-01-25)\"]", "references": "[{\"href\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules\", \"label\": \"JavaScript modules\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1186\", \"label\": \"#1186\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1187\", \"label\": \"#1187\"}, {\"href\": \"https://datasette.io/plugins/datasette-leaflet-freedraw\", \"label\": \"datasette-leaflet-freedraw\"}, {\"href\": \"https://simonwillison.net/2021/Jan/24/drawing-shapes-spatialite/\", \"label\": \"Drawing shapes on a map to query a SpatiaLite database\"}]"}, {"id": "changelog:javascript-plugins", "page": "changelog", "ref": "javascript-plugins", "title": "JavaScript plugins", "content": "Datasette now includes a  JavaScript plugins mechanism , allowing JavaScript to customize Datasette in a way that can collaborate with other plugins. \n                 This provides two initial hooks, with more to come in the future: \n                 \n                     \n                         makeAboveTablePanelConfigs()  can add additional panels to the top of the table page. \n                     \n                     \n                         makeColumnActions()  can add additional actions to the column menu. \n                     \n                 \n                 Thanks  Cameron Yick  for contributing this feature. ( #2052 )", "breadcrumbs": "[\"Changelog\", \"1.0a8 (2024-02-07)\"]", "references": "[{\"href\": \"https://github.com/hydrosquall\", \"label\": \"Cameron Yick\"}, {\"href\": \"https://github.com/simonw/datasette/pull/2052\", \"label\": \"#2052\"}]"}, {"id": "changelog:latest-datasette-io", "page": "changelog", "ref": "latest-datasette-io", "title": "latest.datasette.io", "content": "Every commit to Datasette master is now automatically deployed by Travis CI to\n                     https://latest.datasette.io/  - ensuring there is always a live demo of the\n                    latest version of the software. \n                 The demo uses  the fixtures  from our\n                    unit tests, ensuring it demonstrates the same range of functionality that is\n                    covered by the tests. \n                 You can see how the deployment mechanism works in our  .travis.yml  file.", "breadcrumbs": "[\"Changelog\", \"0.23 (2018-06-18)\"]", "references": "[{\"href\": \"https://latest.datasette.io/\", \"label\": \"https://latest.datasette.io/\"}, {\"href\": \"https://github.com/simonw/datasette/blob/master/tests/fixtures.py\", \"label\": \"the fixtures\"}, {\"href\": \"https://github.com/simonw/datasette/blob/master/.travis.yml\", \"label\": \".travis.yml\"}]"}, {"id": "changelog:log-out", "page": "changelog", "ref": "log-out", "title": "Log out", "content": "The  ds_actor cookie  can be used by plugins (or by Datasette's  --root mechanism ) to authenticate users. The new  /-/logout  page provides a way to clear that cookie. \n                 A \"Log out\" button now shows in the global navigation provided the user is authenticated using the  ds_actor  cookie. ( #840 )", "breadcrumbs": "[\"Changelog\", \"0.45 (2020-07-01)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/840\", \"label\": \"#840\"}]"}, {"id": "changelog:magic-parameters-for-canned-queries", "page": "changelog", "ref": "magic-parameters-for-canned-queries", "title": "Magic parameters for canned queries", "content": "Canned queries now support  Magic parameters , which can be used to insert or select automatically generated values. For example: \n                 insert into logs\n  (user_id, timestamp)\nvalues\n  (:_actor_id, :_now_datetime_utc) \n                 This inserts the currently authenticated actor ID and the current datetime. ( #842 )", "breadcrumbs": "[\"Changelog\", \"0.45 (2020-07-01)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/842\", \"label\": \"#842\"}]"}, {"id": "changelog:minor-fixes", "page": "changelog", "ref": "minor-fixes", "title": "Minor fixes", "content": "Datasette no longer attempts to run SQL queries in parallel when rendering a table page, as this was leading to some rare crashing bugs. ( #2189 ) \n                     \n                     \n                         Fixed warning:  DeprecationWarning: pkg_resources is deprecated as an API  ( #2057 ) \n                     \n                     \n                         Fixed bug where  ?_extra=columns  parameter returned an incorrectly shaped response. ( #2230 )", "breadcrumbs": "[\"Changelog\", \"1.0a8 (2024-02-07)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/2189\", \"label\": \"#2189\"}, {\"href\": \"https://github.com/simonw/datasette/issues/2057\", \"label\": \"#2057\"}, {\"href\": \"https://github.com/simonw/datasette/issues/2230\", \"label\": \"#2230\"}]"}, {"id": "changelog:miscellaneous", "page": "changelog", "ref": "miscellaneous", "title": "Miscellaneous", "content": "Got JSON data in one of your columns? Use the new  ?_json=COLNAME  argument\n                            to tell Datasette to return that JSON value directly rather than encoding it\n                            as a string. \n                     \n                     \n                         If you just want an array of the first value of each row, use the new\n                             ?_shape=arrayfirst  option -  example .", "breadcrumbs": "[\"Changelog\", \"0.23 (2018-06-18)\"]", "references": "[{\"href\": \"https://latest.datasette.io/fixtures.json?sql=select+neighborhood+from+facetable+order+by+pk+limit+101&_shape=arrayfirst\", \"label\": \"example\"}]"}, {"id": "changelog:named-in-memory-database-support", "page": "changelog", "ref": "named-in-memory-database-support", "title": "Named in-memory database support", "content": "As part of the work building the  _internal  database, Datasette now supports named in-memory databases that can be shared across multiple connections. This allows plugins to create in-memory databases which will persist data for the lifetime of the Datasette server process. ( #1151 ) \n                 The new  memory_name=  parameter to the  Database class  can be used to create named, shared in-memory databases.", "breadcrumbs": "[\"Changelog\", \"0.54 (2021-01-25)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/1151\", \"label\": \"#1151\"}]"}, {"id": "changelog:new-configuration-settings", "page": "changelog", "ref": "new-configuration-settings", "title": "New configuration settings", "content": "Datasette's  Settings  now also supports boolean settings. A number of new\n                    configuration options have been added: \n                 \n                     \n                         num_sql_threads  - the number of threads used to execute SQLite queries. Defaults to 3. \n                     \n                     \n                         allow_facet  - enable or disable custom  Facets  using the  _facet=  parameter. Defaults to on. \n                     \n                     \n                         suggest_facets  - should Datasette suggest facets? Defaults to on. \n                     \n                     \n                         allow_download  - should users be allowed to download the entire SQLite database? Defaults to on. \n                     \n                     \n                         allow_sql  - should users be allowed to execute custom SQL queries? Defaults to on. \n                     \n                     \n                         default_cache_ttl  - Default HTTP caching max-age header in seconds. Defaults to 365 days - caching can be disabled entirely by settings this to 0. \n                     \n                     \n                         cache_size_kb  - Set the amount of memory SQLite uses for its  per-connection cache , in KB. \n                     \n                     \n                         allow_csv_stream  - allow users to stream entire result sets as a single CSV file. Defaults to on. \n                     \n                     \n                         max_csv_mb  - maximum size of a returned CSV file in MB. Defaults to 100MB, set to 0 to disable this limit.", "breadcrumbs": "[\"Changelog\", \"0.23 (2018-06-18)\"]", "references": "[{\"href\": \"https://www.sqlite.org/pragma.html#pragma_cache_size\", \"label\": \"per-connection cache\"}]"}, {"id": "changelog:new-features", "page": "changelog", "ref": "new-features", "title": "New features", "content": "If an error occurs while executing a user-provided SQL query, that query is now re-displayed in an editable form along with the error message. ( #619 ) \n                     \n                     \n                         New  ?_col=  and  ?_nocol=  parameters to show and hide columns in a table, plus an interface for hiding and showing columns in the column cog menu. ( #615 ) \n                     \n                     \n                         A new  ?_facet_size=  parameter for customizing the number of facet results returned on a table or view page. ( #1332 ) \n                     \n                     \n                         ?_facet_size=max  sets that to the maximum, which defaults to 1,000 and is controlled by the the  max_returned_rows  setting. If facet results are truncated the \u2026 at the bottom of the facet list now links to this parameter. ( #1337 ) \n                     \n                     \n                         ?_nofacet=1  option to disable all facet calculations on a page, used as a performance optimization for CSV exports and  ?_shape=array/object . ( #1349 ,  #263 ) \n                     \n                     \n                         ?_nocount=1  option to disable full query result counts. ( #1353 ) \n                     \n                     \n                         ?_trace=1  debugging option is now controlled by the new  trace_debug  setting, which is turned off by default. ( #1359 )", "breadcrumbs": "[\"Changelog\", \"0.57 (2021-06-05)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/619\", \"label\": \"#619\"}, {\"href\": \"https://github.com/simonw/datasette/issues/615\", \"label\": \"#615\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1332\", \"label\": \"#1332\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1337\", \"label\": \"#1337\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1349\", \"label\": \"#1349\"}, {\"href\": \"https://github.com/simonw/datasette/issues/263\", \"label\": \"#263\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1353\", \"label\": \"#1353\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1359\", \"label\": \"#1359\"}]"}, {"id": "changelog:new-plugin-hook-asgi-wrapper", "page": "changelog", "ref": "new-plugin-hook-asgi-wrapper", "title": "New plugin hook: asgi_wrapper", "content": "The  asgi_wrapper(datasette)  plugin hook allows plugins to entirely wrap the Datasette ASGI application in their own ASGI middleware. ( #520 ) \n                 Two new plugins take advantage of this hook: \n                 \n                     \n                         datasette-auth-github  adds a authentication layer: users will have to sign in using their GitHub account before they can view data or interact with Datasette. You can also use it to restrict access to specific GitHub users, or to members of specified GitHub  organizations  or  teams . \n                     \n                     \n                         datasette-cors  allows you to configure  CORS headers  for your Datasette instance. You can use this to enable JavaScript running on a whitelisted set of domains to make  fetch()  calls to the JSON API provided by your Datasette instance.", "breadcrumbs": "[\"Changelog\", \"0.29 (2019-07-07)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/520\", \"label\": \"#520\"}, {\"href\": \"https://github.com/simonw/datasette-auth-github\", \"label\": \"datasette-auth-github\"}, {\"href\": \"https://help.github.com/en/articles/about-organizations\", \"label\": \"organizations\"}, {\"href\": \"https://help.github.com/en/articles/organizing-members-into-teams\", \"label\": \"teams\"}, {\"href\": \"https://github.com/simonw/datasette-cors\", \"label\": \"datasette-cors\"}, {\"href\": \"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS\", \"label\": \"CORS headers\"}]"}, {"id": "changelog:new-plugin-hook-extra-template-vars", "page": "changelog", "ref": "new-plugin-hook-extra-template-vars", "title": "New plugin hook: extra_template_vars", "content": "The  extra_template_vars(template, database, table, columns, view_name, request, datasette)  plugin hook allows plugins to inject their own additional variables into the Datasette template context. This can be used in conjunction with custom templates to customize the Datasette interface.  datasette-auth-github  uses this hook to add custom HTML to the new top navigation bar (which is designed to be modified by plugins, see  #540 ).", "breadcrumbs": "[\"Changelog\", \"0.29 (2019-07-07)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette-auth-github\", \"label\": \"datasette-auth-github\"}, {\"href\": \"https://github.com/simonw/datasette/issues/540\", \"label\": \"#540\"}]"}, {"id": "changelog:new-plugin-hooks", "page": "changelog", "ref": "new-plugin-hooks", "title": "New plugin hooks", "content": "register_magic_parameters(datasette)  can be used to define new types of magic canned query parameters. \n                     \n                     \n                         startup(datasette)  can run custom code when Datasette first starts up.  datasette-init  is a new plugin that uses this hook to create database tables and views on startup if they have not yet been created. ( #834 ) \n                     \n                     \n                         canned_queries(datasette, database, actor)  lets plugins provide additional canned queries beyond those defined in Datasette's metadata. See  datasette-saved-queries  for an example of this hook in action. ( #852 ) \n                     \n                     \n                         forbidden(datasette, request, message)  is a hook for customizing how Datasette responds to 403 forbidden errors. ( #812 )", "breadcrumbs": "[\"Changelog\", \"0.45 (2020-07-01)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette-init\", \"label\": \"datasette-init\"}, {\"href\": \"https://github.com/simonw/datasette/issues/834\", \"label\": \"#834\"}, {\"href\": \"https://github.com/simonw/datasette-saved-queries\", \"label\": \"datasette-saved-queries\"}, {\"href\": \"https://github.com/simonw/datasette/issues/852\", \"label\": \"#852\"}, {\"href\": \"https://github.com/simonw/datasette/issues/812\", \"label\": \"#812\"}]"}, {"id": "changelog:new-visual-design", "page": "changelog", "ref": "new-visual-design", "title": "New visual design", "content": "Datasette is no longer white and grey with blue and purple links!  Natalie Downe  has been working on a visual refresh, the first iteration of which is included in this release. ( #1056 )", "breadcrumbs": "[\"Changelog\", \"0.51 (2020-10-31)\"]", "references": "[{\"href\": \"https://twitter.com/natbat\", \"label\": \"Natalie Downe\"}, {\"href\": \"https://github.com/simonw/datasette/pull/1056\", \"label\": \"#1056\"}]"}, {"id": "changelog:other-changes", "page": "changelog", "ref": "other-changes", "title": "Other changes", "content": "Facets defined in metadata now preserve their configured order, instead of being sorted by result count. Request-based facets added via the  _facet  parameter are still sorted by result count and appear after metadata-defined facets. ( #2647 ) \n                     \n                     \n                         Fixed  --reload  incorrectly interpreting the  serve  command as a file argument. Thanks,  Daniel Bates . ( #2646 )", "breadcrumbs": "[\"Changelog\", \"1.0a25 (2026-02-25)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/2647\", \"label\": \"#2647\"}, {\"href\": \"https://github.com/danielalanbates\", \"label\": \"Daniel Bates\"}, {\"href\": \"https://github.com/simonw/datasette/pull/2646\", \"label\": \"#2646\"}]"}, {"id": "changelog:other-small-fixes", "page": "changelog", "ref": "other-small-fixes", "title": "Other small fixes", "content": "Made several performance improvements to the database schema introspection code that runs when Datasette first starts up. ( #1555 ) \n                     \n                     \n                         Label columns detected for foreign keys are now case-insensitive, so  Name  or  TITLE  will be detected in the same way as  name  or  title . ( #1544 ) \n                     \n                     \n                         Upgraded Pluggy dependency to 1.0. ( #1575 ) \n                     \n                     \n                         Now using  Plausible analytics  for the Datasette documentation. \n                     \n                     \n                         explain query plan  is now allowed with varying amounts of whitespace in the query. ( #1588 ) \n                     \n                     \n                         New  CLI reference  page showing the output of  --help  for each of the  datasette  sub-commands. This lead to several small improvements to the help copy. ( #1594 ) \n                     \n                     \n                         Fixed bug where writable canned queries could not be used with custom templates.  ( #1547 ) \n                     \n                     \n                         Improved fix for a bug where columns with a underscore prefix could result in unnecessary hidden form fields. ( #1527 )", "breadcrumbs": "[\"Changelog\", \"0.60 (2022-01-13)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/1555\", \"label\": \"#1555\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1544\", \"label\": \"#1544\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1575\", \"label\": \"#1575\"}, {\"href\": \"https://plausible.io/\", \"label\": \"Plausible analytics\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1588\", \"label\": \"#1588\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1594\", \"label\": \"#1594\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1547\", \"label\": \"#1547\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1527\", \"label\": \"#1527\"}]"}, {"id": "changelog:permission-checks-now-consider-opinions-from-every-plugin", "page": "changelog", "ref": "permission-checks-now-consider-opinions-from-every-plugin", "title": "Permission checks now consider opinions from every plugin", "content": "The  datasette.permission_allowed()  method previously consulted every plugin that implemented the  permission_allowed()  plugin hook and obeyed the opinion of the last plugin to return a value. ( #2275 ) \n                 Datasette now consults every plugin and checks to see if any of them returned  False  (the veto rule), and if none of them did, it then checks to see if any of them returned  True . \n                 This is explained at length in the new documentation covering  How permissions are resolved .", "breadcrumbs": "[\"Changelog\", \"1.0a9 (2024-02-16)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/2275\", \"label\": \"#2275\"}]"}, {"id": "changelog:permission-system-redesign", "page": "changelog", "ref": "permission-system-redesign", "title": "Permission system redesign", "content": "Previously the permission system worked using  datasette.permission_allowed()  checks which consulted all available plugins in turn to determine whether a given actor was allowed to perform a given action on a given resource. \n                 This approach could become prohibitively expensive for large lists of items - for example to determine the list of tables that a user could view in a large Datasette instance each plugin implementation of that hook would be fired for every table. \n                 The new design uses SQL queries against Datasette's internal  catalog tables  to derive the list of resources for which an actor has permission for a given action. This turns an N x M problem (N resources, M plugins) into a single SQL query. \n                 Plugins can use the new  permission_resources_sql(datasette, actor, action)  hook to return SQL fragments which will be used as part of that query. \n                 Plugins that use any of the following features will need to be updated to work with this and following alphas (and Datasette 1.0 stable itself): \n                 \n                     \n                         Checking permissions with  datasette.permission_allowed()  - this method has been replaced with  datasette.allowed() . \n                     \n                     \n                         Implementing the  permission_allowed()  plugin hook - this hook has been removed in favor of  permission_resources_sql() . \n                     \n                     \n                         Using  register_permissions()  to register permissions - this hook has been removed in favor of  register_actions() . \n                     \n                 \n                 Consult the  v1.0a20 upgrade guide  for further details on how to upgrade affected plugins. \n                 Plugins can now make use of two new internal methods to help resolve permission checks: \n                 \n                     \n                         datasette.allowed_resources()  returns a  PaginatedResources  object with a  .resources  list of  Resource  instances that an actor is allowed to access for a given action (and a  .next  token for pagination). \n                     \n                     \n                         datasette.allowed_resources_sql()  returns the SQL and parameters that can be executed against the internal catalog tables to determine which resources an actor is allowed to access for a given action. This can be combined with further SQL to perform advanced custom filtering. \n                     \n                 \n                 Related changes: \n                 \n                     \n                         The way  datasette --root  works has changed. Running Datasette with this flag now causes the root actor to pass  all  permission checks. ( #2521 ) \n                     \n                     \n                         Permission debugging improvements: \n                         \n                             \n                                 The  /-/allowed  endpoint shows resources the user is allowed to interact with for different actions. \n                             \n                             \n                                 /-/rules  shows the raw allow/deny rules that apply to different permission checks. \n                             \n                             \n                                 /-/actions  lists every available action. \n                             \n                             \n                                 /-/check  can be used to try out different permission checks for the current actor.", "breadcrumbs": "[\"Changelog\", \"1.0a20 (2025-11-03)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/2521\", \"label\": \"#2521\"}]"}, {"id": "changelog:permissions", "page": "changelog", "ref": "permissions", "title": "Permissions", "content": "Datasette also now has a built-in concept of  Permissions . The permissions system answers the following question: \n                 \n                     Is this  actor  allowed to perform this  action , optionally against this particular  resource ? \n                 \n                 You can use the new  \"allow\"  block syntax in  metadata.json  (or  metadata.yaml ) to set required permissions at the instance, database, table or canned query level. For example, to restrict access to the  fixtures.db  database to the  \"root\"  user: \n                 {\n    \"databases\": {\n        \"fixtures\": {\n            \"allow\": {\n                \"id\" \"root\"\n            }\n        }\n    }\n} \n                 See  Defining permissions with \"allow\" blocks  for more details. \n                 Plugins can implement their own custom permission checks using the new  plugin_hook_permission_allowed()  plugin hook. \n                 A new debug page at  /-/permissions  shows recent permission checks, to help administrators and plugin authors understand exactly what checks are being performed. This tool defaults to only being available to the root user, but can be exposed to other users by plugins that respond to the  permissions-debug  permission. ( #788 )", "breadcrumbs": "[\"Changelog\", \"0.44 (2020-06-11)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/788\", \"label\": \"#788\"}]"}, {"id": "changelog:permissions-fix-for-the-upsert-api", "page": "changelog", "ref": "permissions-fix-for-the-upsert-api", "title": "Permissions fix for the upsert API", "content": "The  /database/table/-/upsert API  had a minor permissions bug, only affecting Datasette instances that had configured the  insert-row  and  update-row  permissions to apply to a specific table rather than the database or instance as a whole. Full details in issue  #2262 . \n                 To avoid similar mistakes in the future the  datasette.permission_allowed()  method now specifies  default=  as a keyword-only argument.", "breadcrumbs": "[\"Changelog\", \"1.0a9 (2024-02-16)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/2262\", \"label\": \"#2262\"}]"}, {"id": "changelog:plugin-hooks", "page": "changelog", "ref": "plugin-hooks", "title": "Plugin hooks", "content": "New  jinja2_environment_from_request(datasette, request, env)  plugin hook, which can be used to customize the current Jinja environment based on the incoming request. This can be used to modify the template lookup path based on the incoming request hostname, among other things. ( #2225 ) \n                     \n                     \n                         New  family of template slot plugin hooks :  top_homepage ,  top_database ,  top_table ,  top_row ,  top_query ,  top_canned_query . Plugins can use these to provide additional HTML to be injected at the top of the corresponding pages. ( #1191 ) \n                     \n                     \n                         \n                             \n                                 New  track_event() mechanism  for plugins to emit and receive events when certain events occur within Datasette. ( #2240 ) \n                                 \n                                     \n                                         \n                                             Plugins can register additional event classes using  register_events(datasette) . \n                                         \n                                         \n                                             They can then trigger those events with the  datasette.track_event(event)  internal method. \n                                         \n                                         \n                                             Plugins can subscribe to notifications of events using the  track_event(datasette, event)  plugin hook. \n                                         \n                                         \n                                             Datasette core now emits  login ,  logout ,  create-token ,  create-table ,  drop-table ,  insert-rows ,  upsert-rows ,  update-row ,  delete-row  events,  documented here . \n                                         \n                                     \n                                 \n                             \n                         \n                     \n                     \n                         New internal function for plugin authors:  await db.execute_isolated_fn(fn) , for creating a new SQLite connection, executing code and then closing that connection, all while preventing other code from writing to that particular database. This connection will not have the  prepare_connection()  plugin hook executed against it, allowing plugins to perform actions that might otherwise be blocked by existing connection configuration. ( #2218 )", "breadcrumbs": "[\"Changelog\", \"1.0a8 (2024-02-07)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/2225\", \"label\": \"#2225\"}, {\"href\": \"https://github.com/simonw/datasette/issues/1191\", \"label\": \"#1191\"}, {\"href\": \"https://github.com/simonw/datasette/issues/2240\", \"label\": \"#2240\"}, {\"href\": \"https://github.com/simonw/datasette/issues/2218\", \"label\": \"#2218\"}]"}]