How to package up a Python 3 script with modules - python

I created a small script that uses a few 3rd-party modules. I'm not sure how to distribute it. I tried Pyinstaller, but that doesn't seem to work. It can't find the modules. When I give the binary to a co-worker, it says it is looking for files in my home directory ( not his ) and dies. I have found that Pyinstaller is not able to find most modules. I am running Python 3 and installed Pyinstaller with pip from Python 2. It did not work trying to use pip from Python 3. When, I give it a path to my modules, it complains that they are python 3 modules. Just looking for some clarification. Ultimately, I'd like to run this on a linux or OS X box where python and my modules probably won't be installed. I just started Python yesterday and have a ton to learn.

you want to build a standalone executable file, or just a distribution package.
If you want standalone executable file try cx_freeze it supports python 3.x
Or if you want a distribution package then look at this documentation http://docs.python.org/2/distutils/

Related

Modules Not Found - I cannot externally run a .py file developed using PyCharm

I am using PyCharm to develop a python project, which uses an external library called win10toast. I have installed win10toast using PyCharm. However, when I tried to run the .py file using cmd (i.e Externally running the python file), an error shows up:
ModuleNotFoundError: No module named 'win10toast'.
I have python 3.6.4. I installed win10toast using PyCharm.
from win10toast import ToastNotifier
I expect the program to run without any error, but currently I am getting the ModuleNotFound error.
Python can be tricky to run properly because it is sensitive to where you installed your dependencies (such as external libraries and packages). If you installed Python to one directory, but accidentally installed the external library to another directory, when you run your .py program, it will be unable to call from the external library because it doesn't exist in the same library that Python is running from.
Lookup where you installed Python on your computer and then find where you installed the external library. Once your find where you installed the external library, move its entire package content to the same directory where Python is installed. Or better yet, reinstall the external library with pip into the same directory as Python.
If you're on Mac, Python and its related dependencies are usually stored somewhere in /User/bin. If you're on Windows, it will be stored somewhere in your C:// directory (possibly somewhere in C:\Users\username\Local\AppData). If you're on Linux, it will be stored somewhere in /usr/bin. Whatever you do, don't move Python from wherever it is because sometimes that can mess up your system for certain operating systems like Mac, which comes with its own version of Python (Python 2.7 I believe, which is outdated anyway).
Lastly, you may have two different versions of Python on your computer, which is common; Python 2.7 and Python 3+. If you wrote your program in one version, but ran it from the other, the external library can only be called from whichever Python version you installed it to. Try running your .py program with python3 instead of python (or vice versa) and see what happens. If it works with one python version over the other, that tells you that the external library is installed in the other version's directory.
That should solve your issue.
I would suggest that you not use PyCharm to install packages, at least not
if the result deviates in the slightest from doing a "pip install" at the command line. I see no reason to involve PyCharm in configuring Python installations. It's just asking for trouble.
I admit that I'm not familiar with the practice I'm suggesting you avoid. I've been using PyCharm since pretty much the week it came out (was an avid user of the IntelliJ Python plugin before that), and have never once considered doing anything but installing Python modules at the command line. That way, I'm sure right where those modules are going (into which base Python install or venv). Also, I know I'm doing all that I can to minimize the differences that I might see between running code in PyCharm and running it at the command line. I'm making my suggestion based solely on this practice having never gone wrong for me.
I have multiple base Python versions installed, and dozens of venvs defined on top of those. PyCharm is great at allowing me to indicate which of these I want to apply to any project or Run/Debug configuration, and utilizing them seamlessly. But agin, I administer these environments at the command line exclusively.
I still experience issues in switching between the command line and PyCharm in terms of one module referencing others in a single source tree. My company has come up with a simple solution to this that insures that all of our Python scripts still run when moving away from PyCharm and its logic for maintaining the Python Path within a project. I've explained the mechanism before on S.O. I'd be happy to find that if anyone is interested.
The library win10toast installed in the directory: YOUR_PYCHARM_WORKSPACE\PycharmProjects\YOUR_PROJECT_NAME\venv\Lib\site-packages
but when you are running your program using cmd, pycharm interpreter uses site-packages directory that you installed python at there. for Ex: C:\Python27\Lib\site-packages
So, you can install the win10toast library to this windows directory using pip.

Using pyinstaller on c compiled python code

I am trying to convert one single c file into an executable with pyinstaller. Now the reason why I want to compile with pyinstaller is because of the fact, that the exe file is supposed to be run on both a mac as well as a windows machine.
Now, how can this be done?
You can include Cython/C modules in a Pyinstaller executable.
However, Pyinstaller is not suitable for your goal of making a single executable that works on Mac and Windows. From the first question of the Pyinstaller FAQs:
Can I use PyInstaller as a cross-compiler?
Can I package Windows binaries while running under OS X?
No, this is not supported. [...]
It seems like you've fundamentally misunderstood what Pyinstaller does: it packages a Python script with Python and its libraries to allow you to use the Python script without having to install Python separately. To do this though it needs to package a version of Python specific to the platform, and so the executable will only work on the same operating system that it was created on.
In addition, it deals with compiled libraries (like Cython modules) by zipping them up and the extracting them into a temporary folder when run. Therefore, even if Pyinstaller somehow managed to bundle two versions of Python to work on both Windows and Mac your C compiled module would still only be compiled for a single platform, so by doing it they way you describe you've actually made your code less portable.
I don't believe there are any obvious tools to do what you're asking.

How to Destribute python and openCV based tool as single setup file with all the dependencies [duplicate]

This question already has answers here:
Create a single executable from a Python project [closed]
(3 answers)
Closed 1 year ago.
I'm building a Python application and don't want to force my clients to install Python and modules.
So, is there a way to compile a Python script to be a standalone executable?
You can use PyInstaller to package Python programs as standalone executables. It works on Windows, Linux, and Mac.
PyInstaller Quickstart
Install PyInstaller from PyPI:
pip install pyinstaller
Go to your program’s directory and run:
pyinstaller yourprogram.py
This will generate the bundle in a subdirectory called dist.
pyinstaller -F yourprogram.py
Adding -F (or --onefile) parameter will pack everything into single "exe".
pyinstaller -F --paths=<your_path>\Lib\site-packages yourprogram.py
running into "ImportError" you might consider side-packages.
pip install pynput==1.6.8
still runing in Import-Erorr - try to downgrade pyinstaller - see Getting error when using pynput with pyinstaller
For a more detailed walkthrough, see the manual.
You can use py2exe as already answered and use Cython to convert your key .py files in .pyc, C compiled files, like .dll in Windows and .so on Linux.
It is much harder to revert than common .pyo and .pyc files (and also gain in performance!).
You might wish to investigate Nuitka. It takes Python source code and converts it in to C++ API calls. Then it compiles into an executable binary (ELF on Linux). It has been around for a few years now and supports a wide range of Python versions.
You will probably also get a performance improvement if you use it. It is recommended.
Yes, it is possible to compile Python scripts into standalone executables.
PyInstaller can be used to convert Python programs into stand-alone executables, under Windows, Linux, Mac OS X, FreeBSD, Solaris, and AIX. It is one of the recommended converters.
py2exe converts Python scripts into only executable on the Windows platform.
Cython is a static compiler for both the Python programming language and the extended Cython programming language.
I would like to compile some useful information about creating standalone files on Windows using Python 2.7.
I have used py2exe and it works, but I had some problems.
It has shown some problems for creating single files in Windows 64 bits: Using bundle_files = 1 with py2exe is not working;
It is necessary to create a setup.py file for it to work. http://www.py2exe.org/index.cgi/Tutorial#Step2;
I have had problems with dependencies that you have to solve by importing packages in the setup file;
I was not able to make it work together with PyQt.
This last reason made me try PyInstaller http://www.pyinstaller.org/.
In my opinion, it is much better because:
It is easier to use.
I suggest creating a .bat file with the following lines for example (pyinstaller.exe must be in in the Windows path):
pyinstaller.exe --onefile MyCode.py
You can create a single file, among other options (https://pyinstaller.readthedocs.io/en/stable/usage.html#options).
I had only one problem using PyInstaller and multiprocessing package that was solved by using this recipe: https://github.com/pyinstaller/pyinstaller/wiki/Recipe-Multiprocessing.
So, I think that, at least for python 2.7, a better and simpler option is PyInstaller.
And a third option is cx_Freeze, which is cross-platform.
pyinstaller yourfile.py -F --onefile
This creates a standalone EXE file on Windows.
Important note 1: The EXE file will be generated in a folder named 'dist'.
Important note 2: Do not forget --onefile flag
You can install PyInstaller using pip install PyInstaller
NOTE: In rare cases there are hidden dependencies...so if you run the EXE file and get missing library error (win32timezone in the example below) then use something like this:
pyinstaller --hiddenimport win32timezone -F "Backup Program.py"
I like PyInstaller - especially the "windowed" variant:
pyinstaller --onefile --windowed myscript.py
It will create one single *.exe file in a distination/folder.
You may like py2exe. You'll also find information in there for doing it on Linux.
Use py2exe.... use the below set up files:
from distutils.core import setup
import py2exe
from distutils.filelist import findall
import matplotlib
setup(
console = ['PlotMemInfo.py'],
options = {
'py2exe': {
'packages': ['matplotlib'],
'dll_excludes': ['libgdk-win32-2.0-0.dll',
'libgobject-2.0-0.dll',
'libgdk_pixbuf-2.0-0.dll']
}
},
data_files = matplotlib.get_py2exe_datafiles()
)
I also recommend PyInstaller for better backward compatibility such as Python 2.3 - 2.7.
For py2exe, you have to have Python 2.6.
For Python 3.2 scripts, the only choice is cx_Freeze. Build it from sources; otherwise it won't work.
For Python 2.x I suggest PyInstaller as it can package a Python program in a single executable, unlike cx_Freeze which outputs also libraries.
Since it seems to be missing from the current list of answers, I think it is worth mentioning that the standard library includes a zipapp module that can be used for this purpose. Its basic usage is just compressing a bunch of Python files into a zip file with extension .pyz than can be directly executed as python myapp.pyz, but you can also make a self-contained package from a requirements.txt file:
$ python -m pip install -r requirements.txt --target myapp
$ python -m zipapp -p "interpreter" myapp
Where interpreter can be something like /usr/bin/env python (see Specifying the Interpreter).
Usually, the generated .pyz / .pyzw file should be executable, in Unix because it gets marked as such and in Windows because Python installation usually registers those extensions. However, it is relatively easy to make a Windows executable that should work as long as the user has python3.dll in the path.
If you don't want to require the end user to install Python, you can distribute the application along with the embeddable Python package.
py2exe will make the EXE file you want, but you need to have the same version of MSVCR90.dll on the machine you're going to use your new EXE file.
See Tutorial for more information.
You can find the list of distribution utilities listed at Distribution Utilities.
I use bbfreeze and it has been working very well (yet to have Python 3 support though).
Not exactly a packaging of the Python code, but there is now also Grumpy from Google, which transpiles the code to Go.
It doesn't support the Python C API, so it may not work for all projects.
Using PyInstaller, I found a better method using shortcut to the .exe rather than making --onefile. Anyway, there are probably some data files around and if you're running a site-based app then your program depends on HTML, JavaScript, and CSS files too. There isn't any point in moving all these files somewhere... Instead what if we move the working path up?
Make a shortcut to the EXE file, move it at top and set the target and start-in paths as specified, to have relative paths going to dist\folder:
Target: %windir%\system32\cmd.exe /c start dist\web_wrapper\web_wrapper.exe
Start in: "%windir%\system32\cmd.exe /c start dist\web_wrapper\"
We can rename the shortcut to anything, so renaming to "GTFS-Manager".
Now when I double-click the shortcut, it's as if I python-ran the file! I found this approach better than the --onefile one as:
In onefile's case, there's a problem with a .dll missing for the Windows 7 OS which needs some prior installation, etc. Yawn. With the usual build with multiple files, no such issues.
All the files that my Python script uses (it's deploying a tornado web server and needs a whole freakin' website worth of files to be there!) don't need to be moved anywhere: I simply create the shortcut at top.
I can actually use this exact same folder on Ubuntu (run python3 myfile.py) and Windows (double-click the shortcut).
I don't need to bother with the overly complicated hacking of .spec file to include data files, etc.
Oh, remember to delete off the build folder after building. It will save on size.
Use Cython to convert to C, compile, and link with GCC.
Another could be, make the core functions in C (the ones you want to make hard to reverse), compile them and use Boost.Python to import the compiled code (plus you get a much faster code execution). Then use any tool mentioned to distribute.
I'm told that PyRun is also an option. It currently supports Linux, FreeBSD and Mac OS X.

Run a python script in an environment where a library may not be present

I have a python script where I am including a third party library:
from docx import Document.
Now, I need to run this script in an environment where bare-bones python is present but not this library.
Installing this library in the target environment is beyond my scope and I tried using distutils, but couldn't go far with it. The target environment just need to run the script, not install a package.
I am from Java background and in Java I would have just exported and created a jar file which would have included all the libraries I needed. I need to do similar with python.
Edit: With distutils, I tried creating a setup.py:
from distutils.core import setup
import docx
setup(name='mymodule',
version='1.0',
py_modules=['mymodule', docx]
)
But I am not sure this works.
PyInstaller won't work if you can't make a pyc file and you cannot make pyc file unless your code runs without fatal errors.
You could have the import in a try block that excepts ImportError 's but that will result in NameError 's where the package is referenced. Long story short if the package is integral to the script no amount of avoiding it will fix your problem. You need the dependencies.
You said installing the package is beyond your scope, well then, it is time to expand your scope. Docx is an open source package you can find on github here
You can download that and run setup.py
You can include the modules for docx in your application. Just distribute them together.
But docx depends on the lmxl operating system package and needs to run setup on that. You can't just copy it to the target machine.
I'm not sure PyInstaller supports docx, especially add it has the non python dependency.
Really using pip or easy_install is the way to go.
PyInstaller is a program that converts (packages) Python programs into stand-alone executables, under Windows, Linux, Mac OS X, Solaris and AIX.

GUI2exe py2exe not correctly importing module (python 2.7)

I am trying to compile a program under windows 7 that my boss wants distrubuted as a single exe which means I cant use cx_freeze. however, the program has a library in it that is not getting picked up by py2exe called SVFS (https://pypi.python.org/pypi/SVFS). I am using GUI2exe to try and simplify the process and i have looked for where the SVFS package is installed, It doesn't seem to be installed in the site-packages directory. When i run the python shell, the SVFS import works. So my question is:
How do I use python to find the exact location of every 3rd party module i have installed?
How do I then pass this information to py2exe and get my program up and running?
P.S for anyone who wonders why im not using pyinstaller, it is ancient and its not even running on my machines.
I was able to build the executable finally after trying VendorID, which was able to correctly pick up all dependicies and generate an exe with visual studio 2008 nmake.

Categories