Ephes Blog

Miscellaneous things. Not sure what to put here, yet.

Weeknotes 2023-09-18

, Jochen

At work I used htmx and Alpine.js again and I think this is a really powerful combination. I hope the view transition api, which is currently only implemented in Chrome, will be available in other browsers soon. I also did some thinking about how to display PDFs on web pages using PDF.js.

For my personal site, I had to fix the image rendition deletion incident from last week, and I thought a bit about wagtail_srcset and new image formats like AVIF. Maybe I should keep it simple and assume that all devices are now high pixel density devices and always use images that are three times the logical pixel size, and then use AVIF as the file format? I don't know yet.

And since Postgres 16 was released, I upgraded all my stuff to the new version and wrote a TIL post about it. And I also did some non-computer related activities this week: I participated in the local #klimastreik and moved a lot of furniture (whatever it takes to do that all day - I don't have it and like to take a bath in Voltaren now).



Mastodon / Twitter


Upgrading Postgres

, Jochen

I am mainly writing this article to remember how to do this next time 😅 (it is 14 or 15 to 16 here, but it should also work with newer versions too). This writeup is for Debian / Ubuntu and is based on this article I found as the first search result on how to upgrade postgres. First, make sure that the packages on your system are up to date and that you have the version of postgres you want to upgrade installed (usually running on port 5433).

apt-get update
apt dist-upgrade

# Show installed postgres versions
apt list --installed | rg postgresql

Apply any configuration changes you made to the running version to the version you want to upgrade. Then you can stop your running postgres version and run pg_upgrade.

systemctl stop postgresql.service
su - postgres

# Check if clusters are compatible
/usr/lib/postgresql/16/bin/pg_upgrade \
  --old-datadir=/var/lib/postgresql/15/main \
  --new-datadir=/var/lib/postgresql/16/main \
  --old-bindir=/usr/lib/postgresql/15/bin \
  --new-bindir=/usr/lib/postgresql/16/bin \
  --old-options '-c config_file=/etc/postgresql/15/main/postgresql.conf' \
  --new-options '-c config_file=/etc/postgresql/16/main/postgresql.conf' \

# Run without --check to upgrade your cluster

Swap the ports of the old and new versions and restart the postgres service.

# change "port = 5434" to "port = 5432"
vim /etc/postgresql/16/main/postgresql.conf

# change "port = 5432" to "port = 5433"
vim /etc/postgresql/15/main/postgresql.conf

systemctl start postgresql.service

Make sure you are running the new postgres version.

su - postgres
psql -c "SELECT version();"

Remove the old Postgres Version

apt-get remove postgresql-15 postgresql-server-dev-15
rm -rf /etc/postgresql/15/
su - postgres

Postgres on a Mac with Homebrew

I use Macs running Homebrew for development. And I like to keep my postgres databases in the project repository to make it easy to remove the database by just deleting a directory. And to start the right database along with all the other needed services using a Procfile. Upgrading postgres there works the same way. First install the postgres version you want to upgrade to and create a new data directory.

brew install postgresql@16
/opt/homebrew/Cellar/postgresql@16/16.0/bin/initdb -D databases/postgres_new

Then upgrade the database with pg_upgrade and remove the old data directory.

/opt/homebrew/Cellar/postgresql@16/16.0/bin/pg_upgrade \
 --old-datadir databases/postgres \
--new-datadir databases/postgres_new \
--old-bindir /opt/homebrew/Cellar/postgresql@14/14.9/bin \
--new-bindir /opt/homebrew/Cellar/postgresql@16/16.0/bin \

# run pg_upgrade without --check to actually upgrade the database

rm -r databases/postgres
mv databases/postgres_new databases/postgres

Weeknotes 2023-09-11

, Jochen
It was the best of times. It was the worst of terms and conditions. --Nein

At work, setting up Single Sign-On (SSO) via Azure AD for a Django project was easier than expected, thanks to django-saml2-auth. I also found that ChatGPT was surprisingly effective at generating code to create a simplified Excel file, which I then could use to test the effectiveness of the existing pandas code for Excel parsing.

Doing open source, I fixed a bug in the theme-selector feature of django-cast. The bug occurred because Django handles the HTML rendering for SPA-themes and exposes it via a JSON API. I chose this method to avoid rendering a Wagtail streamfield in JavaScript. However, it used the theme from the database instead of the session template, which broke the Vue.js theme. After addressing this, I updated django-stubs and fixed a minor issue that made mypy pass again. I also improved the documentation for the themes feature. While reviewing the request-handling code, I found a simpler method using APIField and wrote a 'Today I Learned' (TIL) post about it. And finally, I broke most of the images on my site by accidentally deleting all the Wagtail renditions. Well, something to do for next week.




Mastodon / Twitter



How to Pass a Request Object from Wagtail API to a Page

, Jochen


When using Wagtail's API to fetch website pages, the APIField class allows you to add custom fields. But what if you also need to incorporate the request object into your custom field?

Why the Request Object is Important

I ran into this issue because I wanted to fetch the fully-rendered HTML of a page via the Wagtail API, eliminating the need to manually render the StreamField in my Vue.js blog theme.

Code Example

To achieve this, use the APIField class as demonstrated in the code snippet below:

from wagtail.models import Page
from wagtail.api import APIField

from rest_framework.fields import Field

class HtmlField(Field):
    def to_representation(self, page):
        return page.serve(self.context["request"])

class Post(Page):
    api_fields = [
        APIField("html", serializer=HtmlField(source="*")),

Understanding the source="*" Parameter

The `source="*"` parameter is special: it enables the `to_representation` method to work with the entire page object, rather than just a specific field on that page.

Weeknotes 2023-09-04

, Jochen
UIs are big, messy, mutable, stateful bags of sadness. --Josh Abernathy

Usual work week. Finally upgraded my Debian boxes from bullseye to bookworm and had no problems. Wow 🤯. Found a workaround for a long-standing PyCharm limitation: If you use a German keyboard layout, it's not possible to switch windows or comment out lines of code using keyboard shortcuts. Just install the Keymap Nationalizer Plugin and select your actual keyboard layout.

Didn't have much time for open source last week, but nonetheless managed to add a theme chooser for django-cast. You can now choose your theme and save the result in the session. So now it's possible for all users to try out new themes. Now I have a reason to polish the other themes a bit 😅. If you want to try it, just click on the B in the menu bar.




Mastodon / Twitter