Thanks to visit codestin.com
Credit goes to stuartm.nz

May 12, 2026

Another supply chain attack, this time on the "mistralai" Python package which is used by Pydantic AI ("mistralai>=2.0.0") and many others. PyPI has already quarantined the package, and it appears as though only version 2.4.6 was affected.

Luckily I've been using the new PDM lock feature: pdm lock --exclude-newer 7d, so I wasn't affected. Although I can't install pydantic-ai at the moment because mistralai is quarantined.


Async Django AI Chat Demo

I created a new project to experiment with async Django and Pydantic AI to implement a reactive chat UI that streams responses from a Gemini agent, and parses the Markdown to HTML as it streams.

Repository: https://github.com/stuartmaxwell/ai-chat-demo

The highlight of this was experimenting with the scripts from The Fixi Project. There are five narrowly-focused scripts that you can easily drop into your project to solve a particular issue.

The project README and a screencast are below...

Read more...


PDM Rocks!

I've been switching all my projects from uv to PDM and have been really enjoying it. It's fairly straight forward to switch from uv since it has a similar interface. Some simple examples:

  • uv initpdm init
  • uv add djangopdm add django
  • uv lockpdm lock
  • uv syncpdm sync
  • uv run manage.py runserverpdm run manage.py runserver.

Read more...


Markdown Architectural Decision Records

Capturing this for my own benefit...

Markdown Architectural Decision Records

An Architectural Decision (AD) is a justified software design choice that addresses a functional or non-functional requirement of architectural significance. This decision is documented in an Architectural Decision Record (ADR), which details a single AD and its underlying rationale. To capture these records in a lean way, the Markdown Architectural Decision Records (MADRs) have been invented: MADR is a streamlined template for recording architectural significant decisions in a structured manner.

Read more...


Apr 15, 2026

“Our doubts are traitors, And make us lose the good we oft might win, By fearing to attempt.” – William Shakespeare, Measure for Measure.


Mar 20, 2026

Next steps...

  • ty was fast but not very useful, wouldn't surprise me if this gets killed off first.
  • ruff was a fast and convenient wrapper to a bunch of tools I was already using, should be easy to revert back to using Black, flake8, etc.
  • uv will be more difficult, especially with the option to download/run a specific version of Python, but should be able to revert back to using pip-tools and pipx.


Mar 4, 2026

You can have a read through the Bootstrap v6 alpha docs here

The new colour palette looks good and uses the modern OKLCH colour space. There are also a bunch of new form components, and some other goodies. Looking forward to giving it a go.




Nov 4, 2025

The next phase in our dystopian future... AISO: AI summarisation optimisation

Meetings—humanity’s most fundamental collaborative ritual—are being silently reengineered by those who understand the algorithm’s preferences. The articulate are gaining an invisible advantage over the wise. Adversarial thinking is becoming routine, embedded in the most ordinary workplace rituals, and, as AI becomes embedded in organizational life, strategic interactions with AI notetakers and summarizers may soon be a necessary executive skill for navigating corporate culture.

https://www.schneier.com/blog/archives/2025/11/ai-summarization-optimization.html



Migrate SQLite to PostgreSQL with pgloader

I recently needed to change one of my Django apps from using SQLite to PostgreSQL. I thought it was going to be challenging to move the data from the SQLite database file to my PostgreSQL server, but it couldn't have been easier! ✨

After installing pgloader with a simple apt install pgloader command, I ran the following command to move the data:

  • pgloader sqlite:///path/to/my/db.sqlite3 postgresql://username:password@host:port/db_name

Done! 🎉

There's a lot more that pgloader can do, and it's worth reading the docs, but my simple SQLite migration worked the first time and without drama. 🥳


I Love Justfiles

About a year ago, I switched my Django development workflow to include justfiles which are "recipes" of tasks to be used with the just task runner.

Since then, I find myself dropping little justfiles all over the place. Here's one I created for an Ansible repository:

# Show all available commands
default:
    @just --list

# Run playbook in check mode (dry-run)
check ENV="dev" PLAYBOOK="site":
    ansible-playbook --diff -i ./inventory/{{ENV}}/hosts.yml --check playbooks/{{PLAYBOOK}}.yml

# Run the main site playbook
run ENV="dev" PLAYBOOK="site":
    ansible-playbook --diff -i ./inventory/{{ENV}}/hosts.yml playbooks/{{PLAYBOOK}}.yml

Super simple 🚀, and it lets me run a bunch of Ansible playbooks like this:

> just check
ansible-playbook --diff -i ./inventory/dev/hosts.yml --check playbooks/site.yml
just check prod
ansible-playbook --diff -i ./inventory/prod/hosts.yml --check playbooks/site.yml
just run prod common
ansible-playbook --diff -i ./inventory/prod/hosts.yml playbooks/common.yml

Sometimes I'll drop one in the root of a remote server with a bunch of common tasks like installing updates, running various maintenance tasks, or monitoring the system. I used to do this with Bash aliases, but I prefer the just syntax, and it feels easier to copy the files around.

😍


Gave up on Datastar

I tried hard to like Datastar—I read docs and articles, watched many YouTube tutorials and interviews with the developers—but I'm giving up. There are some great demos around, but for just swapping DOM elements, HTMX (or Alpine AJAX) are easier to work with.

Also, Datastar has moved features into a "Pro" version that costs US$299! So if you want to update the URL after loading/swapping an element, that will cost you US$299. And from what I can tell (I can't test it), this won't update the browser's history, so the back button gets broken.

Both HTMX and Alpine AJAX can do this. I'm using Alpine AJAX for this in a new project, and it allows you to dynamically load content while updating the URL and the browser's history. Which means you can bookmark or share or refresh the page and use Django's logic to return the full content.


Oct 15, 2025

Trying hard to wrap my head around what Datastar is and isn't. The docs try to get you to use server-sent events, but at the same time it looks like you don't need to - you can use it in the same way you use HTMX with no backend changes.

The server-sent events look interesting, but Django has warnings against using them, especially with WSGI, but also with ASGI. So perhaps Django isn't a good fit for this?


Oct 7, 2025

A little reminder to myself: always check that the test suite is passing before making significant changes to a project!

Just wasted a couple of hours troubleshooting some changes I had made, only to roll them back and find that the tests weren't even working before I started. 🤦‍♂️