mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
Add keyset pagination to allowed_resources() (#2562)
* Add keyset pagination to allowed_resources() This replaces the unbounded list return with PaginatedResources, which supports efficient keyset pagination for handling thousands of resources. Closes #2560 Changes: - allowed_resources() now returns PaginatedResources instead of list - Added limit (1-1000, default 100) and next (keyset token) parameters - Added include_reasons parameter (replaces allowed_resources_with_reasons) - Removed allowed_resources_with_reasons() method entirely - PaginatedResources.all() async generator for automatic pagination - Uses tilde-encoding for tokens (matching table pagination) - Updated all callers to use .resources accessor - Updated documentation with new API and examples The PaginatedResources object has: - resources: List of Resource objects for current page - next: Token for next page (None if no more results) - all(): Async generator that yields all resources across pages Example usage: page = await ds.allowed_resources("view-table", actor, limit=100) for table in page.resources: print(table.child) # Iterate all pages automatically async for table in page.all(): print(table.child) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
b7ef968c6f
commit
400fa08e4c
10 changed files with 366 additions and 223 deletions
|
|
@ -387,32 +387,80 @@ The method returns ``True`` if the permission is granted, ``False`` if denied.
|
|||
|
||||
.. _datasette_allowed_resources:
|
||||
|
||||
await .allowed_resources(action, actor=None, \*, parent=None, include_is_private=False)
|
||||
---------------------------------------------------------------------------------------
|
||||
await .allowed_resources(action, actor=None, \*, parent=None, include_is_private=False, include_reasons=False, limit=100, next=None)
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Returns a list of ``Resource`` objects that the actor can access for the
|
||||
specified action. Each returned object is an instance of the action's
|
||||
``resource_class`` and may include a ``.private`` attribute (when
|
||||
``include_is_private=True``) to indicate that anonymous actors would be denied
|
||||
access.
|
||||
Returns a ``PaginatedResources`` object containing resources that the actor can access for the specified action, with support for keyset pagination.
|
||||
|
||||
Example::
|
||||
``action`` - string
|
||||
The action name (e.g., "view-table", "view-database")
|
||||
|
||||
tables = await datasette.allowed_resources(
|
||||
"view-table", actor=request.actor, parent="fixtures"
|
||||
``actor`` - dictionary, optional
|
||||
The authenticated actor. Defaults to ``None`` for unauthenticated requests.
|
||||
|
||||
``parent`` - string, optional
|
||||
Optional parent filter (e.g., database name) to limit results
|
||||
|
||||
``include_is_private`` - boolean, optional
|
||||
If True, adds a ``.private`` attribute to each Resource indicating whether anonymous users can access it
|
||||
|
||||
``include_reasons`` - boolean, optional
|
||||
If True, adds a ``.reasons`` attribute with a list of strings describing why access was granted (useful for debugging)
|
||||
|
||||
``limit`` - integer, optional
|
||||
Maximum number of results to return per page (1-1000, default 100)
|
||||
|
||||
``next`` - string, optional
|
||||
Keyset token from a previous page for pagination
|
||||
|
||||
The method returns a ``PaginatedResources`` object (from ``datasette.utils``) with the following attributes:
|
||||
|
||||
``resources`` - list
|
||||
List of ``Resource`` objects for the current page
|
||||
|
||||
``next`` - string or None
|
||||
Token for the next page, or ``None`` if no more results exist
|
||||
|
||||
Example usage:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Get first page of tables
|
||||
page = await datasette.allowed_resources(
|
||||
"view-table",
|
||||
actor=request.actor,
|
||||
parent="fixtures",
|
||||
limit=50,
|
||||
)
|
||||
for table in tables:
|
||||
|
||||
for table in page.resources:
|
||||
print(table.parent, table.child)
|
||||
if hasattr(table, "private"):
|
||||
print(f" Private: {table.private}")
|
||||
|
||||
# Get next page if available
|
||||
if page.next:
|
||||
next_page = await datasette.allowed_resources(
|
||||
"view-table", actor=request.actor, next=page.next
|
||||
)
|
||||
|
||||
# Iterate through all results automatically
|
||||
page = await datasette.allowed_resources(
|
||||
"view-table", actor=request.actor
|
||||
)
|
||||
async for table in page.all():
|
||||
print(table.parent, table.child)
|
||||
|
||||
This method uses :ref:`datasette_allowed_resources_sql` under the hood and is an
|
||||
efficient way to list the databases, tables or queries visible to a user.
|
||||
# With reasons for debugging
|
||||
page = await datasette.allowed_resources(
|
||||
"view-table", actor=request.actor, include_reasons=True
|
||||
)
|
||||
for table in page.resources:
|
||||
print(f"{table.child}: {table.reasons}")
|
||||
|
||||
.. _datasette_allowed_resources_with_reasons:
|
||||
The ``page.all()`` async generator automatically handles pagination, fetching additional pages and yielding all resources one at a time.
|
||||
|
||||
await .allowed_resources_with_reasons(action, actor=None)
|
||||
---------------------------------------------------------
|
||||
|
||||
Returns a list of :class:`datasette.permissions.AllowedResource` tuples. Each tuple contains a ``Resource`` plus a list of strings describing the rules that granted access. This powers the debugging data shown by the ``/-/allowed`` endpoint and is helpful when building administrative tooling that needs to show why access was granted.
|
||||
This method uses :ref:`datasette_allowed_resources_sql` under the hood and is an efficient way to list the databases, tables or other resources that an actor can access for a specific action.
|
||||
|
||||
.. _datasette_allowed_resources_sql:
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue