Converting Python scripts into a Windows executable (.exe) allows you to share your application with users who don't have Python installed. One of the most popular tools for this is PyInstaller. In this article, we'll cover the step-by-step process, how to include resources, use custom icons, and understand sys._MEIPASS for bundled resources.
Step 1. Install PyInstaller
You can install PyInstaller via pip:
pip install pyinstaller
Step 2. Basic Conversion
To convert your Python script into an .exe, open your terminal in the project directory and run:
pyinstaller --onefile your_script.py
Step 3. Add an Icon
To add a custom icon to your executable:
pyinstaller --onefile --icon=youricon.ico your_script.py
Make sure your icon is in .ico format.
Step 4. Add External Resources (Images, JSON, Templates)
If your application requires additional resources (images, configuration files, etc.), you need to tell PyInstaller to bundle them. Use the --add-data option:
pyinstaller --onefile --add-data "images/logo.png;images" your_script.py
Explanation
Step 5. Accessing Resources at Runtime (sys._MEIPASS)
When PyInstaller packages your app, it extracts files into a temporary folder at runtime. To access these files reliably, you should use a helper function that checks if sys._MEIPASS exists.
import sys
import os
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
# PyInstaller stores temp folder path in _MEIPASS
base_path = sys._MEIPASS
except AttributeError:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
# Example usage:
img_path = resource_path("images/logo.png")
print("Using image:", img_path)
This ensures your program can find resources both when running from source and when running as an executable.
Step 6. Distribution
After building, your .exe will be in the dist folder. You can share it directly, but note:
The .exe may be large since it includes Python and dependencies.
Use a tool like UPX (optional) to compress the size:
pip install upx
Then rebuild with PyInstaller.
Summary