Skip to content

Welcome to my website 😄¤

Below is the list of all my blog posts.

You can also checkout my About page, or some projects I worked on in the Showcase.


Local HTTP server sending fake files for testing purposes

I have developed a Python client/library for aria2 called aria2p.

To test my code, I spawn aria2c processes to interact with them and see if everything works correctly. I know I could mock the calls, but I feel like actually testing the interaction between my client and aria2c is a better way to ensure my code does its best.

Until recently the test suite fed actual downloads to aria2c (like Linux distributions ISOs, metalinks, magnets, or torrents), but of course the inevitable happened: some URLs broke.

So I decided to go full local. This post describes my attempt at spawning local HTTP servers to serve fake/virtual files efficiently, files that are then fed to aria2c.


Passing Makefile arguments to a command, as they are typed in the command line.

In my Python projects, I use a combination of Duty (my task runner) and make.

My Makefile declares the same tasks as the ones written in duties.py, but in a generic manner:

TASKS = check test release

.PHONY: $(TASKS)
$(TASKS):
    @poetry run duty $@

So, instead of running poetry run duty check, I can run make check. Convenient, right?

Except that some duties (tasks) accept arguments. For example:

poetry run duty release version=0.1.2

So how do I allow the make equivalent?

make release version=0.1.2

Python packages and plugins as namespace packages

A user of mkdocstrings wrote a Crystal handler for their own use-case. They asked on the Gitter channel if we could allow to load external handlers, so they don't have to fork the project and install the fork, but rather just install their lightweight package containing just the handler.

We both saw Python namespace packages as good candidates, so I experimented a bit, and here are my conclusions.


How to edit the contents of a git commit

When you type change git commit or similar keywords in a search engine, you find many answers explaning how to rewrite a commit message, but not how to actually modify the contents of the commit.

This post quickly explains how to do that.


Migrate Disqus comments to Utterances (in GitHub issues) with Python

When I replaced Jekyll and my Jekyll-ReadTheDocs theme with MkDocs and a blog-customised version of the Material for MkDocs theme, the URLs of my posts changed.

I was using Disqus for comments, and they provide a way to migrate threads from old URLs to new URLs. Unfortunately, this time it didn't work for some reason (I had already done it once in the past and it worked fine).

I've read more and more criticism about Disqus related to privacy, so I looked at a replacement. The Disqus thread migration was not working so it was the perfect occasion!

I've read a few webpages and got interested in Isso. Unfortunately again, I did not manage to install it on my Raspberry Pi.

So I went with a much simpler solution: Utterances. You basically enable a GitHub app on your repository, add a script in your posts pages, and voilà: your new comment section powered by GitHub issues.


How to deal with spacing in Jinja2 templates

It started with a comment in a GitHub issue.

I often find it difficult to wrangle spacing jinja2 templates especially around optional clauses.

I couldn't wrap my head either about this. So I decided to write a script and test every combination of newlines, indentation and dashes or no dashes in {%-, with the goal being to find combinations that will not have an extra middle line when an optional Jinja clause is false.


Unify Python logging for a Gunicorn/Uvicorn/FastAPI application

I recently started playing with FastAPI and HTTPX, and I am deploying my app with Gunicorn and Uvicorn workers.

But when serving, the logs from each component looks quite different from the others. I want them to all look the same, so I can easily read them or exploit them in something like Kibana.

After a lot of hours trying to understand how Python logging works, and how to override libraries' logging settings, here is what I have...


Save the logs generated during a pytest run as a job artifact on GitLab/GitHub CI

While I was writing tests for one of my latest project, aria2p, I noticed that some tests that were passing on my local machine were now failing on the GitLab CI runner.

I decided I needed to write all exceptions to log files so I could inspect what happened on GitLab.


Challenge: fill a 2D space with one continuous line doing 90° angle turns in the same direction (left/right)

Last night I was doing that in my head: filling a 2D space with one continuous line doing turns at a 90° angle, always in the same direction. Other people do this as well, right?

Well, today I actually drawn it:


Django application as an authentication / authorization server for Shiny

As you may know, Shiny Server comes in two versions: open-source and professional. The professional adds security and authentication features like password protected applications, and controlled access via SSL and LDAP, Active Directory, Google OAuth, PAM, proxied authentication, or passwords. If you need these authentication features but don't want or can't spend $9,995 per year for the professional edition, then I got a solution for you!


How to install NVidia drivers on BunsenLabs/Debian 8 to setup dual screens

Honestly, this post is mostly a personal memo. I will NOT go through this again!


Docker Compose with NginX, Django, Gunicorn and multiple Postgres databases

This post explains how to setup your Docker configuration for a web application based on the Django framework. I got a lot of inspiration from other tutorials and Docker examples: you can check these resources with the links at the bottom of the post. You can also directly check the repository that reflects this tutorial.


Python static code analysis tools

Python static code analysis is often used in Continuous Integration. I use it in every Python or Django package I develop, into a Tox configuration. The difficult part is to choose the right tools, because there are many, and to configure them correctly.

Thankfully, there also are tools using other tools to reduce the amount of configuration we have to do. This ends up in a big mix of tools, which is represented in the following chart.


Write and use a tox plugin from inside your package

So let's say you wrote a program that is using tox and you want to add some options to tox's command-line. Reading at tox's documentation about plugins, you see that you have to make a pip installable plugin and setup some entry point. In fact, you can skip the pip installable side and integrate the plugin directly within your code.


Documentation in your shell scripts using shellman

When I write a script, I like to have a -h, --help option to help me remember what it does and how it works. But I was never delighted to write this help text. Besides, when your script's options change, you have to update the help text.

I also always liked man pages, their search feature and their ability to scroll up and down and not leave any output in the console. But maintaining a man page is even more tedious than maintaining a help text.

This is why I thought of using documentation in shell scripts. So I wrote shellman.


Django admin dashboard with Suit and Highcharts

One day my boss said "I want to see some statistical data about the users". I immediately thought about adding a custom page in the admin panel instead of creating a new view with admin restriction. I was already using django-suit which is a great theme (and more) for the Django admin panel, so I searched for a way to add a custom view within Suit. Looking at the issue from brunocascio on the repo, I found the comment written by rouxxx and linking to this post about django dashboard. I had then all I needed to start a proof of concept.