Adding a Datasette ASGI app to Django#
Datasette is implemented as an ASGI application.
Django can be run and deployed using ASGI.
At the DjangoCon Sprints this morning I figured out how to run Datasette inside a Django application, talking to the same SQLite databases as Django itself.
Installing Datasette#
Run this in the same environment as your Django application (or add it to requirements.txt
or similar):
1pip install datasette
Adding it to asgi.py#
Django projects have an asgi.py
module automatically generated for them when the project is created.
Replace its content with the following (careful to replace my_django_application.settings
with the correct value):
1from datasette.app import Datasette2from django.core.asgi import get_asgi_application3from django.db import connections4import os5
6os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_django_application.settings")7
8
9datasette_application = Datasette(10 [11 str(db["NAME"])12 for db in connections.databases.values()13 if db["ENGINE"] == "django.db.backends.sqlite3"14 ],15 settings={16 "base_url": "/datasette/",17 },18).app()19django_application = get_asgi_application()20
21
22async def application(scope, receive, send):23 if scope["type"] == "http" and scope.get("path").startswith("/datasette/"):24 await datasette_application(scope, receive, send)25 else:26 await django_application(scope, receive, send)
Prior to this change, the file contained application = get_asgi_application()
. application
is the ASGI application that will be served.
This code replaces that with a tiny ASGI app that looks at the incoming scope["path"]
and, if it starts with /datasette/
, sends it to the Datasette ASGI application. All other requests are sent to Django.
The Datasette()
constructor at the start finds all SQLite databases that have been configured for Django, extracts their file path (db["NAME"]
is a path object for SQLite databases) and passes that to the Datasette constructor.
It also sets base_url
to /datasette/
so that Datasette will know how to generate correct URLs when it is mounted at that path, as opposed to the root /
path of the server.
Running it with Uvicorn#
Since this is an ASGI app, running ./manage.py runserver
will no longer do the right thing.
Instead, you need to install and use an ASGI server to run Django.
I like Uvicorn for this.
Install it with pip install uvicorn
, then start a local Django server running with:
1uvicorn my_django_application.asgi:application
Add --reload
to cause it to automatically reload any time a file on disk is changed:
1uvicorn my_django_application.asgi:application --reload
Using Datasette#
With this in place, browsing to http://127.0.0.1:8000/datasette/
will provide a Datasette interface for running read-only queries against your Django SQLite databases.