PyInstaller is hackish though, I had to add tricks to setup.py by trial-and-error until I found why some config file or sub-module of a sub-package wasn't included when everything else was. It's also slow to launch, because it extracts the code into a temporary directory before importing python.dll, which then imports all the rest.
Containers are fine for a server after installing the runtime, which is already one too many steps. There isn't a self-contained app format that can run without installing something else before starting it.
Or containers.