mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
upgrade-1.0a20.md, refs #2564
And another Markdown conversion, refs #2565
This commit is contained in:
parent
47e4060469
commit
1f8995e776
4 changed files with 225 additions and 130 deletions
4
Justfile
4
Justfile
|
|
@ -31,6 +31,10 @@ export DATASETTE_SECRET := "not_a_secret"
|
||||||
@docs: cog blacken-docs
|
@docs: cog blacken-docs
|
||||||
uv sync --extra docs && cd docs && uv run make livehtml
|
uv sync --extra docs && cd docs && uv run make livehtml
|
||||||
|
|
||||||
|
# Build docs as static HTML
|
||||||
|
@docs-build: cog blacken-docs
|
||||||
|
rm -rf docs/_build && cd docs && uv run make html
|
||||||
|
|
||||||
# Apply Black
|
# Apply Black
|
||||||
@black:
|
@black:
|
||||||
uv run black .
|
uv run black .
|
||||||
|
|
|
||||||
105
docs/upgrade-1.0a20.md
Normal file
105
docs/upgrade-1.0a20.md
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
---
|
||||||
|
orphan: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Datasette 1.0a20 plugin upgrade guide
|
||||||
|
|
||||||
|
<!-- START UPGRADE 1.0a20 -->
|
||||||
|
|
||||||
|
Datasette 1.0a20 makes some breaking changes to Datasette's permission system. Plugins need to be updated if they use any of the following:
|
||||||
|
|
||||||
|
- The `register_permissions()` plugin hook - this should be replaced with `register_actions`
|
||||||
|
- The `permission_allowed()` plugin hook - this should be upgraded to `permission_resources_sql()`.
|
||||||
|
- The `datasette.permission_allowed()` internal method - this should be replaced with `datasette.allowed()`
|
||||||
|
- Logic that grants access to the `"root"` actor can be removed.
|
||||||
|
|
||||||
|
## Permissions are now actions
|
||||||
|
|
||||||
|
The `register_permissions()` hook shoud be replaced with `register_actions()`.
|
||||||
|
|
||||||
|
Old code:
|
||||||
|
|
||||||
|
```python
|
||||||
|
@hookimpl
|
||||||
|
def register_permissions(datasette):
|
||||||
|
return [
|
||||||
|
Permission(
|
||||||
|
name="datasette-pins-write",
|
||||||
|
abbr=None,
|
||||||
|
description="Can pin, unpin, and re-order pins for datasette-pins",
|
||||||
|
takes_database=False,
|
||||||
|
takes_resource=False,
|
||||||
|
default=False,
|
||||||
|
),
|
||||||
|
Permission(
|
||||||
|
name="datasette-pins-read",
|
||||||
|
abbr=None,
|
||||||
|
description="Can read pinned items.",
|
||||||
|
takes_database=False,
|
||||||
|
takes_resource=False,
|
||||||
|
default=False,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
```
|
||||||
|
The new `Action` does not have a `default=` parameter, and `takes_database` and `takes_resource` have been renamed to `takes_parent` and `takes_child. The new code would look like this:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from datasette.permissions import Action
|
||||||
|
|
||||||
|
@hookimpl
|
||||||
|
def register_actions(datasette):
|
||||||
|
return [
|
||||||
|
Action(
|
||||||
|
name="datasette-pins-write",
|
||||||
|
abbr=None,
|
||||||
|
description="Can pin, unpin, and re-order pins for datasette-pins",
|
||||||
|
takes_parent=False,
|
||||||
|
takes_child=False,
|
||||||
|
default=False,
|
||||||
|
),
|
||||||
|
Action(
|
||||||
|
name="datasette-pins-read",
|
||||||
|
abbr=None,
|
||||||
|
description="Can read pinned items.",
|
||||||
|
takes_parent=False,
|
||||||
|
takes_child=False,
|
||||||
|
default=False,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## permission_allowed() hook is replaced by permission_resources_sql()
|
||||||
|
|
||||||
|
The following old code:
|
||||||
|
```python
|
||||||
|
@hookimpl
|
||||||
|
def permission_allowed(action):
|
||||||
|
if action == "permissions-debug":
|
||||||
|
return True
|
||||||
|
```
|
||||||
|
Can be replaced by:
|
||||||
|
```python
|
||||||
|
from datasette.permissions import PermissionSQL
|
||||||
|
|
||||||
|
@hookimpl
|
||||||
|
def permission_resources_sql(action):
|
||||||
|
return PermissionSQL.allow(reason="datasette-allow-permissions-debug")
|
||||||
|
```
|
||||||
|
A `.deny(reason="")` class method is also available.
|
||||||
|
|
||||||
|
For more complex permission checks consult the documentation for that plugin hook:
|
||||||
|
<https://docs.datasette.io/en/latest/plugin_hooks.html#permission-resources-sql-datasette-actor-action>
|
||||||
|
|
||||||
|
## Fixing async with httpx.AsyncClient(app=app)
|
||||||
|
|
||||||
|
Some older plugins may use the following pattern in their tests, which is no longer supported:
|
||||||
|
```python
|
||||||
|
app = Datasette([], memory=True).app()
|
||||||
|
async with httpx.AsyncClient(app=app) as client:
|
||||||
|
response = await client.get("http://localhost/path")
|
||||||
|
```
|
||||||
|
The new pattern is to use `ds.client` like this:
|
||||||
|
```python
|
||||||
|
ds = Datasette([], memory=True)
|
||||||
|
response = ds.client.get("/path")
|
||||||
|
```
|
||||||
|
|
@ -1,90 +1,76 @@
|
||||||
.. _upgrade_guide:
|
(upgrade_guide)=
|
||||||
|
# Upgrade guide
|
||||||
|
|
||||||
===============
|
(upgrade_guide_v1)=
|
||||||
Upgrade guide
|
## Datasette 0.X -> 1.0
|
||||||
===============
|
|
||||||
|
|
||||||
.. _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`.
|
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_sql_queries:
|
(upgrade_guide_v1_sql_queries)=
|
||||||
|
### New URL for SQL queries
|
||||||
New URL for SQL queries
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
Prior to ``1.0a14`` the URL for executing a SQL query looked like this:
|
Prior to ``1.0a14`` the URL for executing a SQL query looked like this:
|
||||||
|
|
||||||
::
|
```text
|
||||||
|
/databasename?sql=select+1
|
||||||
/databasename?sql=select+1
|
# Or for JSON:
|
||||||
# Or for JSON:
|
/databasename.json?sql=select+1
|
||||||
/databasename.json?sql=select+1
|
```
|
||||||
|
|
||||||
This endpoint served two purposes: without a ``?sql=`` it would list the tables in the database, but with that option it would return results of a query instead.
|
This endpoint served two purposes: without a ``?sql=`` it would list the tables in the database, but with that option it would return results of a query instead.
|
||||||
|
|
||||||
The URL for executing a SQL query now looks like this::
|
The URL for executing a SQL query now looks like this:
|
||||||
|
|
||||||
/databasename/-/query?sql=select+1
|
```text
|
||||||
# Or for JSON:
|
/databasename/-/query?sql=select+1
|
||||||
/databasename/-/query.json?sql=select+1
|
# Or for JSON:
|
||||||
|
/databasename/-/query.json?sql=select+1
|
||||||
|
```
|
||||||
|
|
||||||
**This isn't a breaking change.** API calls to the older ``/databasename?sql=...`` endpoint will redirect to the new ``databasename/-/query?sql=...`` endpoint. Upgrading to the new URL is recommended to avoid the overhead of the additional redirect.
|
**This isn't a breaking change.** API calls to the older ``/databasename?sql=...`` endpoint will redirect to the new ``databasename/-/query?sql=...`` endpoint. Upgrading to the new URL is recommended to avoid the overhead of the additional redirect.
|
||||||
|
|
||||||
.. _upgrade_guide_v1_metadata:
|
(upgrade_guide_v1_metadata)=
|
||||||
|
### Metadata changes
|
||||||
|
|
||||||
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.
|
||||||
----------------
|
|
||||||
|
|
||||||
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``
|
||||||
|
|
||||||
.. _upgrade_guide_v1_metadata_split:
|
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 metadata (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`.
|
||||||
|
|
||||||
``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:
|
To start Datasette with both metadata and configuration files, run it like this:
|
||||||
|
|
||||||
.. code-block:: bash
|
```bash
|
||||||
|
datasette --metadata metadata.yaml --config datasette.yaml
|
||||||
|
# Or the shortened version:
|
||||||
|
datasette -m metadata.yml -c datasette.yml
|
||||||
|
```
|
||||||
|
|
||||||
datasette --metadata metadata.yaml --config datasette.yaml
|
(upgrade_guide_v1_metadata_upgrade)=
|
||||||
# Or the shortened version:
|
#### Upgrading an existing ``metadata.yaml`` file
|
||||||
datasette -m metadata.yml -c datasette.yml
|
|
||||||
|
|
||||||
.. _upgrade_guide_v1_metadata_upgrade:
|
The [datasette-upgrade plugin](https://github.com/datasette/datasette-upgrade) 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:
|
||||||
|
|
||||||
Upgrading an existing ``metadata.yaml`` file
|
```bash
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
datasette install datasette-upgrade
|
||||||
|
```
|
||||||
The `datasette-upgrade plugin <https://github.com/datasette/datasette-upgrade>`__ 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:
|
Then run it like this to produce the two new files:
|
||||||
|
|
||||||
.. code-block:: bash
|
```bash
|
||||||
|
datasette upgrade metadata-to-config metadata.json -m metadata.yml -c datasette.yml
|
||||||
|
```
|
||||||
|
|
||||||
datasette upgrade metadata-to-config metadata.json -m metadata.yml -c datasette.yml
|
#### Metadata "fallback" has been removed
|
||||||
|
|
||||||
Metadata "fallback" has been removed
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Certain keys in metadata like ``license`` used to "fallback" up the chain of ownership.
|
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.
|
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.
|
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:
|
(upgrade_guide_v1_metadata_removed)=
|
||||||
|
#### The ``get_metadata()`` plugin hook has been 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.
|
In Datasette ``0.x`` plugins could implement a ``get_metadata()`` plugin hook to customize how metadata was retrieved for different instances, databases and tables.
|
||||||
|
|
||||||
|
|
@ -92,33 +78,29 @@ This hook could be inefficient, since some pages might load metadata for many di
|
||||||
|
|
||||||
As of Datasette ``1.0a14`` (2024-08-05), the ``get_metadata()`` hook has been deprecated:
|
As of Datasette ``1.0a14`` (2024-08-05), the ``get_metadata()`` hook has been deprecated:
|
||||||
|
|
||||||
.. code-block:: python
|
```python
|
||||||
|
# ❌ DEPRECATED in Datasette 1.0
|
||||||
# ❌ DEPRECATED in Datasette 1.0
|
@hookimpl
|
||||||
@hookimpl
|
def get_metadata(datasette, key, database, table):
|
||||||
def get_metadata(datasette, key, database, table):
|
pass
|
||||||
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`:
|
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() <datasette_get_instance_metadata>` and :ref:`set_instance_metadata() <datasette_set_instance_metadata>`
|
- :ref:`get_instance_metadata() <datasette_get_instance_metadata>` and :ref:`set_instance_metadata() <datasette_set_instance_metadata>`
|
||||||
- :ref:`get_database_metadata() <datasette_get_database_metadata>` and :ref:`set_database_metadata() <datasette_set_database_metadata>`
|
- :ref:`get_database_metadata() <datasette_get_database_metadata>` and :ref:`set_database_metadata() <datasette_set_database_metadata>`
|
||||||
- :ref:`get_resource_metadata() <datasette_get_resource_metadata>` and :ref:`set_resource_metadata() <datasette_set_resource_metadata>`
|
- :ref:`get_resource_metadata() <datasette_get_resource_metadata>` and :ref:`set_resource_metadata() <datasette_set_resource_metadata>`
|
||||||
- :ref:`get_column_metadata() <datasette_get_column_metadata>` and :ref:`set_column_metadata() <datasette_set_column_metadata>`
|
- :ref:`get_column_metadata() <datasette_get_column_metadata>` and :ref:`set_column_metadata() <datasette_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.
|
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.
|
||||||
|
|
||||||
.. _upgrade_guide_v1_metadata_json_removed:
|
(upgrade_guide_v1_metadata_json_removed)=
|
||||||
|
#### The ``/metadata.json`` endpoint has been removed
|
||||||
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.
|
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.
|
||||||
|
|
||||||
.. _upgrade_guide_v1_metadata_method_removed:
|
(upgrade_guide_v1_metadata_method_removed)=
|
||||||
|
#### The ``metadata()`` method on the Datasette class 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.
|
As of Datasette ``1.0a14``, the ``.metadata()`` method on the Datasette Python API has been removed.
|
||||||
|
|
||||||
|
|
@ -128,3 +110,7 @@ Instead, one should use the following methods on a Datasette class:
|
||||||
- :ref:`get_database_metadata() <datasette_get_database_metadata>`
|
- :ref:`get_database_metadata() <datasette_get_database_metadata>`
|
||||||
- :ref:`get_resource_metadata() <datasette_get_resource_metadata>`
|
- :ref:`get_resource_metadata() <datasette_get_resource_metadata>`
|
||||||
- :ref:`get_column_metadata() <datasette_get_column_metadata>`
|
- :ref:`get_column_metadata() <datasette_get_column_metadata>`
|
||||||
|
|
||||||
|
```{include} upgrade-1.0a20.md
|
||||||
|
:heading-offset: 1
|
||||||
|
```
|
||||||
Loading…
Add table
Add a link
Reference in a new issue