id,page,ref,title,content,breadcrumbs,references
internals:datasette-absolute-url,internals,datasette-absolute-url,".absolute_url(request, path)","request - Request
The current Request object
path - string
A path, for example /dbname/table.json
Returns the absolute URL for the given path, including the protocol and host. For example:
absolute_url = datasette.absolute_url(
request, ""/dbname/table.json""
)
# Would return ""http://localhost:8001/dbname/table.json""
The current request object is used to determine the hostname and protocol that should be used for the returned URL. The force_https_urls configuration setting is taken into account.","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-actions,internals,datasette-actions,.actions,"Property exposing a dictionary of actions that have been registered using the register_actions(datasette) plugin hook.
The dictionary keys are the action names - e.g. view-instance - and the values are Action() objects describing the permission.","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-actors-from-ids,internals,datasette-actors-from-ids,await .actors_from_ids(actor_ids),"actor_ids - list of strings or integers
A list of actor IDs to look up.
Returns a dictionary, where the keys are the IDs passed to it and the values are the corresponding actor dictionaries.
This method is mainly designed to be used with plugins. See the actors_from_ids(datasette, actor_ids) documentation for details.
If no plugins that implement that hook are installed, the default return value looks like this:
{
""1"": {""id"": ""1""},
""2"": {""id"": ""2""}
}","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-add-database,internals,datasette-add-database,".add_database(db, name=None, route=None)","db - datasette.database.Database instance
The database to be attached.
name - string, optional
The name to be used for this database . If not specified Datasette will pick one based on the filename or memory name.
route - string, optional
This will be used in the URL path. If not specified, it will default to the same thing as the name .
The datasette.add_database(db) method lets you add a new database to the current Datasette instance.
The db parameter should be an instance of the datasette.database.Database class. For example:
from datasette.database import Database
datasette.add_database(
Database(
datasette,
path=""path/to/my-new-database.db"",
)
)
This will add a mutable database and serve it at /my-new-database .
Use is_mutable=False to add an immutable database.
.add_database() returns the Database instance, with its name set as the database.name attribute. Any time you are working with a newly added database you should use the return value of .add_database() , for example:
db = datasette.add_database(
Database(datasette, memory_name=""statistics"")
)
await db.execute_write(
""CREATE TABLE foo(id integer primary key)""
)","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-add-memory-database,internals,datasette-add-memory-database,".add_memory_database(memory_name, name=None, route=None)","Adds a shared in-memory database with the specified name:
datasette.add_memory_database(""statistics"")
This is a shortcut for the following:
from datasette.database import Database
datasette.add_database(
Database(datasette, memory_name=""statistics"")
)
Using either of these patterns will result in the in-memory database being served at /statistics .
The name and route parameters are optional and work the same way as they do for .add_database(db, name=None, route=None) .","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-add-message,internals,datasette-add-message,".add_message(request, message, type=datasette.INFO)","request - Request
The current Request object
message - string
The message string
type - constant, optional
The message type - datasette.INFO , datasette.WARNING or datasette.ERROR
Datasette's flash messaging mechanism allows you to add a message that will be displayed to the user on the next page that they visit. Messages are persisted in a ds_messages cookie. This method adds a message to that cookie.
You can try out these messages (including the different visual styling of the three message types) using the /-/messages debugging tool.","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-allowed,internals,datasette-allowed,"await .allowed(*, action, resource, actor=None)","action - string
The name of the action that is being permission checked.
resource - Resource object
A Resource object representing the database, table, or other resource. Must be an instance of a Resource class such as TableResource , DatabaseResource , QueryResource , or InstanceResource .
actor - dictionary, optional
The authenticated actor. This is usually request.actor . Defaults to None for unauthenticated requests.
This method checks if the given actor has permission to perform the given action on the given resource. All parameters must be passed as keyword arguments.
Example usage:
from datasette.resources import (
TableResource,
DatabaseResource,
)
# Check if actor can view a specific table
can_view = await datasette.allowed(
action=""view-table"",
resource=TableResource(
database=""fixtures"", table=""facetable""
),
actor=request.actor,
)
# Check if actor can execute SQL on a database
can_execute = await datasette.allowed(
action=""execute-sql"",
resource=DatabaseResource(database=""fixtures""),
actor=request.actor,
)
The method returns True if the permission is granted, False if denied.","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-allowed-resources,internals,datasette-allowed-resources,"await .allowed_resources(action, actor=None, *, parent=None, include_is_private=False, include_reasons=False, limit=100, next=None)","Returns a PaginatedResources object containing resources that the actor can access for the specified action, with support for keyset pagination.
action - string
The action name (e.g., ""view-table"", ""view-database"")
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:
# Get first page of tables
page = await datasette.allowed_resources(
""view-table"",
actor=request.actor,
parent=""fixtures"",
limit=50,
)
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)
# 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}"")
The page.all() async generator automatically handles pagination, fetching additional pages and yielding all resources one at a time.
This method uses await .allowed_resources_sql(*, action, actor=None, parent=None, include_is_private=False) 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.","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-allowed-resources-sql,internals,datasette-allowed-resources-sql,"await .allowed_resources_sql(*, action, actor=None, parent=None, include_is_private=False)","Builds the SQL query that Datasette uses to determine which resources an actor may access for a specific action. Returns a (sql: str, params: dict) namedtuple that can be executed against the internal catalog_* database tables. parent can be used to limit results to a specific database, and include_is_private adds a column indicating whether anonymous users would be denied access to that resource.
Plugins that need to execute custom analysis over the raw allow/deny rules can use this helper to run the same query that powers the /-/allowed debugging interface.
The SQL query built by this method will return the following columns:
parent : The parent resource identifier (or NULL)
child : The child resource identifier (or NULL)
reason : The reason from the rule that granted access
is_private : (if include_is_private ) 1 if anonymous users cannot access, 0 otherwise","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-check-visibility,internals,datasette-check-visibility,"await .check_visibility(actor, action, resource=None)","actor - dictionary
The authenticated actor. This is usually request.actor .
action - string
The name of the action that is being permission checked.
resource - Resource object, optional
The resource being checked, as a Resource object such as DatabaseResource(database=...) , TableResource(database=..., table=...) , or QueryResource(database=..., query=...) . Only some permissions apply to a resource.
This convenience method can be used to answer the question ""should this item be considered private, in that it is visible to me but it is not visible to anonymous users?""
It returns a tuple of two booleans, (visible, private) . visible indicates if the actor can see this resource. private will be True if an anonymous user would not be able to view the resource.
This example checks if the user can access a specific table, and sets private so that a padlock icon can later be displayed:
from datasette.resources import TableResource
visible, private = await datasette.check_visibility(
request.actor,
action=""view-table"",
resource=TableResource(database=database, table=table),
)","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-column-types,internals,datasette-column-types,Column types,Column types are stored in the column_types table in the internal database . The following methods provide the API for reading and modifying column type assignments.,"[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-create-token,internals,datasette-create-token,"await .create_token(actor_id, expires_after=None, restrictions=None, handler=None)","actor_id - string
The ID of the actor to create a token for.
expires_after - int, optional
The number of seconds after which the token should expire.
restrictions - TokenRestrictions , optional
A TokenRestrictions object limiting which actions the token can perform.
handler - string, optional
The name of a specific token handler to use. If omitted, the first registered handler is used. See register_token_handler(datasette) .
This is an async method that returns an API token string which can be used to authenticate requests to the Datasette API. The default SignedTokenHandler returns tokens of the format dstok_... .
All tokens must have an actor_id string indicating the ID of the actor which the token will act on behalf of.
Tokens default to lasting forever, but can be set to expire after a given number of seconds using the expires_after argument. The following code creates a token for user1 that will expire after an hour:
token = await datasette.create_token(
actor_id=""user1"",
expires_after=3600,
)","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-databases,internals,datasette-databases,.databases,"Property exposing a collections.OrderedDict of databases currently connected to Datasette.
The dictionary keys are the name of the database that is used in the URL - e.g. /fixtures would have a key of ""fixtures"" . The values are Database class instances.
All databases are listed, irrespective of user permissions.","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-ensure-permission,internals,datasette-ensure-permission,"await .ensure_permission(action, resource=None, actor=None)","action - string
The action to check. See Built-in actions for a list of available actions.
resource - Resource object (optional)
The resource to check the permission against. Must be an instance of InstanceResource , DatabaseResource , or TableResource from the datasette.resources module. If omitted, defaults to InstanceResource() for instance-level permissions.
actor - dictionary (optional)
The authenticated actor. This is usually request.actor .
This is a convenience wrapper around await .allowed(*, action, resource, actor=None) that raises a datasette.Forbidden exception if the permission check fails. Use this when you want to enforce a permission check and halt execution if the actor is not authorized.
Example:
from datasette.resources import TableResource
# Will raise Forbidden if actor cannot view the table
await datasette.ensure_permission(
action=""view-table"",
resource=TableResource(
database=""fixtures"", table=""cities""
),
actor=request.actor,
)
# For instance-level actions, resource can be omitted:
await datasette.ensure_permission(
action=""permissions-debug"", actor=request.actor
)","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-get-database,internals,datasette-get-database,.get_database(name),"name - string, optional
The name of the database - optional.
Returns the specified database object. Raises a KeyError if the database does not exist. Call this method without an argument to return the first connected database.","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-get-set-metadata,internals,datasette-get-set-metadata,Getting and setting metadata,"Metadata about the instance, databases, tables and columns is stored in tables in Datasette's internal database . The following methods are the supported API for plugins to read and update that stored metadata.","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-plugin-config,internals,datasette-plugin-config,".plugin_config(plugin_name, database=None, table=None)","plugin_name - string
The name of the plugin to look up configuration for. Usually this is something similar to datasette-cluster-map .
database - None or string
The database the user is interacting with.
table - None or string
The table the user is interacting with.
This method lets you read plugin configuration values that were set in datasette.yaml . See Writing plugins that accept configuration for full details of how this method should be used.
The return value will be the value from the configuration file - usually a dictionary.
If the plugin is not configured the return value will be None .","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-remove-database,internals,datasette-remove-database,.remove_database(name),"name - string
The name of the database to be removed.
This removes a database that has been previously added. name= is the unique name of that database.","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-render-template,internals,datasette-render-template,"await .render_template(template, context=None, request=None)","template - string, list of strings or jinja2.Template
The template file to be rendered, e.g. my_plugin.html . Datasette will search for this file first in the --template-dir= location, if it was specified - then in the plugin's bundled templates and finally in Datasette's set of default templates.
If this is a list of template file names then the first one that exists will be loaded and rendered.
If this is a Jinja Template object it will be used directly.
context - None or a Python dictionary
The context variables to pass to the template.
request - request object or None
If you pass a Datasette request object here it will be made available to the template.
Renders a Jinja template using Datasette's preconfigured instance of Jinja and returns the resulting string. The template will have access to Datasette's default template functions and any functions that have been made available by other plugins.","[""Internals for plugins"", ""Datasette class""]","[{""href"": ""https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.Template"", ""label"": ""Template object""}, {""href"": ""https://jinja.palletsprojects.com/en/2.11.x/"", ""label"": ""Jinja template""}]"
internals:datasette-resolve-database,internals,datasette-resolve-database,.resolve_database(request),"request - Request object
A request object
If you are implementing your own custom views, you may need to resolve the database that the user is requesting based on a URL path. If the regular expression for your route declares a database named group, you can use this method to resolve the database object.
This returns a Database instance.
If the database cannot be found, it raises a datasette.utils.asgi.DatabaseNotFound exception - which is a subclass of datasette.utils.asgi.NotFound with a .database_name attribute set to the name of the database that was requested.","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-resolve-row,internals,datasette-resolve-row,.resolve_row(request),"request - Request object
A request object
This method assumes your route declares named groups for database , table and pks .
It returns a ResolvedRow named tuple instance with the following fields:
db - Database
The database object
table - string
The name of the table
sql - string
SQL snippet that can be used in a WHERE clause to select the row
params - dict
Parameters that should be passed to the SQL query
pks - list
List of primary key column names
pk_values - list
List of primary key values decoded from the URL
row - sqlite3.Row
The row itself
If the database or table cannot be found it raises a datasette.utils.asgi.DatabaseNotFound exception.
If the table does not exist it raises a datasette.utils.asgi.TableNotFound exception.
If the row cannot be found it raises a datasette.utils.asgi.RowNotFound exception. This has .database_name , .table and .pk_values attributes, extracted from the request path.","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-resolve-table,internals,datasette-resolve-table,.resolve_table(request),"request - Request object
A request object
This assumes that the regular expression for your route declares both a database and a table named group.
It returns a ResolvedTable named tuple instance with the following fields:
db - Database
The database object
table - string
The name of the table (or view)
is_view - boolean
True if this is a view, False if it is a table
If the database or table cannot be found it raises a datasette.utils.asgi.DatabaseNotFound exception.
If the table does not exist it raises a datasette.utils.asgi.TableNotFound exception - a subclass of datasette.utils.asgi.NotFound with .database_name and .table attributes.","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-setting,internals,datasette-setting,.setting(key),"key - string
The name of the setting, e.g. base_url .
Returns the configured value for the specified setting . This can be a string, boolean or integer depending on the requested setting.
For example:
downloads_are_allowed = datasette.setting(""allow_download"")","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-sign,internals,datasette-sign,".sign(value, namespace=""default"")","value - any serializable type
The value to be signed.
namespace - string, optional
An alternative namespace, see the itsdangerous salt documentation .
Utility method for signing values, such that you can safely pass data to and from an untrusted environment. This is a wrapper around the itsdangerous library.
This method returns a signed string, which can be decoded and verified using .unsign(value, namespace=""default"") .","[""Internals for plugins"", ""Datasette class""]","[{""href"": ""https://itsdangerous.palletsprojects.com/en/1.1.x/serializer/#the-salt"", ""label"": ""itsdangerous salt documentation""}, {""href"": ""https://itsdangerous.palletsprojects.com/"", ""label"": ""itsdangerous""}]"
internals:datasette-track-event,internals,datasette-track-event,await .track_event(event),"event - Event
An instance of a subclass of datasette.events.Event .
Plugins can call this to track events, using classes they have previously registered. See Event tracking for details.
The event will then be passed to all plugins that have registered to receive events using the track_event(datasette, event) hook.
Example usage, assuming the plugin has previously registered the BanUserEvent class:
await datasette.track_event(
BanUserEvent(user={""id"": 1, ""username"": ""cleverbot""})
)","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-unsign,internals,datasette-unsign,".unsign(value, namespace=""default"")","signed - any serializable type
The signed string that was created using .sign(value, namespace=""default"") .
namespace - string, optional
The alternative namespace, if one was used.
Returns the original, decoded object that was passed to .sign(value, namespace=""default"") . If the signature is not valid this raises a itsdangerous.BadSignature exception.","[""Internals for plugins"", ""Datasette class""]",[]
internals:datasette-verify-token,internals,datasette-verify-token,await .verify_token(token),"token - string
The token string to verify.
This is an async method that verifies an API token by trying each registered token handler in order. Returns an actor dictionary from the first handler that recognizes the token, or None if no handler accepts it.
actor = await datasette.verify_token(token)
if actor:
# Token was valid
print(actor[""id""])","[""Internals for plugins"", ""Datasette class""]",[]
internals:id2,internals,id2,.get_internal_database(),Returns a database object for reading and writing to the private internal database .,"[""Internals for plugins"", ""Datasette class""]",[]
internals:internals-datasette-client,internals,internals-datasette-client,datasette.client,"Plugins can make internal simulated HTTP requests to the Datasette instance within which they are running. This ensures that all of Datasette's external JSON APIs are also available to plugins, while avoiding the overhead of making an external HTTP call to access those APIs.
The datasette.client object is a wrapper around the HTTPX Python library , providing an async-friendly API that is similar to the widely used Requests library .
It offers the following methods:
await datasette.client.get(path, **kwargs) - returns HTTPX Response
Execute an internal GET request against that path.
await datasette.client.post(path, **kwargs) - returns HTTPX Response
Execute an internal POST request. Use data={""name"": ""value""} to pass form parameters.
await datasette.client.options(path, **kwargs) - returns HTTPX Response
Execute an internal OPTIONS request.
await datasette.client.head(path, **kwargs) - returns HTTPX Response
Execute an internal HEAD request.
await datasette.client.put(path, **kwargs) - returns HTTPX Response
Execute an internal PUT request.
await datasette.client.patch(path, **kwargs) - returns HTTPX Response
Execute an internal PATCH request.
await datasette.client.delete(path, **kwargs) - returns HTTPX Response
Execute an internal DELETE request.
await datasette.client.request(method, path, **kwargs) - returns HTTPX Response
Execute an internal request with the given HTTP method against that path.
These methods can be used with datasette.urls - for example:
table_json = (
await datasette.client.get(
datasette.urls.table(
""fixtures"", ""facetable"", format=""json""
)
)
).json()
datasette.client methods automatically take the current base_url setting into account, whether or not you use the datasette.urls family of methods to construct the path.
For documentation on available **kwargs options and the shape of the HTTPX Response object refer to the HTTPX Async documentation .","[""Internals for plugins"", ""Datasette class""]","[{""href"": ""https://www.python-httpx.org/"", ""label"": ""HTTPX Python library""}, {""href"": ""https://requests.readthedocs.io/"", ""label"": ""Requests library""}, {""href"": ""https://www.python-httpx.org/async/"", ""label"": ""HTTPX Async documentation""}]"
internals:internals-datasette-urls,internals,internals-datasette-urls,datasette.urls,"The datasette.urls object contains methods for building URLs to pages within Datasette. Plugins should use this to link to pages, since these methods take into account any base_url configuration setting that might be in effect.
datasette.urls.instance(format=None)
Returns the URL to the Datasette instance root page. This is usually ""/"" .
datasette.urls.path(path, format=None)
Takes a path and returns the full path, taking base_url into account.
For example, datasette.urls.path(""-/logout"") will return the path to the logout page, which will be ""/-/logout"" by default or /prefix-path/-/logout if base_url is set to /prefix-path/
datasette.urls.logout()
Returns the URL to the logout page, usually ""/-/logout""
datasette.urls.static(path)
Returns the URL of one of Datasette's default static assets, for example ""/-/static/app.css""
datasette.urls.static_plugins(plugin_name, path)
Returns the URL of one of the static assets belonging to a plugin.
datasette.urls.static_plugins(""datasette_cluster_map"", ""datasette-cluster-map.js"") would return ""/-/static-plugins/datasette_cluster_map/datasette-cluster-map.js""
datasette.urls.static(path)
Returns the URL of one of Datasette's default static assets, for example ""/-/static/app.css""
datasette.urls.database(database_name, format=None)
Returns the URL to a database page, for example ""/fixtures""
datasette.urls.table(database_name, table_name, format=None)
Returns the URL to a table page, for example ""/fixtures/facetable""
datasette.urls.query(database_name, query_name, format=None)
Returns the URL to a query page, for example ""/fixtures/pragma_cache_size""
These functions can be accessed via the {{ urls }} object in Datasette templates, for example:
Homepage
Fixtures database
facetable table
pragma_cache_size query
Use the format=""json"" (or ""csv"" or other formats supported by plugins) arguments to get back URLs to the JSON representation. This is the path with .json added on the end.
These methods each return a datasette.utils.PrefixedUrlString object, which is a subclass of the Python str type. This allows the logic that considers the base_url setting to detect if that prefix has already been applied to the path.","[""Internals for plugins"", ""Datasette class""]",[]