Run a python script with Popen with PyInstaller - python-3.x

I need to run a script inside a Popen inside a packaged project (with pyinstaller). The command NEEDS to run in python3 and I (obviously) need it to be portable, which means that I can't rely on the config (python/python3 notation) used on the machine I've used to generate the package neither the one where I am using it (I can't also guarantee that there will be any python in the deployment machine...).
I have computers where python is already the correct version, and others where the correct one is python3. I tried to insert #!/usr/bin python3 in the beginning of the file and then run as python but it didn't work.
subprocess.Popen(['python', 'internal.py', arg1, arg2], universal_newlines=True)
In the non-frozen environment I am able to run using sys.executable instead of python. I tried to "pyinstall" the internal.py then, "pyinstall" the rest copying the internal folder to the new folder and then call:
subprocess.Popen(['./internal/internal', arg1, arg2], universal_newlines=True)
But this doesn't work... In the console (moving to the bigger project folder) it does, but when running the package, it doesn't...
Any idea?
Ps. I can't just import the script as a class or whatever. I can't modify system environment vars (except the ones inside the pyinstaller thing...)
I saw something about the PyInstaller.compat that has a exec_python and a __wrap_python, but I couldn't use it I get errors when trying to run the package due to pkg_resources.DistributionNotFound: The 'PyInstaller' distribution was not found and is required by the application, I tried to create a hook, to add as hidden import... None worked (but the hook part maybe I got it wrong...)

Related

I cannot run pyinstaller on my computer even though I have installed it

This is the problem right here, do you have any advice for that?
installed pip and pyinstaller, but still got this error message when I tried to convert my project into an .exe.
From Pyinstaller installation guide:
If you cannot use the pyinstaller command due to the scripts directory not being in PATH, you can instead invoke the PyInstaller module, by running python -m PyInstaller (pay attention to the module name, which is case sensitive). This form of invocation is also useful when you have PyInstaller installed in multiple python environments, and you cannot be sure from which installation the pyinstaller command will be ran.
So you may run it as e.g.:
python -m PyInstaller some_system.py
Or, as the issue seems that PATH Windows environment variable doesn't include Python's Script folder, it'd better to fix it. From the same guide:
If the command is not found, make sure the execution path includes the proper directory:
Windows: C:\PythonXY\Scripts where XY stands for the major and minor Python version number, for example C:\Python38\Scripts for Python 3.8)
To fix you may run where python to get exact location of Python on your machine (let's say it shows C:\Python38\). Then add to PATH env variable Scripts folder inside it (in this example it'd be C:\Python38\Scripts\)

How can I create a Python executable program that doesn't force the user to actually download Python libraries and that stuff in order to be executed?

Let's say that I already built a program that essentially takes some images from an user's path and make new ones using the following libraries/modules:
os itertools pandas PIL
What I need now is to make that program become an executable file that can be actually executed without having to have installed the Python environment and the libraries used in the code, because the user would not know how to code, and would not likely matter how the code works.
The program would run on Windows OS (PC) only , and would use the cmd.exe as the interpreter and medium for user inputs and results display.
Solved here
You can use wheel, and ship whole environment.
#Vincent Caeles:
"#rh979 a wheel is not meant to have all dependencies. Subsequently you could do pip install path/to/wheel.whl --target /path/to/some/folder and zip the contents of the 'folder' to have all your dependencies in the zip archive and ship that to the environment where you want to run your code.
"
Another options is pyinstaller library, according to documentation it should do what you need.

Pyinstaller executable fails with pkg_resources.DistributionNotFound error

I'm making a PDF Tool executable using tkinter. Anyways, the executable was successfully created by pyinstaller, but it won't run. I flagged --onedir and added the necessary dependency files --add-data. I also added the paths to my non standard library packages using --paths flag. When I run the executable from the command prompt, I get this:
The problem appears to come from the ocrmypdf module and says pkg_resources.DistributionNotFound. I tried searching for the fix, but all the problems I saw were a bit different from my issue because the .py script runs just fine for me. Is this a pyinstaller issue, or am I missing a module? I'm using pyinstaller 4.0 as well.
After researching a little bit more, I've found the solution. The problem lies with pyinstaller, not the ocrmypdf module. The solution is that you have to create hook py scripts within a folder in your project. It's a little bit different depending on which module you use, but for this case, I had to create two hook py scripts within a folder that I called 'hooks'. These are the two scripts I made:
hook-ocrmypdf.py
from PyInstaller.utils.hooks import collect_all
datas, binaries, hiddenimports = collect_all('ocrmypdf')
hook-pikepdf.py
from PyInstaller.utils.hooks import collect_all
datas, binaries, hiddenimports = collect_all('pikepdf')
For more information go here.
Additionally, you must add the --additional-hooks-dir HookFolderPath flag to the pyinstaller command.

How can I run a Flask application

The Flask official website says that we can run a Flask application by
$ export FLASK_APP=hello.py
$ flask run
The second command doesn't work for me.
$ flask run
Command 'flask' not found, but can be installed with:
sudo apt install python3-flask
Instead this works
python3 -m flask run
How can I make the second command works? If I run sudo apt install python3-flask, will I get two installations of flask?
Can the two commands be combined into one command without using environment variable?
Bear with me as I will try to explain the different pieces and how they all interconnect. export FLASK_APP=hello.py is setting an operating system environment variable called FLASK_APP and is simply pointing to the entry file to start your flask application. This is no different than setting any other environment variable on your operating system. Now the flask team has provided everyone with a command called flask run which can be used to start up your flask application and this command will use the value set within your FLASK_APP environment variable when it attempts to start your flask server. So the reason why your python3 -m flask run command works is because you're telling your operating system's install of python to run the flask run command as a script, which is how this command is intended to be invoked.
For reference:
-m mod : run library module as a script (terminates option list)
Additionally, python attempts to resolve modules from it's sys.path environment variable and it looks in the following order of directories to resolve the requested module:
The current directory where the script has been invoked. This is why you can always import modules contained in the same directory as one another.
The value of your PYTHONPATH environment variable
The standard library directory on your path
Lastly, the site packages directory, i.e. your third party packages like flask
Now the reason your flask run command didn't initially work is because python couldn't find flask within any of the four locations listed above. However, once you gave the -m python knew to look in your site-packages directory for flask and was able to find said module.
For reference you can see where python is looking to resolve modules by printing out the sys.path variable to the console:
import sys
print(sys.path)
Ok so that answers the first part of your first question, now as for the second part of your first question:
"If I run sudo apt install python3-flask, will I get two installations of flask?"
Yes, this would install flask globally on your system and I would highly advise against this as you can mess up your system pretty badly if you're not careful. So how do I avoid messing with my system level python configurations?
Virtualenv to the rescue, Virtual environments allow you to have a sandboxed area to play around with libraries. With the worst case scenario being you blow them away and start fresh if you screwed something up, without affecting your Operating System's install of python. You should have a one to one relationship between each python project and virtual environment. If you use virtualenv I highly suggest looking into Virtualenvwrapper which wraps virtualenv with easier to remember commands. Although I think all the cool kids are using pipenv now so you may want to look into that as well, I will leave that decision up to you. What's nice is once you've activated your virtual environment and are developing you can just use flask run since your virtual environment will be on your python path.
As for your second question: "Can the two commands be combined into one command without using environment variable?"
No you would still need to set the FLASK_APP environment variable to use flask run since it looks for the value of that environment variable to start your flask server. Perhaps you could try something like:
FLASK_APP=hello.py flask run
on the command line and see if that helps you, but you're still setting the FLASK_APP environment variable. Alternatively, you could just start the entry file for your flask server directly, with a:
python hello.py
I know that was a lot, but hopefully that helps clarify things for you!

Getting Error: 'No module named flask' in VSCode even when I have installed flask

I want to debug an application using Python and Flask in VSCode. I have installed Flask and the app runs perfectly fine through cmd. But, when I try to debug it through VSCode, it gives the following error:
cd 'c:\Users\Aditi\CleanHandymanApp';
${env:FLASK_APP}='NewApp'; ${env:PYTHONIOENCODING}='UTF-8';
${env:PYTHONUNBUFFERED}='1'; & 'C:\Users\Aditi\envs\CleanHandymanApp\Scripts\python.exe'
'c:\Users\Aditi\.vscode\extensions\ms-python.python-2018.10.1\pythonFiles\experimental\ptvsd_launcher.py' '--client' '--host'
'localhost' '--port' '63143' '-m' 'flask' 'run' '--no-debugger' '--no-reload'
No module named flask
Can you please help me.
This error message can occur if you installed the python3 version of flask but Visual Studio Code tries to run your project with python2.
Make sure to select the correct version of python in the editor. This can be done by running the command Python: Select Interpreter from the Command Palette (Ctrl+Shift+P).
Activate your virtualenv and run
pip3 install -r requirements.txt
to reinstall all packages inside the venv.
For some reason VS Code thought I was missing all my packages the first time I debugged even though the app was running fine locally.
Sometimes you can get this error if you loaded Flask into a folder which has sub-files. For instance, if you loaded flask into the parent folder with the virtual shell instance but you're running your code in the child file (let's say parent is called crypto_files and inside that is a python source code file called blockchain.py ), then in order to get flask to run properly you'd have to run the file like this:
python crypto_files/blockchain.py
This allows your machine to see Flask running inside crypto_files but also run blockchain.py .
OR, it's possibly you could just reload Flask into the sub(child)file... blockchain.py and then you'd run it from within the subfile.
This complication is mainly due to modern "virtual instances" and shells which are basically like creating a virtual computer-machine inside your ACTUAL hard machine. Flask does this to avoid running everywhere, and since Flask is modular it allows each of your projects to run different modular configurations of Flask to suit each project precisely. The alternative would be awful: you'd have to load the fattest version of Flask with dozens of add-ons for each project, and so all your git and all your projects would have tons of extra code. Flask is built to be very small at the core to avoid this problem (too verbose!).
If you have installed flask in virtual environment, you should have activated it first.
source /path to env dir/bin/activate #in linux
workon 'name of env' #windows
Another option is add sys.path.append('d:/programas/anaconda3/lib/site-packages') in c:\Users\Aditi.vscode\extensions\ms-python.python-2018.10.1\pythonFiles\experimental\ptvsd_launcher.py
Being that "d:/programas/anaconda3/lib/site-packages" should be modified by your local python packages.
Use this command in the terminal instead of selecting run code:
python3 "insert your file name here without the quotes"
e.g.: python3 example.py
I had a variant of the issue mentioned by #confusius. I had installed both Python 3.9 and Python 3.10. I had added Flask to Python 3.10. I had been using one vscode workspace which had selected Python 3.10. I started another project in a different vscode workspace and it had selected Python 3.9 by default, which I didn't notice because I thought it would select the same Python I had already selected in the other workspace.

Resources