home / docs / sections

sections

613 rows sorted by references

✎ View and edit SQL

This data as json, CSV (advanced)

Suggested facets: page, ref, title, content, breadcrumbs, references

breadcrumbs (array) 88 ✖

  • Changelog 198
  • Internals for plugins 65
  • Plugin hooks 44
  • Authentication and permissions 37
  • Datasette class 35
  • Settings 28
  • JSON API 18
  • Contributing 16
  • Built-in permissions 14
  • CLI reference 14
  • Installation 14
  • Database class 12
  • Metadata 12
  • Running SQL queries 12
  • Custom pages and templates 11
  • 0.44 (2020-06-11) 10
  • Writing plugins 10
  • Full-text search 9
  • Introspection 9
  • SpatiaLite 9
  • Upgrade guide 9
  • 0.29 (2019-07-07) 8
  • Datasette 0.X -> 1.0 8
  • Getting and setting metadata 8
  • 0.23 (2018-06-18) 7
  • Canned queries 7
  • Configuration 7
  • Deploying Datasette 7
  • Plugins 7
  • Publishing data 7
  • The JSON write API 7
  • 0.28 (2019-05-19) 6
  • 0.51 (2020-10-31) 6
  • Action hooks 6
  • Advanced installation options 6
  • Facets 6
  • JavaScript plugins 6
  • Metadata changes 6
  • Pages and API endpoints 6
  • Template slots 6
  • Testing plugins 6
  • None 5
  • 0.45 (2020-07-01) 5
  • 0.54 (2021-01-25) 5
  • 1.0a8 (2024-02-07) 5
  • Access permissions in 5
  • Getting started 5
  • datasette publish 5
  • 0.62 (2022-08-14) 4
  • 1.0a9 (2024-02-16) 4
  • Page extras 4
  • Performance and caching 4
  • The datasette.utils module 4
  • 0.60 (2022-01-13) 3
  • 0.63 (2022-10-27) 3
  • Basic installation 3
  • Code formatting 3
  • Enabling full-text search for a SQLite table 3
  • Metadata reference 3
  • Permissions 3
  • datasette serve 3
  • 0.57 (2021-06-05) 2
  • 1.0a0 (2022-11-29) 2
  • API Tokens 2
  • Additional canned query options 2
  • Binary data 2
  • CSV export 2
  • Event tracking 2
  • Installing plugins 2
  • JavaScript plugin objects 2
  • Publishing static assets 2
  • Response class 2
  • Running Datasette behind a proxy 2
  • Table arguments 2
  • The Datasette Ecosystem 2
  • The ds_actor cookie 2
  • Using Docker 2
  • Using pipx 2
  • 1.0a3 (2023-08-09) 1
  • Actors 1
  • Custom redirects 1
  • Database 1
  • Datasette 1
  • Datasette's internal database 1
  • Editing and building the documentation 1
  • Plugin configuration 1
  • datasette create-token 1
  • datasette.tracer 1
id page ref title content breadcrumbs references ▼
sql_queries:sql sql_queries sql Running SQL queries Datasette treats SQLite database files as read-only and immutable. This means it is not possible to execute INSERT or UPDATE statements using Datasette, which allows us to expose SELECT statements to the outside world without needing to worry about SQL injection attacks. The easiest way to execute custom SQL against Datasette is through the web UI. The database index page includes a SQL editor that lets you run any SELECT query you like. You can also construct queries using the filter interface on the tables page, then click "View and edit SQL" to open that query in the custom SQL editor. Note that this interface is only available if the execute-sql permission is allowed. See Controlling the ability to execute arbitrary SQL . Any Datasette SQL query is reflected in the URL of the page, allowing you to bookmark them, share them with others and navigate through previous queries using your browser back button. You can also retrieve the results of any query as JSON by adding .json to the base URL. [] []
sql_queries:id1 sql_queries id1 Canned queries As an alternative to adding views to your database, you can define canned queries inside your datasette.yaml file. Here's an example: [[[cog from metadata_doc import config_example, config_example config_example(cog, { "databases": { "sf-trees": { "queries": { "just_species": { "sql": "select qSpecies from Street_Tree_List" } } } } }) ]]] [[[end]]] Then run Datasette like this: datasette sf-trees.db -m metadata.json Each canned query will be listed on the database index page, and will also get its own URL at: /database-name/canned-query-name For the above example, that URL would be: /sf-trees/just_species You can optionally include "title" and "description" keys to show a title and description on the canned query page. As with regular table metadata you can alternatively specify "description_html" to have your description rendered as HTML (rather than having HTML special characters escaped). ["Running SQL queries"] []
sql_queries:canned-queries-options sql_queries canned-queries-options Additional canned query options Additional options can be specified for canned queries in the YAML or JSON configuration. ["Running SQL queries", "Canned queries"] []
sql_queries:hide-sql sql_queries hide-sql hide_sql Canned queries default to displaying their SQL query at the top of the page. If the query is extremely long you may want to hide it by default, with a "show" link that can be used to make it visible. Add the "hide_sql": true option to hide the SQL query by default. ["Running SQL queries", "Canned queries", "Additional canned query options"] []
sql_queries:canned-queries-writable sql_queries canned-queries-writable Writable canned queries Canned queries by default are read-only. You can use the "write": true key to indicate that a canned query can write to the database. See Access to specific canned queries for details on how to add permission checks to canned queries, using the "allow" key. [[[cog config_example(cog, { "databases": { "mydatabase": { "queries": { "add_name": { "sql": "INSERT INTO names (name) VALUES (:name)", "write": True } } } } }) ]]] [[[end]]] This configuration will create a page at /mydatabase/add_name displaying a form with a name field. Submitting that form will execute the configured INSERT query. You can customize how Datasette represents success and errors using the following optional properties: on_success_message - the message shown when a query is successful on_success_message_sql - alternative to on_success_message : a SQL query that should be executed to generate the message on_success_redirect - the path or URL the user is redirected to on success on_error_message - the message shown when a query throws an error on_error_redirect - the path or URL the user is redirected to on error For example: [[[cog config_example(cog, { "databases": { "mydatabase": { "queries": { "add_name": { "sql": "INSERT INTO names (name) VALUES (:name)", "params": ["name"], "write": Tru… ["Running SQL queries", "Canned queries"] []
sql_queries:canned-queries-magic-parameters sql_queries canned-queries-magic-parameters Magic parameters Named parameters that start with an underscore are special: they can be used to automatically add values created by Datasette that are not contained in the incoming form fields or query string. These magic parameters are only supported for canned queries: to avoid security issues (such as queries that extract the user's private cookies) they are not available to SQL that is executed by the user as a custom SQL query. Available magic parameters are: _actor_* - e.g. _actor_id , _actor_name Fields from the currently authenticated Actors . _header_* - e.g. _header_user_agent Header from the incoming HTTP request. The key should be in lower case and with hyphens converted to underscores e.g. _header_user_agent or _header_accept_language . _cookie_* - e.g. _cookie_lang The value of the incoming cookie of that name. _now_epoch The number of seconds since the Unix epoch. _now_date_utc The date in UTC, e.g. 2020-06-01 _now_datetime_utc The ISO 8601 datetime in UTC, e.g. 2020-06-24T18:01:07Z _random_chars_* - e.g. … ["Running SQL queries", "Canned queries"] []
sql_queries:canned-queries-json-api sql_queries canned-queries-json-api JSON API for writable canned queries Writable canned queries can also be accessed using a JSON API. You can POST data to them using JSON, and you can request that their response is returned to you as JSON. To submit JSON to a writable canned query, encode key/value parameters as a JSON document: POST /mydatabase/add_message {"message": "Message goes here"} You can also continue to submit data using regular form encoding, like so: POST /mydatabase/add_message message=Message+goes+here There are three options for specifying that you would like the response to your request to return JSON data, as opposed to an HTTP redirect to another page. Set an Accept: application/json header on your request Include ?_json=1 in the URL that you POST to Include "_json": 1 in your JSON body, or &_json=1 in your form encoded body The JSON response will look like this: { "ok": true, "message": "Query executed, 1 row affected", "redirect": "/data/add_name" } The "message" and "redirect" values here will take into account on_success_message , on_success_message_sql , on_success_redirect , on_error_message and on_error_redirect , if they have been set. ["Running SQL queries", "Canned queries"] []
sql_queries:id2 sql_queries id2 Pagination Datasette's default table pagination is designed to be extremely efficient. SQL OFFSET/LIMIT pagination can have a significant performance penalty once you get into multiple thousands of rows, as each page still requires the database to scan through every preceding row to find the correct offset. When paginating through tables, Datasette instead orders the rows in the table by their primary key and performs a WHERE clause against the last seen primary key for the previous page. For example: select rowid, * from Tree_List where rowid > 200 order by rowid limit 101 This represents page three for this particular table, with a page size of 100. Note that we request 101 items in the limit clause rather than 100. This allows us to detect if we are on the last page of the results: if the query returns less than 101 rows we know we have reached the end of the pagination set. Datasette will only return the first 100 rows - the 101st is used purely to detect if there should be another page. Since the where clause acts against the index on the primary key, the query is extremely fast even for records that are a long way into the overall pagination set. ["Running SQL queries"] []
changelog:id1 changelog id1 Changelog   [] []
changelog:v1-0-a9 changelog v1-0-a9 1.0a9 (2024-02-16) This alpha release adds basic alter table support to the Datasette Write API and fixes a permissions bug relating to the /upsert API endpoint. ["Changelog"] []
changelog:id25 changelog id25 0.60 (2022-01-13)   ["Changelog"] []
changelog:id48 changelog id48 0.51.1 (2020-10-31) Improvements to the new Binary data documentation page. ["Changelog"] []
changelog:id49 changelog id49 0.51 (2020-10-31) A new visual design, plugin hooks for adding navigation options, better handling of binary data, URL building utility methods and better support for running Datasette behind a proxy. ["Changelog"] []
changelog:signed-values-and-secrets changelog signed-values-and-secrets Signed values and secrets Both flash messages and user authentication needed a way to sign values and set signed cookies. Two new methods are now available for plugins to take advantage of this mechanism: .sign(value, namespace="default") and .unsign(value, namespace="default") . Datasette will generate a secret automatically when it starts up, but to avoid resetting the secret (and hence invalidating any cookies) every time the server restarts you should set your own secret. You can pass a secret to Datasette using the new --secret option or with a DATASETTE_SECRET environment variable. See Configuring the secret for more details. You can also set a secret when you deploy Datasette using datasette publish or datasette package - see Using secrets with datasette publish . Plugins can now sign values and verify their signatures using the datasette.sign() and datasette.unsign() methods. ["Changelog", "0.44 (2020-06-11)"] []
changelog:cookie-methods changelog cookie-methods Cookie methods Plugins can now use the new response.set_cookie() method to set cookies. A new request.cookies method on the :ref:internals_request` can be used to read incoming cookies. ["Changelog", "0.44 (2020-06-11)"] []
changelog:id88 changelog id88 0.29 (2019-07-07) ASGI, new plugin hooks, facet by date and much, much more... ["Changelog"] []
changelog:v0-29-medium-changes changelog v0-29-medium-changes Easier custom templates for table rows If you want to customize the display of individual table rows, you can do so using a _table.html template include that looks something like this: {% for row in display_rows %} <div> <h2>{{ row["title"] }}</h2> <p>{{ row["description"] }}<lp> <p>Category: {{ row.display("category_id") }}</p> </div> {% endfor %} This is a backwards incompatible change . If you previously had a custom template called _rows_and_columns.html you need to rename it to _table.html . See Custom templates for full details. ["Changelog", "0.29 (2019-07-07)"] []
changelog:id91 changelog id91 0.27.1 (2019-05-09) Tiny bugfix release: don't install tests/ in the wrong place. Thanks, Veit Heller. ["Changelog"] []
changelog:id95 changelog id95 0.25.2 (2018-12-16) datasette publish heroku now uses the python-3.6.7 runtime Added documentation on how to build the documentation Added documentation covering our release process Upgraded to pytest 4.0.2 ["Changelog"] []
changelog:foreign-key-expansions changelog foreign-key-expansions Foreign key expansions When Datasette detects a foreign key reference it attempts to resolve a label for that reference (automatically or using the Specifying the label column for a table metadata option) so it can display a link to the associated row. This expansion is now also available for JSON and CSV representations of the table, using the new _labels=on query string option. See Expanding foreign key references for more details. ["Changelog", "0.23 (2018-06-18)"] []
changelog:id158 changelog id158 0.17 (2018-04-13) Release 0.17 to fix issues with PyPI ["Changelog"] []
changelog:id212 changelog id212 0.11 (2017-11-14) Added datasette publish now --force option. This calls now with --force - useful as it means you get a fresh copy of datasette even if Now has already cached that docker layer. Enable --cors by default when running in a container. ["Changelog"] []
changelog:id215 changelog id215 0.9 (2017-11-13) Added --sql_time_limit_ms and --extra-options . The serve command now accepts --sql_time_limit_ms for customizing the SQL time limit. The publish and package commands now accept --extra-options which can be used to specify additional options to be passed to the datasite serve command when it executes inside the resulting Docker containers. ["Changelog"] []
cli-reference:id1 cli-reference id1 CLI reference The datasette CLI tool provides a number of commands. Running datasette without specifying a command runs the default command, datasette serve . See datasette serve for the full list of options for that command. [[[cog from datasette import cli from click.testing import CliRunner import textwrap def help(args): title = "datasette " + " ".join(args) cog.out("\n::\n\n") result = CliRunner().invoke(cli.cli, args) output = result.output.replace("Usage: cli ", "Usage: datasette ") cog.out(textwrap.indent(output, ' ')) cog.out("\n\n") ]]] [[[end]]] [] []
cli-reference:cli-help-help cli-reference cli-help-help datasette --help Running datasette --help shows a list of all of the available commands. [[[cog help(["--help"]) ]]] Usage: datasette [OPTIONS] COMMAND [ARGS]... Datasette is an open source multi-tool for exploring and publishing data About Datasette: https://datasette.io/ Full documentation: https://docs.datasette.io/ Options: --version Show the version and exit. --help Show this message and exit. Commands: serve* Serve up specified SQLite database files with a web UI create-token Create a signed API token for the specified actor ID inspect Generate JSON summary of provided database files install Install plugins and packages from PyPI into the same... package Package SQLite files into a Datasette Docker container plugins List currently installed plugins publish Publish specified SQLite database files to the internet... uninstall Uninstall plugins and Python packages from the Datasette... [[[end]]] Additional commands added by plugins that use the register_commands(cli) hook will be listed here as well. ["CLI reference"] []
cli-reference:cli-help-serve-help cli-reference cli-help-serve-help datasette serve This command starts the Datasette web application running on your machine: datasette serve mydatabase.db Or since this is the default command you can run this instead: datasette mydatabase.db Once started you can access it at http://localhost:8001 [[[cog help(["serve", "--help"]) ]]] Usage: datasette serve [OPTIONS] [FILES]... Serve up specified SQLite database files with a web UI Options: -i, --immutable PATH Database files to open in immutable mode -h, --host TEXT Host for server. Defaults to 127.0.0.1 which means only connections from the local machine will be allowed. Use 0.0.0.0 to listen to all IPs and allow access from other machines. -p, --port INTEGER RANGE Port for server, defaults to 8001. Use -p 0 to automatically assign an available port. [0<=x<=65535] --uds TEXT Bind to a Unix domain socket --reload Automatically reload if code or metadata change detected - useful for development --cors Enable CORS by serving Access-Control-Allow- Origin: * --load-extension PATH:ENTRYPOINT? Path to a SQLite extension to load, and optional entrypoint --inspect-file TEXT Path to JSON file created using "datasette inspect" -m, --metadata FILENAME Path to JSON/YAML file containing license/source metadata --template-dir DIRECTORY Path to directory containing custom templates --plugins-dir DIRECTORY Path to directory containing custom plugins --static MOUNT:DIRECTORY Serve static files fr… ["CLI reference"] []
cli-reference:cli-datasette-serve-env cli-reference cli-datasette-serve-env Environment variables Some of the datasette serve options can be provided by environment variables: DATASETTE_SECRET : Equivalent to the --secret option. DATASETTE_SSL_KEYFILE : Equivalent to the --ssl-keyfile option. DATASETTE_SSL_CERTFILE : Equivalent to the --ssl-certfile option. DATASETTE_LOAD_EXTENSION : Equivalent to the --load-extension option. ["CLI reference", "datasette serve"] []
cli-reference:cli-datasette-get cli-reference cli-datasette-get datasette --get The --get option to datasette serve (or just datasette ) specifies the path to a page within Datasette and causes Datasette to output the content from that path without starting the web server. This means that all of Datasette's functionality can be accessed directly from the command-line. For example: datasette --get '/-/versions.json' | jq . { "python": { "version": "3.8.5", "full": "3.8.5 (default, Jul 21 2020, 10:48:26) \n[Clang 11.0.3 (clang-1103.0.32.62)]" }, "datasette": { "version": "0.46+15.g222a84a.dirty" }, "asgi": "3.0", "uvicorn": "0.11.8", "sqlite": { "version": "3.32.3", "fts_versions": [ "FTS5", "FTS4", "FTS3" ], "extensions": { "json1": null }, "compile_options": [ "COMPILER=clang-11.0.3", "ENABLE_COLUMN_METADATA", "ENABLE_FTS3", "ENABLE_FTS3_PARENTHESIS", "ENABLE_FTS4", "ENABLE_FTS5", "ENABLE_GEOPOLY", "ENABLE_JSON1", "ENABLE_PREUPDATE_HOOK", "ENABLE_RTREE", "ENABLE_SESSION", "MAX_VARIABLE_NUMBER=250000", "THREADSAFE=1" ] } } You can use the --token TOKEN option to send an API token with the simulated request. Or you can make a request as a specific actor by passing a JSON representation of that actor to --actor : datasette --memory --actor '{"id": "root"}' --get '/-/actor.json' The exit code of datasette --get will be 0 if the request succeeds and 1 if the request produced an HTTP status code other than 200 - e.g. a 404 or 500 error. This lets you use datasette --get / to run tests against a Datasette application in a continuous integration environment such as GitHub Actions. ["CLI reference", "datasette serve"] []
cli-reference:cli-help-serve-help-settings cli-reference cli-help-serve-help-settings datasette serve --help-settings This command outputs all of the available Datasette settings . These can be passed to datasette serve using datasette serve --setting name value . [[[cog help(["--help-settings"]) ]]] Settings: default_page_size Default page size for the table view (default=100) max_returned_rows Maximum rows that can be returned from a table or custom query (default=1000) max_insert_rows Maximum rows that can be inserted at a time using the bulk insert API (default=100) num_sql_threads Number of threads in the thread pool for executing SQLite queries (default=3) sql_time_limit_ms Time limit for a SQL query in milliseconds (default=1000) default_facet_size Number of values to return for requested facets (default=30) facet_time_limit_ms Time limit for calculating a requested facet (default=200) facet_suggest_time_limit_ms Time limit for calculating a suggested facet (default=50) allow_facet Allow users to specify columns to facet using ?_facet= parameter (default=True) allow_download Allow users to download the original SQLite database files (default=True) allow_signed_tokens Allow users to create and use signed API tokens (default=True) default_allow_sql Allow anyone to run arbitrary SQL queries (default=True) max_signed_tokens_ttl Maximum allowed expiry time for signed API tokens (default=0) suggest_facets Calculate and display suggested facets (default… ["CLI reference", "datasette serve"] []
cli-reference:cli-help-plugins-help cli-reference cli-help-plugins-help datasette plugins Output JSON showing all currently installed plugins, their versions, whether they include static files or templates and which Plugin hooks they use. [[[cog help(["plugins", "--help"]) ]]] Usage: datasette plugins [OPTIONS] List currently installed plugins Options: --all Include built-in default plugins --requirements Output requirements.txt of installed plugins --plugins-dir DIRECTORY Path to directory containing custom plugins --help Show this message and exit. [[[end]]] Example output: [ { "name": "datasette-geojson", "static": false, "templates": false, "version": "0.3.1", "hooks": [ "register_output_renderer" ] }, { "name": "datasette-geojson-map", "static": true, "templates": false, "version": "0.4.0", "hooks": [ "extra_body_script", "extra_css_urls", "extra_js_urls" ] }, { "name": "datasette-leaflet", "static": true, "templates": false, "version": "0.2.2", "hooks": [ "extra_body_script", "extra_template_vars" ] } ] ["CLI reference"] []
cli-reference:cli-help-uninstall-help cli-reference cli-help-uninstall-help datasette uninstall Uninstall one or more plugins. [[[cog help(["uninstall", "--help"]) ]]] Usage: datasette uninstall [OPTIONS] PACKAGES... Uninstall plugins and Python packages from the Datasette environment Options: -y, --yes Don't ask for confirmation --help Show this message and exit. [[[end]]] ["CLI reference"] []
cli-reference:cli-help-publish-help cli-reference cli-help-publish-help datasette publish Shows a list of available deployment targets for publishing data with Datasette. Additional deployment targets can be added by plugins that use the publish_subcommand(publish) hook. [[[cog help(["publish", "--help"]) ]]] Usage: datasette publish [OPTIONS] COMMAND [ARGS]... Publish specified SQLite database files to the internet along with a Datasette-powered interface and API Options: --help Show this message and exit. Commands: cloudrun Publish databases to Datasette running on Cloud Run heroku Publish databases to Datasette running on Heroku [[[end]]] ["CLI reference"] []
cli-reference:cli-help-publish-cloudrun-help cli-reference cli-help-publish-cloudrun-help datasette publish cloudrun See Publishing to Google Cloud Run . [[[cog help(["publish", "cloudrun", "--help"]) ]]] Usage: datasette publish cloudrun [OPTIONS] [FILES]... Publish databases to Datasette running on Cloud Run Options: -m, --metadata FILENAME Path to JSON/YAML file containing metadata to publish --extra-options TEXT Extra options to pass to datasette serve --branch TEXT Install datasette from a GitHub branch e.g. main --template-dir DIRECTORY Path to directory containing custom templates --plugins-dir DIRECTORY Path to directory containing custom plugins --static MOUNT:DIRECTORY Serve static files from this directory at /MOUNT/... --install TEXT Additional packages (e.g. plugins) to install --plugin-secret <TEXT TEXT TEXT>... Secrets to pass to plugins, e.g. --plugin- secret datasette-auth-github client_id xxx --version-note TEXT Additional note to show on /-/versions --secret TEXT Secret used for signing secure values, such as signed cookies --title TEXT Title for metadata --license TEXT License label for metadata --license_url TEXT License URL for metadata --source TEXT Source label for metadata --source_url TEXT Source URL for metadata --about TEXT About label for metadata --about_url TEXT About URL for metadata -n, --name TEXT Application name to use when building --service TEXT Cloud Run service to deploy (or over-write) --spatialite Enable SpatialLite extension --show-files Output the generated Dockerfile and metad… ["CLI reference"] []
cli-reference:cli-help-publish-heroku-help cli-reference cli-help-publish-heroku-help datasette publish heroku See Publishing to Heroku . [[[cog help(["publish", "heroku", "--help"]) ]]] Usage: datasette publish heroku [OPTIONS] [FILES]... Publish databases to Datasette running on Heroku Options: -m, --metadata FILENAME Path to JSON/YAML file containing metadata to publish --extra-options TEXT Extra options to pass to datasette serve --branch TEXT Install datasette from a GitHub branch e.g. main --template-dir DIRECTORY Path to directory containing custom templates --plugins-dir DIRECTORY Path to directory containing custom plugins --static MOUNT:DIRECTORY Serve static files from this directory at /MOUNT/... --install TEXT Additional packages (e.g. plugins) to install --plugin-secret <TEXT TEXT TEXT>... Secrets to pass to plugins, e.g. --plugin- secret datasette-auth-github client_id xxx --version-note TEXT Additional note to show on /-/versions --secret TEXT Secret used for signing secure values, such as signed cookies --title TEXT Title for metadata --license TEXT License label for metadata --license_url TEXT License URL for metadata --source TEXT Source label for metadata --source_url TEXT Source URL for metadata --about TEXT About label for metadata --about_url TEXT About URL for metadata -n, --name TEXT Application name to use when deploying --tar TEXT --tar option to pass to Heroku, e.g. --tar=/usr/local/bin/gtar --generate-dir DIRECTORY Output generated application files and stop without deploying --h… ["CLI reference"] []
cli-reference:cli-help-package-help cli-reference cli-help-package-help datasette package Package SQLite files into a Datasette Docker container, see datasette package . [[[cog help(["package", "--help"]) ]]] Usage: datasette package [OPTIONS] FILES... Package SQLite files into a Datasette Docker container Options: -t, --tag TEXT Name for the resulting Docker container, can optionally use name:tag format -m, --metadata FILENAME Path to JSON/YAML file containing metadata to publish --extra-options TEXT Extra options to pass to datasette serve --branch TEXT Install datasette from a GitHub branch e.g. main --template-dir DIRECTORY Path to directory containing custom templates --plugins-dir DIRECTORY Path to directory containing custom plugins --static MOUNT:DIRECTORY Serve static files from this directory at /MOUNT/... --install TEXT Additional packages (e.g. plugins) to install --spatialite Enable SpatialLite extension --version-note TEXT Additional note to show on /-/versions --secret TEXT Secret used for signing secure values, such as signed cookies -p, --port INTEGER RANGE Port to run the server on, defaults to 8001 [1<=x<=65535] --title TEXT Title for metadata --license TEXT License label for metadata --license_url TEXT License URL for metadata --source TEXT Source label for metadata --source_url TEXT Source URL for metadata --about TEXT About label for metadata --about_url TEXT About URL for metadata --help Show this message and exit. [[[end]]] ["CLI reference"] []
cli-reference:cli-help-inspect-help cli-reference cli-help-inspect-help datasette inspect Outputs JSON representing introspected data about one or more SQLite database files. If you are opening an immutable database, you can pass this file to the --inspect-data option to improve Datasette's performance by allowing it to skip running row counts against the database when it first starts running: datasette inspect mydatabase.db > inspect-data.json datasette serve -i mydatabase.db --inspect-file inspect-data.json This performance optimization is used automatically by some of the datasette publish commands. You are unlikely to need to apply this optimization manually. [[[cog help(["inspect", "--help"]) ]]] Usage: datasette inspect [OPTIONS] [FILES]... Generate JSON summary of provided database files This can then be passed to "datasette --inspect-file" to speed up count operations against immutable database files. Options: --inspect-file TEXT --load-extension PATH:ENTRYPOINT? Path to a SQLite extension to load, and optional entrypoint --help Show this message and exit. [[[end]]] ["CLI reference"] []
cli-reference:cli-help-create-token-help cli-reference cli-help-create-token-help datasette create-token Create a signed API token, see datasette create-token . [[[cog help(["create-token", "--help"]) ]]] Usage: datasette create-token [OPTIONS] ID Create a signed API token for the specified actor ID Example: datasette create-token root --secret mysecret To allow only "view-database-download" for all databases: datasette create-token root --secret mysecret \ --all view-database-download To allow "create-table" against a specific database: datasette create-token root --secret mysecret \ --database mydb create-table To allow "insert-row" against a specific table: datasette create-token root --secret myscret \ --resource mydb mytable insert-row Restricted actions can be specified multiple times using multiple --all, --database, and --resource options. Add --debug to see a decoded version of the token. Options: --secret TEXT Secret used for signing the API tokens [required] -e, --expires-after INTEGER Token should expire after this many seconds -a, --all ACTION Restrict token to this action -d, --database DB ACTION Restrict token to this action on this database -r, --resource DB RESOURCE ACTION Restrict token to this action on this database resource (a table, SQL view or named query) --debug Show decoded token --plugins-dir DIRECTORY Path to directory containing custom plugins --help Show this message and exit. [[[end]]] ["CLI reference"] []
javascript_plugins:id1 javascript_plugins id1 JavaScript plugins Datasette can run custom JavaScript in several different ways: Datasette plugins written in Python can use the extra_js_urls() or extra_body_script() plugin hooks to inject JavaScript into a page Datasette instances with custom templates can include additional JavaScript in those templates The extra_js_urls key in datasette.yaml can be used to include extra JavaScript There are no limitations on what this JavaScript can do. It is executed directly by the browser, so it can manipulate the DOM, fetch additional data and do anything else that JavaScript is capable of. Custom JavaScript has security implications, especially for authenticated Datasette instances where the JavaScript might run in the context of the authenticated user. It's important to carefully review any JavaScript you run in your Datasette instance. [] []
javascript_plugins:javascript-datasette-init javascript_plugins javascript-datasette-init The datasette_init event Datasette emits a custom event called datasette_init when the page is loaded. This event is dispatched on the document object, and includes a detail object with a reference to the datasetteManager object. Your JavaScript code can listen out for this event using document.addEventListener() like this: document.addEventListener("datasette_init", function (evt) { const manager = evt.detail; console.log("Datasette version:", manager.VERSION); }); ["JavaScript plugins"] []
javascript_plugins:javascript-datasette-manager javascript_plugins javascript-datasette-manager datasetteManager The datasetteManager object VERSION - string The version of Datasette plugins - Map() A Map of currently loaded plugin names to plugin implementations registerPlugin(name, implementation) Call this to register a plugin, passing its name and implementation selectors - object An object providing named aliases to useful CSS selectors, listed below ["JavaScript plugins"] []
javascript_plugins:id2 javascript_plugins id2 JavaScript plugin objects JavaScript plugins are blocks of code that can be registered with Datasette using the registerPlugin() method on the datasetteManager object. The implementation object passed to this method should include a version key defining the plugin version, and one or more of the following named functions providing the implementation of the plugin: ["JavaScript plugins"] []
javascript_plugins:javascript-plugins-makeabovetablepanelconfigs javascript_plugins javascript-plugins-makeabovetablepanelconfigs makeAboveTablePanelConfigs() This method should return a JavaScript array of objects defining additional panels to be added to the top of the table page. Each object should have the following: id - string A unique string ID for the panel, for example map-panel label - string A human-readable label for the panel render(node) - function A function that will be called with a DOM node to render the panel into This example shows how a plugin might define a single panel: document.addEventListener('datasette_init', function(ev) { ev.detail.registerPlugin('panel-plugin', { version: 0.1, makeAboveTablePanelConfigs: () => { return [ { id: 'first-panel', label: 'First panel', render: node => { node.innerHTML = '<h2>My custom panel</h2><p>This is a custom panel that I added using a JavaScript plugin</p>'; } } ] } }); }); When a page with a table loads, all registered plugins that implement makeAboveTablePanelConfigs() will be called and panels they return will be added to the top of the table page. ["JavaScript plugins", "JavaScript plugin objects"] []
javascript_plugins:javascript-plugins-makecolumnactions javascript_plugins javascript-plugins-makecolumnactions makeColumnActions(columnDetails) This method, if present, will be called when Datasette is rendering the cog action menu icons that appear at the top of the table view. By default these include options like "Sort ascending/descending" and "Facet by this", but plugins can return additional actions to be included in this menu. The method will be called with a columnDetails object with the following keys: columnName - string The name of the column columnNotNull - boolean True if the column is defined as NOT NULL columnType - string The SQLite data type of the column isPk - boolean True if the column is part of the primary key It should return a JavaScript array of objects each with a label and onClick property: label - string The human-readable label for the action onClick(evt) - function A function that will be called when the action is clicked The evt object passed to the onClick is the standard browser event object that triggered the click. This example plugin adds two menu items - one to copy … ["JavaScript plugins", "JavaScript plugin objects"] []
javascript_plugins:javascript-datasette-manager-selectors javascript_plugins javascript-datasette-manager-selectors Selectors These are available on the selectors property of the datasetteManager object. const DOM_SELECTORS = { /** Should have one match */ jsonExportLink: ".export-links a[href*=json]", /** Event listeners that go outside of the main table, e.g. existing scroll listener */ tableWrapper: ".table-wrapper", table: "table.rows-and-columns", aboveTablePanel: ".above-table-panel", // These could have multiple matches /** Used for selecting table headers. Use makeColumnActions if you want to add menu items. */ tableHeaders: `table.rows-and-columns th`, /** Used to add "where" clauses to query using direct manipulation */ filterRows: ".filter-row", /** Used to show top available enum values for a column ("facets") */ facetResults: ".facet-results [data-column]", }; ["JavaScript plugins"] []
introspection:id1 introspection id1 Introspection 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. Each of these pages can be viewed in your browser. Add .json to the URL to get back the contents as JSON. [] []
introspection:jsondataview-actor introspection jsondataview-actor /-/actor Shows the currently authenticated actor. Useful for debugging Datasette authentication plugins. { "actor": { "id": 1, "username": "some-user" } } ["Introspection"] []
introspection:messagesdebugview introspection messagesdebugview /-/messages The debug tool at /-/messages can be used to set flash messages to try out that feature. See .add_message(request, message, type=datasette.INFO) for details of this feature. ["Introspection"] []
spatialite:spatialite-installation spatialite spatialite-installation Installation   ["SpatiaLite"] []
spatialite:installing-spatialite-on-linux spatialite installing-spatialite-on-linux Installing SpatiaLite on Linux SpatiaLite is packaged for most Linux distributions. apt install spatialite-bin libsqlite3-mod-spatialite Depending on your distribution, you should be able to run Datasette something like this: datasette --load-extension=/usr/lib/x86_64-linux-gnu/mod_spatialite.so If you are unsure of the location of the module, try running locate mod_spatialite and see what comes back. ["SpatiaLite", "Installation"] []
spatialite:spatial-indexing-latitude-longitude-columns spatialite spatial-indexing-latitude-longitude-columns Spatial indexing latitude/longitude columns Here's a recipe for taking a table with existing latitude and longitude columns, adding a SpatiaLite POINT geometry column to that table, populating the new column and then populating a spatial index: import sqlite3 conn = sqlite3.connect("museums.db") # Lead the spatialite extension: conn.enable_load_extension(True) conn.load_extension("/usr/local/lib/mod_spatialite.dylib") # Initialize spatial metadata for this database: conn.execute("select InitSpatialMetadata(1)") # Add a geometry column called point_geom to our museums table: conn.execute( "SELECT AddGeometryColumn('museums', 'point_geom', 4326, 'POINT', 2);" ) # Now update that geometry column with the lat/lon points conn.execute( """ UPDATE museums SET point_geom = GeomFromText('POINT('||"longitude"||' '||"latitude"||')',4326); """ ) # Now add a spatial index to that column conn.execute( 'select CreateSpatialIndex("museums", "point_geom");' ) # If you don't commit your changes will not be persisted: conn.commit() conn.close() ["SpatiaLite"] []
spatialite:querying-polygons-using-within spatialite querying-polygons-using-within Querying polygons using within() The within() SQL function can be used to check if a point is within a geometry: select name from places where within(GeomFromText('POINT(-3.1724366 51.4704448)'), places.geom); The GeomFromText() function takes a string of well-known text. Note that the order used here is longitude then latitude . To run that same within() query in a way that benefits from the spatial index, use the following: select name from places where within(GeomFromText('POINT(-3.1724366 51.4704448)'), places.geom) and rowid in ( SELECT pkid FROM idx_places_geom where xmin < -3.1724366 and xmax > -3.1724366 and ymin < 51.4704448 and ymax > 51.4704448 ); ["SpatiaLite"] []
internals:internals internals internals Internals for plugins Many Plugin hooks are passed objects that provide access to internal Datasette functionality. The interface to these objects should not be considered stable with the exception of methods that are documented here. [] []
internals:internals-multiparams internals internals-multiparams The MultiParams class request.args is a MultiParams object - a dictionary-like object which provides access to query string parameters that may have multiple values. Consider the query string ?foo=1&foo=2&bar=3 - with two values for foo and one value for bar . request.args[key] - string Returns the first value for that key, or raises a KeyError if the key is missing. For the above example request.args["foo"] would return "1" . request.args.get(key) - string or None Returns the first value for that key, or None if the key is missing. Pass a second argument to specify a different default, e.g. q = request.args.get("q", "") . request.args.getlist(key) - list of strings Returns the list of strings for that key. request.args.getlist("foo") would return ["1", "2"] in the above example. request.args.getlist("bar") would return ["3"] . If the key is missing an empty list will be returned. request.args.keys() - list of strings Returns the list of available keys - for the example this would be ["foo", "bar"] . key in request.args - True or False You can use if key in request.args to check if a key is present. for key in request.args - iterator This lets you loop through every available key. le… ["Internals for plugins"] []
internals:internals-response internals internals-response Response class The Response class can be returned from view functions that have been registered using the register_routes(datasette) hook. The Response() constructor takes the following arguments: body - string The body of the response. status - integer (optional) The HTTP status - defaults to 200. headers - dictionary (optional) A dictionary of extra HTTP headers, e.g. {"x-hello": "world"} . content_type - string (optional) The content-type for the response. Defaults to text/plain . For example: from datasette.utils.asgi import Response response = Response( "<xml>This is XML</xml>", content_type="application/xml; charset=utf-8", ) The quickest way to create responses is using the Response.text(...) , Response.html(...) , Response.json(...) or Response.redirect(...) helper methods: from datasette.utils.asgi import Response html_response = Response.html("This is HTML") json_response = Response.json({"this_is": "json"}) text_response = Response.text( "This will become utf-8 encoded text" ) # Redirects are served as 302, unless you pass status=301: redirect_response = Response.redirect( "https://latest.datasette.io/" ) Each of these responses will use the correct corresponding content-type - text/html; charset=utf-8 , application/json; charset=utf-8 or text/plain; charset=utf-8 respectively. Each of the helper methods take optional status= and headers= argument… ["Internals for plugins"] []
internals:internals-response-asgi-send internals internals-response-asgi-send Returning a response with .asgi_send(send) In most cases you will return Response objects from your own view functions. You can also use a Response instance to respond at a lower level via ASGI, for example if you are writing code that uses the asgi_wrapper(datasette) hook. Create a Response object and then use await response.asgi_send(send) , passing the ASGI send function. For example: async def require_authorization(scope, receive, send): response = Response.text( "401 Authorization Required", headers={ "www-authenticate": 'Basic realm="Datasette", charset="UTF-8"' }, status=401, ) await response.asgi_send(send) ["Internals for plugins", "Response class"] []
internals:internals-response-set-cookie internals internals-response-set-cookie Setting cookies with response.set_cookie() To set cookies on the response, use the response.set_cookie(...) method. The method signature looks like this: def set_cookie( self, key, value="", max_age=None, expires=None, path="/", domain=None, secure=False, httponly=False, samesite="lax", ): ... You can use this with datasette.sign() to set signed cookies. Here's how you would set the ds_actor cookie for use with Datasette authentication : response = Response.redirect("/") response.set_cookie( "ds_actor", datasette.sign({"a": {"id": "cleopaws"}}, "actor"), ) return response ["Internals for plugins", "Response class"] []
internals:internals-datasette internals internals-datasette Datasette class This object is an instance of the Datasette class, passed to many plugin hooks as an argument called datasette . You can create your own instance of this - for example to help write tests for a plugin - like so: from datasette.app import Datasette # With no arguments a single in-memory database will be attached datasette = Datasette() # The files= argument can load files from disk datasette = Datasette(files=["/path/to/my-database.db"]) # Pass metadata as a JSON dictionary like this datasette = Datasette( files=["/path/to/my-database.db"], metadata={ "databases": { "my-database": { "description": "This is my database" } } }, ) Constructor parameters include: files=[...] - a list of database files to open immutables=[...] - a list of database files to open in immutable mode metadata={...} - a dictionary of Metadata config_dir=... - the configuration directory to use, stored in datasette.config_dir ["Internals for plugins"] []
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-permissions internals datasette-permissions .permissions Property exposing a dictionary of permissions that have been registered using the register_permissions(datasette) plugin hook. The dictionary keys are the permission names - e.g. view-instance - and the values are Permission() objects describing the permission. Here is a description of that object . ["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-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-permission-allowed internals datasette-permission-allowed await .permission_allowed(actor, action, resource=None, default=...) actor - dictionary The authenticated actor. This is usually request.actor . action - string The name of the action that is being permission checked. resource - string or tuple, optional The resource, e.g. the name of the database, or a tuple of two strings containing the name of the database and the name of the table. Only some permissions apply to a resource. default - optional: True, False or None What value should be returned by default if nothing provides an opinion on this permission check. Set to True for default allow or False for default deny. If not specified the default from the Permission() tuple that was registered using register_permissions(datasette) will be used. Check if the given actor has permission to perform the given action on the given resource. Some permission checks are carried out against rules defined in datasette.yaml , while other custom permissions may be decided by plugins that implement the permission_allowed(datasette, actor, action, resource) plugin hook. If neither metadata.json nor any of the plugins provide an answer to the permission query the default argument will be returned. See Built-in permissions for a full list of permission actions included in Datasette core. ["Internals for plugins", "Datasette class"] []
internals:datasette-ensure-permissions internals datasette-ensure-permissions await .ensure_permissions(actor, permissions) actor - dictionary The authenticated actor. This is usually request.actor . permissions - list A list of permissions to check. Each permission in that list can be a string action name or a 2-tuple of (action, resource) . This method allows multiple permissions to be checked at once. It raises a datasette.Forbidden exception if any of the checks are denied before one of them is explicitly granted. This is useful when you need to check multiple permissions at once. For example, an actor should be able to view a table if either one of the following checks returns True or not a single one of them returns False : await datasette.ensure_permissions( request.actor, [ ("view-table", (database, table)), ("view-database", database), "view-instance", ], ) ["Internals for plugins", "Datasette class"] []
internals:datasette-check-visibility internals datasette-check-visibility await .check_visibility(actor, action=None, resource=None, permissions=None) actor - dictionary The authenticated actor. This is usually request.actor . action - string, optional The name of the action that is being permission checked. resource - string or tuple, optional The resource, e.g. the name of the database, or a tuple of two strings containing the name of the database and the name of the table. Only some permissions apply to a resource. permissions - list of action strings or (action, resource) tuples, optional Provide this instead of action and resource to check multiple permissions at once. 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: visible, private = await datasette.check_visibility( request.actor, action="view-table", resource=(database, table), ) The following example runs three checks in a row, similar to await .ensure_permissions(actor, permissions) . If any of the checks are denied before one of them is explicitly granted then visible will be … ["Internals for plugins", "Datasette class"] []
internals:datasette-create-token internals datasette-create-token .create_token(actor_id, expires_after=None, restrict_all=None, restrict_database=None, restrict_resource=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. restrict_all - iterable, optional A list of actions that this token should be restricted to across all databases and resources. restrict_database - dict, optional For restricting actions within specific databases, e.g. {"mydb": ["view-table", "view-query"]} . restrict_resource - dict, optional For restricting actions to specific resources (tables, SQL views and Canned queries ) within a database. For example: {"mydb": {"mytable": ["insert-row", "update-row"]}} . This method returns a signed API token of the format dstok_... which can be used to authenticate requests to the Datasette API. 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 = datasette.create_token( actor_id="user1", expires_after=3600, ) The three restrict_* arguments can be used to create a token that has … ["Internals for plugins", "Datasette class"] []
internals:datasette-get-permission internals datasette-get-permission .get_permission(name_or_abbr) name_or_abbr - string The name or abbreviation of the permission to look up, e.g. view-table or vt . Returns a Permission object representing the permission, or raises a KeyError if one is not found. ["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:id1 internals id1 .get_internal_database() Returns a database object for reading and writing to the private internal 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-get-instance-metadata internals datasette-get-instance-metadata await .get_instance_metadata(self) Returns metadata keys and values for the entire Datasette instance as a dictionary. Internally queries the metadata_instance table inside the internal database . ["Internals for plugins", "Datasette class", "Getting and setting metadata"] []
internals:datasette-get-database-metadata internals datasette-get-database-metadata await .get_database_metadata(self, database_name) database_name - string The name of the database to query. Returns metadata keys and values for the specified database as a dictionary. Internally queries the metadata_databases table inside the internal database . ["Internals for plugins", "Datasette class", "Getting and setting metadata"] []
internals:datasette-get-resource-metadata internals datasette-get-resource-metadata await .get_resource_metadata(self, database_name, resource_name) database_name - string The name of the database to query. resource_name - string The name of the resource (table, view, or canned query) inside database_name to query. Returns metadata keys and values for the specified "resource" as a dictionary. A "resource" in this context can be a table, view, or canned query. Internally queries the metadata_resources table inside the internal database . ["Internals for plugins", "Datasette class", "Getting and setting metadata"] []
internals:datasette-get-column-metadata internals datasette-get-column-metadata await .get_column_metadata(self, database_name, resource_name, column_name) database_name - string The name of the database to query. resource_name - string The name of the resource (table, view, or canned query) inside database_name to query. column_name - string The name of the column inside resource_name to query. Returns metadata keys and values for the specified column, resource, and table as a dictionary. Internally queries the metadata_columns table inside the internal database . ["Internals for plugins", "Datasette class", "Getting and setting metadata"] []
internals:datasette-set-instance-metadata internals datasette-set-instance-metadata await .set_instance_metadata(self, key, value) key - string The metadata entry key to insert (ex title , description , etc.) value - string The value of the metadata entry to insert. Adds a new metadata entry for the entire Datasette instance. Any previous instance-level metadata entry with the same key will be overwritten. Internally upserts the value into the the metadata_instance table inside the internal database . ["Internals for plugins", "Datasette class", "Getting and setting metadata"] []
internals:datasette-set-database-metadata internals datasette-set-database-metadata await .set_database_metadata(self, database_name, key, value) database_name - string The database the metadata entry belongs to. key - string The metadata entry key to insert (ex title , description , etc.) value - string The value of the metadata entry to insert. Adds a new metadata entry for the specified database. Any previous database-level metadata entry with the same key will be overwritten. Internally upserts the value into the the metadata_databases table inside the internal database . ["Internals for plugins", "Datasette class", "Getting and setting metadata"] []
internals:datasette-set-resource-metadata internals datasette-set-resource-metadata await .set_resource_metadata(self, database_name, resource_name, key, value) database_name - string The database the metadata entry belongs to. resource_name - string The resource (table, view, or canned query) the metadata entry belongs to. key - string The metadata entry key to insert (ex title , description , etc.) value - string The value of the metadata entry to insert. Adds a new metadata entry for the specified "resource". Any previous resource-level metadata entry with the same key will be overwritten. Internally upserts the value into the the metadata_resources table inside the internal database . ["Internals for plugins", "Datasette class", "Getting and setting metadata"] []
internals:datasette-set-column-metadata internals datasette-set-column-metadata await .set_column_metadata(self, database_name, resource_name, column_name, key, value) database_name - string The database the metadata entry belongs to. resource_name - string The resource (table, view, or canned query) the metadata entry belongs to. column-name - string The column the metadata entry belongs to. key - string The metadata entry key to insert (ex title , description , etc.) value - string The value of the metadata entry to insert. Adds a new metadata entry for the specified column. Any previous column-level metadata entry with the same key will be overwritten. Internally upserts the value into the the metadata_columns table inside the internal database . ["Internals for plugins", "Datasette class", "Getting and setting metadata"] []
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(name) 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 pattern will result in the in-memory database being served at /statistics . ["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-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-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-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-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-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-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-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 … ["Internals for plugins", "Datasette class"] []
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) … ["Internals for plugins", "Datasette class"] []
internals:internals-database internals internals-database Database class Instances of the Database class can be used to execute queries against attached SQLite databases, and to run introspection against their schemas. ["Internals for plugins"] []
internals:database-constructor internals database-constructor Database(ds, path=None, is_mutable=True, is_memory=False, memory_name=None) The Database() constructor can be used by plugins, in conjunction with .add_database(db, name=None, route=None) , to create and register new databases. The arguments are as follows: ds - Datasette class (required) The Datasette instance you are attaching this database to. path - string Path to a SQLite database file on disk. is_mutable - boolean Set this to False to cause Datasette to open the file in immutable mode. is_memory - boolean Use this to create non-shared memory connections. memory_name - string or None Use this to create a named in-memory database. Unlike regular memory databases these can be accessed by multiple threads and will persist an changes made to them for the lifetime of the Datasette server process. The first argument is the datasette instance you are attaching to, the second is a path= , then is_mutable and is_memory are both optional arguments. ["Internals for plugins", "Database class"] []
internals:database-hash internals database-hash db.hash If the database was opened in immutable mode, this property returns the 64 character SHA-256 hash of the database contents as a string. Otherwise it returns None . ["Internals for plugins", "Database class"] []
internals:database-execute internals database-execute await db.execute(sql, ...) Executes a SQL query against the database and returns the resulting rows (see Results ). sql - string (required) The SQL query to execute. This can include ? or :named parameters. params - list or dict A list or dictionary of values to use for the parameters. List for ? , dictionary for :named . truncate - boolean Should the rows returned by the query be truncated at the maximum page size? Defaults to True , set this to False to disable truncation. custom_time_limit - integer ms A custom time limit for this query. This can be set to a lower value than the Datasette configured default. If a query takes longer than this it will be terminated early and raise a dataette.database.QueryInterrupted exception. page_size - integer Set a custom page size for truncation, over-riding the configured Datasette default. log_sql_errors - boolean Should any SQL errors be logged to the console in addition to being raised as an error? Defaults to True . ["Internals for plugins", "Database class"] []
internals:database-execute-fn internals database-execute-fn await db.execute_fn(fn) Executes a given callback function against a read-only database connection running in a thread. The function will be passed a SQLite connection, and the return value from the function will be returned by the await . Example usage: def get_version(conn): return conn.execute( "select sqlite_version()" ).fetchall()[0][0] version = await db.execute_fn(get_version) ["Internals for plugins", "Database class"] []
internals:database-execute-write internals database-execute-write await db.execute_write(sql, params=None, block=True) SQLite only allows one database connection to write at a time. Datasette handles this for you by maintaining a queue of writes to be executed against a given database. Plugins can submit write operations to this queue and they will be executed in the order in which they are received. This method can be used to queue up a non-SELECT SQL query to be executed against a single write connection to the database. You can pass additional SQL parameters as a tuple or dictionary. The method will block until the operation is completed, and the return value will be the return from calling conn.execute(...) using the underlying sqlite3 Python library. If you pass block=False this behavior changes to "fire and forget" - queries will be added to the write queue and executed in a separate thread while your code can continue to do other things. The method will return a UUID representing the queued task. Each call to execute_write() will be executed inside a transaction. ["Internals for plugins", "Database class"] []
internals:database-execute-write-fn internals database-execute-write-fn await db.execute_write_fn(fn, block=True, transaction=True) This method works like .execute_write() , but instead of a SQL statement you give it a callable Python function. Your function will be queued up and then called when the write connection is available, passing that connection as the argument to the function. The function can then perform multiple actions, safe in the knowledge that it has exclusive access to the single writable connection for as long as it is executing. fn needs to be a regular function, not an async def function. For example: def delete_and_return_count(conn): conn.execute("delete from some_table where id > 5") return conn.execute( "select count(*) from some_table" ).fetchone()[0] try: num_rows_left = await database.execute_write_fn( delete_and_return_count ) except Exception as e: print("An error occurred:", e) The value returned from await database.execute_write_fn(...) will be the return value from your function. If your function raises an exception that exception will be propagated up to the await line. By default your function will be executed inside a transaction. You can pass transaction=False to disable this behavior, though if you do that you should be careful to manually apply transactions - ideally using the with conn: pattern, or you may see OperationalError: database table is locked errors. If you specify block=False the method becomes fire-and-forget, queueing your function to be executed and then allowing your code after the call to .execute_write_fn() to continue running while the underlying thread waits for an opportunity to run your function. A UUID representing the queued task will be returned. Any exceptions in your code will be silently swallowed. ["Internals for plugins", "Database class"] []
internals:database-close internals database-close db.close() Closes all of the open connections to file-backed databases. This is mainly intended to be used by large test suites, to avoid hitting limits on the number of open files. ["Internals for plugins", "Database class"] []
internals:internals-database-introspection internals internals-database-introspection Database introspection The Database class also provides properties and methods for introspecting the database. db.name - string The name of the database - usually the filename without the .db prefix. db.size - integer The size of the database file in bytes. 0 for :memory: databases. db.mtime_ns - integer or None The last modification time of the database file in nanoseconds since the epoch. None for :memory: databases. db.is_mutable - boolean Is this database mutable, and allowed to accept writes? db.is_memory - boolean Is this database an in-memory database? await db.attached_databases() - list of named tuples Returns a list of additional databases that have been connected to this database using the SQLite ATTACH command. Each named tuple has fields seq , name and file . await db.table_exists(table) - boolean Check if a table called table exists. await db.view_exists(view) - boolean … ["Internals for plugins", "Database class"] []
internals:internals-internal internals internals-internal Datasette's internal database Datasette maintains an "internal" SQLite database used for configuration, caching, and storage. Plugins can store configuration, settings, and other data inside this database. By default, Datasette will use a temporary in-memory SQLite database as the internal database, which is created at startup and destroyed at shutdown. Users of Datasette can optionally pass in a --internal flag to specify the path to a SQLite database to use as the internal database, which will persist internal data across Datasette instances. Datasette maintains tables called catalog_databases , catalog_tables , catalog_columns , catalog_indexes , catalog_foreign_keys with details of the attached databases and their schemas. These tables should not be considered a stable API - they may change between Datasette releases. Metadata is stored in tables metadata_instance , metadata_databases , metadata_resources and metadata_columns . Plugins can interact with these tables via the get_*_metadata() and set_*_metadata() methods . The internal database is not exposed in the Datasette application by default, which means private data can safely be stored without worry of accidentally leaking information through the default Datasette interface and API. However, other plugins do have full read and write access to the internal database. Plugins can access this database by calling internal_db = datasette.get_internal_database() and then executing queries using the Database API . Plugin authors are asked to practice good etiquette when using the internal database, as all plugins use the same database to store data. For example: Use a unique prefix when creating tables, indices, and triggers in the internal database. If your plugin is called datasette-xyz , then prefix names with datasette_xyz_* . Avoid long-running write statements that may stall or block ot… ["Internals for plugins"] []
internals:internals-internal-schema internals internals-internal-schema Internal database schema The internal database schema is as follows: [[[cog from metadata_doc import internal_schema internal_schema(cog) ]]] CREATE TABLE catalog_databases ( database_name TEXT PRIMARY KEY, path TEXT, is_memory INTEGER, schema_version INTEGER ); CREATE TABLE catalog_tables ( database_name TEXT, table_name TEXT, rootpage INTEGER, sql TEXT, PRIMARY KEY (database_name, table_name), FOREIGN KEY (database_name) REFERENCES catalog_databases(database_name) ); CREATE TABLE catalog_columns ( database_name TEXT, table_name TEXT, cid INTEGER, name TEXT, type TEXT, "notnull" INTEGER, default_value TEXT, -- renamed from dflt_value is_pk INTEGER, -- renamed from pk hidden INTEGER, PRIMARY KEY (database_name, table_name, name), FOREIGN KEY (database_name) REFERENCES catalog_databases(database_name), FOREIGN KEY (database_name, table_name) REFERENCES catalog_tables(database_name, table_name) ); CREATE TABLE catalog_indexes ( database_name TEXT, table_name TEXT, seq INTEGER, name TEXT, "unique" INTEGER, origin TEXT, partial INTEGER, PRIMARY KEY (database_name, table_name, name), FOREIGN KEY (database_name) REFERENCES catalog_databases(database_name), FOREIGN KEY (database_name, table_name) REFERENCES catalog_tables(database_name, table_name) ); CREATE TABLE catalog_foreign_keys ( database_name TEXT, table_name TEXT, id INTEGER, seq INTEGER, "table" TEXT, "from" TEXT, "to" TEXT, on_update TEXT, on_delete TEXT, match TEXT, PRIMARY KEY (database_name, table_name, id, seq), FOREIGN KEY (database_name) REFERENCES catalog_databases(database_name), FOREIGN KEY (database_name, table_name) REFERENCES catalog_tables(database_name, table_name) ); CREATE TABLE metadata_instance ( key text, value text, unique(key) ); CREATE TABLE metadata_databases ( database_name text, key text, value text, u… ["Internals for plugins", "Datasette's internal database"] []

Next page

Advanced export

JSON shape: default, array, newline-delimited, object

CSV options:

CREATE TABLE [sections] (
   [id] TEXT PRIMARY KEY,
   [page] TEXT,
   [ref] TEXT,
   [title] TEXT,
   [content] TEXT,
   [breadcrumbs] TEXT,
   [references] TEXT
);
Powered by Datasette · Queries took 1.2ms