Using pyinstaller to convert Python3 and Python2 to .exe - python

I am currently writing a script, on Python 3.
I need to call an already existing Python 2 script, from within my Python 3 script.
In the Python3 script I am doing this using something like:
import subprocess
my_command = 'python script_in_py2.py arg1 arg2'
process = subprocess.Popen(my_command.split(), stdout = subprocess.PIPE)
output, error = process.communicate()
Thus, variable output will get the output that would be displayed on screen if I had just written my_command in terminal.
Although I am currently developing in Ubuntu, eventually I will migrate it to Windows where I will need to convert it to an .exe. For this I have previously used pyinstaller.
I know that running the resulting .exe (of a purely Python3 script) on a Windows machine without Python installed at all works.
However I need to know before going on, whether it will also work like this. My intuition is no (in my knowledge creating a process like that is similar to running the command directly in Terminal/Command Prompt), however I would like to know if anybody knows of a way/workaround. (Installing Python2 on the machine that would run the script is not an option).

A possible solution could be like this:
Convert your python2 script i.e. 'script_in_py2.py' into an executable i.e. 'script_in_py2.exe' using pyinstaller.
pyinstaller script_in_py2.py
In your python3 script, call this python 2 executable instead of calling python 2 script.
import subprocess
my_command = 'script_in_py2.exe arg1 arg2'
process = subprocess.Popen(my_command.split(), stdout = subprocess.PIPE)
output, error = process.communicate()
Now convert your python3 script into an executable using pyinstaller.
pyinstaller script_in_py3.py
Paste the executable 'script_in_py2.exe' and 'python27.dll' in dist folder of 'script_in_py3' (i.e. parallel to location of executable 'script_in_py3.exe')
Run "script_in_py3.exe" and you will get desired output.
I have tried it on my system and its working smoothly.

Related

Using Subprocess to run another python script

I am a newbie to python and would like to seek some advice. I having a script now where the function of this script can only be executed after I run a command i.e. python run trial.py. However, I would like to automate this process by using a subprocess function in a new python file called 'run.py' to run the trial.py script.
After that, I would wish to convert run.py file into an exe file to ease the execution for other users.
I have tried to perform the below steps.
1. saved the scripts (trial.py & run.py) in same directory.
2. Execute both of the files in same conda virtual environment.
3. Successfully execute run.py by using ```subprocess.run('xxx run trial.py')```
4. Converted the run.py into an exe file
5. Tried to execute the exe file and it is running, but **failed** to show the output that suppose to be appeared after running trial.py.
Would like to seek advice is any steps on above did wrongly or need to be improvised? I need to deal with confidential data hence the easiest way I can do is by using pyinstaller to allow another user to execute.
Hope to hear some advice
UPDATE
I had tried to use the codes below,
import subprocess
import sys
from subprocess import PIPE, STDOUT
command ='python run trial.py'
run = subprocess.Popen(command, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
Now the exe file is able to be generated and able to run, but it doesn't appear the expected output. It ended without any error message. It works well when I run the script in python..
Wish to hear advice from all of you..
With subprocess, you can try it:
command = 'Your command' # Example: command = 'python trial.py'
process = subprocess.Popen(command, shell=True, stdout=sys.stdout, stderr=sys.stderr)
I would wish ... to ease the execution for other users.
As I've understood your case, using subprocess and making an exe file out of your python file (which is not an easy task) is not a good fit for you.
Instead, I recommend you to have a look at make files as they are well-known for simplifying your commands.
for example you can have a make file like this:
run:
python trial.py
And users can simply run make run, and python trial.py will run instead.
The possibilities are endless.
You can also make a bash file that is an executable,
# !/bin/bash
python trial.py
And it will simply run like exe files.

why the same powershell command run on the powershell console but not using os.system?

I would like to include a command to create a 7zip archive withinin a Python script. Since I am working on Windows, I need to pass the command to the powershell console. I am planning to do it with os.system (I am aware that this is not the best way to do it and that I should use subprocess, but I really just need a quick fix and it would not be time effective for me to learn to use a new module in this context).
The following command works if run from the powershell console
&'C:\\Program Files\\7-Zip\\7z' a -mx=0 X:/myarch.zip X:/myarch
So I recreate the same string within python like this:
cmdl = r"&'C:\\Program Files\\7-Zip\\7z' a -mx=0 X:/myarch.zip X:/myarch"
The string is interpreted as follow:
"&'C:\\\\Program Files\\\\7-Zip\\\\7z' a -mx=0 X:/myarch.zip X:/myarch"
Now, if I copy-paste the above string within the powershell console, it runs without problems. However, if I run it within python using os.system(cmdl) I got the following error
"The filename, directory name, or volume label syntax is incorrect"
Why is this the case and how can I fix this issue ?
os.system is meant for executing cmd commands, cmd commands can be ran in powershell maybe after all powershell is a bit advanced but I'm sure that you can't run a cmd command in powershell, henceforth your code is not working.
However a creative solution for executing a powershell command from python(not using python) would be to write your command into a .ps file(powershell script)and then run it using os.startfile()(use this code: os.startfile("script.ps"))

Cannot run MATLAB from bash script under Windows/MSYS2

I need to run a MATLAB script from a Python script. I don't care about the output of it nor do I need to give it any arguments.
However, MATLAB R2016B's "engine" does not support Python 3.7 (Upgrading Matlab or down-grading python is not an option at this time)
So, I decided to make a shell script that runs it:
#!matlab -nodisplay -nodesktop -r 'try; myMatlabScript; catch; end; quit'
Now I need to run a bash script from Python. To do so, I did:
import subprocess
subprocess.call("./mybashscript.sh")
(And yes, the python script is at the same level as the shell script)
The python script does not complain directly. However, I do get the following:
'.' is not recognized as an internal or external command, operable program or batch file.
Which to me means that since Windows doesn't directly have bash, it doesn't know what to do with this shell script. I am not sure how to handle this. Some way to tell Python to use MSYS instead of Windows for the shell?
And thus the MATLAB script does not appear to run at all.
When I attempt under Linux (just for testing, I can't run it here for performance reasons), I get:
./mybashscript.sh: matlab: bad interpreter: No such file or directory
Is it possible this is because I didn't do the command addpath(genpath('.'))? If so, I'm not sure how I would do that in the shell script, and some help would be appreciated.
Or some other better solution would also be great.
1: Needed to re-name mybashscript.sh to mybashscript.bat
2: Needed to change the sub-process call to subprocess.call("mybashscript.bat") (as ./ was confusing the windows shell)
3: Needed to add the path properly. Here is what the batch script looked like:
matlab -nodisplay -nodesktop -r "addpath(genpath('C:/path/to/myscript')); myMatlabScript"
The double quotes are neccesary so the single quotes inside genpath do not cause it to end early.
And that was it!
EDIT: You can add -wait in the batch file to get the script to wait until it is complete before handing back to the Python script.

Formatting Windows Command Line Call For Executing R Script from Python

This is similar to a number of questions, but could still use some clarity. My example is still unable to run, so I may be missing something.
I'm trying to run a full R script from Python. I don't need to see it, or get output, but need it to run and preferably know when it's completed.
I am using Python 3.7.0 (Run from Spyder), R 3.5.2, and Windows 10.
I can run this from Windows Command Line with:
Rscript test_script.R
When I'm in the location with the script, or if I'm not in that location:
Rscript C:/Path/to/test_script.R
From Python I tried:
import subprocess
command = 'Rscript'
script = 'C:/Path/to/test_script.R'
subprocess.Popen([command,script], shell=True)
This does not give an error, but I can see from the directories where the Rscript would create files, that nothing has run (And it would take awhile to run). In the Python console, the 'output' displays '1'
I have also tried:
import subprocess
command = 'C:/Path/to/Rscript.exe --vanilla -q -f C:/Path/to/test_script.R'
subprocess.Popen(command, shell=True)
I'm not sure what the --Vannilla -q -f means, but I saw it used often in other questions.
Any ideas on where I am going wrong or how to get this to execute?

Launching a python script in a new terminal from another python script

I'm using LXDE, I would like to Launch a python script in a new terminal from another python script.
I would like the new python script to be totally independent.
I have tried a lot of things...
Calling xterm (or x-terminal-emulator) directly from python with the subprocess.call or subprocess.Popen with or without shell=True argument, it didn't work. It gives me an error about display not being set.
I have also created a sh file which calls the other python script and tried to call it, same results.
Any way to do this?
This works fine for me:
blocking:
import os
os.system("xterm -e \"python christmaskittens.py\"")
non blocking:
import os
os.system("xterm -e \"python christmaskittens.py\" &")

Categories