https://www.gravatar.com/avatar/485df9434f4908b5f6fab0750c113972?s=240&d=mp

Han

Introduction to logging in Python

A gentle, practical introduction to logging in Python


Why bother with a dedicated logging library?

  • Prints don’t scale. print() is fine during quick experiments, but real programs need a record that can be filtered, rotated, or shipped elsewhere.
  • Separation of concerns. You decide what to log in your code; logging decides where and how to write it (console, file, etc.).
  • Built-in, no extra dependency. The standard library’s logging module is powerful enough for most applications.

Core concepts

ConceptRole in the ecosystemTypical examples
LoggerThe entry point your code calls (logger.info(...)). You can have many, one per module."__main__", "my_package.worker"
HandlerDecides where the record goes.StreamHandler (stdout), FileHandler, TimedRotatingFileHandler, SMTPHandler
FormatterDecides how the record looks.'%(asctime)s - %(levelname)s - %(name)s - %(message)s'

A minimal logger

import logging

logging.basicConfig(
    level=logging.INFO,
    format="%(levelname)s | %(message)s"
)

logging.info("Hello, world!")
  • basicConfig is a one-liner good for small scripts.
  • In bigger projects, mixing multiple modules / log files, you’ll want finer control.

Rotating files at midnight

Rotating a log file means creating a new log file after a certain time or size limit is reached. In this case, a new file is created every night at midnight. Only the most recent two log files are kept—yesterday’s and today’s—while older ones are deleted automatically.

Rediscovering Python's Pathlib

From Type Hint to Power Tool: Python’s Pathlib

For a long time, I used Path from Python’s pathlib module purely as a type hint - a way to make function signatures look more modern and semantically clear. Like this:

from pathlib import Path

def process_file(file_path: Path):
    ...

It changed when I started building an application that handled user-uploaded documents. I had to create temporary folders, write intermediate files, manage output paths, and ensure directories existed before saving results. That’s when Path went from just a type hint to a core part of my file management logic.

Git with Vim Fugitive: A Streamlined Workflow

If you’re working with Git and Vim, vim-fugitive is an essential plugin that transforms your editor into a full-fledged Git interface. Here’s how I use Fugitive to review, stage, and commit changes—without ever leaving Vim.

Browsing Git History and Logs First

Before jumping into edits, it’s often useful to understand the file’s history or recent project changes.

  • :Git log — shows the project’s commit history in reverse chronological order
  • :0Gllog — shows the history of the current file

To explore who changed what in a file:

UV Tutorial: All‑in‑One Python Package Manager!

📝Update (2025-09-06): I’ve added a new section on using --native-tls with corporate proxies. It covers why uv may fail with SSL errors at work and how to fix it by making uv trust your system certificates.

Meet uv – A Blazingly Fast, All‑in‑One Python Package Manager

In my last post, I covered Poetry. It’s a solid dependency manager—but it still leaves you juggling other tools: pip for installs, virtualenv for isolation, pyenv for Python versions, and pip-tools or Pipenv for locks. That bounce between tools adds friction. uv removes it. This single, Rust-built project manager—now one of the most popular tools in the Python ecosystem—installs Python, creates virtual environments, resolves and locks dependencies, and even publishes to PyPI, all from one blazing-fast CLI (often 10–1000× faster).

Inside DeepSeek-R1

DeepSeek’s latest moves have sent ripples through the AI community. Not only has it marked the beginning of a new era in artificial intelligence, but it has also made significant contributions to the open-source AI landscape. Their engineering techniques behind DeepSeek are truly impressive, and their reports are quite enjoyable. However, understanding their core ideas can be challenging and demands a substantial amount of effort.

At the forefront of this innovation is DeepSeek-R1, a model that built upon the foundation established by preceding projects such as DeepSeek Coder, Math, MoE, and notably, the DeepSeek-V3 model. While DeepSeek-R1 is the center of the DeepSeek’s frenzy, its success is rooted on these past works.

Abstract Classes or Protocols

Introduction

When it comes to writing clean, maintainable, and scalable Python code, design matters. As your projects grow, you’ll often find yourself needing to enforce structure, ensure consistency, and promote reusability. This is where Python’s Abstract Base Classes (ABCs) and Protocols come into play—two powerful features that help you design better software.

Abstract classes act as blueprints for other classes, allowing you to define methods that must be implemented by any subclass. They’re typically used for creating a shared foundation while enforcing a specific structure. Protocols, on the other hand, take a more flexible approach. Instead of relying on inheritance, they let you define interfaces based on behavior, making them ideal for duck typing (or structural subtyping) and runtime flexibility.