ninia / jep

Embed Python in Java
Other
1.31k stars 149 forks source link

Loading Jep itself from a virtual environment #493

Open Adriaanse opened 1 year ago

Adriaanse commented 1 year ago

Is your feature request related to a problem? Please describe. I have found how to load JEP from a virtual environment (env, virtualenv, conda) by using both the VIRTUAL_ENV and PYTHONPATH environment variables to allow JEP itself to be loaded from the virtual environment without the need (and permissions) to install JEP in the system python environment. Just using JepCofig.setIncludePath() unfortunately does not achieve this, and cannot be used with the SharedInterpreter anyway (!).

Describe the solution you'd like It would be just perfect if using JepConfig.setIncludePath() is also usable with SharedInterpreter and takes care of setting these environment variables within the current JEP session so our users don't need to install JEP in the system Python environment, for which they typically do not have the required permissions

Describe alternatives you've considered I have tried using JNI to set these environment variables (before initializing JEP) but that does not work, as PYTHON does not see these variables when set from the JVM process. and setting them from a shell script before starting our Java application is not flexible enough to be able to use more than one virtual environment from the same Java application.

Additional context Add any other context or screenshots about the feature request here.

Adriaanse commented 1 year ago

I just figured out I can use addIncludePaths() like this:

jepConfig.addIncludePaths("C:\jep\python39", "C:\jep\python39\Lib\site-packages");

But this is only part of the solution, why I cannot reach the config of SharedInterpreter ?

bsteffensmeier commented 1 year ago

To use jep from a virtual environment yI recommend you activate the virtual environment before starting the JVM. In my experience that is the most reliable way to ensure the virtual environment is active.

But this is only part of the solution, why I cannot reach the config of SharedInterpreter ?

Use SharedInterpreter.setConfig() to control the configuration of SharedInterpreters.

Adriaanse commented 1 year ago

Thanks for the quick reply, I had missed the setConfig() method expecting to find it in the constructor, check.

Our application is a bit complex, it is running as a service/deamon and may have more than one virtual environment where a Python model is running, So switching to a different environment without the need to start a new JVM would be a valuable feature considering performance.

The users configuring these Python models do not have admin rights so cannot install JEP in the system Python environment, looking at the code of LibraryLocator I see that UserSitePackages are searched, maybe that is a route we can explore using the service account our application is running under.

As a work-around, would you recommend for or against using Java ProcessBuilder to activate an enviroment and run Jep with it ?