Python

PySide6 in Practice #8 Release Polish: Icons, Versioning, Signing, GitHub Actions
5 min read

PySide6 in Practice #8 Release Polish: Icons, Versioning, Signing, GitHub Actions

The series finale: finishing the app into something you can hand to others. Managing icons, names, and resources with a PyInstaller spec file, defining the version in one place and feeding it to the app and the build, why unsigned apps get blocked on download and the lay of macOS notarization and Windows signing, a GitHub Actions matrix that builds for three operating systems, and a retrospective of the whole series.

PySide6 in Practice #7 Testing: pytest-qt and a Per-Layer Strategy
4 min read

PySide6 in Practice #7 Testing: pytest-qt and a Per-Layer Strategy

Dismantling the belief that GUI apps are hard to test, using the layer structure: why Qt-free core tests should be the most numerous, verifying the repository against a temp-file database, how pytest-qt's qtbot manages QApplication and the event loop for you, testing a model's contract (rowCount, data, setData), waiting on signals with waitSignal and widget interaction tests, and running Qt tests headless in CI.

PySide6 in Practice #6 The Settings Screen: QSettings, Dark Theme, Data Backup
4 min read

PySide6 in Practice #6 The Settings Screen: QSettings, Dark Theme, Data Backup

Handing the hardcoded decisions to the user: how QSettings stores values in each platform's standard location and its type traps, wiring the settings screen to live behavior (reminder hour, close-button action), dark and light themes via stylesheet swapping with system-theme detection, and the final piece of respecting user data — CSV export and database backup.

PySide6 in Practice #5 Tray Residency and Reminders: An App That Survives Its Window
5 min read

PySide6 in Practice #5 Tray Residency and Reminders: An App That Survives Its Window

Implementing the residency that turns a habit tracker into a real tool: putting an icon and menu in the system tray with QSystemTrayIcon, converting window close into hide via closeEvent and the UX debate around it, sending daily reminders at a set hour with QTimer, the limits and platform differences of tray notifications, and single-instance handling that prevents two copies of the app.

PySide6 in Practice #4 The Stats Screen: Painting a Contribution Heatmap with QPainter
5 min read

PySide6 in Practice #4 The Stats Screen: Painting a Contribution Heatmap with QPainter

Drawing the screen no stock widget provides: keeping statistics logic (completion rate, streaks) in the Qt-free core layer where it stays testable, painting a GitHub-style heatmap widget with paintEvent and QPainter, coordinate math and size handling with sizeHint, hit-testing the cell under the mouse for tooltips, and the custom-widget rule that repaints are requested through update().

PySide6 in Practice #3 The Today Screen: A Custom Model and Check Toggling
4 min read

PySide6 in Practice #3 The Today Screen: A Custom Model and Check Toggling

Building the app's first real screen: why stuffing items directly into a list widget hits its limits fast in real apps, subclassing QAbstractListModel to connect the repository to the view, exposing multiple faces of data through roles, the path a check toggle travels from view through model to database, updating views precisely with the dataChanged signal, and the add-habit dialog.

PySide6 in Practice #2 The SQLite Data Layer: Repository Pattern and Migrations
5 min read

PySide6 in Practice #2 The SQLite Data Layer: Repository Pattern and Migrations

Building the app's memory: why SQLite is the default for desktop apps, finding the OS-specific app-data folder correctly, designing the habits and checks schema, the repository pattern that confines SQL to one place, and the tiny user_version-based migration scheme that keeps user data intact across app updates.

PySide6 in Practice #1 Project Design: App Architecture Through a Habit Tracker
4 min read

PySide6 in Practice #1 Project Design: App Architecture Through a Habit Tracker

First post of a hands-on series that takes a PySide6 beginner all the way to a finished app: what we build (a local habit tracker) and why this subject, breaking feature requirements into screens, splitting code into UI, core, and data layers and why, uv-based project setup, and the main-window skeleton that will carry the next seven parts.

NumPy Fundamentals: Why Arrays Beat Python Lists, and How to Use Them
6 min read

NumPy Fundamentals: Why Arrays Beat Python Lists, and How to Use Them

NumPy, the foundation of Python data work, from first principles: the memory layout that makes Python lists inherently slow and how ndarray fixes it, vectorized operations that eliminate loops, the broadcasting rules that let differently-shaped arrays compute together, the trap of slices being views rather than copies, reading aggregations through the axis concept, and the cases where NumPy is the wrong tool.

What's New in Python 3.14: t-strings, Deferred Annotations, Official Free-Threading
5 min read

What's New in Python 3.14: t-strings, Deferred Annotations, Official Free-Threading

The practical changes in Python 3.14, released October 2025: t-strings that look like f-strings but produce template objects, deferred annotation evaluation becoming the default, what the free-threaded (no-GIL) build losing its experimental label means, multiple interpreters and Zstandard compression landing in the standard library, parenthesis-free except syntax, and the remote debugging interface — everything worth knowing before upgrading.

Deploying Python Web Apps to Production: gunicorn, uvicorn, systemd, Docker
5 min read

Deploying Python Web Apps to Production: gunicorn, uvicorn, systemd, Docker

From why the development server must never serve production traffic to the standard deployment stack: the WSGI and ASGI split, combining gunicorn with uvicorn workers, how to choose a worker count, managing the process with a systemd service, what the nginx reverse proxy is actually for, the basic shape of a Docker deployment, logs to stdout, health checks, and graceful shutdown — as a checklist.

Async Task Processing in Python with Celery: Queues, Workers, and an Ops Checklist
5 min read

Async Task Processing in Python with Celery: Queues, Workers, and an Ops Checklist

How to move work that never belonged inside a web request into Celery: the task-queue architecture of broker, worker, and result backend, defining tasks and calling delay, configuring retries with exponential backoff, the idempotency principle that follows from at-least-once delivery, operational settings like acks_late and time limits, monitoring with Flower, and when FastAPI BackgroundTasks or RQ is all you actually need.