Function types and single-method interfaces in Go

People love single-method interfaces (SMIs) in Go. They’re simple to implement and easy to reason about. The standard library is packed with SMIs like io.Reader, io.Writer, io.Closer, io.Seeker, and more. One cool thing about SMIs is that you don’t always need to create a full-bl … | Continue reading


@rednafi.com | 20 hours ago

SSH saga

Setting up SSH access to a new VM usually follows the same routine: generate a key pair, copy it to the VM, tweak some configs, confirm the host’s identity, and maybe set up an agent to avoid typing passphrases all day. Tools like cloud-init and Ansible handle most of the setup f … | Continue reading


@rednafi.com | 5 days ago

Injecting Pytest fixtures without cluttering test signatures

Sometimes, when writing tests in Pytest, I find myself using fixtures that the test function/method doesn’t directly reference. Instead, Pytest runs the fixture, and the test function implicitly leverages its side effects. For example: import os from collections.abc import Iterat … | Continue reading


@rednafi.com | 20 days ago

Explicit method overriding with @typing.override

Although I’ve been using Python 3.12 in production for nearly a year, one neat feature in the typing module that escaped me was the @override decorator. Proposed in PEP-6981, it’s been hanging out in typing_extensions for a while. This is one of those small features you either do … | Continue reading


@rednafi.com | 1 month ago

Explicit method overriding with @typing.override

Although I’ve been using Python 3.12 in production for nearly a year, one neat feature in the typing module that escaped me was the @override decorator. Proposed in PEP-6981, it’s been hanging out in typing_extensions for a while. This is one of those small features you either do … | Continue reading


@rednafi.com | 1 month ago

Quicker startup with module-level __getattr__

This morning, someone on Twitter pointed me to PEP 5621, which introduces __getattr__ and __dir__ at the module level. While __dir__ helps control which attributes are printed when calling dir(module), __getattr__ is the more interesting addition. The __getattr__ method in a modu … | Continue reading


@rednafi.com | 1 month ago

Quicker startup with module-level __getattr__

This morning, someone on Twitter pointed me to PEP 5621, which introduces __getattr__ and __dir__ at the module level. While __dir__ helps control which attributes are printed when calling dir(module), __getattr__ is the more interesting addition. The __getattr__ method in a modu … | Continue reading


@rednafi.com | 1 month ago

Docker mount revisited

I always get tripped up by Docker’s different mount types and their syntax, whether I’m stringing together some CLI commands or writing a docker-compose file. Docker’s docs cover these, but for me, the confusion often comes from how “bind” is used in various contexts and how “vol … | Continue reading


@rednafi.com | 2 months ago

Docker mount revisited

I always get tripped up by Docker’s different mount types and their syntax, whether I’m stringing together some CLI commands or writing a docker-compose file. Docker’s docs cover these, but for me, the confusion often comes from how “bind” is used in various contexts and how “vol … | Continue reading


@rednafi.com | 2 months ago

Topological sort

I was fiddling with graphlib in the Python stdlib and found it quite nifty. It processes a Directed Acyclic Graph (DAG), where tasks (nodes) are connected by directed edges (dependencies), and returns the correct execution order. The “acyclic” part ensures no circular dependencie … | Continue reading


@rednafi.com | 2 months ago

Topological sort

I was fiddling with graphlib in the Python stdlib and found it quite nifty. It processes a Directed Acyclic Graph (DAG), where tasks (nodes) are connected by directed edges (dependencies), and returns the correct execution order. The “acyclic” part ensures no circular dependencie … | Continue reading


@rednafi.com | 2 months ago

Writing a circuit breaker in Go

Besides retries, circuit breakers1 are probably one of the most commonly employed resilience patterns in distributed systems. While writing a retry routine is pretty simple, implementing a circuit breaker needs a little bit of work. I realized that I usually just go for off-the-s … | Continue reading


@rednafi.com | 2 months ago

Writing a circuit breaker in Go

Besides retries, circuit breakers1 are probably one of the most commonly employed resilience patterns in distributed systems. While writing a retry routine is pretty simple, implementing a circuit breaker needs a little bit of work. I realized that I usually just go for off-the-s … | Continue reading


@rednafi.com | 2 months ago

Discovering direnv

I’m not really a fan of shims—code that automatically performs actions as a side effect or intercepts actions when you use the shell or when a prompt runs. That’s mainly why I’ve stayed away from tools like asdf or pyenv, and instead stick to apt or brew for managing my binary in … | Continue reading


@rednafi.com | 2 months ago

Discovering direnv

I’m not really a fan of shims—code that automatically performs actions as a side effect or intercepts commands when you use the shell or when a prompt runs. That’s why, other than the occasional dabbling, I’ve mostly stayed away from tools like asdf or pyenv and instead stick to … | Continue reading


@rednafi.com | 2 months ago

Notes on building event-driven systems

I spent the evening watching this incredibly grokkable talk on event-driven services by James Eastham at NDC London 2024. Below is a cleaned-up version of my notes. I highly recommend watching the full talk if you’re interested before reading this distillation. The curse of tight … | Continue reading


@rednafi.com | 3 months ago

Notes on building event-driven systems

I spent the evening watching this incredibly grokkable talk on event-driven services by James Eastham at NDC London 2024. Below is a cleaned-up version of my notes. I highly recommend watching the full talk if you’re interested before reading this distillation. The curse of tight … | Continue reading


@rednafi.com | 3 months ago

Bash namerefs for dynamic variable referencing

While going through a script at work today, I came across Bash’s nameref feature. It uses declare -n ref="$1" to set up a variable that allows you to reference another variable by name—kind of like pass-by-reference in C. I’m pretty sure I’ve seen it before, but I probably just s … | Continue reading


@rednafi.com | 3 months ago

Bash namerefs for dynamic variable referencing

While going through a script at work today, I came across Bash’s nameref feature. It uses declare -n ref="$1" to set up a variable that allows you to reference another variable by name—kind of like pass-by-reference in C. I’m pretty sure I’ve seen it before, but I probably just s … | Continue reading


@rednafi.com | 3 months ago

Behind the blog

When I started writing here about five years ago, I made a promise to myself that I wouldn’t give in to the trend of starting a blog, adding one overly enthusiastic entry about the stack behind it, and then vanishing into the ether. I was somewhat successful at that and wanted to … | Continue reading


@rednafi.com | 3 months ago

Behind the blog

When I started writing here about five years ago, I made a promise to myself that I wouldn’t give in to the trend of starting a blog, adding one overly enthusiastic entry about the stack behind it, and then vanishing into the ether. I was somewhat successful at that and wanted to … | Continue reading


@rednafi.com | 3 months ago

Shell redirection syntax soup

I always struggle with the syntax for redirecting multiple streams to another command or a file. LLMs do help, but beyond the most obvious cases, it takes a few prompts to get the syntax right. When I know exactly what I’m after, scanning a quick post is much faster than wrestlin … | Continue reading


@rednafi.com | 3 months ago

Shell redirection syntax soup

I always struggle with the syntax for redirecting multiple streams to another command or a file. LLMs do help, but beyond the most obvious cases, it takes a few prompts to get the syntax right. When I know exactly what I’m after, scanning a quick post is much faster than wrestlin … | Continue reading


@rednafi.com | 3 months ago

Shades of testing HTTP requests in Python

Here’s a Python snippet that makes an HTTP POST request: # script.py import httpx from typing import Any async def make_request(url: str) -> dict[str, Any]: headers = {"Content-Type": "application/json"} async with httpx.AsyncClient(headers=headers) as client: response = await cl … | Continue reading


@rednafi.com | 3 months ago

Shades of testing HTTP requests in Python

Here’s a Python snippet that makes an HTTP POST request: # script.py import httpx from typing import Any async def make_request(url: str) -> dict[str, Any]: headers = {"Content-Type": "application/json"} async with httpx.AsyncClient(headers=headers) as client: … | Continue reading


@rednafi.com | 3 months ago

Taming parametrize with pytest.param

I love @pytest.mark.parametrize—so much so that I sometimes shoehorn my tests to fit into it. But the default style of writing tests with parametrize can quickly turn into an unreadable mess when the test complexity grows. For example: import pytest from math import atan2 def pol … | Continue reading


@rednafi.com | 3 months ago

Taming parametrize with pytest.param

I love @pytest.mark.parametrize1—so much so that I sometimes shoehorn my tests to fit into it. But the default style of writing tests with parametrize can quickly turn into an unreadable mess as the test complexity grows. For example: import pytest from math import atan2 def po … | Continue reading


@rednafi.com | 3 months ago

HTTP requests via /dev/tcp

I learned this neat Bash trick today where you can make a raw HTTP request using the /dev/tcp file descriptor without using tools like curl or wget. This came in handy while writing a health check script that needed to make a TCP request to a service. The following script opens a … | Continue reading


@rednafi.com | 4 months ago

HTTP requests via /dev/tcp

I learned this neat Bash trick today where you can make a raw HTTP request using the /dev/tcp file descriptor without using tools like curl or wget. This came in handy while writing a health check script that needed to make a TCP request to a service. The following script opens a … | Continue reading


@rednafi.com | 4 months ago

Log context propagation in Python ASGI apps

Let’s say you have a web app that emits log messages from different layers. Your log shipper collects and sends these messages to a destination like Datadog where you can query them. One common requirement is to tag the log messages with some common attributes, which you can use … | Continue reading


@rednafi.com | 4 months ago

Log context propagation in Python ASGI apps

Let’s say you have a web app that emits log messages from different layers. Your log shipper collects and sends these messages to a destination like Datadog where you can query them. One common requirement is to tag the log messages with some common attributes, which you can use … | Continue reading


@rednafi.com | 4 months ago

Please don't hijack my Python root logger

With the recent explosion of LLM tools, I often like to kill time fiddling with different LLM client libraries and SDKs in one-off scripts. Lately, I’ve noticed that some newer tools frequently mess up the logger settings, meddling with my application logs. While it’s less common … | Continue reading


@rednafi.com | 4 months ago

Please don't hijack my Python root logger

With the recent explosion of LLM tools, I often like to kill time fiddling with different LLM client libraries and SDKs in one-off scripts. Lately, I’ve noticed that some newer tools frequently mess up the logger settings, meddling with my application logs. While it’s less common … | Continue reading


@rednafi.com | 4 months ago

The *nix install command

TIL about the install command on *nix systems. A quick GitHub search for the term brought up a ton of matches1. I’m surprised I just found out about it now. Often, in shell scripts I need to: Create a directory hierarchy Copy a config or binary file to the new directory Set permi … | Continue reading


@rednafi.com | 4 months ago

The *nix install command

TIL about the install command on *nix systems. A quick GitHub search for the term brought up a ton of matches1. I’m surprised I just found out about it now. Often, in shell scripts I need to: Create a directory hierarchy Copy a config or binary file to the new directory Set permi … | Continue reading


@rednafi.com | 4 months ago

Here-doc headache

I was working on the deployment pipeline for a service that launches an app in a dedicated VM using GitHub Actions. In the last step of the workflow, the CI SSHs into the VM and runs several commands using a here document1 in bash. The simplified version looks like this: # SSH in … | Continue reading


@rednafi.com | 5 months ago

Here-doc headache

I was working on the deployment pipeline for a service that launches an app in a dedicated VM using GitHub Actions. In the last step of the workflow, the CI SSHs into the VM and runs several commands using a here document1 in bash. The simplified version looks like this: # SSH in … | Continue reading


@rednafi.com | 5 months ago

The sane pull request

One of the reasons why I’m a big advocate of rebasing and cleaning up feature branches, even when the changes get squash-merged to the mainline, is that it makes the PR reviewer’s life a little easier. I’ve written about my rebase workflow before1 and learned a lot from the Hacke … | Continue reading


@rednafi.com | 5 months ago

The sane pull request

One of the reasons why I’m a big advocate of rebasing and cleaning up feature branches, even when the changes get squash-merged to the mainline, is that it makes the PR reviewer’s life a little easier. I’ve written about my rebase workflow before1 and learned a few new things fro … | Continue reading


@rednafi.com | 5 months ago

I kind of like rebasing

People tend to get pretty passionate about Git workflows on different online forums. Some like to rebase, while others prefer to keep the disorganized records. Some dislike the extra merge commit, while others love to preserve all the historical artifacts. There’s merit to both s … | Continue reading


@rednafi.com | 6 months ago

I kind of like rebasing

People tend to get pretty passionate about Git workflows on different online forums. Some like to rebase, while others prefer to keep the disorganized records. Some dislike the extra merge commit, while others love to preserve all the historical artifacts. There’s merit to both s … | Continue reading


@rednafi.com | 6 months ago

Protobuffed contracts

People typically associate Google’s Protocol Buffer1 with gRPC2 services, and rightfully so. But things often get confusing when discussing protobufs because the term can mean different things: A binary protocol for efficiently serializing structured data. A language used to spec … | Continue reading


@rednafi.com | 7 months ago

Protobuffed contracts

People typically associate Google’s Protocol Buffer1 with gRPC2 services, and rightfully so. But things often get confusing when discussing protobufs because the term can mean different things: A binary protocol for efficiently serializing structured data. A language used to spec … | Continue reading


@rednafi.com | 7 months ago

TypeIs does what I thought TypeGuard would do in Python

The handful of times I’ve reached for typing.TypeGuard in Python, I’ve always been confused by its behavior and ended up ditching it with a # type: ignore comment. For the uninitiated, TypeGuard allows you to apply custom type narrowing1. For example, let’s say you have a functio … | Continue reading


@rednafi.com | 7 months ago

TypeIs does what I thought TypeGuard would do in Python

The handful of times I’ve reached for typing.TypeGuard in Python, I’ve always been confused by its behavior and ended up ditching it with a # type: ignore comment. For the uninitiated, TypeGuard allows you to apply custom type narrowing1. For example, let’s say you have a functio … | Continue reading


@rednafi.com | 7 months ago

ETag and HTTP caching

One neat use case for the HTTP ETag header is client-side HTTP caching for GET requests. Along with the ETag header, the caching workflow requires you to fiddle with other conditional HTTP headers like If-Match or If-None-Match. However, their interaction can feel a bit confusing … | Continue reading


@rednafi.com | 8 months ago

ETag and HTTP caching

One neat use case for the HTTP ETag header is client-side HTTP caching for GET requests. Along with the ETag header, the caching workflow requires you to fiddle with other conditional HTTP headers like If-Match or If-None-Match. However, their interaction can feel a bit confusing … | Continue reading


@rednafi.com | 8 months ago

Crossing the CORS crossroad

Every once in a while, I find myself skimming through the MDN docs to jog my memory on how CORS1 works and which HTTP headers are associated with it. This is particularly true when a frontend app can’t talk to a backend service I manage due to a CORS error2. MDN’s CORS documentat … | Continue reading


@rednafi.com | 9 months ago