diff --git a/docs/index.rst b/docs/index.rst index bf1bc085..4d4d1d96 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -65,6 +65,6 @@ Contents testing_plugins internals events - upgrade_guide_v1 + upgrade_guide contributing changelog diff --git a/docs/plugin_hooks.rst b/docs/plugin_hooks.rst index f4ef5d64..d3764dcc 100644 --- a/docs/plugin_hooks.rst +++ b/docs/plugin_hooks.rst @@ -1463,50 +1463,6 @@ This example will disable CSRF protection for that specific URL path: If any of the currently active ``skip_csrf()`` plugin hooks return ``True``, CSRF protection will be skipped for the request. -.. _plugin_hook_get_metadata: - -get_metadata(datasette, key, database, table) ---------------------------------------------- - -``datasette`` - :ref:`internals_datasette` - You can use this to access plugin configuration options via ``datasette.plugin_config(your_plugin_name)``. - -``actor`` - dictionary or None - The currently authenticated :ref:`actor `. - -``database`` - string or None - The name of the database metadata is being asked for. - -``table`` - string or None - The name of the table. - -``key`` - string or None - The name of the key for which data is being asked for. - -This hook is responsible for returning a dictionary corresponding to Datasette :ref:`metadata`. This function is passed the ``database``, ``table`` and ``key`` which were passed to the upstream internal request for metadata. Regardless, it is important to return a global metadata object, where ``"databases": []`` would be a top-level key. The dictionary returned here, will be merged with, and overwritten by, the contents of the physical ``metadata.yaml`` if one is present. - -.. warning:: - The design of this plugin hook does not currently provide a mechanism for interacting with async code, and may change in the future. See `issue 1384 `__. - -.. code-block:: python - - @hookimpl - def get_metadata(datasette, key, database, table): - metadata = { - "title": "This will be the Datasette landing page title!", - "description": get_instance_description(datasette), - "databases": [], - } - for db_name, db_data_dict in get_my_database_meta( - datasette, database, table, key - ): - metadata["databases"][db_name] = db_data_dict - # whatever we return here will be merged with any other plugins using this hook and - # will be overwritten by a local metadata.yaml if one exists! - return metadata - -Example: `datasette-remote-metadata plugin `__ - .. _plugin_hook_menu_links: menu_links(datasette, actor, request) diff --git a/docs/upgrade_guide.rst b/docs/upgrade_guide.rst new file mode 100644 index 00000000..09023166 --- /dev/null +++ b/docs/upgrade_guide.rst @@ -0,0 +1,125 @@ +.. _upgrade_guide: + +=============== + Upgrade guide +=============== + +.. _upgrade_guide_v1: + +Datasette 0.X -> 1.0 +==================== + +This section reviews breaking changes Datasette ``1.0`` has when upgrading from a ``0.XX`` version. +For new features that ``1.0`` offers, see the :ref:`changelog`. + +.. _upgrade_guide_v1_metadata: + +Metadata changes +---------------- + +Metadata was completely revamped for Datasette 1.0. There are a number of related breaking changes, from the ``metadata.yaml`` file to Python APIs, that you'll need to consider when upgrading. + +.. _upgrade_guide_v1_metadata_split: + +``metadata.yaml`` split into ``datasette.yaml`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Before Datasette 1.0, the ``metadata.yaml`` file became a kitchen sink if a mix of metadata, configuration, and settings. Now ``metadata.yaml`` is strictly for metaata (ex title and descriptions of database and tables, licensing info, etc). Other settings have been moved to a ``datasette.yml`` configuration file, described in :ref:`configuration`. + +To start Datasette with both metadata and configuration files, run it like this: + +.. code-block:: bash + + datasette --metadata metadata.yaml --config datasette.yaml + # Or the shortened version: + datasette -m metadata.yml -c datasette.yml + +.. _upgrade_guide_v1_metadata_upgrade: + +Upgrading an existing ``metadata.yaml`` file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The `datasette-upgrade plugin `__ can be used to split a Datasette 0.x.x ``metadata.yaml`` (or ``.json``) file into separate ``metadata.yaml`` and ``datasette.yaml`` files. First, install the plugin: + +.. code-block:: bash + + datasette install datasette-upgrade + +Then run it like this to produce the two new files: + +.. code-block:: bash + + datasette upgrade metadata-to-config metadata.json -m metadata.yml -c datasette.yml + +Metadata "fallback" has been removed +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Certain keys in metadata like ``license`` used to "fallback" up the chain of ownership. +For example, if you set an ``MIT`` to a database and a table within that database did not have a specified license, then that table would inherit an ``MIT`` license. + +This behavior has been removed in Datasette 1.0. Now license fields must be placed on all items, including individual databases and tables. + +.. _upgrade_guide_v1_metadata_removed: + +The ``get_metadata()`` plugin hook has been removed +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In Datasette ``0.x`` plugins could implement a ``get_metadata()`` plugin hook to customize how metadata was retrieved for different instances, databases and tables. + +This hook could be inefficient, since some pages might load metadata for many different items (to list a large number of tables, for example) which could result in a large number of calls to potentially expensive plugin hook implementations. + +As of Datasette ``1.0a14`` (2024-08-05), the ``get_metadata()`` hook has been deprecated: + +.. code-block:: python + + # ❌ DEPRECATED in Datasette 1.0 + @hookimpl + def get_metadata(datasette, key, database, table): + pass + +Instead, plugins are encouraged to interact directly with Datasette's in-memory metadata tables in SQLite using the following methods on the :ref:`internals_datasette`: + +- :ref:`get_instance_metadata() ` and :ref:`set_instance_metadata() ` +- :ref:`get_database_metadata() ` and :ref:`set_database_metadata() ` +- :ref:`get_resource_metadata() ` and :ref:`set_resource_metadata() ` +- :ref:`get_column_metadata() ` and :ref:`set_column_metadata() ` + +A plugin that stores or calculates its own metadata can implement the :ref:`plugin_hook_startup` hook to populate those items on startup, and then call those methods while it is running to persist any new metadata changes. + +The ``/metadata.json`` endpoint has been removed +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As of Datasette ``1.0a14``, the root level ``/metadata.json`` endpoint has been removed. Metadata for tables will become available through currently in-development extras in a future alpha. + +The ``metadata()`` method on the Datasette class has been removed +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As of Datasette ``1.0a14``, the ``.metadata()`` method on the Datasette Python API has been removed. + +Instead, one should use the following methods on a Datasette class: + +- :ref:`get_instance_metadata() ` +- :ref:`get_database_metadata() ` +- :ref:`get_resource_metadata() ` +- :ref:`get_column_metadata() ` + +New endpoint for SQL queries +---------------------------- + +Previously, if you wanted to run SQL code using the Datasette HTTP API, you could call an endpoint that looked like: + +:: + + # DEPRECATED: Older endpoint for Datasette 0.XX + curl http://localhost:8001/_memory?sql=select+123 + +However, in Datasette 1.0, the endpoint was slightly changed to: + +:: + + # ✅ Datasette 1.0 and beyond + curl http://localhost:8001/_memory/-/query?sql=select+123 + +Specifically, now there's a ``/-/query`` "action" that should be used. + +**This isn't a breaking change.** API calls to the older ``/database?sql=...`` endpoint will redirect to the new ``database/-/query?sql=...`` endpoint. However, documentations and example will use the new query endpoint, so it is recommended to use that instead. diff --git a/docs/upgrade_guide_v1.rst b/docs/upgrade_guide_v1.rst deleted file mode 100644 index 90024ff5..00000000 --- a/docs/upgrade_guide_v1.rst +++ /dev/null @@ -1,91 +0,0 @@ -.. upgrade_guide_v1: - -==================================== - Datasette 0.X -> 1.0 Upgrade Guide -==================================== - - -This document specifically reviews what breaking changes Datasette ``1.0`` has when upgrading from a ``0.XX`` version. -For new features that ``1.0`` offers, see the [Changelog](https://docs.datasette.io/en/latest/changelog.html). - - -Metadata changes -================ - -Metadata in Datasette.10 was completely revamped. -There are a number of related breaking changes, from the ``metadata.yaml`` file to Python APIs that you'll need to consider when upgrading. - -``metadata.yaml`` split into ``datasette.yaml`` ------------------------------------------------ - -Before Datasette 1.0, the ``metadata.yaml`` file became a kitchen sink if a mix of metadata, configuration, and settings. -Now ``metadata.yaml`` is strictly for metaata (ex title and descriptions of database and tables, licensing info, etc). - - -Metadata "fallback" has been removed ------------------------------------- - -Certain keys in metadata like ``license`` used to "fallback" up the chain of ownership. -For example, if you set an ``MIT`` to a database and a table within that database did not have a specified license, -then that table would inherit an ``MIT`` license. - -This behavior has been removed in Datasette 1.0. Now license fields must be placed on all items, including individual databases and tables. - -The ``get_metadata()`` Plugin hook has been removed ---------------------------------------------------- - -As of Datasette ``1.0a14`` (2024-XX-XX), the ``get_metadata()`` hook has been deprecated. - -.. code-block:: python - - # ❌ DEPRECATED in Datasette 1.0 - @hookimpl - def get_metadata(datasette, key, database, table): - pass - -Instead, one should use the following methods on a Datasette class: - -- :ref:`get_instance_metadata() ` and :ref:`set_instance_metadata() ` -- :ref:`get_database_metadata() ` and :ref:`set_database_metadata() ` -- :ref:`get_resource_metadata() ` and :ref:`set_resource_metadata() ` -- :ref:`get_column_metadata() ` and :ref:`set_column_metadata() ` - -The ``/metadata.json`` endpoint has been removed ------------------------------------------------- - -As of Datasette `1.0a14`, the root level ``/metadata.json`` endpoint has been removed. - -The ``metadata()`` method on the Datasette class has been removed ------------------------------------------------------------------ - -As of Datasette ``1.0a14``, the ``.metadata()`` method on the Datasette Python API has been removed. - -Instead, one should use the following methods on a Datasette class: - - -- :ref:`get_instance_metadata() ` -- :ref:`get_database_metadata() ` -- :ref:`get_resource_metadata() ` -- :ref:`get_column_metadata() ` - - -New endpoint for SQL queries -============================ - -Previously, if you wanted to run SQL code using the Datasette HTTP API, you could call an endpoint that looked like: - -:: - - # DEPRECATED: Older endpoint for Datasette 0.XX - curl http://localhost:8001/_memory?sql=select+123 - -However, in Datasette 1.0, the endpoint was slightly changed to: - -:: - - # ✅ Datasette 1.0 and beyond - curl http://localhost:8001/_memory/-/query?sql=select+123 - -Specifically, now there's a ``/-/query`` "action" that should be used. - -**This isn't a breaking change.** API calls to the older ``/database?sql=...`` endpoint will redirect to the new ``database/-/query?sql=...`` endpoint. However, documentations and example will use the new query endpoint, so it is recommended to use that instead.