In this Python tutorial, we will introduce you to “Nuitka” which is a Python Library used to convert your code to standalone executables. You may have heard of similar libraries like Pyinstaller, but rest assured Nuitka stands out from the rest!
To quickly summarize a few benefits on Nuitka,
- Improved performance since it converts the Python code to a binary format first, then compiling it to machine code with a C compiler (faster than native Python code).
- Fast Load times.
- Improved security and protection of source code as compared to most other
.py to .exe
converters. - Easy to use (all done through the console window)
- Cross-platform support.
How does Nuitka Work?
How exactly does Nuitka work though? Let’s take a slightly more detailed look at the whole process.
- Nuitka starts by parsing the Python source code and building an abstract syntax tree (AST) representation of it. The AST represents the structure of the code and contains information about the code’s variables, functions, and control structures.
- Nuitka converts the AST into an intermediate representation (IR). The IR is a lower-level representation of the code that is easier for a computer to understand and execute. It is also more portable, as it is not tied to any specific programming language or runtime environment.
- Nuitka generates C code from the IR. This C code is a direct translation of the IR and represents the same program as the original Python code.
- Nuitka uses a C compiler to compile the C code into machine code. This machine code is specific to the target system and can be executed directly by the computer’s processor.
- Nuitka packages the machine code into an executable file. This file can be run on the target system without requiring a Python interpreter to be installed.
Tutorial: How to setup Nuitka
Time to begin using Nuitka!
First we need to install it, just like how we would install any other python library. We will be using pip to install it as shown below.
python -m pip install nuitka
Next, we will just double check that everything is “O.K” by running the below command. It should gives you the current version number of your Nuitka installation.
python -m nuitka --version
And that’s it! Nuitka is now installed on your system and we can begin using it to create Executables for our program.
All you have to do is run the following command. The --standalone
option specifies that we wish to create a standalone executable. There is another option called “onefile” which we will discuss a bit later.
python -m nuitka --standalone file.py
“file.py” here is the name of our Python file which we wish to convert. This can also be a file path if you are calling this command from a different folder.
If you have a simple script, with no additional libraries installed then the above command will work perfectly for you. You will see two new folders popup in the same directory where you called this command from.
The folders will be named name.build
and name.dist
, where name
is the name of your Python file. The build
folder contains the compiled object code, and the dist
folder contains the Exe, and other required dependencies.
The dist
is the main folder of importance here. You can copy it around to other machines now to distribute your applications. If you want a single executable file, you can look at the onefile option (discussed in this article a bit later).
Tutorial: Advanced Nuitka Usage
What we have discussed so far will work perfectly fine for simple scripts. There are many libraries however, which need to be explicitly included as Nuitka isn’t able to detect and copy them over properly.
Furthermore, there are other minor options and features you need to be aware. We will be discussing those in this section.
First up is the concept of plugins. Lets assume we have the following Tkinter (used for GUI) code (which simply creates an empty window).
import tkinter as tk
from tkinter.filedialog import askopenfilename, asksaveasfile
class Window():
def __init__(self, master):
self.main = tk.Frame(master, background="white")
master.geometry('300x200')
self.main.pack()
root = tk.Tk()
window = Window(root)
root.mainloop()
Attempting to compile this will raise the following warning.
Nuitka-Plugins:WARNING: Use '--enable-plugin=tk-inter' for: Tkinter needs TCL included.
Attempting to compile your code while ignoring these warnings will not work, so don’t even try it. Use CTRL + C to break the compilation immediately, and restart the compilation with the required plugin enabled.
A “plugin” is basically just an additional option that can be enabled. We will re-run the compile command with the plugin for Tkinter enabled this time.
python -m nuitka --standalone --enable-plugin=tk-inter file.py
Other known libraries which will require this explicit include are PyQt5, Pyside6, Pyside2, and TensorFlow. You can find a complete list of plugins here.
There is still one other issue though. Whenever we run our EXE, a console window will also be created by default. This needs to be disabled (unless you want it for some reason) for our application as it is GUI based.
python -m nuitka --disable-console --standalone --enable-plugin=tk-inter file.py
As shown above, we have added an extra option called --disable-console
which will achieve the desired effect.
Onefile Mode
To use onefile instead of standalone, all you need to do is swap out the --standalone
option for --onefile
.
Here is an example.
python -m nuitka --onefile file.py
This will produce a single executable file which can be distributed. It’s more compact, though its load time will be a bit longer than Standalone as the EXE will unpack itself first (in a temporary directory).
Onefile can be a bit tricker to use than Standalone though. It is recommended to always try using Standalone before moving to Onefile. This is mostly due to data files and their file paths.
Note: If you feel like the Onefile load time is a bit high, then you have the option of adding a “Splash-screen” to your Nuitka EXE.
Optimizations
Here are some useful optimizations that can be enabled to improve your Nuitka experiance.
Ordered-Set
Nuitka will most likely give you the following warning right in the start of the compilation process if you do not have the ‘ordered-set’ library.
Nuitka:WARNING: Using very slow fallback for ordered sets, please install 'ordered-set' PyPI package for best Python compile time
Nuitka:WARNING: performance.
Simply run the following command to enable this optimization to speed up the compilation process a bit.
pip install ordered-set
zstandard
To reduce the Nuitka executable size, we can install the following module, zstandard (which Nuitka also recommends). All you need to do is install it, Nuitka does the rest (when you compile your program).
pip install zstandard
Here is how much of an improvement we observed. It brought down the EXE size from 25mb to 7mb. That’s amazing.
Nuitka-Onefile:INFO: Onefile payload compression ratio (29.63%) size 25958834 to 7690762.
Note: Adding this compression step will increase compilation time a bit.
This marks the end of the Nuitka Tutorial for creating Python EXE’s. Any suggestions or contributions for CodersLegacy are more than welcome. Questions regarding the tutorial content can be asked in the comments section below.