Python environments and Maya
January 21, 2022Working cleanly with python environments is something that I feel is quite obscure for a lot of people but is not actually hard or convoluted.
In this blog post I'm going to describe how I typically setup my python environments when developing tools and how to make maya aware of them without having bloat mayapy by installing dependencies to it directly.
Info
The workflow I'm describing here is likely more suited to developping standalone tools rather setting up a studio environment with lots of dependencies.
For that you should probably look into Rez or some kind of environment manager.
TLDR
Simply create a virtualenv with a python interpreter matching your mayapy version and add the venv's site-packages
folder to mayapy's PYTHONPATH like so:
import site
site.addsitedir("/path/to/venv/Lib/site-packages")
And that's it. You can now pip install packages in your venv and you'll be able to import them in maya.
Note
Make sure to use
site.addsitedir()
and notsys.path.append()
.
The first one properly adds paths to your PYTHONPATH by taking the.pth
files into account.
In most cases you won't see a difference but it can avoid some confusing issues.
Going Further
Managing python interpreters and virtualenvs is sadly pretty barebones by default but there's two great great tools I've been using lately that I want to talk about. It's by all means not necessary to use these tools but they have made my life much easier.
Pyenv
Contrary to what its name suggests pyenv is not something that manages virtualenvs but a tool used to manage multiple python versions easily.
Note
If you use windows, you can use pyenv-win.
You can install as many python version as you want like so:
pyenv install 3.7.9
pyenv install 2.7.18
Then pick the system wide python with to easily run python
from anywhere
pyenv global 3.7.9
And finally pick which interpreter is used per project by adding a .python-version
file containg the version number you want to use.
2.7.18
Note
It's a good idea to specify the python version even if it's the same as your system wide one so that other people can use the right one.
Poetry
Poetry is a package manager for python, similar to NPM for NodeJS, cargo for Rust and many others. Poetry ensures that you and everyone working on your project will have a consistent environment
Even for solo projects, poetry is my go to package manager because it makes everything much more comfortable.
Poetry's docs are great so I won't go about everything but here's the basics you need to know:
Once installed, you can create a new project with:
poetry new my-project-name
It will create a default folder structure for you with a pyproject.toml
file (more on that in a second).
Or you can init poetry in an existing project with:
poetry init
You will be asked to give some informations about your project (name, description, license, etc.) as well as the possibility to add dependencies. I tend to skip that last part and add my dependencies after the fact.
Before doing anything more, I like for poetry to create my virtualenvs inside of my projects (Instead of my user folder) which you can do like this:
poetry config virtualenvs.in-project true
This is absolutely not necessary but it makes it easy to add the virtualenv to mayapy's PYTHONPATH since it is now accessible with a relative path to your project.
Now to add dependencies to your project, simply run:
poetry add Qt.py
You can also install dev only dependencies (only required for people working on the project):
poetry add black --dev
If you have a look in pyproject.toml
, you'll see that those dependencies have been added along with the minimum required version.
You will also notice that a poetry.lock
file has been created. It contains information about every package installed in your venv and their exact version.
This file is important and should be commited to your repository.
When people run poetry install
they will have the exact same version of all your project's dependencies as you have.
To update your dependencies, use:
poetry update
There is more to Poetry like building and publishing packages to pypi but these aren't features I've used yet.
Hopefully that gave you a good sense of how you can better manage virtualenvs and how you can use them to bring dependencies in maya without bloating the mayapy interpreter directly.