Skip to main content

Python-to-exe SFX builder using PyInstaller

Project description

q2sfx

https://github.com/AndreiPuchko/q2sfx

q2sfx is a Python package and CLI tool to create self-extracting executables (SFX) from Python applications built with PyInstaller.

It embeds your Python application (as a ZIP archive) into a Go-based SFX installer, supports console or GUI modes, and can optionally create a desktop shortcut.


✨ Key Features

  • Build Python apps using PyInstaller (optional, can start from existing build).
  • Pack PyInstaller output into a ZIP payload (optional, can start from existing ZIP).
  • Embed payload into a Go-based self-extracting executable (SFX).

The generated SFX executable provides:

  • Installer: on the first run extracts all payload data (PyApp) into the given folder(optional), creates the shortcut (optional) and runs PyApp.

  • Updater: When updating, the tool only overwrites core components (.exe, .ver, _internal/, and assets/) and runs PyApp. Custom user folders, logs, or local databases remain untouched. Before overwriting, existing core files and directories are automatically backed up as .bak. A platform-specific rollback script (_rollback.bat on Windows or _rollback.sh on Linux/macOS) is generated, allowing the previous version to be fully restored if needed.

  • CLI Flexibility: SFX Supports flags to force console mode, change the installation path or shortcut name.

  • Progress bar with animated spinner.

  • Cross-platform: Windows, Linux, macOS.

  • Progress indication during extraction, including an animated spinner.

  • Safe overwrite behavior — only predefined folders and files are modified (_internal, assets, and the executable itself), preventing accidental data loss.


Requirements

  • Python 3.8–3.11
  • Go (for building the SFX)
  • PyInstaller (if you want the builder to run it automatically)

Installation

For End Users

Install q2sfx as a Python package via Poetry:

poetry add q2sfx

or

pip install q2sfx

For Developers

git clone https://github.com/AndreiPuchko/q2sfx
cd q2sfx
poetry install
poetry add --group dev pytest pytest-cov

Usage

CLI usage

q2sfx --help
usage: q2sfx [-h] [--version] [-o OUTPUT] [--console] [--no-pyinstaller] [--dist DIST] [--payload PAYLOAD] [--build-time BUILD_TIME] [--no-ver-file] app

Build a self-extracting executable (SFX) from a Python application using PyInstaller + Go.

positional arguments:
  app                   Path to the Python entry script (e.g. app.py)

options:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  -o OUTPUT, --output OUTPUT
                        Output SFX file path (default: <app_name>_sfx.exe in dist.sfx)
  --console             Build payload application with console (default: GUI)
  --no-pyinstaller      Assume PyInstaller build already exists (skip PyInstaller step)
  --dist DIST           Use existing PyInstaller dist directory instead of running PyInstaller
  --payload PAYLOAD     Use existing payload zip instead of creating one
  --build-time BUILD_TIME
                        Build timestamp for .ver file (default: current datetime)
  --no-ver-file         Do not include a .ver file in dist.zip

Basic usage

Build a console application from Python code
This runs PyInstaller with default options and wraps the result into an SFX.

from q2sfx import Q2SFXBuilder

final_exe = Q2SFXBuilder.build_sfx_from("tests/test_app.py", console=True)
print("Built SFX:", final_exe)

Build an SFX from an existing PyInstaller dist/ directory Useful when PyInstaller requires custom options or hooks.

final_exe = Q2SFXBuilder.build_sfx_from(dist_path="dist/test_app", output_name="t2.exe")
print("Built SFX:", final_exe)

Build an SFX from a ZIP payload Useful when your distribution contains extra assets or was prepared externally.

final_exe = Q2SFXBuilder.build_sfx_from(payload_zip="dist.zip/test_app.zip", output_name="t3.exe")
print("Built SFX:", final_exe)

Advanced usage

You can start the builder from any stage:

builder = Q2SFXBuilder("your_app.py", console=True)

Use an existing PyInstaller dist folder

builder.set_dist("dist/your_app")

Or use an existing ZIP payload

builder.set_payload("dist/your_app.zip")

Build SFX

builder.build_sfx("dist.sfx/my_app_setup.exe")


ZIP file notes

  • The Python application name must match the ZIP archive name.
  • By default, SFX will be generated in the dist.sfx/ folder.

Simple Auto-update example

Source Code

Each SFX build produced by q2sfx can include a .ver file containing the build timestamp (for example: 2025-12-31 18:42:10).

The application can compare its local .ver file with a remote one and automatically download and run a newer SFX build.

Expected files on the update server

test_app_sfx.exe test_app_sfx.ver

How it works

  1. On startup, the application checks whether it is running as a frozen executable.
  2. It reads its local <app>.ver file.
  3. It downloads and compares the remote .ver file.
  4. If a newer build is available:
    • the new SFX is downloaded
    • launched in detached mode
    • the current application exits
  5. The new SFX handles safe replacement and rollback internally (.bak files + _rollback.bat / _rollback.sh) and starts updated app

Example update logic

if new_build_time > current_build_time:
    # download new SFX
    # run installer
    # exit current app

Simple GUI demo workflow (for Windows)

# create virtual enviroment (python 3.9 used)
py -3.9 -m venv .venv
# activate virtual enviroment
.\.venv\Scripts\activate
# install deps for demo project
pip install q2db q2gui
pip install git+https://github.com/AndreiPuchko/q2sfx.git
# clone demo project
git clone https://github.com/AndreiPuchko/q2-short.git
# build SFX
q2sfx .\q2-short\app.py
# run the result
cd dist.sfx
./app_sfx.exe

License

MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

q2sfx-0.1.8.tar.gz (11.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

q2sfx-0.1.8-py3-none-any.whl (12.2 kB view details)

Uploaded Python 3

File details

Details for the file q2sfx-0.1.8.tar.gz.

File metadata

  • Download URL: q2sfx-0.1.8.tar.gz
  • Upload date:
  • Size: 11.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.5.0 CPython/3.11.7 Windows/10

File hashes

Hashes for q2sfx-0.1.8.tar.gz
Algorithm Hash digest
SHA256 64ee6d6f9ab2df6eb759db9086bab92879ec6b4fe0a3315e3cf552f6df30fdf2
MD5 d19e705381ec0b533043319fc5438264
BLAKE2b-256 ef2f03e0e63b6e9a59d0b42fa5a6182b4617a38c6024ea784ce05cfc142bd793

See more details on using hashes here.

File details

Details for the file q2sfx-0.1.8-py3-none-any.whl.

File metadata

  • Download URL: q2sfx-0.1.8-py3-none-any.whl
  • Upload date:
  • Size: 12.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.5.0 CPython/3.11.7 Windows/10

File hashes

Hashes for q2sfx-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 a29dde34e89b66cd1d1484d194fbfb5006e1f92be9ab5c482d4ac1e643eb6d6e
MD5 1a8d6c5562d633088631529bd14424d3
BLAKE2b-256 7be96688ba252e2fea13471c80b90c4a273f020c11745ed2804a30ef827f3b0b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page