Redowan Delowar

Roving amateur fumbling through software, systems, & sundry. Engineering @Doordash/Wolt Writing rednafi.com Currently in Berlin, Germany

1737 followers536 following224 stories

Longform Stories

If you won't carry the pager, maybe don't push to mainline

Drive-by AI changes break the shared model a team builds around its code, and the ICs end up cleaning up the mess. Why pushing to mainline should come with the pager.

May 30·8 min read·1587 words

Testing Go CLIs with testscript

How cmd/go's script tests led me to testscript, and how to use it for CLI tests that exercise argv, stdout, stderr, exit codes, and scratch files.

May 18·7 min read·1237 words

A tour of txtar

txtar is a tiny plain-text archive format Russ Cox introduced in 2018 for multi-file test fixtures. The Go Playground, cmd/go's script tests, gopls's marker tests, and rsc.io/rf all reach for it.

May 10·8 min read·1447 words

Type-safe slogging

The default slog API is loose enough that a careless line ships broken JSON to production. Pin it down with Attr constructors, LogAttrs, a context-borne logger, and sloglint.

May 9·6 min read·1171 words

Hoisting wire plumbing out of your Go handlers

Four of the five steps in every unary RPC handler are wire plumbing. Pin the service function signature and they fit in one generic adapter per transport.

May 2·8 min read·1599 words

Go quirks: function closures capturing mutable references

A Go closure holds a live reference to whatever it captures, not a snapshot. Real examples of where this trips people up, and how to keep it boring.

Apr 25·6 min read·1194 words

Accepted proposal: UUID in the Go standard library

Notes on Go's newly accepted uuid proposal and the tradeoffs behind the API.

Apr 19·3 min read·469 words

Peeking into Go struct tags

A quick tour of Go struct tags: how different libraries use them, how you read them at runtime with reflection, and how other tools read them at build time instead.

Apr 18·5 min read·933 words

Error translation in Go services

Translating errors at layer boundaries so storage details don't leak into the handler or, worse, into client responses.

Apr 12·8 min read·1433 words

Dynamo: Amazon's highly available key-value store

Key takeaways from Amazon's 2007 Dynamo paper.

Apr 11·3 min read·524 words

Stacked log lines considered harmful

Why logging at every layer of a service produces noise, and how to log only at the handler level while propagating context from below.

Apr 7·6 min read·1158 words

What's the ideal dispatch mechanism?

Switch, map of functions, and interface registry for dispatching in Go.

Mar 31·2 min read·373 words

Background jobs and inherited file descriptors

Why & backgrounds execution but doesn't stop output from flooding your terminal.

Mar 28·3 min read·414 words

Testing unary gRPC services in Go

How to test unary gRPC services in Go - handler logic, interceptors, deadlines, metadata propagation, and rich error details - all in-memory with bufconn.

Mar 23·13 min read·2428 words

Repositories, transactions, and unit of work in Go

Decoupling business logic from storage in Go, adding transaction support without leaking SQL details, and coordinating atomic writes across multiple repositories using a unit of work.

Mar 21·13 min read·2443 words

How do you handle transactions with the repository pattern?

Adding transaction support to a repository interface without leaking storage details.

Mar 20·3 min read·572 words

Is passing user ID through context an antipattern?

Why the middleware-to-handler boundary is a special case for context values.

Mar 18·3 min read·440 words

What belongs in Go's context values?

A simple litmus test for when to use context values in Go.

Mar 17·4 min read·684 words

Do you need a repository layer on top of sqlc?

Decoupling business logic from storage with a small interface in Go.

Mar 16·2 min read·386 words

Wrapping a gRPC client in Go

How to wrap a generated gRPC client behind a clean Go API so users never have to touch protobuf types or connection management directly.

Mar 15·7 min read·1393 words

In praise of the etcd codebase

Why the etcd codebase is my go-to reference for building gRPC services in Go.

Mar 14·3 min read·513 words

Go errors: to wrap or not to wrap?

Exploring the tradeoffs between wrapping errors at every return site versus wrapping only at boundaries, with no definitive answer - just honest tradeoffs for the kind of software I write.

Mar 7·13 min read·2596 words

Mutate your locked state inside a closure

Why your mutex wrapper should accept a closure for mutation instead of a plain value, with examples from the standard library and Tailscale.

Mar 5·6 min read·1179 words

What canceled my Go context?

How Go 1.20's WithCancelCause and Go 1.21's WithTimeoutCause let you attach a reason to context cancellation, plus a gotcha with manual cancel and the stdlib pattern that covers every path.

Feb 24·12 min read·2272 words

Structured concurrency & Go

How Python and Kotlin provide structured concurrency out of the box while Go achieves the same patterns explicitly using errgroup, WaitGroup, and context.

Feb 21·14 min read·2704 words

Your Go tests probably don't need a mocking library

Practical patterns for mocking in Go without external libraries. Learn to mock functions, methods, interfaces, HTTP calls, and time using only the standard library

Jan 23·12 min read·2297 words

Tap compare testing for service migration

Master shadow testing for large-scale system migrations. Learn to safely rewrite services by comparing outputs between old and new implementations.

Dec 13·16 min read·3075 words

Splintered failure modes in Go

Simplify Go error handling by consolidating validation and system errors. Learn when to return boolean vs error for clearer failure modes.

Nov 30·4 min read·710 words

Re-exec testing Go subprocesses

Test Go subprocesses with the re-exec pattern: spawn your test binary as a subprocess to emulate real command behavior reliably.

Nov 16·5 min read·845 words

Revisiting interface segregation in Go

Apply SOLID's Interface Segregation Principle in Go with consumer-defined contracts. Learn why small interfaces and implicit implementation matter.

Nov 1·5 min read·928 words

Avoiding collisions in Go context keys

Master Go context keys with custom types, avoid collisions using empty structs, and learn accessor patterns for safe request-scoped values.

Oct 22·6 min read·1126 words

Organizing Go tests

Organize Go tests with in-package, external _test packages, and integration tests. Learn white-box vs black-box testing conventions.

Oct 8·6 min read·1097 words

Subtest grouping in Go

Organize Go subtests with t.Run nesting and parallel execution. Learn patterns for setup, teardown, and readable test hierarchies.

Oct 1·7 min read·1396 words

Let the domain guide your application structure

Organize Go apps by domain, not technology. Learn why models/controllers structure hurts and how bounded contexts create better separation.

Sep 20·5 min read·944 words

Test state, not interactions

Avoid brittle AI-generated tests that check implementation details. Write maintainable tests that verify behavior, not method calls.

Sep 14·7 min read·1312 words

Early return and goroutine leak

Prevent goroutine leaks caused by early returns with unbuffered channels. Learn buffering, draining, errgroup patterns, and goleak testing.

Sep 7·4 min read·693 words

Gateway pattern for external service calls

Separate business logic from external service calls using the Gateway pattern. Apply dependency inversion and interface segregation in Go.

Aug 3·5 min read·888 words

Flags for discoverable test config in Go

Control Go test behavior with custom flags instead of build tags or env vars. Enable integration and snapshot tests with discoverable CLI options.

Jun 28·7 min read·1203 words

You probably don't need a DI framework

Dependency injection in Go doesn't need Dig or Wire. Learn why manual wiring beats reflection magic and how Go's design makes DI frameworks overkill.

May 24·6 min read·1133 words

Preventing accidental struct copies in Go

Prevent dangerous struct copies with noCopy sentinel and go vet's copylock checker. Protect mutexes and sync primitives from value copies.

Apr 21·4 min read·619 words

Go 1.24's "tool" directive

Pin tool versions in Go 1.24 with the new 'tool' directive. Replace tools.go pattern with native go.mod support for project tooling.

Apr 13·4 min read·630 words

Capturing console output in Go tests

Test functions that write to stdout/stderr in Go by capturing output with os.Pipe. Learn patterns to avoid deadlocks in concurrent tests.

Apr 12·4 min read·637 words

Deferred teardown closure in Go testing

Return teardown closures from test helpers to manage cleanup elegantly. Learn patterns for temp files, mock servers, and t.Cleanup() usage.

Mar 28·3 min read·557 words

Three flavors of sorting Go slices

Compare three Go slice sorting methods: sort.Interface, sort.Slice with closures, and modern generic slices.Sort with type safety.

Mar 22·5 min read·970 words

Nil comparisons and Go interface

Debug tricky nil comparisons in Go interfaces. Understand dynamic types, type assertions, and use reflect for generic nil checking.

Mar 12·4 min read·671 words

Stacked middleware vs embedded delegation in Go

Compare middleware stacking with embedded delegation in Go HTTP servers. Learn when to override ServeHTTP for simpler request handling.

Mar 6·4 min read·616 words

Why does Go's io.Reader have such a weird signature?

Understand why io.Reader takes a byte slice parameter instead of returning one. Learn about heap allocations and buffer reuse in Go streams.

Feb 8·3 min read·460 words

Go slice gotchas

Avoid common Go slice mistakes: shared backing arrays, nil vs empty slices, append behavior, and slice copying pitfalls explained.

Feb 6·5 min read·848 words

The domain knowledge dilemma

Navigating the balance between building valuable domain expertise and avoiding over-specialization that limits career mobility.

Jan 19·3 min read·511 words

Hierarchical rate limiting with Redis sorted sets

Build multi-level rate limiting with Redis sorted sets and Lua. Enforce global and category-specific limits with ZREMRANGEBYSCORE and ZCARD commands.

Jan 12·5 min read·985 words

Dynamic shell variables

Learn variable indirection in Bash with ${!var} syntax. Build context-aware configs, function dispatch, and dynamic variable name resolution.

Jan 11·3 min read·451 words

Link blog in a static site

Build a link blog without a backend using Hugo and markdown. Track reading, articles, and activities with yearly detail pages and RSS filtering.

Jan 6·3 min read·554 words

Running only a single instance of a process

Prevent multiple script instances with file locking. Use flock in Bash, fcntl in Python, and syscall.Flock in Go for single-instance processes.

Dec 31·3 min read·532 words

Function types and single-method interfaces in Go

Implement single-method interfaces with function types instead of structs. Master http.HandlerFunc patterns for middlewares, mocks, and adapters.

Dec 22·4 min read·659 words

SSH saga

Complete SSH setup guide: key pairs, authorized_keys, sshd_config, ssh_config, known_hosts, agent forwarding, and hardening for secure remote access.

Dec 17·4 min read·638 words

Injecting Pytest fixtures without cluttering test signatures

Clean up pytest test signatures using @pytest.mark.usefixtures to inject implicit fixtures without autouse or unused parameter warnings.

Dec 2·2 min read·228 words

Explicit method overriding with @typing.override

Catch method override errors at type-check time with Python's @override decorator from PEP 698, preventing typos and signature mismatches.

Nov 6·2 min read·290 words

Quicker startup with module-level __getattr__

Speed up Python module imports with __getattr__ from PEP 562 for lazy loading, deprecation warnings, and dynamic attribute access.

Nov 3·3 min read·479 words

Docker mount revisited

Master Docker mount types: volumes, bind mounts, tmpfs, and build cache. Clear syntax comparison between -v and --mount options with docker-compose.

Oct 22·5 min read·914 words

Topological sort

Implement topological sorting in Go to order tasks by dependencies. Process directed acyclic graphs for build systems and scheduling.

Oct 13·4 min read·764 words

Writing a circuit breaker in Go

Build a production-ready circuit breaker in Go from scratch with closed, open, and half-open states to prevent cascading failures.

Oct 6·6 min read·1178 words

Discovering direnv

Automate environment variables per directory with direnv. Load .envrc files on entry, unload on exit. Integrate with Python venv and uv workflow.

Oct 2·6 min read·1123 words

Notes on building event-driven systems

Deep dive into event-driven architecture patterns. Learn publish-subscribe, CQRS, outbox pattern, eventual consistency, and handling microservice coupling.

Sep 21·12 min read·2209 words

Bash namerefs for dynamic variable referencing

Master Bash namerefs with declare -n to create dynamic variable references. Build generic functions for arrays and associative arrays without eval.

Sep 20·5 min read·815 words

Behind the blog

How this blog is built: Hugo static site generator, GitHub Actions deployment, Cloudflare caching, and R2 storage. Simple, stable, and cost-free.

Sep 14·4 min read·716 words

Shell redirection syntax soup

Complete guide to Bash redirection. Master stdout, stderr, pipes, tee, file descriptors, and shorthand syntax with practical examples for every case.

Sep 12·4 min read·642 words

Shades of testing HTTP requests in Python

Test HTTP requests in Python with pytest-httpx for full mocking, respx for pattern matching, or VCR.py for recording real responses.

Sep 2·3 min read·452 words

Taming parametrize with pytest.param

Write readable parametrized tests with pytest.param for better test names, conditional skips, custom IDs, and structured test data.

Aug 28·2 min read·391 words

HTTP requests via /dev/tcp

Make raw HTTP requests with Bash's /dev/tcp file descriptor. Build health check scripts without curl or wget using TCP socket connections.

Aug 8·2 min read·381 words

Log context propagation in Python ASGI apps

Automatically tag Python logs with request context using middleware and contextvars for distributed tracing in ASGI web applications.

Aug 6·5 min read·812 words

Please don't hijack my Python root logger

Avoid configuring Python's root logger in libraries; use named loggers with NullHandler to let application code control logging behavior.

Aug 3·4 min read·785 words

The *nix install command

Replace mkdir, cp, and chmod with a single install command. Copy files, create directories, and set permissions in one step with GNU coreutils.

Jul 28·2 min read·309 words

Here-doc headache

Avoid here-doc pitfalls when running remote commands via SSH. Learn variable expansion gotchas and simpler alternatives for deployment scripts.

Jul 19·3 min read·468 words

The sane pull request

Make pull requests easier to review. Learn commit organization, diff filtering, annotations, and context that helps reviewers understand changes faster.

Jul 14·4 min read·608 words

I kind of like rebasing

Master git rebase for cleaner commit history. Learn interactive rebasing, squashing commits, and rebasing feature branches onto main with practical examples.

Jun 18·6 min read·1190 words

Protobuffed contracts

Define service contracts with Protocol Buffers for non-gRPC systems. Generate serializers, maintain self-documented APIs, and ensure cross-language compatibility.

May 10·3 min read·591 words

TypeIs does what I thought TypeGuard would do in Python

Understand TypeIs vs TypeGuard in Python: TypeIs provides more intuitive type narrowing by narrowing both positive and negative branches.

Apr 27·4 min read·647 words

ETag and HTTP caching

Implement client-side HTTP caching with ETag headers. Learn If-None-Match, 304 Not Modified responses, and weak validation in Go servers.

Apr 10·6 min read·1133 words

Crossing the CORS crossroad

Troubleshoot CORS errors with this practical guide. Learn Access-Control-Allow-Origin headers, preflight requests, and domain allowlisting in Go.

Mar 12·4 min read·644 words

Dysfunctional options pattern in Go

Discover a simpler alternative to functional options: method chaining with builder-style configuration that's 76x faster and easier to understand.

Mar 6·5 min read·997 words

Einstellung effect

Why accumulated knowledge can prevent learning new paradigms, and how past expertise becomes the barrier to future growth.

Feb 24·4 min read·761 words

Strategy pattern in Go

Replace inheritance with the Strategy pattern in Go using interfaces. Achieve composable, testable code without class hierarchies.

Feb 17·5 min read·903 words

Anemic stack traces in Go

Learn how to build custom error types in Go to create stack traces without runtime overhead, inspired by Rob Pike's Upspin error handling.

Feb 10·5 min read·805 words

Retry function in Go

Build retry logic in Go without reflection using generics. Implement exponential backoff and configurable retry strategies with type safety.

Feb 4·3 min read·499 words

Type assertion vs type switches in Go

Master Go type assertions with i.(T) syntax and type switches. Extract concrete types from interfaces safely with ok idiom examples.

Jan 31·5 min read·801 words

Patching pydantic settings in pytest

Mock pydantic_settings in pytest tests by patching the settings class to prevent flaky tests from environment variable dependencies.

Jan 27·4 min read·653 words

Omitting dev dependencies in Go binaries

Track dev dependencies like golangci-lint in go.mod with a tools.go file and build tags to exclude them from production binaries.

Jan 21·3 min read·475 words

Eschewing black box API calls

Why you should define API response structures explicitly. Compare approaches in Python, JavaScript, and Go with Pydantic, Zod, and structs.

Jan 15·4 min read·735 words

Annotating args and kwargs in Python

Properly annotate Python *args and **kwargs with heterogeneous types using Unpack, TypedDict, and modern type hints from PEP-692.

Jan 8·3 min read·446 words

Rate limiting via Nginx

Implement rate limiting at the infrastructure layer with Nginx reverse proxy. Protect Go services from DDoS with leaky bucket algorithm.

Jan 6·6 min read·1180 words

Statically enforcing frozen data classes in Python

Enforce immutable dataclasses at type-check time with @final decorator to catch mutations before runtime without frozen=True performance cost.

Jan 4·3 min read·419 words

Planning palooza

Why scattered planning documents across RFCs, ADRs, and multiple tools hinder productivity compared to centralized documentation.

Jan 1·3 min read·600 words

Reminiscing CGI scripts

Build a CGI script from scratch using Go's stdlib and Bash. Understand why Common Gateway Interface fell out of favor for modern web apps.

Dec 25·4 min read·789 words

Debugging dockerized Python apps in VSCode

Set up VSCode debugger for containerized Python applications using debugpy. Step-by-step guide with Docker Compose and launch configurations.

Dec 22·4 min read·609 words

Banish state-mutating methods from data classes

Why you shouldn't add state-mutating methods to Python dataclasses. Maintain semantic clarity and use dataclasses as pure data containers.

Dec 16·4 min read·757 words

Finding flow amid chaos

Strategies for achieving deep work and focus time as an engineer drowning in meetings, Slack messages, and corporate interruptions.

Nov 25·3 min read·489 words

The diminishing half-life of knowledge

How technical skills decay faster than ever in software engineering, and strategies for continuous learning in a rapidly changing field.

Nov 12·4 min read·610 words

Oh my poor business logic

How resume-driven development and technical maximalism distract engineers from solving real business problems and delivering value.

Nov 5·3 min read·572 words

Pesky little scripts

Organize custom scripts with comma-prefixed naming. Improve tab completion and eliminate clutter by prefixing script names with special characters.

Oct 29·2 min read·330 words

Footnotes for the win

Why footnote-style reference links create cleaner Markdown documents and improve the writing experience over inline links.

Oct 7·4 min read·679 words

Dotfile stewardship for the indolent

Manage dotfiles across devices with GNU Stow. Symlink configuration files from git repo to home directory with simple, idempotent commands.

Sep 27·4 min read·635 words

Self-hosted Google Fonts in Hugo

Host Google Fonts locally in Hugo without CDN dependency. Download woff2 files, configure CSS, and improve performance while maintaining GDPR compliance.

Sep 14·2 min read·385 words

Configuring options in Go

Compare three Go option patterns: exposed structs, option constructors, and functional options. Learn when to use each for clean APIs.

Sep 5·5 min read·875 words

Dummy load balancer in a single Go script

Build a working round-robin load balancer in Go with goroutines and the standard library. No dependencies needed for this educational prototype.

Aug 30·5 min read·899 words

Limit goroutines with buffered channels

Control goroutine concurrency with buffered channels as semaphores. Prevent resource exhaustion with backpressure patterns in Go workers.

Aug 23·4 min read·613 words

Writing a TOTP client in Go

Build a TOTP-based 2FA client in Go using the standard library. Generate time-based one-time passwords like Google Authenticator.

Aug 20·3 min read·470 words

Interface guards in Go

Use compile-time interface guards to verify type conformity in Go without runtime overhead. Learn the var _ Interface = (*Type)(nil) pattern.

Aug 18·2 min read·370 words

Writing on well-trodden topics

Why writing about common topics matters for personal growth, even when countless others have covered the same ground before you.

Aug 14·3 min read·532 words

Go structured logging with slog

Master Go 1.21's log/slog package for structured logging with levels, JSON output, and attribute grouping. No third-party libraries needed.

Aug 10·7 min read·1400 words

Notes on exit interviews

Practical advice for navigating exit interviews from an employee's perspective, minimizing risk while maintaining professionalism.

Aug 7·2 min read·365 words

Taming conditionals with bitmasks

Replace complex nested conditionals with Python's enum.Flag and bitmasks for cleaner, more maintainable logic using bitwise operations.

Jul 29·8 min read·1474 words

Using DNS record to share text data

Share data via DNS TXT records using dig and base64 encoding. Learn limitations, security concerns, and practical use cases for DNS tunneling.

Jul 17·2 min read·340 words

Memory leakage in Python descriptors

Prevent memory leaks in Python descriptors by using weakref to avoid hard references that prevent garbage collection of validated objects.

Jul 16·4 min read·740 words

Unix-style pipelining with Python's subprocess module

Build Unix-style command pipelines in Python using subprocess.run with stdout piping for efficient process chaining and output capture.

Jul 14·5 min read·937 words

Enabling repeatable lazy iterations in Python

Create reusable generators by implementing __iter__ in a class, allowing multiple lazy iterations without memory overhead or repeated function calls.

Jul 13·3 min read·583 words

Descending into the aether

A reflection on choosing the MacBook Air M2 15-inch for portability without sacrificing screen size and development capabilities.

Jul 9·5 min read·820 words

Escaping the template pattern hellscape in Python

Replace inheritance-based template pattern with composition and Protocol types to create cleaner, testable Python code without namespace pollution.

Jul 1·15 min read·2816 words

Python dependency management redux

Modern Python dependency management using pip-tools, hatch, and PEP-621 for web apps and libraries with reproducible builds.

Jun 27·6 min read·1103 words

Implementing a simple traceroute clone in Python

Build a traceroute clone in Python using UDP and ICMP sockets to trace network packet routes and measure hop latency with TTL manipulation.

Jun 1·6 min read·1066 words

Bulk request Google search indexing with API

Learn how to programmatically request Google search indexing for multiple URLs using the Indexing API and NodeJS for faster reindexing.

May 26·4 min read·601 words

Building a CORS proxy with Cloudflare Workers

Build your own CORS proxy using Cloudflare Workers to bypass browser CORS restrictions. Includes deployment with GitHub Actions automation.

May 21·8 min read·1504 words

Fixed-time job scheduling with UNIX 'at' command

Schedule one-time commands with UNIX at command. Learn job queuing, remote scheduling via HTTP API, and managing atd/atrun daemons.

May 14·7 min read·1304 words

Sorting a Django queryset by a custom sequence of an attribute

Sort Django querysets by custom attribute sequences using Case and When expressions for database-level ordering with SQL CASE statements.

May 9·4 min read·721 words

Periodic readme updates with GitHub Actions

Automate your GitHub profile README with periodic updates using Actions. Parse RSS feeds and dynamically display latest blog posts with NodeJS.

May 4·3 min read·550 words

Associative arrays in Bash

Learn how to use associative arrays in Bash to create key-value pairs, mimic dictionaries, and manage complex data structures in shell scripts.

May 3·4 min read·728 words

Deduplicating iterables while preserving order in Python

Master techniques to remove duplicates from Python iterables while maintaining original order using sets, OrderedDict, and nested deduplication.

May 1·4 min read·640 words

Process substitution in Bash

Use process substitution <() to treat command output as files in Bash. Compare directories, process data, and avoid temporary files with this technique.

Apr 30·6 min read·1102 words

Dynamic menu with select statement in Bash

Build interactive CLI menus with Bash select statement. Create user-friendly command-line tools with option selection and function dispatch.

Apr 29·3 min read·414 words

Simple terminal text formatting with tput

Format terminal output with tput instead of ANSI codes. Set colors, bold text, underlines, and backgrounds with simple commands in shell scripts.

Apr 23·3 min read·450 words

Building a web app to display CSV file stats with ChatGPT & Observable

Create a client-side CSV comparison tool using ObservableHQ notebooks and ChatGPT. Learn to build interactive data apps without deployment hassles.

Apr 10·4 min read·763 words

Pushing real-time updates to clients with Server-Sent Events (SSEs)

Stream real-time server updates to web clients using Server-Sent Events (SSE) as a simpler alternative to WebSockets for unidirectional data flow.

Apr 8·10 min read·1866 words

Tinkering with Unix domain sockets

Build Unix domain socket servers and clients with Python and socat. Access Docker API via UDS, create HTTP servers, and optimize inter-process communication.

Mar 11·7 min read·1281 words

Signal handling in a multithreaded socket server

Gracefully shutdown Python's ThreadingTCPServer with signal handlers for SIGINT, SIGTERM handling and client notification on server shutdown.

Feb 26·8 min read·1444 words

Switching between multiple data streams in a single thread

Poll multiple data sources in a single thread using Python generators with itertools.cycle to alternate between infinite data streams efficiently.

Feb 19·2 min read·378 words

Skipping the first part of an iterable in Python

Skip elements in iterables until a condition is met using itertools.dropwhile for efficient lazy evaluation that works with generators.

Feb 12·2 min read·315 words

Pausing and resuming a socket server in Python

Build a pausable socket server with Python's socketserver module using threading for intermittent request handling and background tasks.

Feb 5·5 min read·852 words

Debugging a containerized Django application in Jupyter Notebook

Connect Jupyter Notebook to Dockerized Django apps using ipykernel and django-extensions for interactive debugging and data exploration.

Jan 14·4 min read·684 words

Manipulating text with query expressions in Django

Use Django query expressions like Replace, Upper, Lower, Concat, and Substr for efficient database-level text manipulation without fetching data.

Jan 7·4 min read·675 words

Using tqdm with concurrent.fututes in Python

Display progress bars for concurrent Python tasks using tqdm with ThreadPoolExecutor and as_completed for real-time execution monitoring.

Jan 6·2 min read·310 words

Colon command in shell scripts

Use the colon : command as a no-op in Bash scripts for cleaner debug output with -x flag. Alternative to echo for section markers and comments.

Dec 23·2 min read·277 words

Faster bulk_update in Django

Accelerate Django bulk_update operations by 4x using multiprocessing to parallelize database writes across chunked record batches.

Nov 30·2 min read·344 words

Installing Python on macOS with asdf

Manage multiple Python versions on macOS using asdf, a unified version manager replacing pyenv, nvm, and language-specific tools.

Nov 13·3 min read·528 words

Save models with update_fields for better performance in Django

Optimize Django model saves with update_fields parameter to generate leaner SQL queries and improve performance in tight update loops.

Nov 9·2 min read·388 words

Python logging quirks in AWS Lambda environment

Configure Python logging for AWS Lambda's pre-configured handlers while maintaining compatibility with local development environments.

Oct 20·3 min read·585 words

Dissecting an outage caused by eager-loading file content

Learn from a production outage caused by loading large CSV files into memory. Stream process files to prevent OOM errors and crashes.

Oct 14·5 min read·977 words

Auditing commit messages on GitHub

Automate commit message validation with GitHub Actions. Enforce refs and closes patterns to maintain clean Git history and link commits to issues.

Oct 6·5 min read·940 words

To quote or not to quote

Master shell quoting rules: single vs double quotes, backticks vs $(). Learn when to quote variables to prevent spaces and special characters from breaking commands.

Oct 5·3 min read·517 words

Returning values from a shell function

Understand how return values work in Bash functions. Learn exit codes, status evaluation patterns, and proper boolean returns with true/false commands.

Sep 25·3 min read·450 words

Verifying webhook origin via payload hash signing

Secure webhooks by verifying payload authenticity using HMAC hash signatures with shared secrets, preventing man-in-the-middle attacks.

Sep 18·4 min read·667 words

Recipes from Python SQLite docs

Practical SQLite recipes for Python: execute statements, batch operations, transactions, row factories, and context managers with sqlite3.

Sep 11·11 min read·2161 words

Prefer urlsplit over urlparse to destructure URLs

Use Python's urlsplit instead of urlparse for faster URL parsing by skipping the rarely-needed params component in URL decomposition.

Sep 10·2 min read·326 words

Pick random values from an array in SQL(ite)

Emulate Python's random.choice in SQLite using JSON arrays and the random() function. Populate tables with realistic test data efficiently.

Sep 2·3 min read·523 words

ExitStack in Python

Master Python's ExitStack for managing multiple context managers, conditional callbacks, request rollbacks, and avoiding nested with statements.

Aug 27·3 min read·593 words

Compose multiple levels of fixtures in pytest

Combine session and function-scoped pytest fixtures to avoid expensive test setup while maintaining test isolation and preventing state coupling.

Jul 21·3 min read·580 words

Patch where the object is used

Master Python mocking: patch objects at their import location, not where they're defined, to avoid common unittest.mock pitfalls.

Jul 18·2 min read·365 words

Partially assert callable arguments with 'unittest.mock.ANY'

Assert specific mock call arguments while ignoring others using unittest.mock.ANY for flexible test assertions without brittle checks.

Jul 17·2 min read·235 words

When to use 'git pull --rebase'

Fix divergent branch errors with git pull --rebase. Learn when to rebase local commits on top of remote changes for cleaner Git history.

Jul 14·2 min read·277 words

Apply constraints with 'assert' in Python

Use Python assert statements to apply runtime constraints more succinctly than raising ValueError. Learn the trade-offs and best practices.

Jul 10·3 min read·409 words

Automerge Dependabot PRs on GitHub

Automatically merge Dependabot pull requests using GitHub Actions. Configure branch protection and status checks for safe automated dependency updates.

Jul 7·4 min read·624 words

Stream process a CSV file in Python

Process large CSV files without OOM errors by streaming content line-by-line with HTTPX and concurrent.futures for parallel processing.

Jul 1·4 min read·667 words

Bulk operations in Django with process pool

Speed up Django bulk operations with ProcessPoolExecutor while preserving signals and hooks that bulk_create/bulk_update bypass.

Jun 27·3 min read·572 words

Read a CSV file from s3 without saving it to the disk

Download and process S3 CSV files in memory using boto3 and tempfile.NamedTemporaryFile without cluttering disk with temporary files.

Jun 26·4 min read·618 words

Distil git logs attached to a single file

View git commit history for a single file with git log --follow. Learn to track multiple files with xargs and concatenate their commit logs.

Jun 21·2 min read·208 words

Safer 'operator.itemgetter' in Python

Use operator.itemgetter for faster sorting and element access with graceful KeyError handling via methodcaller for safer operations.

Jun 16·3 min read·566 words

Guard clause and exhaustiveness checking

Master TypeScript's never type and Python's NoReturn for exhaustiveness checking. Flatten nested conditionals with guard clauses for cleaner code.

May 22·3 min read·465 words

Health check a server with 'nohup $(cmd) &'

Run background health checks in CI with nohup and ampersand. Test server readiness with retry loops and automatic cleanup on success or failure.

Apr 18·2 min read·341 words

Return JSON error payload instead of HTML text in DRF

Fix Django REST Framework to return JSON error responses for 403, 404, 500 errors using middleware instead of default HTML pages.

Apr 13·3 min read·467 words

Decoupling producers and consumers of iterables with generators in Python

Learn how Python generators decouple data production from consumption, enabling cleaner code for streaming, polling, and pipeline patterns.

Apr 3·4 min read·602 words

Pre-allocated lists in Python

Understand CPython list memory allocation: how lists store pointer references, grow dynamically, and when pre-allocation with [None]*n helps.

Mar 27·3 min read·559 words

In favor of sentence case

Embracing sentence case over title case in technical writing eliminates capitalization ambiguity and improves readability.

Mar 26·3 min read·468 words

Disallow large file download from URLs in Python

Prevent excessive file downloads in Python by streaming with HTTPX and limiting file size with chunk-based validation and memory-safe processing.

Mar 23·2 min read·276 words

Declaratively transform data class fields in Python

Leverage Python's __post_init__ hook to declaratively transform dataclass fields. Automatically serialize data with clean, maintainable code.

Mar 20·2 min read·371 words

Mocking chained methods of datetime objects in Python

Mock chained datetime methods in Python tests using unittest.mock to handle immutable datetime objects without external dependencies.

Mar 16·1 min read·190 words

How not to run a script in Python

Fix Python ModuleNotFoundError by using python -m instead of direct script execution to ensure correct sys.path handling for imports.

Mar 16·2 min read·274 words

Caching connection objects in Python

Learn efficient patterns for caching database connection objects in Python without import-time side effects or lru_cache complexity.

Mar 16·2 min read·221 words

Declarative payloads with TypedDict in Python

Use Python TypedDict to declaratively define API payload structures. Get type safety for nested dictionaries and improve code maintainability.

Mar 11·4 min read·699 words

Parametrized fixtures in pytest

Create dynamic pytest fixtures with @pytest.fixture(params) to run tests with multiple configurations and parameter combinations.

Mar 10·2 min read·390 words

Modify iterables while iterating in Python

Safely modify lists, sets, and dictionaries while iterating using list comprehensions, filters, or copying to avoid skipping elements.

Mar 4·3 min read·481 words

Github action template for Python based projects

Production-ready GitHub Actions workflow for Python with multi-OS testing, dependency caching, automated updates, and daily scheduled runs.

Mar 2·1 min read·155 words

Self type in Python

Use Python's Self type from PEP 673 to annotate methods returning class instances, eliminating complex forward references and TypeVars.

Feb 28·2 min read·379 words

Patching test dependencies via pytest fixture & unittest mock

Combine pytest fixtures with unittest.mock.patch for clean, reusable test mocking patterns that integrate seamlessly with pytest's ecosystem.

Feb 27·7 min read·1202 words

Narrowing types with TypeGuard in Python

Use Python's TypeGuard to create custom type narrowing functions that help static type checkers understand runtime type checks and validations.

Feb 23·5 min read·845 words

Why 'NoReturn' type exists in Python

Use Python's NoReturn type to annotate functions that never return normally, helping type checkers understand exception-raising and infinite loop code.

Feb 21·2 min read·376 words

Add extra attributes to enum members in Python

Master adding multiple attributes to Python enum members using __new__ method. Avoid hardcoded indexes and create more maintainable enums.

Feb 17·3 min read·484 words

Peeking into the internals of Python's 'functools.wraps' decorator

Explore how functools.wraps preserves function identity by copying metadata from wrapped functions using update_wrapper and partial application.

Feb 14·3 min read·405 words

Limit concurrency with semaphore in Python asyncio

Control concurrent async requests with Python asyncio.Semaphore to respect rate limits and prevent overwhelming APIs or services.

Feb 10·3 min read·503 words

Amphibian decorators in Python

Build Python decorators that work seamlessly with both sync and async functions using inspect.iscoroutinefunction for maximum flexibility.

Feb 6·3 min read·447 words

Go Rusty with exception handling in Python

Implement Rust-style Result types for type-safe exception handling in Python using generic Ok and Err types inspired by Black formatter.

Feb 2·2 min read·288 words

Variance of generic types in Python

Understand covariance, contravariance, and invariance in Python generics with practical examples of type relationships and subtyping rules.

Jan 31·4 min read·711 words

Create a sub dictionary with O(K) complexity in Python

Optimize Python dictionary slicing from O(DK) to O(K) complexity using direct key lookups instead of iterating through all items.

Jan 30·2 min read·317 words

Gotchas of early-bound function argument defaults in Python

Avoid Python function default argument pitfalls caused by early binding, where mutable defaults and function calls bind at definition time.

Jan 27·3 min read·536 words

Use 'assertIs' to check literal booleans in Python unittest

Test literal booleans correctly in Python unittest using assertIs instead of assertTrue/assertFalse to avoid truthy/falsy confusion.

Jan 24·1 min read·159 words

Static typing Python decorators

Type Python decorators accurately using ParamSpec and Concatenate to preserve wrapped function signatures and enable proper static analysis.

Jan 23·4 min read·640 words

Inspect docstrings with Pydoc

View Python docstrings from the command line with pydoc or serve them as HTML documentation for modules, classes, and functions.

Jan 22·2 min read·231 words

Check whether an integer is a power of two in Python

Use Python's bit_count() method to elegantly check if an integer is a power of two by counting on-bits in binary representation.

Jan 21·1 min read·169 words

Uniform error response in Django Rest Framework

Standardize Django REST Framework error responses using custom exception handlers to match Microsoft's REST API guidelines format.

Jan 20·2 min read·299 words

Difference between constrained 'TypeVar' and 'Union' in Python

Understand when to use constrained TypeVar vs Union in Python type hints for consistent types across function parameters and return values.

Jan 19·2 min read·291 words

Don't wrap instance methods with 'functools.lru_cache' decorator in Python

Avoid memory leaks when caching instance methods with lru_cache by making cache containers local to instances instead of global.

Jan 15·5 min read·924 words

Cropping texts in Python with 'textwrap.shorten'

Crop text to character limits without breaking words using Python's textwrap.shorten for clean truncation with customizable placeholders.

Jan 6·2 min read·328 words

String interning in Python

Learn how Python's string interning optimizes memory by caching strings and using sys.intern() for custom string caching to improve performance.

Jan 5·3 min read·597 words

Structural subtyping in Python

Implement Go-style structural subtyping in Python with Protocol for duck typing and interface-based APIs without inheritance dependencies.

Dec 4·6 min read·1174 words

Automatic attribute delegation in Python composition

Implement automatic attribute delegation in Python composition using __getattr__ magic method for inheritance-like attribute access patterns.

Nov 28·2 min read·322 words

Access 'classmethod's like 'property' methods in Python

Learn how to access Python classmethods like property methods using metaclasses or Python 3.9+ decorator stacking for Enum classes.

Nov 26·2 min read·210 words

Don't add extensions to shell executables

Why executable scripts shouldn't have extensions. Learn GitHub's scripts-to-rule-them-all pattern for language-agnostic project automation.

Nov 23·1 min read·179 words

Use __init_subclass__ hook to validate subclasses in Python

Validate subclass schemas at definition time with Python's __init_subclass__ hook, a cleaner alternative to metaclasses for enforcing structure.

Nov 20·1 min read·121 words

Use daemon threads to test infinite while loops in Python

Test Python infinite loops safely using daemon threads with timeouts, allowing tests to complete without hanging or blocking execution.

Nov 18·1 min read·96 words

Running tqdm with Python multiprocessing

Integrate tqdm progress bars with multiprocessing.imap_unordered for visual feedback on parallel task execution across worker processes.

Nov 18·1 min read·88 words

Use 'command -v' over 'which' to find a program's executable

Replace which with command -v for POSIX-compliant executable lookup. Learn why command -v is the portable alternative for finding program paths.

Nov 16·1 min read·103 words

Write git commit messages properly

Master Git commit message conventions: imperative mood, 50-character subject, proper capitalization. Build coherent project history with consistent formatting.

Nov 11·1 min read·200 words

Python's 'functools.partial' flattens nestings Automatically

Discover how Python's functools.partial automatically detects and flattens nested partial applications for optimal performance and cleaner code.

Nov 8·1 min read·53 words

Use strict mode while running bash scripts

Enable Bash strict mode with set -euo pipefail to catch errors early. Exit on failures, treat unset variables as errors, and handle pipeline failures properly.

Nov 8·1 min read·67 words

Use curly braces while pasting shell commands

Prevent shell commands from executing immediately when pasting. Use curly braces to safely paste multi-line commands with hidden newline characters.

Nov 8·1 min read·82 words

Pedantic configuration management with Pydantic

Build a scalable Python configuration system with Pydantic and dotenv. Manage dev, staging, and production configs with type validation.

Jul 13·10 min read·1827 words

Interfaces, mixins and building powerful custom data structures in Python

Build custom data structures with Python's collection.abc mixins, abstract base classes, and interfaces for dict-like and set-like objects.

Jul 3·18 min read·3450 words

Deciphering Python's metaclasses

Explore Python metaclasses for metaprogramming: learn how classes are created, customize class behavior, and understand type as the default metaclass.

Jun 26·14 min read·2642 words

Implementing proxy pattern in Python

Learn the proxy design pattern in Python to add access control, caching, and validation layers without modifying core functionality.

Jun 16·12 min read·2216 words

Effortless API response caching with Python & Redis

Cache API responses with Redis in Python to reduce redundant requests, improve response times, and handle expiring key-value pairs efficiently.

May 25·7 min read·1242 words

Untangling Python decorators

Complete guide to Python decorators from first principles. Learn closures, higher-order functions, decorator patterns, and advanced techniques.

May 13·14 min read·2772 words

Effortless concurrency with Python's concurrent.futures

Master Python's concurrent.futures module for easy threading and multiprocessing. Learn ThreadPoolExecutor and ProcessPoolExecutor with examples.

Apr 21·13 min read·2460 words

No really, Python's pathlib is great

Replace os.path with Python's pathlib for elegant, object-oriented path manipulation with intuitive operators and unified file operations.

Apr 13·9 min read·1618 words

Running Python linters with pre-commit hooks

Automate Python code quality with pre-commit hooks running Black, isort, flake8, and mypy before each git commit for consistent formatting.

Apr 6·4 min read·636 words

Generic functions with Python's singledispatch

Replace complex if-elif chains with functools.singledispatch for type-based function dispatch and cleaner polymorphic behavior in Python.

Apr 5·3 min read·499 words

The curious case of Python's context manager

Deep dive into Python context managers. Learn to write custom managers with __enter__/__exit__, use contextlib decorators, and manage resources elegantly.

Mar 26·6 min read·1043 words

Reduce boilerplate code with Python's dataclasses

Master Python dataclasses to eliminate boilerplate code. Learn ordering, immutability, hashing, default values, and post-init processing.

Mar 12·4 min read·607 words