Why does setting PYTHONPATH corrupt package lookup? - python

I have the following python file, importproblem.py:
#!/usr/bin/env python2.6
import gobject
import pygtk
pygtk.require('2.0')
import gtk
When I run it at the command line as such:
-bash-4.1$ ./importproblem.py
-bash-4.1$
It is fine. I confirm that I am using Python 2.6.6
-bash-4.1$ python --version
Python 2.6.6
When I send it to the python interpreter directly:
-bash-4.1$ python importproblem.py
-bash-4.1$
It is fine. I am trying to resolve a threading problem [my UI locks up when I start plain old threads that monitor sockets], so I built a local version of pyGTK, documented as a requirement pyGTK FAQ Archive
When I add the path to that module setting the PYTHONPATH, python then fails to find gtk:
-bash-4.1$ PYTHONPATH=/home/dscoughl/lib64/python2.6/site-packages python
importproblem.py
Traceback (most recent call last):
File "importproblem.py", line 5, in <module>
import gtk
ImportError: No module named gtk
-bash-4.1$
How do I resolve this or diagnose it further?

PYTHONPATH tells Python where to look for its libraries. If the library is not under PYTHONPATH, it is not going to find it.
A better way to handle this sort of thing is to leave PYTHONPATH as a whole pointing to the system packages, and then use virtualenv.
The default way to set this up is to make sure that pip is installed for your distribution and python version, then run
pip install virtualenv
pip may be pip2 or pip3 instead depending on your distro and its default assumptions about python.
Then to create the virtual environment for your project, go to a folder that you can relatively easily reference and execute:
virtualenv projectenv
Replace projectenv with the folder name that you want it to create the environment in.
This will create a virtual environment using your system's default Python install. If you have multiple version of python, and you want to use something other than the default, then use the following.
virtualenv projectenv -p PYTHON_EXE
or
virtualenv projectenv --PYTHON=PYTHON_EXE
PYTHON_EXE will be the name of the binary for the correct version of python. For instance on a newer system you may need to use --PYTHON=python2 in order to use version 2.6 rather than version 3.x.
To activate the virtual environment, depending on your distro and shell, use one of the following:
source /path/to/ENV/bin/activate
or
./path/to/ENV/bin/activate
Relative paths are generally ok. This will take you into the virtual execution environment.
From there you can use pip to install the packages that you want. My first step is often to upgrade pip itself within the environment.
When you are ready to stop using the virtual environment, just use:
deactivate
exiting the shell session will do the trick as well, but if you are accessing a remote system it is good to know the proper way.
Check out the documentation here for more thorough information on virtualenv, including how to use it on a Windows system: https://virtualenv.pypa.io/en/latest/
There is plenty of information on the web about how to use virtualenv, including on using it with Apache2 and Nginx for web development. Most python web frameworks will have instructions for using virtualenv.

Related

Is it possible to have two distinct install of Python 3 of the same revision on a Windows system?

I know it possible to have two installs of Python of different versions on a Windows system. But I cannot manage to have two installs of the same revision (in my case 3.8.10) to coexist.
I'm designing an application that creates a Python process. That process needs to run from a specific version of Python with packages of specific versions installed on it. In order to fully control the Python install, decision was made to install it inside the application distribution directory, segregating it from any other Python installed on the system. No environment variable refers to it.
As part of the the deployment/install process for the application, a PowerShell script downloads the Python installer and installs Python and the necessary packages into the application distribution directory. The Python installer is invoked as follows:
.\\python-3.8.10-amd64.exe /quiet InstallAllUsers=1 PrependPath=1 Include_test=0 TargetDir="$curDir\\Python" Include_exe=1 Include_lib=1 Include_pip=1 Include_tcltk=1 | Out-Null
It works well unless the system has already a Python install of the same version installed on it. In that case, running the installer will break the existing install, and not fully install the new one.
I tried to run the installer manually and I noticed that it is able, somehow, to detect that an install of the same revision exist on the system. In that case, it does not allow an new install. To do so, I would have to uninstall Python at its current location to be able to install it somewhere else.
Is there a way to have two distinct installs of Python 3 of the same revision on a Windows system? And if yes, how can it be done?
A better aproach instead of installing python again would be using virtual environments.
To create a new python env. Open the command line (Powershell) on Windows and navigate to the directory you want your python env to be.
Type python3 -m venv tutorial-env. This will create a new python virtual env named tutorial-env
To activate that env on Windows powershell type: tutorial-env\Scripts\activate.bat
To deactivate the env type deactivate
If you are wondering what python virtual environments do. They basically do what you are trying to do but without installing python globally again. When you create a new python env, a new python3 is placed in your env directory, in this case in the tutorial-env directory, and when you activate the environment, it replaces the python global path to the path in your env (in this case in tutorial-env). Now when you are on this virtual env and install new python packages, they will only be available when you activate that env.
For more information about virtual environments please refer to Python official docs.

How to install python module local to a single project

I've been going around but was not able to find a definitive answer...
So here's my question..
I come from javascript background. I'm trying to pickup python now.
In javascript, the basic practice would be to npm install (or use yarn)
This would install some required module in a specific project.
Now, for python, I've figured out that pip install is the module manager.
I can't seem to figure out how to install this specific to a project (like how javascript does it)
Instead, it's all global.. I've found --user flag, but that's not really I'm looking for.
I've come to conclusion that this is just a complete different schema and I shouldn't try to approach as I have when using javascript.
However, I can't really find a good document why this method was favored.
It may be just my problem but I just can't not think about how I'm consistently bloating my pip global folder with modules that I'm only ever gonna use once for some single project.
Thanks.
A.) Anaconda (the simplest) Just download “Anaconda” that contains a lots of python modules pre installed just use them and it also has code editors. You can creat multiple module collections with the GUI.
B.) Venv = virtual environments (if you need something light and specific that contains specific packages for every project
macOS terminal commands:
Install venv
pip install virtualenv
Setup Venve (INSIDE BASE Project folder)
python3 -m venv thenameofyourvirtualenvironment
Start Venve
source thenameofyourvirtualenvironment/bin/activate
Stop Venve
deactivate
while it is activated you can install specific packages ex.:
pip -q install bcrypt
C.) Use “Docker” it is great if you want to go in depth and have a solide experience, but it can get complicated.
Pip is a program used to manage Python distribution. You usually have one system distribution which is by default managed by Pip. When you do pip install scipy, you install package scipy to your system Python. Everytime you try to import scipy after it will work because your system Python has it.
Project specific distributions are acomplished by using virtual environments. python -m venv env or venv env creates a copy of system Python interpreter, pip, setuptools and a couple of other essential tools. In other words, virtual environment created this way is empty.
To use created virtual environement one should use source env/bin/activate. After that, everytime you invoke python command it will use activated Python interpreter. When you install packages using pip, it will install them in the virtual environment rather than to your system python. To use system Python again use deactivate.
Such usage is actually prefered for projects because some user applications could rely on system Python and some packages, and installing, updating etc. could be potentionally dangerous.
Further reading: venv documentation

How can I configure Django setup to not need sudo?

I have pip, virtualenv, and django installed globally. Using py3, default is set using alias line in ~./bash_profile - so py2 packaged with Mac still there.
In new virtualenv, activated, but when I try to do anything with django get following error:
$ python manage.py migrate
Traceback (most recent call last):
File "manage.py", line 8, in <module>
from django.core.management import execute_from_command_line
ImportError: No module named 'django'
If I run with sudo (i.e. sudo python manage.py migrate) command works.
I know problem is likely how I installed pip, but anyway to fix this without re-installing everything?
Instead of python manage.py migrate, simply tell it python. It will start an interactive python interpreter. Tell it the following:
import sys
sys.executable
sys.path
sys.executable is the full pathname of the Python executable. It should be something inside your virtualenv. sys.path is the list of directories in which Python searches for modules whenever you try to import something. This should include your virtualenv.
Now exit Python and tell it sudo python. Enter the same directives. What are the differences?
This should give you a hint on what you've done wrong and you should be able to debug it further.
You might also find my article, virtualenv demystified, useful.
This can happen for several different reasons (from most basic to more complicated):
Django not installed, either globally, in your virtualenv, or both. Check using pip list. Most of the time pip install django will fix. Do not sudo this, or you will have to sudo everything. Also: double check django version matches python version; pip install --upgrade django to get latest version.
Virtualenv not activated - use source your_path/venv/bin/activate
Mac users - running python3 on virtualenv, but python2.7 default on comp. Fix by deactivating first virtualenv, manually deleting bin||venv, start new virtualenv set to use python2.7. Use virtualenv -p /usr/bin/python2.7 env.
Similar - server running different versions. Sometimes you can fix with alias (ala alias python=python2.7), but make sure to only use on instance being used for project, not on local comp. Local comp wont work, because sudo being run for default python version regardless.
In manage.py defaulted path not correct. This depends on your setup and where python dependencies stored. If this is your problem, replace shebang with #!/usr/bin/env python. Be careful re: python versions here, so if issue with OS default different from using, just add number to end of python (ex: python3).
Follow #antonis answer, figure out where in $PYTHONPATH not matching up with sudo PATH. Pipe/update profile to fix.

How to move django project from ubuntu env to virtual env?

I have an existing django project which I have developed using python libraries installed in system and adding missing ones to the system. But now conflict has come for python-requests as system has 2.2 version but I need >2.5. Dont't want to uninstall and put newer one as it may break the OS. So now, I want to use virtual env and install packages there in complete isolation to that of OS.
I think the solution you're looking for is to download a different version of python without uninstalling your original, then start up virtualenv venv, but by passing in a path to the new python.exe file. Like this: virtualenv -p venv <path-to-executable-here>, then just do source bin\activate, as usual. This starts the virtual environment using the python executable you passed to virtualenv through the terminal.
Also, this might not be the only way, but, there's something called ModuleFinder which enables you to get a list of all the modules your script is importing--That is if you don't want to type them out manually, and you have extra modules installed (otherwise pip freeze > requirements.txt would do the job, and your new virtual environment would install all the packages in requirements.txt).

How to setup PyDev's python interpreter in eclipse using pip within a virtualenv

I want to use pip to install new packages and they say to install pip in a virtualenv. I did that and installed some packages and use them no problem.
But I have a problem setting up the simple google app engine helloworld app under PyDev using python2.7. I set it up to use C:\Python27\env\Scripts\python.exe. But running it gave an error that it couldn't import pdb.
Running the virtualenv python from the cmd line and calling 'import pdb' gave no errors. And typing pdb echoed: module 'pdb' from 'C:\Python27\lib\pdb.py'. So from the cmd line, it could find pdb in the root lib dir. The debug out from appengine said it was using the virtualenv python. I made sure that I had C:\Python27\lib in the System PYTHONPATH when setting up the PyDev interpreter, but this did not matter. Strange. (I also have C:\Python27\DLLs and C:\Python27\lib\lib-tk).
So I tried using the root python exe as the interpreter and it works fine. No problem with pdb, so my code is correct. But now it can't find the modules I added using pip in the virtualenv.
It seems there are 3 options for setting this up correctly:
Somehow setup the PyDev python interpreter using the virtualenv python that will find the root pdb package. (Don't know how to do this, but it seems like the right answer.)
Or will it work to use the root python and add the virtualenv site-packages to my path. (not sure if this will work).
Don't listen to the pip advice - install pip in the root env and install my modules in the root env.
I hope someone who has gone through this before can give some advice as to the best way to proceed with the least amount of problems later.
I did some research on the google-appengine-python group and they say to go with option 3: Don't listen to the pip advice when using it with google appengine. appengine does not play nice with virtualenv.
Refs:
Appengine with virtualenv
Strange imports (and WARNINGs) in development server

Categories