Issue with my Python environment - python

Brand new to Python, coming from Ruby.
I have a script that works perfectly if I run it form ipython or ipython qtconsole. I then tried to turn it into an executable script -- threw #!/usr/bin/env python at the top.
Running the script throws an error:
$ ./script/myscript.py
Traceback (most recent call last):
File "./script/myscript.py", line 6, in <module>
import yaml
ImportError: No module named yaml
Obviously there's something wrong with how python is loading modules (as it works perfectly fine from the REPL) but I have no idea how to fix it.
Thanks!

What is likely happening is you have more than one version of Python installed on your system, and the yaml module is only installed in one of them. When you run ipython it's using one version, but your script's shebang line is finding another version. Run
head `which ipython`
and see if it matches up to the result of which python (I'm betting it won't). Once you know the path to the python binary being used by ipython, you can specifically define it in your script's shebang line.
As a long-term fix, edit your $PATH variable and put the directory containing your desired version of Python ahead of the directory shown by which python, so that you can continue to use #!/usr/bin/env python as a shebang.

ipython must be pointing at a different version of python than what is in PYTHONPATH.
You can find out by looking at cat /usr/local/bin/ipython.
Look at
ipython reads wrong python version

Related

VSCode Output and Terminal using different Python interpreters; one can't find module?

Solution: I had a sneaky system environment variable that put the 3.10 python variable into the path. Deleted that variable.
I'm super new and trying to import modules like matplotlib to Python. When I hit "run python file", the terminal produces exactly what I want, confirming the import worked. But when I hit "run code" I get the following in the output:
Traceback (most recent call last):
File "c:\Users\user\AppData\Local\Programs\Python\Python39\Workpls\test.py", line 1, in module
import matplotlib
ModuleNotFoundError: No module named 'matplotlib'"
This is the code I ran in both terminal and output:
import matplotlib
help(matplotlib)
For more context:
It appears I have two python folders of differing versions (v3.9 & v3.10) in my APPDATA/Local/Programs folder. In VSCode I changed everything to the one of interest(v3.9): the vscode default python interpreter path, the interpreter in the blue ribbon at the bottom of vscode, and the command palette Python: Select Interpreter (note that for some reason it still shows v3.10 as the global version in the palette drop down). Yet it still doesn't produce the desired output.
I think this should be related to the confusion of your Python version. I suggest you leave only one Python version, and you can put another version into the virtual environment.
At the same time, we recommend using run Python file. After all, code-runner is not the official extension of Microsoft.

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.

What is the advantage of "#!/usr/bin/env python" in the shebang rather than just calling the "#!python" interpreter?

I understand the difference between starting a python script like:
#!/usr/bin/env python
or
#!/usr/bin/python
From what I understood, just executes python as we would do in our shell, so it looks in $PATH. The second one is not a fixed path, which has the inconvenient that in a different system the python interpreter might be located in another path.
My question is, why do we need env? Why can we just do:
#!python
This works perfectly fine in my computer? Is there a reason to prefer calling env?
Short answer:
This depends on the shell. in bash #!python will just be ignored and you have to use #!/usr/bin/env python. zsh on the other hand seems to be able to handle #!python.
The long answer (for bash):
let's imagine your python file is named 'tst.py'
and has following contents
#!python
import sys
print(sys.executable, sys.version)
then you can always type
python tst.py
The first line is completely irrelevant and is not even looked at.
However if you do following (for example on linux)
chmod +x tst.py
./tst.py
Then the first line is looked at to determine which interpreter shall be used (bash, perl, python, something else?) and here at least for my OS (ubuntu) and my shell (bash) an absolute path is required for the executable name (e.g. /bin/bash, /bin/python, /usr/bin/env)
If I call ./tst.py on my ubuntu machine I get
bash: ./tst.py: python: bad interpreter: No such file or directory
Special case Windows, when typing tst.py or clicking on a python script.
If you're on windows, the line is looked at, but even if it is wrong a default python interpreter will be used. On Windows, this line could be used to select explicitly python2 or python3 for example.
Windows uses file type associations to determine which executable to call for which suffix. for .py files (python 3.x is installed) this is normally py.exe which is an executable located in the system path, that will just call a python interpreter. depending on installed versions, the shebang line and environment vars, that might indicate a virtualenv
Addendum:
The first line is interpreted by the shell or in the windows case by py.exe.
It seems bash requires absolute paths for command, whereas zsh accepts relative paths as well.
So for zsh only
#!python
works perfectly well whereas bash requiers absolute paths and thus the trick with the env command
#!/usr/bin/env python
For scripts that shall be executed by a cronjob it's best to hardcode the path of the python executable as PATH is rather minimalistic for cronjobs, so there it's best to have something like
#!/usr/bin/python3.5
or
#!/home/username/myvirtualenv/bin/python
Each Python script is written with a particular version of Python in mind. If the shebang is #!/usr/bin/env python, that puts the version used under the control of the individual caller, whose PATH may not provide the right version.
#!/usr/bin/python is a little better, as it puts the decision in the hands of the script itself. However, the script author doesn't necessarily know where the correction version of Python is on your system, so it still may not work.
The solution is to specify the correct location on your system when you install the module or script. The Python installer (pip, etc) will, at that time, rewrite any shebang containing the word python (#!python being the minimal such shebang) to the path specified by the installer.
Now when you run the script, it will point to the correct path that you have already provided, without being subject to runtime PATH lookup that could choose the wrong version.
Note that #!python is not meant to be used as-is, though for various reasons it might work for you. It's is a means towards making sure the script gets a fixed, absolute path to the correct interpreter. #!/usr/bin/python is also subject to install-time replacement, so may serve as a usable default.

Run python script from another directory

I feel a little foolish that I don't know this, but I tried to do it today and was surprised when it didn't work....
I have a directory C:\test with a demo script, lets call it demo.py
If i am in C:\test then I can just do python demo.py. Easy
I could also use a relative path, so from C:\, it's python test\demo.py
What if C:\test is on the path?
I was expecting to be able to now do python demo.py from anywhere however...
python: can't open file 'demo.py': [Errno 2] No such file or directory
I feel foolish because I thought this was straightforward, but I have searched around and have not found a solution. Am I fundamentally misunderstanding something here about how the Python interpreter finds scripts to run? I don't think this is anything to do with PYTHONPATH, as I understood that to relate to loading of modules inside scripts.
This is on Windows 7, by the way.
The PATH is only used to search for commands. A first way is that a Python script can be used directly as a command and in that case the PATH will be used: just use demo.py instead of python demo.py.
It will rely on OS specific ways. On Windows, file type (given by the extension - here .py) can be given default application to process them, while on Unix-like, the first line of a script can declare the program that will process it.
Alternatively, python allows to launch a module that will be searched in the PYTHONPATH (not PATH) by using python -m module or for Windows py -m module.

/usr/bin/python: No module named barista.__main__; 'barista' is a package and cannot be directly executed

I am trying to drive github project: https://github.com/kjchavez/distributed-deep-q with Ubuntu16.04 python2.7.12. I have installed caffe and pycaffe correctly.
When i am trying to make a new caffemodel as with command below (given in readme)
python -m barista models/deepq/train_val.prototxt models/deepq/deepq.caffemodel --solver models/deepq/solver.prototxt
it gives me error
/usr/bin/python: No module named barista.__main __; 'barista' is a package and cannot be directly executed
I have read about same kind of errors in python2.6 with command "python -m" but im using python 2.7. Barista is a directory inside of the main project directory and it consist python files with __init __.py but not __main __.py. I have included to $PYTHONPATH in .bashrc file paths /caffe/python and /main_project_directory.
If someone have an idea where I fail I would be very happy. I think that problem is in python version but not sure about that. I can give extra information about my systems and setups in later posts.
The readme says you're supposed to use something like this to start the program:
python main.py models/deepq/train_val.prototxt models/deepq/deepq16.caffemodel
It seems that at some point there was a file [...]/barista/__main__.py which would allow to use python -m barista, but that file has been renamed to [...]/main.py, the description here probably just wasn't updated.

Categories