[Python] I examined the exe conversion method for distributing business efficiency tools.

Thing you want to do

I want to distribute a business efficiency tool made with python in-house. Many members are not familiar with PCs, so distribute them as exe files. There are several ways to make it into an exe. Think for yourself which method to use from the viewpoints of "startup time", "file size", "ease of distribution / introduction", etc.

Conclusion first

** I thought it was safe to make ** onefile with ** pyinstall ** ** + ** make it into an exe with the minimum required libraries installed in the virtual environment **. In situations where startup time is required, it may be necessary to give up on onefile conversion.

environment

Windows10 Home Python3.8.2(32bit) Visual Studio Code 1.45.1 PyInstaller3.6

Contents studied and verified

  1. Code to verify
    1. Execution by PyInstaller 1-1. Do not make it onefile (default) 1-2. Make one file
  2. Methods other than PyInstaller
    1. Make an exe in a virtual environment

0. Code to verify

I created a super simple test.py and made this file an exe by each method. There is no particular meaning to the imported pyautogui (because I felt lonely that there was no external library)

test.py


import pyautogui
print("Hello,World!")

The start-up time was measured with the tool described at the end of this paper.

1. 1. Execution by PyInstaller

The means of exe conversion that seems to be the most major at present. Since it is not a standard library, install it with pip. Install from the terminal with > pip install pyinstaller. After that, execute > pyinstaller <file to be converted.py> <-option> from the terminal, and exe conversion will start. As an option, you can set one file, which will be described later, rename the exe file, and hide the console (black screen) when it is started. Note that the optional "-" (hyphen) may be one or two.

python


> pyinstaller test.py --name test2 --noconsole --onefile

When the message ~ INFO: Building EXE from EXE-00.toc completed successfully. is displayed, the process is complete. The exe file is created in a folder called "dist" in the current directory. If no name is specified in the option, a file with the file name .exe to be converted is generated.

1-1. Do not make it onefile (default)

If --onefile is not specified in the option (= default), a folder with the file name is created in the dist folder, and the exe file is stored in it. The advantage is the fast startup time. It takes more than 5 seconds to start up with the one-file method described later, but it can be started up in less than one second without making it one-file. However, the inside of the directory looks like this. image.png In the case of my workplace, it is easy to imagine that even if this folder is distributed by saying "Please click XXX.exe in this to start it", it will not be used after a while. (If you can create a shortcut, there may be one chan)

1-2. Make one file

After all, I want to put the tools together in one file so that they can be used simply after distribution. It's easy to do. Just add the --onefile (or -F) option when running pyinstaller. This will add a single exe-only file to the dist folder. The disadvantage is the startup time. If no measures are taken, even a super-simple code like test.py will take more than 5 seconds to start.

2. Methods other than PyInstaller

"Cx-Freeze" and "py2ex" seem to be famous for Windows. It is said that py2ex only supports up to Python 3.4. (For the time being, if you download it directly from Github, it seems that it can support up to Python 3.7. I tried it, but I gave up because I did not understand the version switching of Python well) So I tried cx-Freeze. The following site was helpful for how to install and exe, so I will omit it. I tried to make Python an exe with cx_Freeze Since it is necessary to create a setting file called setup.py separately from the script to be converted, I am worried that it will take some time. (It seems that py2ex is the same) The startup time is fairly fast (about 0.6 seconds), but it seems that it can not be converted to one file, and the file size does not change much, so I felt that there was little merit compared to PyInstaller.

3. 3. Make an exe in a virtual environment

When test.py was converted with PyInstaller + onefile, the file that just displayed "Hello, World!" Became about 36M. This is still a good person, and it seems that it often exceeds 100MB depending on the environment. Apparently, PyInstaller tends to make files bloated, and the cause seems to be that it packages all the libraries installed in Python that you are using. Therefore, as a countermeasure, I learned in the following article that I should build a blank virtual environment with nothing installed, put the minimum necessary libraries in it, and make it an exe with pyinstaller. [Sad news] PyInstaller will spit out a 300MB exe file

I've organized my own way of building a virtual environment, so I'll write it down as a memorandum.

3-1. Create a virtual environment

Execute the "venv" command from the general terminal to build a virtual environment (abbreviation for Vertial ENVironment?)

python


> py -m venv <Arbitrary virtual environment name (here pyautogui_only)>

⇒ A folder with an arbitrary virtual environment name is created in the current directory.

3-2. Activate the created virtual environment.

Right-click "Activate.ps1" from the "Scripts" folder of the folder created earlier ⇒ Copy as a path ⇒ Paste to the general terminal ⇒ Delete "(double quotation marks) before and after ⇒ Execute with ENTER (move with cd) It is OK to execute it)

python


> C:\Users\aaa\Desktop\python\pyautogui_only\Scripts\Activate.ps1

If you get the error "Since script execution is disabled in this system", the script cannot be executed probably due to security settings. So, first execute the following command on the general terminal.

python


> Set-ExecutionPolicy RemoteSigned -Scope Process

Then run Activate.ps1 again and you should probably be able to activate it. This setting needs to be set again every time the terminal is shut down. The reference page ↓ also describes how to change the settings of VS Code permanently. Summary of settings for using smooth venv with Visual Studio Code for Windows If activation is successful, the virtual environment name will be displayed on the left side of the current directory of HyperTerminal.

python


(pyautogui_only) PS C:Users\~\ > _
3-3. Install only the required libraries with the pip command.

In the case of test.py this time, only pyautogui is installed. Don't forget to install PyInstaller as well. (By the way, if you get an error when installing the latest pyautogui, please also see here)

3-4. Run PyInstaller

It's OK as if it wasn't a virtual environment.

python


(pyautogui_only) PS C:Users\~\ > pyinstaller test.py --onefile

⇒ The exe file is output in the dist folder. (By the way, to get out of the virtual environment, execute the deactivate command in the general terminal)

As a result, in my case, the file size, which was about 36MB as it was, could be suppressed to about 10MB. The startup time was reduced from about 6 seconds to about 2.3 seconds.

Summary

The numerical values verified this time are as follows. As mentioned above, for the purpose of distributing business improvement tools, I think that PyInstaller + onefile + minimum library installation in a virtual environment is sufficient. (If it starts for a few seconds, it shouldn't be so painful every time) Creating a virtual environment one by one is a little troublesome, but it seems that exe conversion is not a task that occurs so frequently. image.png Of course, this result is the case of a super simple program like test.py. The situation may change as the number of external libraries used increases, so it is necessary to make a judgment each time.

Bonus: A program created to measure startup time

python



import time
import subprocess
import sys
import csv
import pyautogui
import os

if len(sys.argv) >= 2:

    start_time = time.time()
    subprocess.run(sys.argv[1]) #← Drag&Receive the path of the dropped file and execute
    end_time = time.time()
    process_time = end_time - start_time

    pyautogui.alert(str(sys.argv[1]) + " " + str(process_time)) #Just result display

    #Output the result as csv in the same directory as this file
    file_name = os.path.join(os.path.dirname(sys.argv[0]), "check_time.csv")
    with open(file_name, "a", newline="") as fo:
        csv_file = csv.writer(fo)
        csv_file.writerow([sys.argv[1], process_time])

↑ Make this an exe file, start the program by dragging and dropping, and measure the time it took to finish ⇒ Output.

Recommended Posts

[Python] I examined the exe conversion method for distributing business efficiency tools.
[Python] I tried substituting the function name for the function name
vprof --I tried using the profiler for Python
I tried the least squares method in Python
I tried python programming for the first time.
What I got into Python for the first time
I tried Python on Mac for the first time.
HoloViews may become the standard for Python visualization tools
I tried python on heroku for the first time
Refactoring tools for Python
I was hooked for 2 minutes with the Python debugger pdb
I didn't know how to use the [python] for statement
Miscellaneous notes that I tried using python for the matter
I examined the device tree
I downloaded the python source
I tried using the python module Kwant for quantum transport calculation
I got an AttributeError when mocking the open method in python
I passed the python engineer certification exam, so I released the study method
I made a scaffolding tool for the Python web framework Bottle
I tried to improve the efficiency of daily work with Python