2020-10-29 12:35:25 -07:00
.. _introspection:
2018-05-20 14:28:53 -07:00
Introspection
=============
2018-05-20 14:30:48 -07:00
Datasette includes some pages and JSON API endpoints for introspecting the current instance. These can be used to understand some of the internals of Datasette and to see how a particular instance has been configured.
2018-05-20 14:28:53 -07:00
Each of these pages can be viewed in your browser. Add `` .json `` to the URL to get back the contents as JSON.
2018-07-27 20:26:18 -07:00
.. _JsonDataView_metadata:
2018-05-20 14:28:53 -07:00
/-/metadata
-----------
2020-05-30 18:51:00 -07:00
Shows the contents of the `` metadata.json `` file that was passed to `` datasette serve `` , if any. `Metadata example <https://fivethirtyeight.datasettes.com/-/metadata> `_ :
.. code-block :: json
2018-05-20 14:28:53 -07:00
{
"license": "CC Attribution 4.0 License",
"license_url": "http://creativecommons.org/licenses/by/4.0/",
"source": "fivethirtyeight/data on GitHub",
"source_url": "https://github.com/fivethirtyeight/data",
"title": "Five Thirty Eight",
2020-05-30 18:51:00 -07:00
"databases": {
}
2018-05-20 14:28:53 -07:00
}
2018-07-27 20:26:18 -07:00
.. _JsonDataView_versions:
2018-05-20 14:28:53 -07:00
/-/versions
-----------
2020-05-30 18:51:00 -07:00
Shows the version of Datasette, Python and SQLite. `Versions example <https://latest.datasette.io/-/versions> `_ :
.. code-block :: json
2018-05-20 14:28:53 -07:00
{
"datasette": {
2022-01-19 20:31:22 -08:00
"version": "0.60"
2018-05-20 14:28:53 -07:00
},
"python": {
2022-01-19 20:31:22 -08:00
"full": "3.8.12 (default, Dec 21 2021, 10:45:09) \n[GCC 10.2.1 20210110]",
"version": "3.8.12"
2018-05-20 14:28:53 -07:00
},
"sqlite": {
"extensions": {
"json1": null
},
"fts_versions": [
2019-01-10 16:44:37 -08:00
"FTS5",
2018-05-20 14:28:53 -07:00
"FTS4",
"FTS3"
],
2019-01-10 16:44:37 -08:00
"compile_options": [
"COMPILER=gcc-6.3.0 20170516",
"ENABLE_FTS3",
"ENABLE_FTS4",
"ENABLE_FTS5",
"ENABLE_JSON1",
"ENABLE_RTREE",
"THREADSAFE=1"
],
2022-01-19 20:31:22 -08:00
"version": "3.37.0"
2018-05-20 14:28:53 -07:00
}
}
2018-07-27 20:26:18 -07:00
.. _JsonDataView_plugins:
2018-05-20 14:28:53 -07:00
/-/plugins
----------
2020-05-30 18:51:00 -07:00
Shows a list of currently installed plugins and their versions. `Plugins example <https://san-francisco.datasettes.com/-/plugins> `_ :
.. code-block :: json
2018-05-20 14:28:53 -07:00
[
{
"name": "datasette_cluster_map",
"static": true,
"templates": false,
2020-06-02 14:49:28 -07:00
"version": "0.10",
"hooks": ["extra_css_urls", "extra_js_urls", "extra_body_script"]
2018-05-20 14:28:53 -07:00
}
]
2020-06-02 14:49:28 -07:00
Add `` ?all=1 `` to include details of the default plugins baked into Datasette.
2024-02-06 12:33:46 -08:00
.. _JsonDataView_settings:
2018-07-27 20:26:18 -07:00
2020-11-24 12:19:14 -08:00
/-/settings
-----------
2018-05-20 14:28:53 -07:00
2020-11-24 13:22:33 -08:00
Shows the :ref: `settings` for this instance of Datasette. `Settings example <https://fivethirtyeight.datasettes.com/-/settings> `_ :
2020-05-30 18:51:00 -07:00
.. code-block :: json
2018-05-20 14:28:53 -07:00
{
"default_facet_size": 30,
"default_page_size": 100,
"facet_suggest_time_limit_ms": 50,
"facet_time_limit_ms": 1000,
"max_returned_rows": 1000,
"sql_time_limit_ms": 1000
}
2019-05-16 07:49:34 -07:00
2024-02-06 12:33:46 -08:00
.. _JsonDataView_config:
/-/config
---------
2024-02-06 15:22:03 -08:00
Shows the :ref: `configuration <configuration>` for this instance of Datasette. This is generally the contents of the :ref: `datasette.yaml or datasette.json <configuration_reference>` file, which can include plugin configuration as well. `Config example <https://latest.datasette.io/-/config> `_ :
.. code-block :: json
{
"settings": {
"template_debug": true,
"trace_debug": true,
"force_https_urls": true
}
}
2024-02-06 12:33:46 -08:00
Any keys that include the one of the following substrings in their names will be returned as redacted `` *** `` output, to help avoid accidentally leaking private configuration information: `` secret `` , `` key `` , `` password `` , `` token `` , `` hash `` , `` dsn `` .
2019-10-02 08:32:47 -07:00
.. _JsonDataView_databases:
2019-05-16 07:49:34 -07:00
/-/databases
------------
2020-11-24 12:19:14 -08:00
Shows currently attached databases. `Databases example <https://latest.datasette.io/-/databases> `_ :
2020-05-30 18:51:00 -07:00
.. code-block :: json
2019-05-16 07:49:34 -07:00
[
{
"hash": null,
"is_memory": false,
"is_mutable": true,
"name": "fixtures",
"path": "fixtures.db",
"size": 225280
}
]
2019-10-02 08:32:47 -07:00
Implement resource-based permission system with SQL-driven access control
This introduces a new hierarchical permission system that uses SQL queries
for efficient permission checking across resources. The system replaces the
older permission_allowed() pattern with a more flexible resource-based
approach.
Core changes:
- New Resource ABC and Action dataclass in datasette/permissions.py
* Resources represent hierarchical entities (instance, database, table)
* Each resource type implements resources_sql() to list all instances
* Actions define operations on resources with cascading rules
- New plugin hook: register_actions(datasette)
* Plugins register actions with their associated resource types
* Replaces register_permissions() and register_resource_types()
* See docs/plugin_hooks.rst for full documentation
- Three new Datasette methods for permission checks:
* allowed_resources(action, actor) - returns list[Resource]
* allowed_resources_with_reasons(action, actor) - for debugging
* allowed(action, resource, actor) - checks single resource
* All use SQL for filtering, never Python iteration
- New /-/tables endpoint (TablesView)
* Returns JSON list of tables user can view
* Supports ?q= parameter for regex filtering
* Format: {"matches": [{"name": "db/table", "url": "/db/table"}]}
* Respects all permission rules from configuration and plugins
- SQL-based permission evaluation (datasette/utils/actions_sql.py)
* Cascading rules: child-level → parent-level → global-level
* DENY beats ALLOW at same specificity
* Uses CTEs for efficient SQL-only filtering
* Combines permission_resources_sql() hook results
- Default actions in datasette/default_actions.py
* InstanceResource, DatabaseResource, TableResource, QueryResource
* Core actions: view-instance, view-database, view-table, etc.
- Fixed default_permissions.py to handle database-level allow blocks
* Now creates parent-level rules for view-table action
* Fixes: datasette ... -s databases.fixtures.allow.id root
Documentation:
- Comprehensive register_actions() hook documentation
- Detailed resources_sql() method explanation
- /-/tables endpoint documentation in docs/introspection.rst
- Deprecated register_permissions() with migration guide
Tests:
- tests/test_actions_sql.py: 7 tests for core permission API
- tests/test_tables_endpoint.py: 13 tests for /-/tables endpoint
- All 118 documentation tests pass
- Tests verify SQL does filtering (not Python)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 15:59:37 -07:00
.. _TablesView:
/-/tables
---------
Returns a JSON list of all tables that the current actor has permission to view. This endpoint uses the resource-based permission system and respects database and table-level access controls.
The endpoint supports a `` ?q= `` query parameter for filtering tables by name using case-insensitive regex matching.
`Tables example <https://latest.datasette.io/-/tables> `_ :
.. code-block :: json
{
"matches": [
{
"name": "fixtures/facetable",
"url": "/fixtures/facetable"
},
{
"name": "fixtures/searchable",
"url": "/fixtures/searchable"
}
]
}
Search example with `` ?q=facet `` returns only tables matching `` .*facet.* `` :
.. code-block :: json
{
"matches": [
{
"name": "fixtures/facetable",
"url": "/fixtures/facetable"
}
]
}
When multiple search terms are provided (e.g., `` ?q=user+profile `` ), tables must match the pattern `` .*user.*profile.* `` . Results are ordered by shortest table name first.
2019-10-02 08:32:47 -07:00
.. _JsonDataView_threads:
/-/threads
----------
2020-05-30 18:51:00 -07:00
Shows details of threads and `` asyncio `` tasks. `Threads example <https://latest.datasette.io/-/threads> `_ :
.. code-block :: json
2019-10-02 08:32:47 -07:00
{
"num_threads": 2,
"threads": [
{
"daemon": false,
"ident": 4759197120,
"name": "MainThread"
},
{
"daemon": true,
"ident": 123145319682048,
"name": "Thread-1"
},
2019-12-04 22:46:39 -08:00
],
"num_tasks": 3,
"tasks": [
"<Task pending coro=<RequestResponseCycle.run_asgi() running at uvicorn/protocols/http/httptools_impl.py:385> cb=[set.discard()]>",
"<Task pending coro=<Server.serve() running at uvicorn/main.py:361> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x10365c3d0> ()]> cb=[run_until_complete.<locals>.<lambda>()]>",
"<Task pending coro=<LifespanOn.main() running at uvicorn/lifespan/on.py:48> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x10364f050> ()]>>"
2019-10-02 08:32:47 -07:00
]
}
2020-05-30 18:51:00 -07:00
.. _JsonDataView_actor:
/-/actor
--------
Shows the currently authenticated actor. Useful for debugging Datasette authentication plugins.
.. code-block :: json
{
"actor": {
"id": 1,
"username": "some-user"
}
}
2020-06-02 14:08:12 -07:00
.. _MessagesDebugView:
/-/messages
-----------
The debug tool at `` /-/messages `` can be used to set flash messages to try out that feature. See :ref: `datasette_add_message` for details of this feature.