1

I want to dynamically convert a python file into a .exe. I have already tried using auto-py-to-exe, but it involves the usage of a GUI and does not involve programmatic conversion of the file.

Taking the example of the code provided below, I want to convert the file second.py, into a .exe file, purely using code, and without any manual actions whatsoever.

first.py -:

import os

code = """
print(hello world)
"""

with open("second.py", "w") as second_file:
        second_file.write(code)

convert_to_exe('second.py') # Yet not clear, on how to achieve this.
UpAndAdam
  • 4,515
  • 3
  • 28
  • 46
  • Did you try to solve the problem yourself? What sources have you referred to, prior to asking this question? Please read [**How to ask**](https://stackoverflow.com/help/how-to-ask) – typedecker Jun 30 '23 at 11:03
  • why do i ask the question if i can answer it in the first place – Prison Mike Jun 30 '23 at 11:16
  • Its not about being able to answer a question, its about having done appropriate research before hand prior to asking a question. Unlike other forum websites, stack overflow has one of it's rules for asking questions as "Research before you ask". If you have not even tried to find a solution to it elsewhere on the internet, then chances are it can and has already been solved and you're filling the website up with a redundant new question. Of course we are all here to help each other, but only when the help is really needed and there is no other source of information available. – typedecker Jun 30 '23 at 11:21
  • If you had a question regarding something very basic that could be found anywhere on the internet, and someone else the next day asked the same question since they had the same doubt, the site would be filled with duplicate questions. This site has been made specifically to provide a safe storage to all programming knowledge for programmers to use whenever they run into an issue, but asking a question that has already been answered in multiple other places on the internet and can be easily found via some research is redundant. Furthermore, all of this is part of the site's rules. – typedecker Jun 30 '23 at 11:23
  • yes i actually try to find solution for hours i just couldnt find the solution i needed – Prison Mike Jun 30 '23 at 11:25
  • 1
    Oh I see, well it would be of help in solving the problem, if you could link the sources you visited to try and find a solution to this. :D – typedecker Jun 30 '23 at 11:26
  • https://www.datacamp.com/tutorial/two-simple-methods-to-convert-a-python-file-to-an-exe-file now this is good for manually build the exe file but i kinda want to automate the whole process – Prison Mike Jun 30 '23 at 11:28
  • make, invoke, doit ? – rasjani Jun 30 '23 at 11:42
  • @rasjani am sorry i dont understand what you meant – Prison Mike Jun 30 '23 at 11:44
  • @PrisonMike Have you looked into cx_freeze? Also can you mention exactly in what way you expect to programmatically/dynamically create an exe? What are going to be your configurations for it? How is it going to know which file to pick and from where? – typedecker Jun 30 '23 at 11:47
  • @typedecker please look the edited question... – Prison Mike Jun 30 '23 at 12:04
  • @PrisonMike Okay so if you've researched into this field, you must've noticed that, every program has a different configuration and depending on the modules, methods and many other circumstances, files and dependencies used, and the type of `.exe` file required, the method to create an exe can differ. Basically the creation of an exe involves `Freezing` of the scripts being used, and for that purpose, the program needs to be supplied with all dependencies. One way of achieveing this is by using [cx_freeze](https://pypi.org/project/cx-Freeze/), [docs](https://cx-freeze.readthedocs.io/) – typedecker Jun 30 '23 at 12:09
  • 2
    https://pyinstaller.org/en/stable/ – Kostas Nitaf Jun 30 '23 at 12:09
  • 1
    @typedecker ok thank you i will do more research on that – Prison Mike Jun 30 '23 at 12:20

2 Answers2

2

There isn't one very clean way to make an executable in python, but you can combine two libraries to get the job done:

  1. subprocess
  2. pyinstaller

You can use subprocess.run('pyinstaller', '--onefile', 'pythonScriptName.py') to get the functionality you're looking for.

You can check out pyinstaller's documentation to add more arguments to the command.

Adding that, your program would look like this:

import os
import subprocess

code = """
print(hello world)
"""

with open("second.py", "w") as second_file:
        second_file.write(code)

subprocess.run('pyinstaller', '--onefile', 'secondfile.py')

You can also use the subprocess library to run that newly made executable as well if that's what you're looking for.

TheDeafOne
  • 93
  • 10
2

Looking at the question, and based off of the conversation I had in the comments, it seems like the goal here, is to create an exe dynamically/programmatically(completely using code). There are many ways of achieving this, one such way is by using the cx_freeze module.

Using this module, you can write a setup script for the exe and then use a command to build the exe -:

import sys
from cx_Freeze import setup, Executable

# Dependencies are automatically detected, but it might need fine tuning.
build_exe_options = {
    "excludes": ["tkinter", "unittest"],
    "zip_include_packages": ["encodings", "PySide6"],
}

# base="Win32GUI" should be used only for Windows GUI app
base = "Win32GUI" if sys.platform == "win32" else None

setup(
    name="guifoo",
    version="0.1",
    description="My GUI application!",
    options={"build_exe": build_exe_options},
    executables=[Executable("guifoo.py", base=base)],
)

Building the exe -:

python setup.py build

(from docs)

The result of the execution of this command has been described in the docs as follows -:

This command will create a subdirectory called build with a further subdirectory starting with the letters exe. and ending with the typical identifier for the platform and python version. This allows for multiple platforms to be built without conflicts.


Furthermore, if you wish to create the exe entirely using code without any separate manual work whatsoever, the configurations need to still be ascertained, but other than that, you can use the subprocess module's call method with shell = True as the argument, to run the command-line command programmatically as well. Somewhat like so -:

import subprocess

def create_exe(code, excludes, zip_include_packages, name, version, description) :
    with open('source_for_exe_file.py', 'w') as f :
        f.write(code)
    
    setup_script = 'import sys\nfrom cx_Freeze import setup, Executable\n# Dependencies are automatically detected, but it might need fine tuning.\nbuild_exe_options = {"excludes" : {excludes}, "zip_include_packages" : {zip_include_packages},}\n# base = "Win32GUI" should be used only for Windows GUI app\nbase = "Win32GUI" if sys.platform == "win32" else None\nsetup(name = {name}, version = {version}, description = {description}, options = {"build_exe" : build_exe_options}, executables = [Executable("source_for_exe.py", base = base)],)'.format(excludes = excludes, zip_include_packages = zip_include_packages, name = name, version = version, description = description)
    with open('setup.py', 'w') as f :
        f.write(setup_script)
    
    result = subprocess.call('python setup.py build', shell = True)
    return result # Just returning any command line output.

Please note that the code provided, has not been tested, and thus it's proper functionality is uncertain, given the lack of proper explanation of the kind of code that can be expected. Also note that, the result of this function will be the creation of the exe in the build folder's subfolder as mentioned in the first approach. The only difference here being that, no manual execution of the command was involved.


Also, as mentioned previously in the answer, there are multiple other ways of achieving the same as well, one such way is by using pyinstaller like so -:

import PyInstaller.__main__

PyInstaller.__main__.run([
    'second.py',
    '--onefile',
    '--windowed'
])

Note that, this was partially taken from the docs, with the only modification being the change in the name of the file, but this is a viable and more simplistic approach, if the complex differences are to be ignored.

Also, since py2exe was mentioned in the question, I would suggest having a look at this source. Its a tutorial to create an executable by using a setup script similar to the cx_freeze approach demonstrated above, but with the advantage of simplicity. I must mention though, that the tutorial seems to have been written for python 2.0 and any changes to the method explained there, can cause it to not work for python 3.0.

typedecker
  • 1,351
  • 2
  • 13
  • 25