Commit graph

109 commits

Author SHA1 Message Date
Simon Willison
2d07c3b99e Ran cog 2026-05-25 09:47:12 -07:00
Simon Willison
3b26b7aff0 Document canned query hook removal
Refs #2735
2026-05-24 23:00:00 -07:00
Simon Willison
21a79b34b8 Improvements to Jump SQL columns
- Removed database_name and resource_name
- url can now optionally return JSON to reuse datasette.urls. methods
- description is now used as a truncated text description
2026-05-23 20:28:02 -07:00
Simon Willison
be1b5b2b5c Move debug links into jump menu 2026-05-23 16:57:09 -07:00
Copilot
09ccab97cc
Run cog to update generated plugin docs (#2734)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-05-23 09:34:03 -07:00
Simon Willison
0b639a8122
Replace token-based CSRF with Sec-Fetch-Site header protection (#2689)
- New CSRF protection middleware inspired by Go 1.25 and research by Filippo Valsorda - https://words.filippo.io/csrf/ - this replaces the old CSRF token based protection.
- Removes all instances of `<input type="hidden" name="csrftoken" value="{{ csrftoken() }}">` in the templates - they are no longer needed.
- Removes the `def skip_csrf(datasette, scope):` plugin hook defined in `datasette/hookspecs.py` and its documentation and tests.
- Updated CSRF protection documentation to describe the new approach.
- Upgrade guide now describes the CSRF change.
2026-04-14 17:11:36 -07:00
Simon Willison
312f41b0c2
RenameTableEvent, plus write connection track_event() mechanism (#2682)
* Add track_event callback to execute_write_fn and write_wrapper

Allows write functions and write_wrapper generators to queue events
during a write operation that are dispatched after successful commit.
The fn or wrapper can optionally accept a `track_event` parameter
(detected via call_with_supported_arguments). Events are discarded
if the write raises an exception.

Does not yet handle the block=False (non-blocking) case - events
queued during non-blocking writes are currently silently discarded.

Refs https://github.com/simonw/datasette/issues/2681

* Dispatch track_event events for non-blocking (block=False) writes

Spawns a background asyncio task that awaits the write thread's reply
queue and dispatches pending events after a successful non-blocking
write. Events are still discarded if the write raises an exception.

Refs https://github.com/simonw/datasette/issues/2681

* Warn that events won't fire for other processes

Refs https://github.com/simonw/datasette/issues/2681#issuecomment-4157118662
2026-03-30 11:20:46 -07:00
Claude
da0ea4382c
Update cog-generated plugin list to include default_column_types
https://claude.ai/code/session_01SvPEPqHgURTWESRp28pTC3
2026-03-17 05:18:42 +00:00
Simon Willison
c96dc5ce26
register_token_handler() plugin hook for custom API token backends (#2650)
Closes #2649

* Add register_token_handler plugin hook for pluggable token backends

Adds a new register_token_handler hook that allows plugins to provide
custom token creation and verification backends. This enables plugins
like datasette-oauth to issue tokens without depending on specific
backend plugins like datasette-auth-tokens.

Key changes:
- New datasette/tokens.py with TokenHandler base class and SignedTokenHandler
  (the default signed-token implementation moved here)
- New register_token_handler hookspec in hookspecs.py
- Datasette.create_token() is now async and delegates to token handlers
- New Datasette.verify_token() method tries all handlers in sequence
- handler= parameter on create_token() to select a specific backend
- TokenHandler exported from datasette package for plugin use
- Fixed actor_from_request loop to await all coroutines (avoids warnings)

* Add documentation and hook test for register_token_handler

Fixes CI failures: the new hook needs a section in docs/plugin_hooks.rst
(checked by test_plugin_hooks_are_documented) and a test_hook_* function
in test_plugins.py (checked by test_plugin_hooks_have_tests).

* Register tokens module as separate default plugin

Instead of re-exporting hookimpls from default_permissions/__init__.py,
register datasette.default_permissions.tokens as its own DEFAULT_PLUGINS
entry. Cleaner and avoids confusing import-for-side-effect patterns.

* Replace restrict_x params with TokenRestrictions dataclass

Consolidates the three separate restrict_all, restrict_database, and
restrict_resource parameters into a single TokenRestrictions dataclass.
Cleaner API surface for both Datasette.create_token() and
TokenHandler.create_token().

Also clarifies docs re: default handler selection via pluggy ordering.

* Add builder methods to TokenRestrictions

Adds allow_all(), allow_database(), and allow_resource() methods that
return self for chaining. Callers no longer need to manipulate nested
dicts directly:

    restrictions = (TokenRestrictions()
        .allow_all("view-instance")
        .allow_database("mydb", "create-table")
        .allow_resource("mydb", "mytable", "insert-row"))

* docs: add 1.0a25 upgrade guide section for create_token() signature change

Ref: https://github.com/simonw/datasette/issues/2649#issuecomment-3962639393

* docs: note that create_token() is now async in upgrade guide

* docs: update internals, plugin_hooks, authentication for new token API

- internals.rst: new async create_token() signature with restrictions
  and handler params, add TokenRestrictions reference docs
- plugin_hooks.rst: show full create_token signature in TokenHandler
  example, note list returns and error cases
- authentication.rst: cross-reference TokenRestrictions from the
  restrictions section

* style: apply black formatting to token handler files

* docs: fix RST heading underline length in internals.rst

* tests: add restrictions round-trip and expiration tests for token handler

Covers allow_database/allow_resource builders, _r payload encoding,
and token_expires in verified actors. Coverage 76% -> 90%.

* tests: add test for signed tokens disabled

* fix: add TokenRestrictions TYPE_CHECKING import to fix ruff F821

* docs: regenerate plugins.rst with cog

* docs: reformat code blocks in plugin_hooks.rst with blacken-docs

* docs: add await .verify_token() to internals.rst

* tests: rewrite register_token_handler test to use real plugin handler

Adds a HardcodedTokenHandler to the test plugins dir that creates
tokens like dstok_hardcoded_token_1. The test now exercises creating
tokens via the default handler (which is the plugin's hardcoded one),
by explicitly naming the hardcoded handler, and by explicitly naming
the signed handler -- then verifies each token round-trips correctly.

* tests: clarify test_token_handler_via_http tests the default signed handler

* fix: use handler="signed" explicitly where signed tokens are expected

The HardcodedTokenHandler in my_plugin.py gets globally registered,
so create_token() without a handler name picks it up as the default.
Fix the create-token view, CLI, and tests to explicitly request the
signed handler where they depend on signed token behavior.

* fix: use handler="signed" in test_create_table_permissions

https://claude.ai/code/session_013cQFiDQjYRrRBH2biFfKuS
2026-02-25 16:32:45 -08:00
Simon Willison
d7d7ead0ef Ran cog 2025-10-25 15:38:07 -07:00
Simon Willison
6df364cb2c Ran cog 2025-10-25 15:38:07 -07:00
Simon Willison
c0b5ce04c3 Ran cog 2025-10-24 10:32:18 -07:00
Simon Willison
27084caa04
New allowed_resources_sql plugin hook and debug tools (#2505)
* allowed_resources_sql plugin hook and infrastructure
* New methods for checking permissions with the new system
* New /-/allowed and /-/check and /-/rules special endpoints

Still needs to be integrated more deeply into Datasette, especially for listing visible tables.

Refs: #2502

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-08 14:27:51 -07:00
Simon Willison
b466749e88 Filled out docs/configuration.rst, closes #2246 2024-01-31 20:03:19 -08:00
Simon Willison
bcc4f6bf1f
track_event() mechanism for analytics and plugins
* Closes #2240
* Documentation for event plugin hooks, refs #2240
* Include example track_event plugin in docs, refs #2240
* Tests for track_event() and register_events() hooks, refs #2240
* Initial documentation for core events, refs #2240
* Internals documentation for datasette.track_event()
2024-01-31 15:21:40 -08:00
Alex Garcia
35deaabcb1
Move non-metadata configuration from metadata.yaml to datasette.yaml
* Allow and permission blocks moved to datasette.yaml
* Documentation updates, initial framework for configuration reference
2023-10-12 09:16:37 -07:00
Simon Willison
6bfe104d47
DATASETTE_LOAD_PLUGINS environment variable for loading specific plugins
Closes #2164

* Load only specified plugins for DATASETTE_LOAD_PLUGINS=datasette-one,datasette-two
* Load no plugins if DATASETTE_LOAD_PLUGINS=''
* Automated tests in a Bash script for DATASETTE_LOAD_PLUGINS
2023-08-30 15:12:24 -07:00
Simon Willison
4a42476bb7 datasette plugins --requirements, closes #2133 2023-08-09 15:04:16 -07:00
Simon Willison
c076fb65e0 Applied sphinx-inline-tabs to remaining examples, refs #1153 2023-07-08 11:00:08 -07:00
Simon Willison
1ad92a1d87 datasette install -r requirements.txt, closes #2033 2023-03-06 14:27:30 -08:00
Simon Willison
1fda4806d4 Small documentation tweaks 2022-12-31 10:52:37 -08:00
Simon Willison
14f1cc4984 Update CLI reference help, refs #1855 2022-12-12 20:21:48 -08:00
Simon Willison
8bf06a76b5
register_permissions() plugin hook (#1940)
* Docs for permissions: in metadata, refs #1636
* Refactor default_permissions.py to help with implementation of #1636
* register_permissions() plugin hook, closes #1939 - also refs #1938
* Tests for register_permissions() hook, refs #1939
* Documentation for datasette.permissions, refs #1939
* permission_allowed() falls back on Permission.default, refs #1939
* Raise StartupError on duplicate permissions
* Allow dupe permisisons if exact matches
2022-12-12 18:05:54 -08:00
Simon Willison
4f16e14d7a Update cog 2022-10-30 14:53:33 -07:00
Simon Willison
c7956eed77 datasette create-token command, refs #1859 2022-10-25 21:26:12 -07:00
Simon Willison
c23fa850e7 allow_signed_tokens setting, closes #1856 2022-10-25 19:55:47 -07:00
Simon Willison
e543a095cc Updated default plugins in docs, refs #1770 2022-07-17 17:57:41 -07:00
Simon Willison
e1770766ce Return plugins and hooks in predictable order 2022-01-19 21:14:04 -08:00
Simon Willison
43c30ce023 Use cog to maintain default plugin list in plugins.rst, closes #1600
Also fixed a bug I spotted where datasette.filters showed the same hook three times.
2022-01-19 21:04:09 -08:00
Simon Willison
ed15c9908e Shrunk ecosystem docs in favour of datasette.io, closes #1182 2021-01-09 14:17:18 -08:00
Simon Willison
6fd35be64d
Fixed invalid JSON in exampl 2020-11-15 08:45:26 -08:00
Simon Willison
200284e1a7
Clarified how --plugin-secret works 2020-11-15 08:43:13 -08:00
Simon Willison
69033c6ec4 datasette install --upgrade option, closes #945 2020-08-19 10:20:41 -07:00
Simon Willison
01fe5b7401 datasette install / datasette uninstall commands, closes #925 2020-08-11 15:32:06 -07:00
Simon Willison
c32af6f693 Split out new 'Writing plugins' page, refs #687 2020-06-21 19:37:48 -07:00
Simon Willison
36e77e1006 Move plugin hooks docs to plugin_hooks.rst, refs #687 2020-06-21 17:34:10 -07:00
Simon Willison
55a6ffb93c Link to datasette-saved-queries plugin, closes #852 2020-06-19 20:08:30 -07:00
Simon Willison
9216127ace Documentation tweak, refs #852 2020-06-18 16:39:43 -07:00
Simon Willison
6c26345836 New plugin hook: canned_queries(), refs #852 2020-06-18 16:35:15 -07:00
Simon Willison
0c27f10f9d
Updated plugin examples to include datasette-psutil 2020-06-13 16:41:26 -07:00
Simon Willison
ae99af2536 Fixed rST code formatting, refs #834 2020-06-13 10:59:35 -07:00
Simon Willison
09a3479a54 New "startup" plugin hook, closes #834 2020-06-13 10:55:41 -07:00
Simon Willison
793a52b317 Link to datasett-auth-tokens and datasette-permissions-sql in docs, refs #806 2020-06-11 17:43:51 -07:00
Simon Willison
98632f0a87
--secret command for datasette publish
Closes #787
2020-06-11 09:02:03 -07:00
Simon Willison
9f236c4c00 Warn that register_facet_classes may change, refs #830
Also documented policy that plugin hooks should not be shipped without a real example. Refs #818
2020-06-10 13:06:46 -07:00
Simon Willison
fac8e93815 request.url_vars property, closes #822 2020-06-08 20:40:00 -07:00
Simon Willison
db660db463 Docs + unit tests for Response, closes #821 2020-06-08 20:32:10 -07:00
Simon Willison
f5e79adf26
register_routes() plugin hook (#819)
Fixes #215
2020-06-08 20:12:06 -07:00
Simon Willison
e0a4664fba Better example plugin for permission_allowed
Also fixed it so default permission checks run after plugin permission checks, refs #818
2020-06-08 15:09:57 -07:00
Simon Willison
c7d145e016 Updated example for extra_template_vars hook, closes #816 2020-06-08 12:06:05 -07:00