Django-Ninja, Ruff, Helpscout
Sorry for the week off! I spent it in Florida with my soon-to-be in-laws (it was relaxing, in the way that Florida always is) and am digging myself out of the various administrative holes that ensue. In lieu of a traditional narrative update for these weeknotes — and perhaps a little inspired by the holiday festivities — I wanted to highlight three little things that have made me happy this past week.
Django-ninja
Django-ninja is a very good set of ideas with an unfortunate name. (Seriously, I cringe to see the word ‘ninja’ in my pyproject.toml
.)
I am knee-deep in the process of replacing django-rest-framework in my public-facing API with django-ninja. DN offers two main advantages over DRF:
- It replaces DRF’s concept of “serializers” (exactly what it sounds like — a translation layer between JSON and Django models) with a more generic concept of “schemas” that are themselves just dataclasses, ensuring a better level of run-time validation & typesafety.
- Its introspection is much better, and as a result its ability to spit out a reasonable OpenAPI spec is much better.
That latter reason is really where I got started on this quixotic journey: I wanted a nicer automatically generated OpenAPI* spec for Buttondown and it literally appeared easier to completely replace my API plumbing than to get DRF to do what I wanted it to.
I have used DRF for… I think around eight years, at this point. It has served me very well, but I think many of its core primitives are less attractive in a world with typed Python, much as many of Django’s core primitives are less attractive in a world with performant Typescript. (It won’t be going away from Buttondown’s codebase any time soon, as it powers a glut of internal endpoints that aren’t worth the effort of replacing en masse.)
Ruff
I am very thrilled by the recent fad of “let’s take relatively stale CLIs that are written in slow languages and rewrite them in fast languages.” Ruff is exactly this (a Python linter written in Rust) and boy is it delightful.
I was going to try onboarding onto it for a lark to write a friction log and see if it was worth keeping around, and the long and short of it is: flake8
(which I was using previously, and as far as I know is the most prominent Python linter) spends eighteen seconds on Buttondown’s codebase whereas ruff
takes point two seconds.
Beyond the “oh my god that’s so much faster” reaction, I don’t have many notes. Ruff ships with a very useful migration tool that parses a flake8
config which meant that switching tools took around ten minutes; the only complaint I have, which is not a complaint with Ruff so much as with Rust’s Python parser, is that Ruff does not support structural matching or a couple other Python 3.10 syntactical goodies.
Helpscout
I wrote about Helpscout a few weeks ago; I am writing about it again because I find myself in the odd position of being enthusiastic about customer service software. I have received no annoying activation sequences; I have received no annoying upsells; it remains boring and fast and has made my daily triage of customer support much more enjoyable.
I’ve had a number of conversations with founders & owners in similar positions to where I am: Zendesk feels too onerous but Gmail isn’t quite enough. If you are one of these people, consider using Helpscout. (Or is it “Help Scout”? Unclear. Either way.)