Writing Python scripts for Ledger and compiling to a binary (with the Nix package manager)

5 views
Skip to first unread message

IanTwenty

unread,
Oct 20, 2025, 6:35:26 AM (7 days ago) Oct 20
to Ledger
Hope this might help anyone else who wants to get quickly started writing Python scripts for Ledger on Linux and optionally package them as a binary. It requires the nix package manager (not NixOS the distro, though that would work too). By the end we'll have our script in the form of a binary that can be run on any Linux.

On my distro (Fedora) ledger does not come with Python support, this can be seen from running ledger with arguments:

$ ledger
Ledger 3.3.2-20230330, the command-line accounting tool
without support for gpg encrypted journals and without Python support

If we attempt to use the python command anyway we get an error:

$ ledger -f myledger.ldg python
Error: Unrecognized command 'python'

So, we first need to get either a ledger binary with python support enabled or install the python module by itself. At this point there are some choices:

  1. Find a suitable package for our distro. For Fedora the standard repos only have plain ledger. There is the EPEL 7 repo which has a ledger-python, however adding this repo can cause conflicts with existing packages. Not ideal.
  2. Compile and install ledger ourselves with Python enabled. If you're already familiar with this process it might be the fastest approach.
  3. Use a container with a distro that does package ledger+python.
  4. Use the nix package manager to create an isolated environment with the right packages installed.

I'm going to look at (4) as I think it's the fastest approach if you already have or use the nix package manager.

Ledger's python module is already packaged in the nix repository as python313Packages.ledger. With the nix package manager installed we can simply start a new nix shell with python and the ledger module installed:

$ nix-shell -p python313Packages.ledger python3
$ python
Python 3.13.7 (main, Aug 14 2025, 11:12:11) [GCC 14.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

> > > import ledger
> > > help(ledger)
> > > ...


Success. We can now write and run python ledger scripts in this environment.

What if we want to take this work outside the nix environment to run anywhere and share with others?

The options for packaging in Python are numerous* but pyinstaller stood out to me as it can produce standalone binaries that will run on the same OS you build on (Linux/Windows/Mac/BSDs). If we add that to our nix environment we can produce a self-contained binary of our ledger python scripts. Say we've written a myscript.py we can package it up very simply in our environment:

$ nix-shell -p python313Packages.ledger python3 python313Packages.pyinstaller
$ pyinstaller --onefile myscript.py
...
7517 INFO: Build complete! The results are available in: /home/me/ledger/dist

The resulting binary is about 30MB on my system but it contains everything (the `onefile` flag). Users will not need to install anything else, not even python.

Due to the nature of nix a final step is needed to prepare the binary for running on non-nix systems:

$ patchelf --set-interpreter /lib64/ld-linux-x86-64.so.2 myscript
$ patchelf --remove-rpath myscript


The `patchelf` tool is readily available on any distro. Here we use it to rewrite the binary and remove the 'nix'ness so it can run anywhere. Namely setting the standard interpreter for glibc Linux distros and removing the library lookup rpath (which in nix is used to point at the nix store.) If curious there's more about why nix does this here: Binaries (nixos.wiki)- https://nixos.wiki/wiki/Packaging/Binaries

That's all there is to it. We now have a single binary we can we can share with any Linux users to let them run our ledger python script. It's a chunky binary at 30MB but in exchange for that size we greatly simplify the install process for users.

There a many tools for managing nix developer environments so you don't have to manage a nix shell all by hand, my current favourite is https://devenv.sh/ but there are others.

* = https://packaging.python.org/en/latest/overview/#packaging-applications
Reply all
Reply to author
Forward
0 new messages