Simon Willison’s Weblog

Subscribe

TILs

Filters: Sorted by date

TIL Escaping a SQL query to use with curl and Datasette — I used this pattern to pass a SQL query to Datasette's CSV export via curl and output the results, stripping off the first row (the header row) using `tail -n +2`.
TIL Controlling the style of dumped YAML using PyYAML — I had a list of Python dictionaries I wanted to output as YAML, but I wanted to control the style of the output.
TIL Using custom Sphinx templates on Read the Docs — I wanted to make a small customization to one of my documentation templates on Read the Docs.
TIL Running Python code in a subprocess with a time limit — I figured out how to run a subprocess with a time limit for [datasette-ripgrep](https://github.com/simonw/datasette-ripgrep), using the `asyncio.create_subprocess_exec()` method. The pattern looks like this:
TIL Redirects for Datasette — I made some changes to my https://til.simonwillison.net/ site that resulted in cleaner URL designs, so I needed to setup some redirects. I configured the redirects using a one-off Datasette plugin called `redirects.py` which I dropped into the `plugins/` directory for the Datasette instance:
TIL Dropdown menu with details summary — I added dropdown menus to [Datasette 0.51](https://docs.datasette.io/en/stable/changelog.html#v0-51) - see [#1064](https://github.com/simonw/datasette/issues/1064).
TIL Decorators with optional arguments — [sqlite-utils](https://sqlite-utils.datasette.io/) provides [a decorator](https://sqlite-utils.datasette.io/en/stable/python-api.html#registering-custom-sql-functions) for registering custom Python functions that looks like this:
TIL Writing JavaScript that responds to media queries — I wanted to change the layout of [my blog](https://simonwillison.net/) on mobile screens such that the content from the "Elsewhere" right hand column combined with the main column in the correct order (issue [#165](https://github.com/simonw/simonwillisonblog/issues/165)). I couldn't find a way to do this in pure CSS without duplicating a bunch of content, so I decided to do it with JavaScript.
TIL Explicit file encodings using click.File — I wanted to add a `--encoding` option to `sqlite-utils insert` which could be used to change the file encoding used to read the incoming CSV or TSV file - see [sqlite-utils #182](https://github.com/simonw/sqlite-utils/issues/182).
TIL Upgrading Python Homebrew packages using pip — [VisiData 2.0](https://www.visidata.org/) came out today. I previously installed VisiData using Homebrew, but the VisiData tap has not yet been updated with the latest version.
TIL Searching for repositories by topic using the GitHub GraphQL API — I wanted to use the GitHub GraphQL API to return all of the repositories on the https://github.com/topics/git-scraping page.
TIL Running Datasette on DigitalOcean App Platform — [App Platform](https://www.digitalocean.com/docs/app-platform/) is the new PaaS from DigitalOcean. I figured out how to run Datasette on it.
TIL Manipulating query strings with URLSearchParams — The `URLSearchParams` class, in [every modern browser](https://caniuse.com/?search=URLSearchParams) since IE 11, provides a sensible API for manipulating query string parameters in JavaScript. I first used it to build Datasette's column action menu, see [table.js](https://github.com/simonw/datasette/blob/0.50a0/datasette/static/table.js) and [issue 981](https://github.com/simonw/datasette/issues/981).
TIL Using async/await in JavaScript in Selenium — Thanks [Stuart Langridge](https://twitter.com/sil/status/1312137808111304704) for showing me how to do this:
TIL Installing Selenium for Python on macOS with ChromeDriver — I needed to run Selenium on macOS for the first time today. Here's how I got it working.
TIL Escaping strings in Bash using !:q — TIL this trick, [via Pascal Hirsch](https://twitter.com/phphys/status/1311727268398465029) on Twitter. Enter a line of Bash starting with a `#` comment, then run `!:q` on the next line to see what that would be with proper Bash escaping applied.
TIL Figuring out if a text value in SQLite is a valid integer or float — Given a table with a `TEXT` column in SQLite I want to figure out if every value in that table is actually the text representation of an integer or floating point value, so I can decide if it's a good idea to change the type of the column (using [sqlite-utils transform](https://sqlite-utils.datasette.io/en/stable/python-api.html#transforming-a-table)).
TIL Understanding option names in Click — I hit [a bug today](https://github.com/simonw/datasette/issues/973) where I had defined a Click option called `open` but in doing so I replaced the Python bulit-in `open()` function:
TIL Compiling the SQLite spellfix.c module on macOS — I wanted to browse a backup copy of my Plex database, which is a SQLite file. I tried this:
TIL Turning on Jinja autoescaping when using Template() directly — Jinja autoescaping is turned off by default. Coming from Django this frequently catches me out.
TIL Talking to a PostgreSQL service container from inside a Docker container — I have a Django application which uses PostgreSQL. I build the Django application into its own Docker container, push that built container to the GitHub package registery and then deploy that container to production.
TIL Open a debugging shell in GitHub Actions with tmate — > :warning: **17 Feb 2022: There have been reports of running tmate causing account suspensions**. See [this issue](https://github.com/mxschmitt/action-tmate/issues/104) for details. Continue with caution.
TIL Basic strace to see what a process is doing — I had a long-running process and I wanted to check that it was at least doing _something_.
TIL Display EC2 instance costs per month — The [EC2 pricing page](https://aws.amazon.com/ec2/pricing/on-demand/) shows cost per hour, which is pretty much useless. I want cost per month. The following JavaScript, pasted into the browser developer console, modifies the page to show cost-per-month instead.
TIL Very basic tsc usage — I guess I [have to learn TypeScript](https://twitter.com/simonw/status/1302517496767938561) now.
TIL Debugging a Click application using pdb — This tip is for when you are working on a Python command-line application that runs using that program's name, as opposed to typing `python my_script.py`. I usually need this when I'm working on applications built using [Click](https://click.palletsprojects.com/), e.g. projects I start using my [click-app](https://github.com/simonw/click-app) cookiecutter template.
TIL Using the gcloud run services list command — The `gcloud run services list` command lists your services running on Google Cloud Run:
TIL Looping over comma-separated values in Bash — Given a file (or a process) that produces comma separated values, here's how to split those into separate variables and use them in a bash script.
TIL Start a server in a subprocess during a pytest session — I wanted to start an actual server process, run it for the duration of my pytest session and shut it down at the end.
TIL Minifying JavaScript with npx uglify-js — While [upgrading CodeMirror](https://github.com/simonw/datasette/issues/948) in Datasette I figured out how to minify JavaScript using `uglify-js` on the command line without first installing any teels, using [npx](https://www.npmjs.com/package/npx) (which downloads and executes a CLI tool while skipping the install step):

Years