Simon Willison’s Weblog

Subscribe

April 2022

59 posts: 5 entries, 15 links, 39 beats

April 19, 2022

Netlify Edge Functions: A new serverless runtime powered by Deno. You can now run Deno scripts directly in Netlify’s edge CDN—bundled as part of their default pricing plan. Interesting that they decided to host it on Deno’s Deno Deploy infrastructure. The hello world example is pleasingly succinct:

export default () => new Response(“Hello world”)

# 4:46 pm / serverless, deno

Glue code to quickly copy data from one Postgres table to another (via) The Python script that Retool used to migrate 4TB of data between two PostgreSQL databases. I find the structure of this script really interesting—it uses Python to spin up a queue full of ID ranges to be transferred and then starts some threads, but then each thread shells out to a command that runs “psql COPY (SELECT ...) TO STDOUT” and pipes the result to “psql COPY xxx FROM STDIN”. Clearly this works really well (“saturate the database’s hardware capacity” according to a comment on HN), and neatly sidesteps any issues with Python’s GIL.

# 4:57 pm / postgresql, python

April 20, 2022

Release django-sql-dashboard 1.1 — Django app for building dashboards using raw SQL queries

April 21, 2022

Web Components as Progressive Enhancement (via) I think this is a key aspect of Web Components I had been missing: since they default to rendering their contents, you can use them as a wrapper around regular HTML elements that can then be progressively enhanced once the JavaScript has loaded.

# 9:33 pm / web-components

April 22, 2022

Release asyncinject 0.5 — Run async workflows using pytest-fixtures-style dependency injection

April 24, 2022

Useful tricks with pip install URL and GitHub

Visit Useful tricks with pip install URL and GitHub

The pip install command can accept a URL to a zip file or tarball. GitHub provides URLs that can create a zip file of any branch, tag or commit in any repository. Combining these is a really useful trick for maintaining Python packages.

[... 929 words]

TIL Format code examples in documentation with blacken-docs — I decided to enforce that all code examples in the [Datasette documentation](https://docs.datasette.io/) be formatted using [Black](https://github.com/psf/black). Here's [issue 1718](https://github.com/simonw/datasette/issues/1718) where I researched the options for doing this.

WebAIM guide to using iOS VoiceOver to evaluate web accessibility (via) I asked for pointers on learning to use VoiceOver on my iPhone for accessibility testing today and Matt Hobbs pointed me to this tutorial from the WebAIM group at Utah State University.

# 7:35 pm / accessibility, screen-readers, ios

April 26, 2022

A tiny CI system (via) Christian Ştefănescu shares a recipe for building a tiny self-hosted CI system using Git and Redis. A post-receive hook runs when a commit is pushed to the repo and uses redis-cli to push jobs to a list. Then a separate bash script runs a loop with a blocking “redis-cli blpop jobs” operation which waits for new jobs and then executes the CI job as a shell script.

# 3:39 pm / bash, continuous-integration, git, redis

TIL Seeing files opened by a process using opensnoop — I decided to try out [atuin](https://github.com/ellie/atuin?utm_source=tldrnewsletter), a shell extension that writes your history to a SQLite database.
TIL Atuin for zsh shell history in SQLite — [Atuin](https://github.com/ellie/atuin) (via [Rhet Turnbull](https://twitter.com/RhetTurnbull/status/1518942324004319232)) "replaces your existing shell history with a SQLite database". Obviously I had to try this out!

jq language description (via) I love jq but I’ve always found it difficult to remember how to use it, and the manual hasn’t helped me as much as I would hope. It turns out the jq wiki on GitHub offers an alternative, more detailed description of the language which fits the way my brain works a lot better.

# 7:04 pm / documentation, programming-languages, jq

Learn Go with tests. I really like this approach to learning a new language: start by learning to write tests (which gets you through hello world, environment setup and test running right from the beginning) and use them to explore the language. I also really like how modern Go development no longer depends on the GOPATH, which I always found really confusing.

# 7:12 pm / go

Mac OS 8 emulated in WebAssembly (via) Absolutely incredible project by Mihai Parparita. This is a full, working copy of Mac OS 8 (from 1997) running in your browser via WebAssembly—and it’s fully loaded with games and applications too. I played with Photoshop 3.0 and Civilization and there’s so much more on there to explore too—I finally get to try out HyperCard!

# 7:16 pm / computer-history, mac, mihai-parparita, webassembly

HTML event handler attributes: down the rabbit hole (via) onclick="myfunction(event)" is an idiom for passing the click event to a function - but how does it work? It turns out the answer is buried deep in the HTML spec - the browser wraps that string of code in a function(event) { ... that string ... } function and makes the event available to its local scope that way.

# 8:35 pm / dom-scripting, html, javascript

Release datasette-total-page-time 0.1 — Add a note to the Datasette footer measuring the total page load time

April 27, 2022

Release datasette-gzip 0.1 — Add gzip compression to Datasette

Weeknotes: Parallel SQL queries for Datasette, plus some middleware tricks

Visit Weeknotes: Parallel SQL queries for Datasette, plus some middleware tricks

A promising new performance optimization for Datasette, plus new datasette-gzip and datasette-total-page-time plugins.

[... 1,534 words]

April 28, 2022

Release asgi-gzip 0.1 — gzip middleware for ASGI applications, extracted from Starlette
Release datasette-gzip 0.2 — Add gzip compression to Datasette

Automatically opening issues when tracked file content changes

Visit Automatically opening issues when tracked file content changes

I figured out a GitHub Actions pattern to keep track of a file published somewhere on the internet and automatically open a new repository issue any time the contents of that file changes.

[... 1,211 words]

Release datasette-copy-to-memory 0.1a0 — Copy database files into an in-memory database on startup
Release datasette-copy-to-memory 0.1a1 — Copy database files into an in-memory database on startup
Release datasette-copy-to-memory 0.1a2 — Copy database files into an in-memory database on startup
Release datasette-copy-to-memory 0.1a3 — Copy database files into an in-memory database on startup

April 29, 2022

Testing Datasette parallel SQL queries in the nogil/python fork. As part of my ongoing research into whether Datasette can be sped up by running SQL queries in parallel I’ve been growing increasingly suspicious that the GIL is holding me back. I know the sqlite3 module releases the GIL and was hoping that would give me parallel queries, but it looks like there’s still a ton of work going on in Python GIL land creating Python objects representing the results of the query.

Sam Gross has been working on a nogil fork of Python and I decided to give it a go. It’s published as a Docker image and it turns out trying it out really did just take a few commands... and it produced the desired results, my parallel code started beating my serial code where previously the two had produced effectively the same performance numbers.

I’m pretty stunned by this. I had no idea how far along the nogil fork was. It’s amazing to see it in action.

# 5:45 am / gil, python, docker

April 30, 2022

Release datasette-copy-to-memory 0.2 — Copy database files into an in-memory database on startup

PyScript demos (via) PyScript was announced at PyCon this morning. It’s a new open source project that provides Web Components built on top of Pyodide, allowing you to use Python directly within your HTML pages in a way that is executed using a WebAssembly copy of Python running in your browser. These demos really help illustrate what it can do—it’s a fascinating new piece of the Python web ecosystem.

# 9:50 pm / python, web-components, webassembly, pyodide

TIL Intercepting fetch in a service worker — I'm learning service workers. I wanted to start with one that intercepts calls to a `/path` and returns "Hello World".

2022 » April

MTWTFSS
    123
45678910
11121314151617
18192021222324
252627282930