python3 Compile with PyInstaller
Setup your venv
python -m venv someprogram
cd someprogram
scripts\activate
python -m pip install -r requirements.txt
Assumptions
We are going to assume there are several files in the same directory such as:
- main.py
- config.py
- database.py
- gui.py
- image_processing.py
- models.py
- pdf_generation.py
We will further assume that you start the program with the entry point of main.py such as:
python main.py
My particular program above also had image files and a database file, also in the same directory. This compilation did not include them, so I need to provide them with the executable it makes.iter
Install “PyInstaller”
pip install pyinstaller
Create app.spec
The .spec file can be named anything. It must end with .spec though. Note you must modify it to match your existing project, including subfolders. Extra files like images, databases, etc are not included in the compilation.
# -*- mode: python ; coding: utf-8 -*-
# Encryption type for code - None means no encryption
block_cipher = None
# Main Analysis object that finds all dependencies
a = Analysis(
['main.py'], # Entry point script
pathex=[], # Additional paths to search for imports
binaries=[], # Additional binary files (.dll, .so)
datas=[ # Non-Python files to include
('config.py', '.'), # Source file -> destination directory
('database.py', '.'), # '.' means same directory as exe
('gui.py', '.'),
('image_processing.py', '.'),
('models.py', '.'),
('pdf_generation.py', '.')
],
hiddenimports=['PIL', 'ttkbootstrap', 'fpdf'], # Imports PyInstaller might miss
hookspath=[], # Custom PyInstaller hooks
hooksconfig={}, # Configuration for hooks
runtime_hooks=[], # Scripts to run before frozen app
excludes=[], # Modules to ignore
win_no_prefer_redirects=False, # Windows-specific redirect behavior
win_private_assemblies=False, # Windows DLL handling
cipher=block_cipher, # Encryption settings
noarchive=False # Whether to embed Python bytecode
)
# Creates a Python executable archive
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
# Creates the final executable
exe = EXE(
pyz, # Include the PYZ archive
a.scripts, # Scripts to include
a.binaries, # Binary dependencies
a.zipfiles, # Zipped Python modules
a.datas, # Data files
[], # Additional files to include
name='YogaFlow', # Name of output executable
debug=False, # Include debug info
bootloader_ignore_signals=False, # Signal handling
strip=False, # Strip debug symbols
upx=True, # Use UPX compression
upx_exclude=[], # Files to not compress
runtime_tmpdir=None, # Temp directory at runtime
console=False, # GUI mode (no console window)
disable_windowed_traceback=False, # Error handling
target_arch=None, # Target architecture
codesign_identity=None, # Code signing (macOS)
entitlements_file=None # macOS entitlements
)
pyinstaller app.spec
Get the exe
My actual exe is now located and created in the ./dist folder. Your friends do not need to install venv anymore, they can just run the exe.
Signing
Signing alerts (unsigned binary) might give an error when your friend runs the program. You can get around this and not show the error by purchasing a code signing certificate for between $100-$1000 a year. If you have purchased this cert, then you can sign your executable:
signtool sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /f "YourCertificate.pfx" /p YourPassword "dist\yourapp.exe"
https://learn.microsoft.com/en-us/windows/win32/seccrypto/signtool