PyInstaller makes my 4kb python program 163MB. Is this normal? - python

There are dozens of questions on here asking how to decrease the size of Py2EXE and PyInstaller windows binaries (complaining about executables 10MB in size), but my issue is two orders of magnitude greater, as my PyInstaller binary is over 160MB! I'm importing TK, PyQT4, scipy, numpy, and a few other doozies. I understand each of these binary packages is huge, so my question is if this sheer size is to be expected. Do I just have to suck it up and deal with it, or is there something I can do to shave off 100+ MB?
My imports are:
from PyQt4 import QtGui,QtCore
import sys
import numpy as np
import pyqtgraph
import time
import pyqtgraph.exporters
import webbrowser
import pyaudio
import time
import threading
import scipy
import scipy.fftpack
import scipy.io.wavfile
I'm building my primary script (go.py) with PyInstaller using:
pyinstaller.exe -y -F --distpath="./build" -p "C:\python3\Lib\site-packages\PyQt4" go.py
Is 160+ MB expected? Thanks for your advice!

Related

pyinstaller "unable to find a txt file when adding a binary"

When i was converting my script to exe using pyinstaller i got an error:-
Unable to find "c:\users\praveen\appdata\local\programs\python\python36\lib\site-packages\importlib_resources\version.txt" when adding binary and data files
You can view the full error here:
https://drive.google.com/file/d/1FmV5kdb7p6TgEZwKBFDmFIszC-Qha0BD/view?usp=sharing
my script has alot of imports, they are:-
import tkinter as tk
import os
import time
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
from PIL import ImageGrab
import numpy as np
import cv2
import pytesseract
import webview
what does that error mean? and why am i getting it?
You need to write the command correctly, example:
pyinstaller --add-data web_folder;web_folder --add-data db.sqlite;. gui.py
Description: title_of_folder_or_file;path_to_it (if your OS Windows use ";", else ":". On windows it's 100% but on linux or mac i don't know) for folder you need after ; set path to this folder, example web_folder;web_folder
Source - Official Documentation

Why does my tkinter app will show a node.js window?

I use pyinstaller to pack a .py file.
Then when I use something about web crawler (I use requests module).
This window will show and disappear fastly.
I want to say that it is maybe incredible.It wouldn't pop this window when I run this .py file,but after using pyinstaller to pack it,it will pop this window.
(In another computer,it doesn't install node.js.And it doesn't pop this window)
Here is the module I use:
from pynput import keyboard
from PIL import Image, ImageTk
import ctypes
from io import BytesIO
import threading
from win10toast import ToastNotifier
import base64
from win32com.shell import shell
import requests
import execjs
import sys
import pythoncom
import getpass
import tkinter
from random import randint
from tkinter import ttk
from tkinter import messagebox
import os
import json
import traceback
from webbrowser import open_new_tab
from tkinter import scrolledtext
import win32con, win32clipboard, win32gui
from PIL.ImageGrab import grabclipboard, grab
from aip import AipOcr
import time
And the window is this:
What should I do except uninstall node.js? How to avoid this node.js window shows?
Thanks in advance.
Thanks bro,acw1668's suggestion enlighten me a lot.
I want to say,execjs module will run js code.
And if your computer install node.js and you set PATH for node.js,Then your default js environment is node.js(If you don't install node.js,then your default js environment is Jscript in windows system).
So if you doesn't want to use node.js,you should set the default js environment in python.
# change the js environment.
os.environ["EXECJS_RUNTIME"] = "JScript"
# all of environment which execjs support
PyV8 = "PyV8"
Node = "Node"
JavaScriptCore = "JavaScriptCore"
SpiderMonkey = "SpiderMonkey"
JScript = "JScript"
PhantomJS = "PhantomJS"
SlimerJS = "SlimerJS"
Nashorn = "Nashorn"

How to Import Image from PILLOW In Jupyter?

I am trying to import Image from PILLOW.
from PILLOW import Image
im = Image.open("bride.jpg")
im.rotate(45).show()
Undefined function 'from' for input arguments of type 'char'.
>> import PIL.Image
im = Image.open("bride.jpg")
im.rotate(45).show()
Error using import
Import argument 'PIL.Image' cannot be found or cannot be imported.
Undefined function 'from' for input arguments of type 'char'.
I keep getting the same error. Am I using the wrong import statement?
EDIT:
I noticed something else. when i browse through my C:/ drive and look inside the folders where Pip, and PIL ,etc is. There is nothing inside them. Even when i copy a file with stuff to that area, and open that new file, i cant see any of the stuff inside. When i copy it though, and the green bar goes it shows data being transferred.
The Code:
https://hub.gke.mybinder.org/user/alexmill-website_notebooks-fcqkeh7a/notebooks/fourier-spinning-circles.ipynb#
Example:
enter code here
from PIL import Image, ImageEnhance
# Main imports/Initialization
%matplotlib inline
import matplotlib
from matplotlib import animation, rc
import matplotlib.pyplot as plt
from matplotlib.pyplot import imshow
from IPython.display import HTML
import numpy as np
from PIL import Image, ImageEnhance
import requests
from io import BytesIO
from copy import deepcopy
from scipy.spatial import distance
from scipy.interpolate import UnivariateSpline
from copy import deepcopy
​
# Default figure size in notebook
matplotlib.rcParams['figure.figsize'] = (6,6)
matplotlib.rcParams['image.aspect'] = 'equal'
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
<ipython-input-16-7c75157a7886> in <module>
7 from IPython.display import HTML
8 import numpy as np
----> 9 from PIL import Image, ImageEnhance
10 import requests
11 from io import BytesIO
ModuleNotFoundError: No module named 'PIL'
The reason your binder doesn't work is because your requirements.txt looks like this:
matplotlib==2.0.2
requests==2.20.0
Pillow==5.0.0
numpy==1.13.0
scipy==0.19.0
pandas==0.20.2
scikit-learn==0.18.1
tzlocal-1.5.1
This line:
tzlocal-1.5.1
Probably breaks the binder dependency install. Another thing is that these are very specific versions that might generate too specific dependencies (ref. here). I recommend changing it to this:
matplotlib
requests
pillow
numpy
scipy
pandas
scikit-learn
tzlocal
At least your binder started working when I did that.
Locally you will just have to run pip install -r requirements.txt with an admin command prompt and then your local Jupyter installation should automatically work, at least it did when I cloned your notebook to a Windows VM.

PyInstaller - How do you handle environmental variables?

Background:
I am trying to convert a python script to an executable file that can be used on other computers. I decided to use PyInstaller. I am using Python 2.7.13/Anaconda 2.2.0 (64-bit). I have of course seen many examples and I can achieve this for basic examples. However, the script I am now working on uses environmental variables. The following block of code appears at the start of my python script:
import os
# force qt4
os.environ['ETS_TOOLKIT'] = 'qt4'
os.environ['QT_API'] = 'pyqt'
from traits.api import HasTraits, Range, Instance, Button, on_trait_change, Bool, Str, Enum, Float, Int
from traitsui.api import View, Item, Group, HGroup, spring, Handler, Action, InstanceEditor, Menu, MenuBar, message, \
Tabbed
from mayavi.core.ui.api import MayaviScene, SceneEditor, MlabSceneModel
from pyface.api import FileDialog, OK
import yaml
from mayavi import mlab
import numpy as np
from collections import namedtuple
import gdal
Problem:
Running pyinstaller --onefile filename.py on the command line produces an .exe, but it doesn't run because of the error: ImportError: No module named qt4."qt4" isn't a module, so I am assuming the problem is with the line " os.environ['ETS_TOOLKIT'] = 'qt4'".
After looking at various questions related to PyInstaller, I know how to use 'hiddenimports', but I have no idea how to handle environmental variables. Obviously something like pyinstaller --onefile --hidden-import qt4 filename.py didn't work.
You should try pyinstaller --onefile --hidden-import "os" filename.py

Windows Python 2.7 wxwidgets and 'gizmos'

Can anyone give me precise instructions on how to access the wx 'gizmos' module?
import wx.gizmos
ImportError: No module named gizmos
The code in question has this:
import wx
import string
import wx.gizmos
from wx.lib.mixins import treemixin
import Descriptor
'pip list' reports
wxPython-Phoenix (3.0.3.dev1830+0b5f910)
Do I have the right package installed? I should add that these files are present:
\python27\Lib\wxpython\wx-3.0-msw\wx\gizmos.py
\python27\Lib\wxpython\wx-3.0-msw\wx\_gizmos.pyd
[edit] For clarification, this seems to be OK so I'm reasonably sure the WX module is installed correctly.
import wx
import copy
# had to add .agw to get this to load
import wx.lib.agw.customtreectrl as CT
import DescriptorDetailsPanel
TAIA
Congrats, you have two installs of wx. You can use pkg_resources to get the one you want. Put the following at the top of the script:
__requires__ = ["wx >= 3.0"]
import pkg_resources
This will tell pkg_resources to set things up so that a version of wx of at least 3.0 will be available if you import wx rather than the default 2.x.
You can try to remove wxpython from pip install and reinstall wxpython from this site:
https://www.wxpython.org/download.php
It worked for me!

Categories