New python editor venv

Hi! Is it possible to use virtual environment with python in rhino8?

Not at the moment. The problem is that we are running in a Rhino process so can not load multiple python 3 versions. Supporting separate envs to install pip packages is also a little tricky. For example numpy uses c-libraries that when they are loaded, they canā€™t be unloaded. So you canā€™t really install a specific numpy version in one env and another version in another env and have them both successfully work inside Rhino.

Iā€™m looking at options to improve this continously.

3 Likes

sorry, my question is perhaps a little stupid, but is it possible to indicate at the start of a script to use this or that library folder?
Franck.

The standard way is to add the path where your libraries are to sys.path
In the next build I have added something to make this simpler byt adding # env: path/to/env to the top of the script.

Are you both referring to python scripting in Rhino or also to the python components in Grasshopper?

@eirannejad is the next build a matter of days or weeks?
Iā€™m asking because having cpython with conda envs in Grasshopper would be a gamechanger for our plugin project.

Another Beta was released yesterday

Thatā€™s what I seemed to have readā€¦ but I understood that it was rather complicated to set up, it seemed rather simple to me.

Franck

I had the path to the folder of a virtual environment I made for a script with pandas, at the beginning of a script, I import pandas, but it canā€™t import it when I launch itā€¦ maybe I didnā€™t understand what you explainā€¦

Have you a simple example?

Iā€™m so sorry, but i donā€™t understand how does it worksā€¦ i tried:

"""
NOTE:

- Reference to RhinoCommmon.dll is added by default

- You can specify your script requirements like:

    # r: <package-specifier> [, <package-specifier>]
    # requirements: <package-specifier> [, <package-specifier>]

    For example this line will ask the runtime to install
    the listed packages before running the script:

    # requirements: pytoml, keras

    You can install specific versions of a package
    using pip-like package specifiers:

    # r: pytoml==0.10.2, keras>=2.6.0
"""
# env: C:\Users\fbaba\Documents\SCRIPT\bdd\env
#! python3
import sys

sys.path.append('C:\\Users\\fbaba\\Documents\\SCRIPT\\bdd\\env')

import rhinoscriptsyntax as rs
import scriptcontext as sc

import System
import System.Collections.Generic
import Rhino
import psycopg2

Psycopg2 is on an virtual environment, i use for a script without rhinoā€¦

does rhino install a python executable in rhino installation or does it use the python interpreter already installedā€¦

thanks for your helpā€¦

1 Like

Could you please work on the env setting and make the virtual environment possible? or Rhino will miss all AI era. Iā€™ve been using Rhino since 2005 in ZHA. Itā€™s important and please update.
best wishes,
shiqi

@lishiqi We donā€™t want to miss the AI area obviously, do weā€¦

The core of the problem is that you are running mutliple scripts with different envrionments inside the same long-running process (Rhino). Normally when you use python with virtual environments, you are running an independent python process that is tied to that very environment.

We do support one convention in Rhino. You can use the # venv: directive to provide a name for an separate environment your packages would be installed in (instead of default). This avoids conflicting packages problem but comes with a pretty important caveat. You are still running in the same Rhino process, so although this helps installing package requirements for various scripts in separate environments, if you have numpy loaded from one environment, and a different numpy loaded from another environment, you ā€˜mayā€™ run into conflicts.

#! python 3
# venv: <environ-name>

What is the specific path for psycopg2 in this example case?

Is it different then # env: C:\Users\fbaba\Documents\SCRIPT\bdd\env

Hi @eirannejad, thanks for your work for adding py3 capabilities to Rhino. It is surely a long waited feature for the community.

I have gone back and forth at multiple responses here in the forum to grasp what to do and it is still confusing for me and my team how to manage packages installed from different sources.

I suggest writing an official documentation explaining these different usages and how they are/are not the same:

  1. Using the ā€œrā€ call

r: numpy

Which for me will install at /.rhinocode/ a version of a package using pip. Understanding how to define a specific version would be useful here too. And what happens if you switch to a different package version? Overwrites it forever at .rhinocode folder?

  1. Using the ā€œenvā€ call

env: path/to/env

I tried this and it is not working as expected. First of all can you clarify if you expect the path to the environment root (user/anaconda3/env/myenv) or to the site-packages folder (ā€¦env/myenv/Lib/site-packages)?

Another question here is that I often have my packages in a local folder (/user/code/package1) and install them using ā€œpip install -e .ā€ In which case the package is not copied to /myenv/Lib/site-packages. Do I need then to add ā€œ/user/code/ā€œ to my call?

env: path/to/env

env: user/code

i.e., do I need then to call two environments? That sounds not really the right thing to doā€¦

A continuing question is what happens at the .rhinocode folder with all of that? And whatā€™s gonna happen if I mix this with the r call?

  1. Setting a path at Editor Options

From v8.6 you added an Option function where we can set the env path using the UI. I remain with the same questions regarding which address should be provided (site-package folders or not). And how should we expect that this behaves versus adding # env: path/to/env and adding #r? Also, what happens at .rhinocode in the meanwhile?

Still, what will happen if an address set in the UI is different from the # env: call? Both get called?

  1. Using venv

venv: myenv

This is new for me, should we only provide the anaconda3 environment name here? Would be interesting to understand if locally installed packages ā€œpip install -e .ā€ get included too and what happens at .rhinocode folder/ how it crashed with all the other options above.

  1. Using sys.path.add

In the middle of all these different calls, I am not sure whether we should or should not use this method? Should this point to the environment root or the site-package folder?

Sorry for the long post but I hope this also help others with similar questions.

2 Likes

Ricardo -

I am also trying to write a guide on this. I hope early next week to have a draft. But, letā€™s take a look at each of these issues you take up in this thread as a way to work through each. it will help me get it in the guide.

This is not the complete guide, just some notes from it.

The conda virtual environment situation is not easily handled yet. So I am going to skip that for now.

Introduction:

There are 4 main sources of Python modules that may be installed or loaded into Python 3.

  1. Built-in Modules - Built into Python 3, this also includes our Rhino specific libraries such as RhinoscriptSyntax and RhinoCommon.
  2. Local Modules - Created from other user .py files using def
  3. Packages on PyPI website - 300,000 Python Modules
  4. Downloaded Packages - Downloaded libraries and unzipped modules into folders.

Using PIP: - Packages on Pypi

Using r: or requirements: can be set at the start of a script.

It is recommended that multiple packages are listed on a single line, as the installer will then be able to combine shared packages:

#r: numpy, scipy

Dependency Specifiers can also be used:

#r: numpy >= 1.3, scipy == 3.4.*

I have not found a simple guide on dependency specifiers yet.

Local Modules and Downloaded Modules:

Both user created local modules and downloaded modules must be stored in a folder or sub-folder that can be found by the rhino.python sys environment.

The sys.path is set at a few different levels:

  1. The default rhino.python sys.path
  2. The local folder the current python file is stored in
  3. Any folders added in the Tools > Options > Python3 > Module search paths
  4. A path set in the script by # env: \\xxx\xxx\x
  5. Folders added within the script by: sys.path.append('C:\\Users\\fbaba\\Documents\\SCRIPT\\bdd\\env')

The built in default location for modules and library folders on Windows is:
%HOMEPATH%\.rhinocode\py39-rh8\\Lib\site-packages\

For Mac:
~/.rhinocode/py39-rh8

All of these simply add to the search path. To print the current path in the middle of a script use this:

import sys
paths = sys.path

for path in paths:
    print(path)
4 Likes

hello,
no it is not different, in fact I a made a python script to save project datas, outside of rhino, so i work with virtual environement for a tkinter application, this app use pandas, psycopg2, customtkinterā€¦

if i want to make a script in rhino, to acces the projects datas i easier to use the same virtual environementā€¦

Virtual environments inside of Rhino are very different from the way they are setup by conda or other virtual environment (venv) managers that you are used to with your python 3 workflows. Take a look at this swimlane chart for example:

Top:
Running multiple python scripts using python.exe. Note the gray boxes marked as P1 and P2. Each python execution a separate process, and independent venv with no conflicts.

Bottom:
Running multiple python scripts in rhino.exe - Note everything is in the same gray box. They all share the same process and memory so multiple venvs could potentially conflict.

This is why we are not supporting python 3 virtual environments inside of Rhino yet. We use independent folders with some python packages (# venv ) so scripts donā€™t have to constantly override each others packages. For example script 1 can install numpy==1 in their own folder # venv: script-one, and script 2 can install numpy==2 in their own # venv: script-two

But if you run both scripts in the same rhino, numpy 1 and 2 ā€˜mightā€™ conflict during load or running the two scripts.

Tkinter also does not work inside of Rhino yet as it needs its own application instance with event loop that is different from Rhino.

2 Likes

Hi Ehsan,

Thank you for the detailed explanation and the swimlane charts illustrating the differences between running Python scripts in standard environments and within Rhino. Your clarification on why Rhino currently handles Python virtual environments (venvs) in this unique way is insightful.

I understand the challenges of maintaining a stable platform for users at all levels and the potential for conflicts when multiple venvs are used within the same Rhino instance. However, as an advanced user who raises this question, I often find myself needing more control over the development environment, including the ability to manage dependencies through pip and virtual environments. This control is especially crucial when working with complex projects that require specific versions of libraries or when integrating external Python tools.

I believe that while the current system ensures stability, it may limit advanced users who are accustomed to a more flexible Python development workflow. Perhaps a compromise could be introducing an advanced mode or an option for users to opt-in for more control over their environments. This way, users who are comfortable managing potential conflicts could take advantage of Rhinoā€™s full capabilities alongside their preferred Python development tools.

I am looking forward to any developments in this area and would be happy to provide more feedback or participate in a beta testing phase if that would be helpful.

Best regards,
Shiqi

1 Like

@lishiqi

You can use an independent deployment of python matching Rhino python version (3.9.10 as of writing this post) to create environments and install any combination of packages in those environments. Then you can add the path of the Libs\site-packages in that environment to your scripts in Rhino:

# env: /path/to/venv/Libs/site-packages

or add the path directly to sys.path

The problem however remains that if you are using multiple virtual environments in the ā€˜same Rhino processā€™ there is always a potential for runtime conflicts.

1 Like