Releases: simonw/datasette
1.0a23
1.0a22
datasette serve --default-denyoption for running Datasette configured to deny all permissions by default. (#2592)datasette.is_client()method for detecting if code is executing inside a datasette.client request. (#2594)datasette.pmproperty can now be used to register and unregister plugins in tests. (#2595)
1.0a21
- Fixes an open redirect security issue: Datasette instances would redirect to
example.com/foo/barif you accessed the path//example.com/foo/bar. Thanks to James Jefferies for the fix. (#2429) - Fixed
datasette publish cloudrunto work with changes to the underlying Cloud Run architecture. (#2511) - New
datasette --get /path --headersoption for inspecting the headers returned by a path. (#2578) - New
datasette.client.get(..., skip_permission_checks=True)parameter to bypass permission checks when making requests using the internal client. (#2583)
0.65.2
- Fixes an open redirect security issue: Datasette instances would redirect to
example.com/foo/barif you accessed the path//example.com/foo/bar. Thanks to James Jefferies for the fix. #2429 - Upgraded for compatibility with Python 3.14.
- Fixed
datasette publish cloudrunto work with changes to the underlying Cloud Run architecture. #2511 - Minor upgrades to fix warnings, including
pkg_resourcesdeprecation.
1.0a20
This alpha introduces a major breaking change prior to the 1.0 release of Datasette concerning how Datasette's permission system works.
Permission system redesign
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.
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.
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.
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.
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):
- Checking permissions with
datasette.permission_allowed()- this method has been replaced with datasette.allowed(). - Implementing the
permission_allowed()plugin hook - this hook has been removed in favor of permission_resources_sql(). - Using
register_permissions()to register permissions - this hook has been removed in favor of register_actions().
Consult the v1.0a20 upgrade guide for further details on how to upgrade affected plugins.
Plugins can now make use of two new internal methods to help resolve permission checks:
- datasette.allowed_resources() returns a
PaginatedResourcesobject with a.resourceslist ofResourceinstances that an actor is allowed to access for a given action (and a.nexttoken for pagination). - 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.
Related changes:
- The way
datasette --rootworks has changed. Running Datasette with this flag now causes the root actor to pass all permission checks. (#2521) - Permission debugging improvements:
- The
/-/allowedendpoint shows resources the user is allowed to interact with for different actions. /-/rulesshows the raw allow/deny rules that apply to different permission checks./-/actionslists every available action./-/checkcan be used to try out different permission checks for the current actor.
- The
Other changes
- The internal
catalog_viewstable now tracks SQLite views alongside tables in the introspection database. (#2495) - Hitting the
/brings up a search interface for navigating to tables that the current user can view. A new/-/tablesendpoint supports this functionality. (#2523) - Datasette attempts to detect some configuration errors on startup.
- Datasette now supports Python 3.14 and no longer tests against Python 3.9.
1.0a19
1.0a18
- Fix for incorrect foreign key references in the internal database schema. #2466
- The
prepare_connection()hook no longer runs for the internal database. #2468 - Fixed bug where
link:HTTP headers used invalid syntax. #2470 - No longer tested against Python 3.8. Now tests against Python 3.13.
- FTS tables are now hidden by default if they correspond to a content table. #2477
- Fixed bug with foreign key links to rows in databases with filenames containing a special character. Thanks, Jack Stratton. #2476
1.0a17
DATASETTE_SSL_KEYFILEandDATASETTE_SSL_CERTFILEenvironment variables as alternatives to--ssl-keyfileand--ssl-certfile. Thanks, Alex Garcia. (#2422)SQLITE_EXTENSIONSenvironment variable has been renamed toDATASETTE_LOAD_EXTENSION. (#2424)datasette serveenvironment variables are now documented here.- The register_magic_parameters(datasette) plugin hook can now register async functions. (#2441)
- Datasette is now tested against Python 3.13.
- Breadcrumbs on database and table pages now include a consistent self-link for resetting query string parameters. (#2454)
- Fixed issue where Datasette could crash on
metadata.jsonwith nested values. (#2455) - New internal methods
datasette.set_actor_cookie()anddatasette.delete_actor_cookie(), described here. (#1690) /-/permissionspage now shows a list of all permissions registered by plugins. (#1943)- If a table has a single unique text column Datasette now detects that as the foreign key label for that table. (#2458)
- The
/-/permissionspage now includes options for filtering or exclude permission checks recorded against the current user. (#2460) - Fixed a bug where replacing a database with a new one with the same name did not pick up the new database correctly. (#2465)