Simon Willison’s Weblog

Weeknotes: datasette-ephemeral-tables, datasette-export

Most of what I’ve been working on for the past week and a half is already documented:

I also released two new Datasette plugins—one of them to support the Datasette 1.0 alpha release, and another which is still shaping up.


For the Datasette 1.0 alpha I wanted a way for people to try out the new write API, without having to install Datasette themselves.

But I didn’t want to commit to running a public writable demo that anyone could use for the long-term.

I decided to solve this using a new plugin. I built datasette-ephemeral-tables, which creates an in-memory SQLite database with tables that are automatically dropped fifteen minutes after they are created.

It’s a pretty fun little plugin. The source code is here—it works by running a task every 2 seconds which scans the ephemeral database for new tables and adds their creation time to a dictionary, then drops any that were created more than X minutes ago.

It also adds a UI element to the table page using JavaScript, which shows a prominent countdown timer to warn you that the table is not long for this world:

Screenshot of the table page, with a message that says This table expires in 5s which ticks down until it reads This table has expired.

I then built the demo on top of a new ephemeral table hosted by the demo instance.

Getting that demo to work involved figuring out CORS for the write API, a very useful new ability which I shipped in the Datasette 1.0a1 alpha release.


The datasette-export plugin is still in early alpha. The idea is to turn Datasette into a static site generator tool, by providing a CLI that can export multiple pages from a Datasette instance directly to static files on disk.

Here’s an example of it in action:

datasette export . \
  --path / \
  --path /plugins \
  --sql "select '/plugins/' || name from content.plugins" \

This would run against database files, templates and plugins files in the current directory (the . argument) and exports the / page and the /plugins page, then uses a SQL query to specify a list of additional pages and exports those too.

The --crossdb option is necessary because this example project (the site) has more than one database, and using that option lets you select ... from content.plugins to specify a particular database.

Plenty more details on what works and what’s coming next for that project in that repository’s issues.

Releases this week

TIL this week