Skip to main content

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

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.

Release history Release notifications | RSS feed

This release

0.1.8 This release

2 files

Supported by

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