Lobstersgram, a fast lobste.rs client on Telegram

Lobsters (lobste.rs) is probably my main source1 of tech reading: it is a human-curated feed that prioritizes content quality, with no shady clickbait, abusive ads, or hostile comments. Even though I am not a member (it requires an invitation), I strongly identify with its "old internet" spirit.

Yesterday, mostly via ChatGPT on my phone, I built Lobstersgram, a bot that works as a fast Lobste.rs client on Telegram.

Every now and then, if the bot detects new posts, it sends you a short message with an intro and a link to the article copied to telegra.ph, plus the original source link and the discussion thread on the forum. Why republish on Telegraph? Because it supports instant view, which allows preloading the content with a simple, consistent style that is ideal for mobile reading.

If you have Telegram, you can try it at @lobstersgram_bot

Commands:

  • /start to subscribe
  • /unsubscribe to stop receiving

(Note: it only runs every 2 hours, so it will reply eventually, but do not expect immediacy.)

Here is a demo I recorded capturing my phone screen (with a notification from the family group included).

Read more…

My opinionated scaffolding for modern Python projects

Python is a pragmatic programming language and asks for very little to get started. A text file with valid code, conventionally ending in .py and forming a “module” in Python jargon, is already a small program (a script); we run it with python <file> and we are done. But when that simple piece of code needs to grow into more files or deserves to be distributed —maybe because it will be a dependency of another project or simply because someone else might benefit— then it needs some structure and metadata.

That is not exclusive to Python: when you start a software project there is always a basic set of files and structures that serve as a starting point; the minimum set of files, folders, configs, and "basic" code you need when you want to share code as an app or library: the project boilerplate. The boilerplate does not define logic, but it does lay the technical foundation—often based on conventions and sometimes on personal taste—on which everything else will be built.

This article details the decisions I made for the template and automated scaffolding I created for my projects, based on Copier.

In short:

  • 🐍 Modern Python package (3.12+)
  • 📦 Build and dependency management with uv, split by groups (dev/qa/docs)
  • 🧹 Linting and formatting via Ruff with a broad set of rules enabled
  • ✅ Type checking via ty
  • 🧪 Tests with pytest, coverage.py and extensions
  • 📚 Docs with Sphinx, MyST and a few extensions, deployed to GitHub Pages
  • 🤖 GitHub project creation automated through GitHub CLI
  • ⚙️ CI workflow on GitHub Actions
  • 🚀 Automated releases via Trusted Publishing
  • 🧠 Sensible defaults via introspection to minimize answers in the initial questionnaire
  • 🛠️ Makefile with shortcuts for common tasks
  • 📄 Generation of generic docs such as LICENSE/CODE_OF_CONDUCT/AGENTS.md, etc.
  • 🌀 Initial setup of the development environment and git repo
  • ♻️ Projects updatable with copier update

And a bunch more details I am surely forgetting.

Read more…

Expanding the Python universe with Rust

My wife Natalia, among many other talents she has, is a German-to-Spanish translator and, besides freelancing, works as a researcher and lecturer at the Universidad Nacional de Córdoba, Argentina.

Probably because foreign languages are almost as hard for me as dancing or singing (sorry to my colleagues who have had--and will have--to suffer through my spoken English), I have deep admiration for polyglots. Not for the mere ability to swap words or produce more vowel sounds, but for the power to know and feel different universes. That is what Jorge L. Borges was complaining about when someone mangled one of his tales with a translation:

According to dictionaries, languages are repertoires of synonyms, but they are not. Bilingual dictionaries make you believe that every word in one language can be replaced by another word in a different language. The mistake is ignoring that each language is a way of feeling the universe.

I extrapolate that admiration for polyglotism--the art of widening your vital universe--to people who know many programming languages deeply. They bring ideas from one universe to the next, bursting bubbles, prejudices, blind spots. They propose new ways and limits, taking inspiration from here to create over there. Python would not exist without that kind of people. Long live those "Marco Polos" who connect universes.

Since I'm ambitious (but not quite dedicated enough) to open a small window into the Rust universe, I compensate for my slowness and distraction with tools and shortcuts.

This is a simple way to expand my Python universe with a "Marco Polo" who knows the Rust world and can open a window to that other realm full of possibilities.

Read more…

How to use WhisperX in Google Colab (2025)

WhisperX is an advanced speech-recognition pipeline built on top of Whisper, OpenAI's open-source ASR model. It runs on PyTorch, and while it can operate on a CPU, performance is significantly enhanced with a CUDA-compatible GPU (i.e., NVIDIA). WhisperX improves upon the original model with more accurate and faster alignment, support for larger models, and optional speaker diarization. The result is high-quality transcriptions with precise word-level timestamps and clear speaker identification, and it claims to be up to 70x faster than the original model.

My laptop doesn't have a GPU with CUDA support, so I run WhisperX on Google Colab, and this is a short tutorial on how I set it up and use it in this cloud environment.

Read more…

textual-tetris, a Tetris in the terminal

Since I remain unemployed while prioritizing my search for mental health, I spend my nerdy time on two worthwhile tasks:

  1. Collaborating with organizations that need technological solutions but do not have the budget to compete in the market for my skills.
  2. The one relevant to this post: learning new things by implementing old ideas from the permanent TO DO list I keep here, the ones I almost never found time for.

This time I wanted to learn a bit about Textual (the elder sibling of rich), an excellent Python framework for building text-based users interfaces.

And while I was at it, I learned how to make a Tetris clone that is pretty decent to play, does not look that ugly, and currently sits at under 600 lines of Python code, comments included. It looks like this:

But a taste is worth more than a thousand screenshots: open a terminal and, if you have uv installed (you should!), run:

uvx textual-tetris

And you are already playing Tetris!

Read more…