{"id": "plugin_hooks:plugin-asgi-wrapper", "page": "plugin_hooks", "ref": "plugin-asgi-wrapper", "title": "asgi_wrapper(datasette)", "content": "Return an ASGI middleware wrapper function that will be applied to the Datasette ASGI application. \n This is a very powerful hook. You can use it to manipulate the entire Datasette response, or even to configure new URL routes that will be handled by your own custom code. \n You can write your ASGI code directly against the low-level specification, or you can use the middleware utilities provided by an ASGI framework such as Starlette . \n This example plugin adds a x-databases HTTP header listing the currently attached databases: \n from datasette import hookimpl\nfrom functools import wraps\n\n\n@hookimpl\ndef asgi_wrapper(datasette):\n def wrap_with_databases_header(app):\n @wraps(app)\n async def add_x_databases_header(\n scope, receive, send\n ):\n async def wrapped_send(event):\n if event[\"type\"] == \"http.response.start\":\n original_headers = (\n event.get(\"headers\") or []\n )\n event = {\n \"type\": event[\"type\"],\n \"status\": event[\"status\"],\n \"headers\": original_headers\n + [\n [\n b\"x-databases\",\n \", \".join(\n datasette.databases.keys()\n ).encode(\"utf-8\"),\n ]\n ],\n }\n await send(event)\n\n await app(scope, receive, wrapped_send)\n\n return add_x_databases_header\n\n return wrap_with_databases_header \n Examples: datasette-cors , datasette-pyinstrument , datasette-total-page-time", "breadcrumbs": "[\"Plugin hooks\"]", "references": "[{\"href\": \"https://asgi.readthedocs.io/\", \"label\": \"ASGI\"}, {\"href\": \"https://www.starlette.io/middleware/\", \"label\": \"Starlette\"}, {\"href\": \"https://datasette.io/plugins/datasette-cors\", \"label\": \"datasette-cors\"}, {\"href\": \"https://datasette.io/plugins/datasette-pyinstrument\", \"label\": \"datasette-pyinstrument\"}, {\"href\": \"https://datasette.io/plugins/datasette-total-page-time\", \"label\": \"datasette-total-page-time\"}]"}