Move takes_child/takes_parent information from Action to Resource (#2567)

Simplified Action by moving takes_child/takes_parent logic to Resource

- Removed InstanceResource - global actions are now simply those with resource_class=None
- Resource.parent_class - Replaced parent_name: str with parent_class: type[Resource] | None for direct class references
- Simplified Action dataclass - No more redundant fields, everything is derived from the Resource class structure
- Validation - The __init_subclass__ method now checks parent_class.parent_class to enforce the 2-level hierarchy

Closes #2563
This commit is contained in:
Simon Willison 2025-11-01 11:35:08 -07:00 committed by GitHub
commit 5705ce0d95
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 417 additions and 186 deletions

View file

@ -41,7 +41,7 @@ def register_permissions(datasette):
),
]
```
The new `Action` does not have a `default=` parameter, and `takes_database` and `takes_resource` have been renamed to `takes_parent` and `takes_child. The new code would look like this:
The new `Action` does not have a `default=` parameter. For global actions (those that don't apply to specific resources), omit `resource_class`:
```python
from datasette.permissions import Action
@ -53,21 +53,41 @@ def register_actions(datasette):
name="datasette-pins-write",
abbr=None,
description="Can pin, unpin, and re-order pins for datasette-pins",
takes_parent=False,
takes_child=False,
default=False,
),
Action(
name="datasette-pins-read",
abbr=None,
description="Can read pinned items.",
takes_parent=False,
takes_child=False,
default=False,
),
]
```
For actions that apply to specific resources (like databases or tables), specify the `resource_class` instead of `takes_parent` and `takes_child`:
```python
from datasette.permissions import Action
from datasette.resources import DatabaseResource, TableResource
@hookimpl
def register_actions(datasette):
return [
Action(
name="execute-sql",
abbr="es",
description="Execute SQL queries",
resource_class=DatabaseResource, # Parent-level resource
),
Action(
name="insert-row",
abbr="ir",
description="Insert rows",
resource_class=TableResource, # Child-level resource
),
]
```
The hierarchy information (whether an action takes parent/child parameters) is now derived from the `Resource` class hierarchy. `Action` has `takes_parent` and `takes_child` properties that are computed based on the `resource_class` and its `parent_class` attribute.
## permission_allowed() hook is replaced by permission_resources_sql()
The following old code: