kopia lustrzana https://github.com/simonw/datasette
Made register_output_renderer callback optionally awaitable, closes #776
rodzic
52c4387c7d
commit
57f48b8416
|
@ -403,6 +403,8 @@ class DataView(BaseView):
|
||||||
args=request.args,
|
args=request.args,
|
||||||
data=data,
|
data=data,
|
||||||
)
|
)
|
||||||
|
if asyncio.iscoroutine(result):
|
||||||
|
result = await result
|
||||||
if result is None:
|
if result is None:
|
||||||
raise NotFound("No data")
|
raise NotFound("No data")
|
||||||
|
|
||||||
|
|
|
@ -736,7 +736,7 @@ register_output_renderer(datasette)
|
||||||
``datasette`` - :ref:`internals_datasette`
|
``datasette`` - :ref:`internals_datasette`
|
||||||
You can use this to access plugin configuration options via ``datasette.plugin_config(your_plugin_name)``
|
You can use this to access plugin configuration options via ``datasette.plugin_config(your_plugin_name)``
|
||||||
|
|
||||||
Allows the plugin to register a new output renderer, to output data in a custom format. The hook function should return a dictionary, or a list of dictionaries, which contain the file extension you want to handle and a callback function:
|
Registers a new output renderer, to output data in a custom format. The hook function should return a dictionary, or a list of dictionaries, of the following shape:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
@ -747,7 +747,11 @@ Allows the plugin to register a new output renderer, to output data in a custom
|
||||||
"render": render_test
|
"render": render_test
|
||||||
}
|
}
|
||||||
|
|
||||||
This will register ``render_test`` to be called when paths with the extension ``.test`` (for example ``/database.test``, ``/database/table.test``, or ``/database/table/row.test``) are requested. When a request is received, the callback function is called with zero or more of the following arguments. Datasette will inspect your callback function and pass arguments that match its function signature.
|
This will register ``render_test`` to be called when paths with the extension ``.test`` (for example ``/database.test``, ``/database/table.test``, or ``/database/table/row.test``) are requested.
|
||||||
|
|
||||||
|
``render_test`` is a Python function. It can be a regular function or an ``async def render_test()`` awaitable function, depending on if it needs to make any asynchronous calls.
|
||||||
|
|
||||||
|
When a request is received, the callback function is called with zero or more of the following arguments. Datasette will inspect your callback function and pass arguments that match its function signature.
|
||||||
|
|
||||||
``datasette`` - :ref:`internals_datasette`
|
``datasette`` - :ref:`internals_datasette`
|
||||||
For accessing plugin configuration and executing queries.
|
For accessing plugin configuration and executing queries.
|
||||||
|
@ -803,16 +807,18 @@ Here is a more complex example:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def render_test(columns, rows):
|
async def render_test(datasette, columns, rows):
|
||||||
|
db = next(iter(datasette.databases.values()))
|
||||||
|
result = await db.execute("select sqlite_version()")
|
||||||
first_row = " | ".join(columns)
|
first_row = " | ".join(columns)
|
||||||
lines = [first_row]
|
lines = [first_row]
|
||||||
lines.append("=" * len(first_row))
|
lines.append("=" * len(first_row))
|
||||||
for row in rows:
|
for row in rows:
|
||||||
lines.append(" | ".join(row))
|
lines.append(" | ".join(row))
|
||||||
return {
|
return {
|
||||||
"body": "Hello World",
|
"body": "\n".join(lines),
|
||||||
"content_type": "text/plain; charset=utf-8",
|
"content_type": "text/plain; charset=utf-8",
|
||||||
"headers": {"x-pipes": "yay-pipes"}
|
"headers": {"x-sqlite-version": result.first()[0]},
|
||||||
}
|
}
|
||||||
|
|
||||||
Examples: `datasette-atom <https://github.com/simonw/datasette-atom>`_, `datasette-ics <https://github.com/simonw/datasette-ics>`_
|
Examples: `datasette-atom <https://github.com/simonw/datasette-atom>`_, `datasette-ics <https://github.com/simonw/datasette-ics>`_
|
||||||
|
|
|
@ -2,13 +2,14 @@ from datasette import hookimpl
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
def render_test_all_parameters(
|
async def render_test_all_parameters(
|
||||||
datasette, columns, rows, sql, query_name, database, table, request, view_name, data
|
datasette, columns, rows, sql, query_name, database, table, request, view_name, data
|
||||||
):
|
):
|
||||||
headers = {}
|
headers = {}
|
||||||
for custom_header in request.args.getlist("header") or []:
|
for custom_header in request.args.getlist("header") or []:
|
||||||
key, value = custom_header.split(":")
|
key, value = custom_header.split(":")
|
||||||
headers[key] = value
|
headers[key] = value
|
||||||
|
result = await datasette.databases["fixtures"].execute("select 1 + 1")
|
||||||
return {
|
return {
|
||||||
"body": json.dumps(
|
"body": json.dumps(
|
||||||
{
|
{
|
||||||
|
@ -21,6 +22,7 @@ def render_test_all_parameters(
|
||||||
"table": table,
|
"table": table,
|
||||||
"request": request,
|
"request": request,
|
||||||
"view_name": view_name,
|
"view_name": view_name,
|
||||||
|
"1+1": result.first()[0],
|
||||||
},
|
},
|
||||||
default=repr,
|
default=repr,
|
||||||
),
|
),
|
||||||
|
|
|
@ -347,6 +347,7 @@ def test_register_output_renderer_all_parameters(app_client):
|
||||||
body = response.body.decode("utf-8")
|
body = response.body.decode("utf-8")
|
||||||
body = at_memory_re.sub(" at 0xXXX", body)
|
body = at_memory_re.sub(" at 0xXXX", body)
|
||||||
assert {
|
assert {
|
||||||
|
"1+1": 2,
|
||||||
"datasette": "<datasette.app.Datasette object at 0xXXX>",
|
"datasette": "<datasette.app.Datasette object at 0xXXX>",
|
||||||
"columns": [
|
"columns": [
|
||||||
"pk",
|
"pk",
|
||||||
|
|
Ładowanie…
Reference in New Issue