Python
2025

How to Migrate your Python & Django Projects to uv
Editor’s note: This post was updated on July 17th, 2025, to use the
PATH_add
hook for direnv and to recommend including uv sync --locked
in your .envrc
file.

Upgrade Smarter, Not Harder: Python Tools for Code Modernization
Upgrading projects is somewhat equivalent to flossing, you know you have to do it, but rarely make time for it. After all, if the project is in active development, there are exciting new features to build. And we all know that new features > project upgrades. Well not to worry, Caktus wants to make you aware of some tools that will save you from considerable repetitive work & time while simultaneously modernizing your codebase. Combined, these tools will automate part of the upgrade process, decreasing the likelihood of neglecting parts of the codebase.

How to fix factory_boy post-generation deprecation warnings
We use factory_boy for
bootstrapping test data on many Python and Django projects at Caktus.
Recently, we encountered a deprecation warning on an older project that
had been using factory_boy
for some time:
2024

Getting Started with Dagster
Recently, Caktus has been using Tailscale to manage VPN connections between Android tablets and a central server. We wanted to report on the devices connected to the network using the Tailscale API. While we could use tools like Celery to fetch data from the API and load it into a database—given its widespread use in the Django ecosystem—we also wanted to explore other options.
2023

Analyze data with SQL window functions
We regularly use tools like PostgreSQL, Pandas, and Jupyter Notebooks to analyze data here at Caktus. Recently, we were reviewing North Carolina traffic stop data for the NC CopWatch project and had the opportunity to use PostgreSQL's window functions, which are helpful when aggregating data.

Begin your Data Analysis Journey with Pandas and Seaborn
Lately, there has been a lot of talk about scoring in the NBA because LeBron James surpassed Kareem Abdul-Jabbar with 38,390 career points. I have noticed that there is not much discussion about post-season scoring, so I searched for this dataset on Kaggle (nba_playoffs.csv) which contains the top 25 all-time post-season scoring leaders. Post-season scoring is its own beast. Since teams face one opponent multiple times in a row, they can better concentrate on the opposing team and its individual players, particularly star players. This results in improved defenses across the board. However, the post-season also means players improving their game. What is the result of improved defenses and players alike? Only elite players score consistently and thus, only the NBA's elite are on this list. This post will first examine the dataset using Pandas and then use Seaborn to graph such data.

An introduction to Django Simple History
Wouldn’t it be useful if we could document changes in our life and revisit them later at will? It would allow us to better analyze situations, remember what we were thinking, or help us remember how we got to our current state. Although no such tool currently exists for changes in life, one such tool does exist in Django. It is called django-simple-history.
2022

Meet the New Owners of Caktus
Nearly every week, I receive an email or two from a third party expressing interest in buying Caktus. As a matter of habit, I don't open them, let alone respond. Most are scattershot, venture capital firms looking for Software-as-a-Service companies (which Caktus is not). But when an employee approached me in 2018 expressing an interest in making Caktus employee-owned, I listened.
2021

How to Use Celery for Scheduling Tasks
There are multiple ways to schedule tasks in your Django app, but there are some advantages to using Celery. It’s supported, scales well, and works nicely with Django. Given its wide use, there are also lots of resources for learning more about it, and once learned, that knowledge is likely to be useful on other projects.

Highlights from PyCon US 2021
I had the opportunity to attend PyCon US, which was held entirely virtually. Though an in-person experience is impossible to replicate (the last time I attended PyCon in person was in 2018), I found that many aspects of the live conference were still available in an online format. Here are some of my highlights: