Django deployment and virtual environment - python

I am aware that there are many questions regarding Django and virtual environments, but I cannot wrap my head around the use of virtual environments with respect to deploying my Django app (locally) via uwsgi/nginx.
My setup includes a virtual environment (with Django and uwsgi), my Django app, nginx and PostgreSQL. The app was created before the virtual environment, and I applied only a single change to manage.py:
#!/Users/snafu/virtualdjango/bin/python3
When I start up the uwsgi located in the virtual environment (with the appropriate .ini file), everything works right away, but I wonder why. I did not need to fiddle around with the $PYTHONPATH, or append the site packages directory to the system path in manage.py, or activate the virtual environment at any point (apart from the initial installation of packages), although the boilerplate comment in manage.py explicitly mentions an inactive virtual environment as a possible reason for an import error.

Activating a virtual environment does nothing but prepend the virtual environment's bin/ to the $PATH thus making python and pip without explicit paths running from the virtual environment. Everything else related to virtual environments is implemented inside Python — it automatically changes sys.path and other paths (sys.prefix, sys.exec_prefix, etc).
This means that when you run python with an absolute path from a virtual environment Python automatically activates the virtual environment for this particular Python session. So you don't need to activate the virtual environment explicitly.
There is a minor warning sign on the road though: to run any Python script from a non-activated virtual environment you must set the shebang for all scripts to point to the virtual environment or use sys.executable. Do not use explicit python because that could be a different Python from the $PATH.

Related

What does Python Virtual Env "activate_this.py" actually do?

I'm working on a python CLI project that, unfortunately, is a little complex on the virtual environments side, as it has to deal with multiple ones.
In my quest to get my tool to work properly and robustly, I came across Virtual Env's "activate_this.py" file, which is generated inside the .venv/bin/ directory.
I thought this could be useful for my needs so I started experimenting with it, but I haven't truly understood what it is actually doing under the hood.
For example, it says that the script should be used when a file must be called from an existing python interpreter (which is my case), but the virtual environment must be activated.
What I'm struggling to understand is: What exactly does activating a virtual environment on a given file mean? (Since we're not changing the interpreter)
Also, on the activate_this.py file there's this bit of code:
# add the virtual environments libraries to the host python import mechanism
prev_length = len(sys.path)
for lib in "../lib/python3.9/site-packages".split(os.pathsep):
path = os.path.realpath(os.path.join(bin_dir, lib))
site.addsitedir(path.decode("utf-8") if "" else path)
sys.path[:] = sys.path[prev_length:] + sys.path[0:prev_length]
Does this mean that you can now import libraries that are installed on the virtual env you've just activated, even if they are not installed in the environment of the base interpreter?
You've got it. It rewrites your sys.path to expose the stuff installed in the virtual environment, and it cuts off access to the globally installed third-party libraries not in the virtual environment.

what does activating virtualenv in python exactly mean and what it does?

When we want to do anything with our python virtual environment in terminal/command prompt/shell, we have to activate it by navigating to the scripts folder. But, what does this activation do?
I can access the contents of the virtualenv folder in file explorer without activating it.
At its core, the main purpose of Python virtual environments is to create an isolated environment for Python projects. This means that each project can have its own dependencies, regardless of what dependencies every other project has.
More interesting are the activate scripts in the bin directory. These scripts are used to set up your shell to use the environment’s Python executable and its site-packages by default.
After activating the environment, we’re now getting a different path for the python executable because, in an active environment, the $PATH environment variable is slightly modified.

What makes in Python a virtual environment a virtual environment?

I want to find the Python virtual environments ("venvs" for short) in my file system, and for this I need to know what set of files constitutes a venv.
Some tools - when they want to make sure a directory is a venv - check for the pyvenv.cfg file, but older virtual environments and environments created by Pipenv do not have this file. - Furthermore pyvenv.cfg does not seem to be necessary for activating the venv either.
So what is the minimal set of files to define a working virtual environment? And what is an easy way to check for this in Python?
Clarification:
With "working virtual environment" I mean:
A way to use a specific version of Python executable defined in that environment (and possibly different to the default system Python)
A way to use specific packages (usually installed via pip, bit that's not a requirement).
The Python executable in the venv should be aware of being run inside a venv (see
sys.base_prefix and sys.prefix in the Python documentation.)

Django and 'virtualenv' - proper project structure

I have a dilemma setting up a local development projet structure. Here is my setup:
Python 2.7
Django 1.9
Mac OSX El Capitan 10.11
MySQL 5.7
I made a "Mistake" of setting my project globally instead of in a virtual environment (using 'pip' to install everything in />). After reading this article I still don't get all the steps. Is this correct:
I install global python ( pip, virtualenv in '/>' )
I then go to a location where my projects will reside, like /users/user/documents/projects/project1 and from within 'project1' I use 'virtualenv' to create a virtual environment for this project (this creates a /virtual env/ folder inside /project1/ folder)
activate this virtual environment and pip install django
then from within newly created /virtual env/ folder I startprojectwhich creates another /project1/ folder within /virtual env/ folder
with virtual environment still activated in the current shell session, I proceed with creating my scripts, site and app files
Ad 2. should the virtualenv folder be INSIDE the main "project1" folder or should it encompass it?
Ad 4. Is this correct or can I do it without activating virtual environment first?
My structure currently looks like this (starts from the root: /users/myUser/documents/projects/):
/project1/
/website1/
/static/
/templates/
__init.py__
settings.py
urls.py
views.py
wsgi.py
Common solution is to keep virtual environments and projects in separate folders, e.g. have /users/myUser/.venvs for virtual environments and /users/myUser/documents/projects/ for projects. In other aspects you got it pretty much right yourself. So:
You need to install global Python and virtualenv.
Create directoriy for virtual environments, e.g. run mkdir /users/myUser/.venvs.
Create the virtual environment for your project, virtualenv /users/myUser/.venvs/project1_venv.
Activate the environment for your current shell session /users/myUser/.venvs/project1_venv/bin/activate.
Install django and anything else in this environment pip install django, or better use requirements.txt file to keep track of all project dependencies.
Deactivate the environment, run deactivate.
Now when you'll want to run your project using created virtual environment, in your console window run /users/myUser/.venvs/project1_venv/bin/activate and then python /users/myUser/documents/projects/project1/manage.py runserver. You can activate the venv from any directory, it's activated for current shell window and any python ... run in that window after activation will use this virtual environment. The activation script modifies environment variables in a way, so that the interpreter and libraries from venv are used instead of global ones. (Though there are options to use global ones too.)
It doesn't really matter where you store your virtual environment. Find a project structure that works for you.
I wouldn't put the virtual env inside the project, because you shouldn't check it into version control (although you could use an ignore). Normally, you just need to check in your requirements file, so that you can recreate the environment.
I wouldn't put the project inside the virtual env, because virtual envs are disposable. You might want to destroy the virtual env without destroying the project. Also, you might want to run the same project under different virtual envs e.g. test your code on Django 1.8 and 1.9 before upgrading.
You might find virtualenvwrapper useful. It has some tools that make it easy to create and switch between virtual environments. It stores all of your virtual environments in one place, so you don't have to worry about where to put them.
Is this correct or can I do it without activating virtual environment first?
You should activate the virtual environment and install django before you create / work on your project.

Virtual environment can't find module that is installed outside the virtual environment

I am trying to set up a virtual environment on my machine, and I am really having trouble.
EDIT: I set up my virtual environment by installing virtualenvironment1.9 and running:
python virtualenv.py -p myVE
Then I add the line
alias goVE='source ~/virtualenv-1.9/myVE/bin/activate'
to my bashrc, and I use goVE to activate the virtual environment. I get a (myVE) at the beginning of the commandline in terminal, so I think it's working. It's just losing the gtk module somehow.
END EDIT
Basically, if I try to
import gtk
in python, it tells me there is no module named gtk. But outside my virtual environment, gtk imports with no problem. I decided it was a problem with the path, so I added
export VIRTUALENV_EXTRA_SEARCH_DIR=$PYTHONPATH
export VIRTUALENV_EXTRA_SEARCH_DIR=/usr/lib64/python2.6/site-packages/gtk-2.0
to my bashrc. Since evidently the gtk module was found in the pythonpath, I thought the first line would do it. When that was insufficient, I tried adding a path specifically to the directory where gtk was located, which I verified by trying
import gtk
gtk.__file__
Since this still didn't work, I tried modifying the virtualenvironment/bin/activate file, so:
PATH = ="$VIRTUAL_ENV/bin:$PATH:/usr/lib64/python2.6/site-packages/gtk-2.0/"
Again, this should be included in the original PATH (unless I'm mistaken), but I'm getting desperate so I tried adding it explicitly to the PATH. For completeness, my PYTHONPATH is set by:
export PYTHONPATH=${PYTHONPATH}:/data/monroe/ebexcode/trunk/GetData/:/home/user1/geach/:/usr/lib64/python2.6/site-packages/
You haven't explained how you created your virtual environment so there's no way to tell if that succeeded. If your virtual environment was created successfully, there's no need to manually munge the paths.
Assuming you have a virtual environment, you haven't demonstrated that you were able to activate it. In order to activate it, you have to run a script in the virtual environment's bin directory. Example, if your virtual environment is in ~/myvenv and you run bash, activate your virtual environment by issuing this at your prompt:
source ~/myvenv/bin/activate
At this point you can use this instance of your shell to install packages into your virtual environment:
pip install PyGTK
Depending on your system installation, this might fail if you do not have all the tools and libraries installed to build the Python GTK bindings.

Categories