I just started doing some scripts with Sikuli in Python.
I would like to know if it's possible (and if yes, how) to create a jar or exe file from my python script (file .py and images).
I would like to easily run my program from other machines that do not have sikuli install (e.g., java -jar my_script.jar or my_script.exe) or give the utility to some colleagues, but I don't want that they see the source code.
Use a jar file, as Sikuli is written in Java and uses Jython. You need to do three things in order for this to work.
Get Sikuli jar:
First get the sikuli-java.jar file (step-by-step instructions here), which you can get by downloading sikuli-setup.jar, and run it using options 4 (only Java) and 6 (all OS compatible). This should download the sikuli-java.jar file.
Distribute your script itself as a jar:
Obfuscated Version:
You can compile your Python using Jython (full instructions here):
$JYTHON_HOME/jython $JYTHON_HOME/Lib/compileall.py python_src/
where python_src is the directory containing all your .py files.
Then you can call these compiled files (which look like myFile$py.class) from Java, using a wrapper class (see full instructions for an example).
This wrapper calls a single Python method, so you can just make that method be your main Python method that kicks off the rest of your program.
Compile the wrapper class:
javac -cp $JYTHON_HOME/jython.jar TestJ.java
Then jar all your .class files:
jar cvfe myapp.jar <packageName>.TestJ *.class
where <packageName> is the package for your wrapper TestJ.java class.
You'll need to add Jython to this jar as well. Just follow the first few steps of the "Python .py files in jar" section below, or download the standalone Jython jar and include it the same way as sikuli-java.jar in the "Combine the jars" section below.
Python .py files in jar:
Now you have to create the jar for your script itself. The full instructions are here, but if you want a summary:
Take the jython.jar file that you get when you install Jython and zip the Jython Lib directory into it, then zip your .py files in, and then add a __run__.py file with your startup logic (this file is treated specially by Jython and will be the file executed when you call the jar with java -jar).
There is also a more general guide from python.org if you prefer.
Note:
The full instructions above assume you have the zip program. If you don't, you can use jar uvf jythonlib.jar Lib instead of zip -r jythonlib.jar Lib (and do similar wherever zip is used). See here for more
Combine the jars
You can simply add sikuli-java.jar to the jar containing your scripts using jar as mentioned in the note above. You can also combine the two jar files (also using jar) if you prefer.
Either way, this should give you a single jar file that can run your Sikuli program across any system with a compatible JVM. Run it using
java -jar myapp.jar
Congratulations, you're done!
See the stack overflow guide or the full Python guide if you need to deal with command line arguments, or generally need more detail.
There are many ways to convert a .py to .exe and excetra
While I believe it is possible to change the extension, the process would be much easier and smoother if you use an extension to python, like Py2exe the download to which can be found with a simple google search (I have also included a link to their site below). The program will allow you to convert the program into a .exe and will run without needing a python installation.
Here is a list of reputable and good options: http://www.freehackers.org/Packaging_a_python_program
I would personally recommend Py2exe (http://www.py2exe.org/) and the tutorial to Py2exe can be found here (http://www.py2exe.org/index.cgi/Tutorial)
Related
I have a question if I use Pyinstaller to convert python file to exe will convert the modules with or not? , because i have python file with a lot of modules and i want to convert it how i can do it and avoiding this issue,
Thank u.
import requests
error:
ImportError: No module named requests
.
After discussion in comments basically the error is occurring when you try to open the generated file in another computer, however your aren't using any virtual environment so you can install the requirements and try to rebuild again but rather you want a stanalone exe file.
For that use :
pyinstaller --onefile your-script.py
# or pyinstaller -F your-script.py
## this should generate a stand alone executable file located in the dist folder.
About your concerns on how pyinstaller works
Does pyinstaller make copies of modules when building ?
The answer is simply : yes , as mentioned in the docs here PyInstaller reads a Python script written by you. It analyzes your code to discover every other module and library your script needs in order to execute. Then it collects copies of all those files – including the active Python interpreter! – and puts them with your script in a single folder, or optionally in a single executable file.
However, the variations of Python and third-party libraries are endless and unpredictable, if something goes wrong you can learn how to fix those issues by reading this page on the docs here
What to generate ?
you can read more here
Create a one-folder bundle containing an executable (default), -D, --onedir
Create a one-file bundled executable. you need to use -F ore --onefile
Finally
I highly encourage you to use separate virtual environment for each project.
I have a Python software that I created using pyinstaller. I used pyinstaller to create a single 60 MB executable file which contains all my module dependencies.
I have used the pyinstaller code :
pyinstaller --noconfirm --onefile --windowed file.py
I was going to release a beta version of this software to a lot of people I know. I know people can extract the source code if I create a directory containing scripts but will it still be possible for someone to extract the source code from the executable if it is just a single .exe file?
I have looked into using pyarmor and obfuscating my code before creating an executable but that would require sending a folder of some sort when I want to compile everything into a single exe file.
From the documentation
The bundled app does not include any source code. However, PyInstaller bundles compiled Python scripts (.pyc files). These could in principle be decompiled to reveal the logic of your code.
So one can still reverse engineer the code, but it isn't the source code. If you want to see how the bytecode looks like you may use the dis tool.
I don't mean to compile code and interpreter as an exe as it is 99% questions there. I mean to build a static single python.exe to be able to execute any script by giving it as argument any *.py file.
I mean the same situation as it is with nodeJS when you download only single executable.
Or if it is not possible to single exe, maybe to just a few files instead of huge default package such as is with for example Sublime text where all python engine is in python33.dll and python3.3.zip all about 5mb, but there is no python exe to run code externally that is not as a plugin.
On Windows you need three files. You question lists two of them. The third is python.exe. On Windows the interpreter must be built separately from the actual executable so that C modules can access the functions within the interpreter.
The DLL must be built from the Python source so that all the C modules that come with Python can be built into it instead of being contained in the .pyd files that come with Python. The zip file is composed of all the Python modules in the standard library; see the zipimport documentation for more information about the import process.
My Problem is the following:
I want to create an script that can create other executables. These new executables have to be standalone, so they don't require any DLL's, etc.
I know this is possible with PyInstaller, but only from console/command line.
So essentially, what I want to do is make a python script that imports pyinstaller, creates another .py-file and uses pyinstaller to compile the new script to a .exe, so people who don't have python installed can use this program.
EDIT: The script itself should only use one file, so it can also be a one-file executable
Supposing you have already installed Pyinstaller in PYINSTALLER_PATH (you should have called the Configure.py script in the distribution for the first time), Pyinstaller generates a spec file from your main script by calling the Makespec.py. You can add some flags to generate one dir binary distribution or one file. Finally you have to call Build.py with spec file.
This is easy scriptable with a couple of system calls. Something like :
import os
PROJECT_NAME = "test"
PROJECT_MAIN_SCRIPT = "main_script.py"
MAKESPEC_CMD = """%s %s\Makespec.py -X -n %s -F %s""" % (PYTHON_EXECUTABLE, PYINSTALLER_PATH, PROJECT_NAME, PROJECT_MAIN_SCRIPT)
BUILD_CMD = """%s %s\Build.py %s.spec""" % (PYTHON_EXECUTABLE, PYINSTALLER_PATH, PROJECT_NAME)
os.system(MAKESPEC_CMD)
os.system(BUILD_CMD)
You can avoid to generate the spec file every time and hack it, adding embedded resources (i.e. xml files or configuration) and specifying some other flag. Basically this is a python file, with the definition of some dictionaries.
I don't think there is a Pyinstaller module you can use directly, but you can look at Build.py and mimic its behaviour to do the same. Build.py is the main script which does the trick.
You may want to check out cx_Freeze, which can be used to do this kind of thing.
There are three different ways to use cx_Freeze. The first is to use the included cxfreeze script which works well for simple scripts. The second is to create a distutils setup script which can be used for more complicated configuration or to retain the configuration for future use. The third method involves working directly with the classes and modules used internally by cx_Freeze and should be reserved for complicated scripts or extending or embedding.
Source
Try downloading Pyinstaller's latest development code. There they trying to implement GUI toolkit for building executables.
I use PyDev in Eclipse with the Qt integration. With an external tool I can create python source in a .py from a qt .ui file. This is the external tool:
http://permalink.gmane.org/gmane.comp.python.xy.devel/413
The problem is that the generated python .py file has a name like MyGeneratedFile.ui.py.
How can I adapt the external tool to have the extension of the generated file without .ui thus MyGeneratedFile.py ?
So it seems the problem boils down to ${resource_loc}, since this gives you the full path name /path/to/file/filename.ui - Yes, it does include the .ui hence when you say ${resource_loc}.py this translates into /path/to/file/filename.ui.py
So probably the simplest way to correct this problem since I couldn't find a way to make eclipse remove the file extension for me was making a very small script to do work.
You might need to modify it slightly to work for your pyuic installation.
/usr/bin/pyuicEclipse:
#!/bin/bash
pyUICCommand="/usr/bin/pyuic" # change this per your installation
x=$1
f=`basename $x`
d=`dirname $x`
fNoUI="`echo $f | sed 's/\.ui$//'`" # removes .ui extension from file basename
$pyUICCommand -o ${d}/${fNoUI}.py $x
make it executable and the eclipse configuration I used was much simpler:
PyUIC->Main->Location: /usr/bin/pyuicEclipse ---obviously change this to yours
PyUIC->Main->Arguments: ${resource_loc}
PyUIC->Refresh - check "Refresh Resources upon Completion"
PyUIC->Build - uncheck "Build before Launch"
PyUIC->Common - don't do the File option that was mentioned in that article
This works on linux, so if you're on another OS it may need some slight modification, but I hope this solves your problem :)
In the interests of maintaining the cross-platform nature of Eclipse, I've knocked up a DOS equivalent of platinummonkey's bash script. It's not quite so robust, but it does the job:
#echo off
set pyUICCommand="pyuic"
set fname=%1
set fname=%fname:.ui=.py%
%pyUICCommand% -o %fname% %1
There is an easy solution to this problem that requires no scripting at all.
Install pathtools plugin either through Eclipse updates or via the Eclipse marketplace:
Setup an External Tools Configurations option in Eclipse as follows
In Main:
Name: pyuic_run. (or something similar)
Location: path to the python interpreter (or pyside-uic.exe if you use this)
Arguments: On the first line, put the path to pyuic.py (not needed if you use pyside-uic.exe as it will be above). Use double quotes around the path if it contains spaces. On the second line put "${resource_loc}" (this will set the name of the resource file)
In refresh: Enable "Refresh resources upon completion" (to see the final file)
In Build: Disable "Build before launch" #not necessary here
In Environment: No changes
In Common: Activate the "File" option and set the path to be:
${parent-path}/${name-sans-extension}.py
Note that ${parent-path} and ${name-sans-extension} are arguments made available through the pathtools plugin.
If you apply this and then run the configuration on a .ui resource file, you'll see a new .py file created.