PyInstaller file fails to execute script - DistributionNotFound - python

I'm trying to convert my python file to an executable using PyInstaller. The program uses the Google Cloud Translate API to translate given text between languages. When running python quicktrans.py in the terminal, the program works fine. Then I ran pyinstaller quicktrans.py, SHIFT + right-clicked the directory the executable was in, and ran the .exe file in the terminal. This is the traceback that it spit out (Note this is not the whole traceback because it is a little lengthy):
File "c:\users\kalab\realpython\quicktrans\google\cloud\connection.py", line 31, in <module>
get_distribution('google-cloud-core').version)
File "site-packages\pkg_resources\__init__.py", line 559, in get_distribution
File "site-packages\pkg_resources\__init__.py", line 433, in get_provider
File "site-packages\pkg_resources\__init__.py", line 970, in require
File "site-packages\pkg_resources\__init__.py", line 856, in resolve
pkg_resources.DistributionNotFound: The 'google-cloud-core' distribution was not found and is required by the application
Failed to execute script quicktrans
I've tried looking into this and some reason it's giving me a pip-like error. I've been trying to fix this for hours and no luck.
Note: To install its client library, as per the documentation, you must run pip install --upgrade google-cloud-translate
I'm thinking this might have something to do with this because the last application I used dealt with the Facebook client module and you only had to do pip install facebook-sdk and the executable made by PyInstaller ran with no issues.
If you want to examine my code used in my program, it's hosted on my GitHub.
Thanks to anyone helping me out here!

It is basically package building name issue. Pyinstaller tries to import
google.cloud
where Google cloud package is now called
gcloud
. So you need to create a hook file for that names
C:\Users\\AppData\Local\Programs\Python\Python36-32\Lib\site-packages\PyInstaller\hooks\hook-gcloud.py
File contents:
from PyInstaller.utils.hooks import copy_metadata
datas = copy_metadata('gcloud')

In my experience base on the helps in https://github.com/GoogleCloudPlatform/google-cloud-python/issues/1187 :
Go \Anaconda3\Lib\site-packages\PyInstaller\hooks folder (if you use anaconda otherwise you need to find it under python folder)
Find the hook-google-cloud.py (If exist, otherwise you need to creat the hook.
Write to existing code as shown below
'''
Copyright (c) 2017, PyInstaller Development Team.
Distributed under the terms of the GNU General Public License with exception
for distributing bootloader.
The full license is in the file COPYING.txt, distributed with this software.
'''
from PyInstaller.utils.hooks import copy_metadata
datas = copy_metadata('google-cloud-core')
datas += copy_metadata('google-cloud-translate')
datas += copy_metadata('google-api-core')
Hope you find this explaination helpful. Thank you.

Alternate hook tweak
I'm running into this same essential problem with the Google speech engine.
It's odd how everyone here seems to have success with slightly alternate solutions to this. I really don't understand how the "patches" to the hook which leave copy_metadata('google-cloud-core') in place can work? The error thrown back reads The 'google-cloud-core' distribution was not found..., so how can one execute that line as is?
This is my replacement for the file content of hook-google.cloud.py, in order to build an exe using google speech:
# PATCH: PROVIDED ALTERNATE PACKAGE NAME
from PyInstaller.utils.hooks import copy_metadata
try:
datas = copy_metadata('google-cloud-core')
except:
datas = copy_metadata('google-cloud-speech')

My personal solution:
Change all calls to get_distribution with it returned values (0.21.0 in my case)
Remove from pkg_resources import get_distribution from import
for all files in the package.

I had the exact same issue. I solved it by doing this:
Goto the Pyinstaller hooks folder (~\Lib\site-packages\PyInstaller\hooks)
Find the file hook-google.cloud.py, open it, and add the following code to it
datas += copy_metadata('google-cloud-translate')
datas += copy_metadata('google-api-core')
The issue seems to be that get_distribution is not working with the default google.cloud.translate hook, so I just added this to a hook that was working.
Hope this helps someone.

I was using PyCharm venv for my project, and the only solution that worked for me is changing the project over to a system interpreter (and install the required packages to that).

Today, when I tried to build an EXE out of my Python script, I got the same error:
pkg_resources.DistributionNotFound: The 'google-cloud-core' distribution was not found and is required by the application
I thought the reason was one of the listed ones in this thread, since I was sure I had all dependencies installed with pipenv because my code compiled and I could debug and run the code without issues. Note I used pipenv shell in an empty folder and created my app in it, installing all necessary libraries using pipenv install ..., and one of the libraries was google-cloud-dialogflow (the app is a chatbot manager).
The solution was simply to run pipenv install google-cloud-core.
Now, pyinstaller chatbot_manager.py --onefile --windowed created the c:\Users\...\dist\chatbot_manager.exe file without issues.

Related

pydeps fails to generate dependency graph

I'm attempting to use the Python module pydeps (installed with mamba install pydeps) to analyze the dependencies in my project. However, when I run the command pydeps main.py (perhaps "main.py" is not the most informative script name ever), I get the following output:
<pydeps_folder>/pystdlib.py:17: UserWarning: stdlib_list does't support Python 3.10 yet, pydeps will use symbols from 3.9 for now.
warnings.warn(
ERROR: While opening '<working_directory>/main.svg': [Errno 2] No such file or directory: 'xdg-open' (can be caused by not finding the program to open this file)
When I then run the command firefox main.svg, I see a graph containing some of the files in my project, but not all of them, so it seems like pydeps succeeded partially. Do I need xdg-open for pydeps to work? Or is there any way I can make pydeps work by telling it to just generate the svg file and not try to open it?
Answer
xdg-open in this context is used to open the main.svg resulting file. It is a linux utility that opens a file or URL with a preferred/default application. (i.e jpg -> image viewer). In this case it tries to open main.svg with your preferred image/svg file viewer.
It sounds like it errors out when trying to open the final result main.svg, which is what you're doing by executing:
firefox main.svg
Therefore I don't think its a partial result of the dependencies.
References:
xdg-open docs: https://linux.die.net/man/1/xdg-open

Pyinstaller - Python exe when run shows error "Failed to execute script pyi_rth_nltk"

I have developed a simple software in python with GUI. I'm actually working on Natural Language Processing and I've just put the whole NLP process in a GUI.
I tried to convert the whole project to a exe file in python using Pyinstaller. I successfully converted it to an exe file but when I run it , it shows an error message something like this
This is the image of my error
I have already solved it but by using another way of converting py to exe which is the cx_Freeze.
I had the same issue earlier today and finally got it to work using the following software versions:
Python 3.6.8, nltk 3.5 and a dev version of pyinstaller:
pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip
Additionally, I used scikit-learn version 0.21.1.
Few days back, I had the same problem while compressing to EXE. This Problem generally occurs when PyInstaller failes to find Libraries and Modules to import to the directory. But I overcame this problem and the wise solution yet tedious method to do is mentioned below,
Convert Python Scripts to EXE with console = True in the .spec file or to be simple, do not add --noconsole argument while converting using System Argmuents method.(execute GUI with CMD)
After successfully building the file, go to respective directory (dist folder) and open command prompt
Run the Exe file using Command Prompt.
Find the error message and rectify it correspondingly. For example, consider the following Error Message, vcomp140.dll is missing from \\sklearn\\libs directory.
At the end of this Error Message, you'll find Failed to load dynlib/dll , Therefore, find the file or program which is missing. Say, Here we've .libs\\vcomp140.dll
Find vcomp140.dll using window search bar in your C Drive.
Copy the specific file and paste in the directory(under "dist" folder) where the file is missing. Here, the directory is dist\\PyScriptToEXE\\sklearn\\.libs
MatplotlibDeprecationWarning:
The MATPLOTLIBDATA environment variable was deprecated in Matplotlib 3.1 and will be removed in 3.3.
exec(bytecode, module.__dict__)
Traceback (most recent call last):
...
...
...
py3.7.egg\PyInstaller\loader\pyiboot01_bootstrap.py", line 169, in __init__
__main__.PyInstallerImportError: Failed to load dynlib/dll 'C:\\Users\\MOHAMM~1\\AppData\\Local\\Temp\\_MEI38242\\sklearn\\.libs\\vcomp140.dll'. Most probably this dynlib/dll was not found when the application was frozen.
[13968] Failed to execute script try
Follow the steps again using CMD to eliminate each error.

Lots of trouble running a python script from the command line

Context for how you answer: I am new to the command line environment, except when it comes to basic git commands. I've always just used an IDE like PyCharm or NetBeans to run stuff for school projects. Please frame your answer accordingly.
I have a very small python script that pulls down a URL:
import sys
sys.path.append(r'C:\Users\WNeill\PycharmProjects\bloomskyGrantGrove\venv\Lib\site-packages\bloomsky_api')
import bloomsky_api as bs
client = bs.BloomSkyAPIClient(api_key='pr-XXXXXXXXXX')
data = client.get_data()[0] # Dictionary formatted like JSON, if you want data besides the latest image
with open("image_URL.txt", 'w') as file:
print(data.get('outdoor').get('image_url'), file=file)
I did the sys.path.append() because I read in a different question that it would solve my problems of "module not found" when running my scripts from the command line.
Well, it did, sort of... now, it finds my imports, but apparently my imports have imports...
$ py -m bloomtest.py
Traceback (most recent call last):
File "C:\Program Files\Python38\lib\runpy.py", line 183, in _run_module_as_main
mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
File "C:\Program Files\Python38\lib\runpy.py", line 109, in _get_module_details
__import__(pkg_name)
File "C:\Users\WNeill\PycharmProjects\bloomskyGrantGrove\bloomtest.py", line 4, in <module>
import bloomsky_api as bs
File "C:\Users\WNeill\PycharmProjects\bloomskyGrantGrove\venv\Lib\site-packages\bloomsky_api\bloomsky_api.py", line 2, in <module>
import requests
ModuleNotFoundError: No module named 'requests'
So what do I do to make this work when my dependencies have dependencies?
Don't use sys.path.append. Imagine sending your code to someone else, their packages won't be in the same path and they won't be able to run your program. You might not plan on distributing your code but it's just bad practice.
Instead you should use pip to install your packages, as i assume you've been using the PyCharm package manager. I think it automatically installs with current versions of python (not sure though, I'm on Linux) and it's used like so:
pip install BloomSky-API
it'll automatically get all the dependencies and put them in the right places.
I've never used the py command before (am I missing out?), try using python bloomtest.py to run it instead just to be sure. You might get an error telling you that python is an unrecognized command or file, if that's the case it means your PATH is not set up correctly. I've found the easiest way to resolve this is to simply reinstall python, making sure to check the checkbox that says to add python to your PATH.
I'd usually post suggestions like this in a comment if I'm not sure if it solves the problem you're having, but the answer is too long to fit in a comment. Hope this helps!
I want to post the final solution to my problem, which I stumbled on thanks to DutChen18's answer.
He said I should use pip install to install all of my packages, which is one thing that I already do. I don't know much about the command line, except basic git and that. Trying to do it again gave me requirement already satisfied errors.
However, I was using an embedded terminal in PyCharm: C:\Program Files\Git\bin\bash.exe, which comes when you download Git. This works great in PyCharm because it automatically starts in the working directory of your project. Very convenient for me, a new command line user.
I decided to open up Git Bash separately from PyCharm and run pip install again. The first thing I found is that it didn't work without python -m pip install, unlike in the PyCharm embedded terminal.
Once I figured that out, I tried to python -m pip install BloomSky-API, but this time it didn't tell me that the libraries were already installed. All of a sudden, I could run my python script from the command line.
I have ZERO clue as to why this happened or why it now works, and I would love to hear a more technical explanation now that I have things working.

Problem with Python project after clone the project from Git repo

I create a Python project using Flask and it works perfectly.
Then I upload it to my private Azure repository.
After that, another coworker clone the project and try to run in his machine, but it didn't work. He got the following error:
File "run.py", line 1, in <module>
from api import app
File "E:\PUC_Conexao_Colaborativa_API\api\__init__.py", line 7, in <module>
from api.instance.config import app_config, ambiente
ModuleNotFoundError: No module named 'api.instance'
I look on Stackoverflow and found this post:
Python error "ImportError: No module named"
One of the answer say that:
You edited init.py on windows.
The windows editor added something non-printing, perhaps a carriage-return (end-of-line in Windows is CR/LF; in unix it is LF only), or perhaps a CTRL-Z (windows end-of-file).
I remember when I install "Git for Windows" exe, it asks for how I want to config the line ending conversions and I select "Checkout Windows-style, commit Unix-style line endings".
Is this the cause that my Python project fails to run in another machines?
The project runs fine on my machine and I copy the entire project and give to the another coworker using a pendrive. When the coworker run the project using the files in the pendrive, it runs perfectly, just like in my machine.
But if I or anyone else try to run the project downloading it from the repository, if fails to run with the error that I mention above.
I suppose the error is caused by the conversion of Git when I push the project to the repo. If am I correct, how can I fix that?

App Engine dev server: bad runtime process port [''] No module named google.appengine.dist27.threading

When I try to run any of my app engine projects by python GoogleAppEngineLauncher
I got the error log as follows:
Does anyone have any ideas of what's going on?
I tried remove the SDK and reinstall it. Nothing happens. Still got the same error.
Everything is working fine and I don't think I made any changes before this happens.
The only thing that I can think of is that I install bigquery command line tool before this happens. But I don't think this should be the reason of this.
bad runtime process port ['']
Traceback (most recent call last):
File
"/Users/txzhang/Documents/App/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/_python_runtime.py",
line 197, in
_run_file(file, globals()) File "/Users/txzhang/Documents/App/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/_python_runtime.py",
line 193, in _run_file
execfile(script_path, globals_) File "/Users/txzhang/Documents/App/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/python/runtime.py",
line 175, in
main() File "/Users/txzhang/Documents/App/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/python/runtime.py",
line 153, in main
sandbox.enable_sandbox(config) File "/Users/txzhang/Documents/App/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/python/sandbox.py",
line 159, in enable_sandbox
import('%s.threading' % dist27.name) File "/Users/txzhang/Documents/App/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/python/sandbox.py",
line 903, in load_module
raise ImportError('No module named %s' % fullname) ImportError: No module named google.appengine.dist27.threading
The most probable reason is having another python package that is coming from google. Run
python in verbose mode with python -vvvvv and try following command import google.
If the above import is successful make sure its coming from /Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google which is the path of python google appengine libraries on my system (OSX, fresh install of google appengine sdk).
If that is not the case (but the import is successful) then its most likely other existing google libraries which are creating issue and the path of the same would be visible on python prompt after the successful import google command like following:
>>> import google
import google # loaded from Zip
/Library/Python/2.7/site-packages/protobuf-2.4.1-py2.7.egg/google/init.pyc
In this case my google protobuf package was the culprit.
Solution:
Use virtualenv: If you haven't used python virtualenv before, may be this is the best time to use it. (a) Make sure that your PYTHONPATH variable is not set to include anything that has a google package! Unset it running unset PYTHONPATH (in your bash prompt) unless you are very sure what you have there. (b) Create a new python virtualenv, activate it and try to run google appengine commands in it:
virtualenv --no-site-packages /tmp/googleapps
source /tmp/googleapps/bin/activate
dev_appserver.py path_to_google_app
Remove conflicting packages from path: Move conflicting packages a new virtualenv. This is likely to break other stuff so not recommended.
I had hit the same issue today. This being the top result on google but lacked any answers, I add this after fixing same issue on my system. There may be other possible reasons which thankfully I haven't come across.
Good luck!
A recent upgrade of the development SDK started causing this problem for me. After much turmoil, I found that the problem was that the SDK was in a sub-directory of my project code. When I ran the SDK from a different (parent) directory the error went away.

Categories