Issue
I am not able to load a virtual environment I have using virtual-env in the same directory as the C# file.
Here is my code
var eng = IronPython.Hosting.Python.CreateEngine();
var scope = eng.CreateScope();
// Load Virtual Env
ICollection<string> searchPaths = eng.GetSearchPaths();
searchPaths.Add(@"/Users/Desktop/CSharpProjects/demo1/.venv/lib");
searchPaths.Add(@"/Users/Desktop/CSharpProjects/demo1/.venv/lib/site-packages");
searchPaths.Add(AppDomain.CurrentDomain.BaseDirectory);
eng.SetSearchPaths(searchPaths);
string file = @"script.py";
eng.ExecuteFile(file, scope);
Unhandled exception. IronPython.Runtime.Exceptions.ImportException: No module named 'numpy'
Python code is which I can execute on the terminal of the virtualenv created.
import numpy as np
def name(a, b=1):
return np.add(a,b)
UPDATE:
Seems like IronPython3 is quite hopeless, I will accept an implementation in Pythonnet!
Here is my current code on Pythonnet and I am using NuGet - Pythonnet prerelease 3.0.0-preview2022-06-27
The following works fine as it uses the system@s python 3.7, however I would like it to use the virtualenv located in C:\envs\venv2
. How can I modify the below code to use the virtual environment located in C:\envs\venv2
?
My class1.cs is:
using Python.Runtime;
using System;
namespace ConsoleApp1
{
public class PythonOperation
{
PyModule scope;
public void Initialize()
{
Runtime.PythonDLL = @"C:\\Python37\python37.dll";
string pathToVirtualEnv = @"C:\envs\venv2";
string pathToPython = @"C:\Python37\";
Environment.SetEnvironmentVariable("PATH", pathToPython, EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("PYTHONHOME", pathToVirtualEnv, EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("PYTHONPATH", $"{pathToVirtualEnv}\\Lib\\site-packages;{pathToVirtualEnv}\\Lib", EnvironmentVariableTarget.Process);
PythonEngine.PythonHome = pathToVirtualEnv;
PythonEngine.PythonPath = Environment.GetEnvironmentVariable("PYTHONPATH", EnvironmentVariableTarget.Process);
PythonEngine.Initialize();
scope = Py.CreateScope();
PythonEngine.BeginAllowThreads();
}
public void Execute()
{
using (Py.GIL())
{
}}}}
Error:
Fatal Python error: initfsencoding: unable to load the file system codec ModuleNotFoundError: No module named 'encodings'
Solution
You may need to try this way of setting up the PythonEngine.PythonPath
:
string pathToVirtualEnv = /path/to/venv/;
var path = Environment.GetEnvironmentVariable("PATH").TrimEnd(';');
path = string.IsNullOrEmpty(path) ? pathToVirtualEnv : path + ";" + pathToVirtualEnv;
Environment.SetEnvironmentVariable("PATH", path, EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("PATH", pathToVirtualEnv, EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("PYTHONHOME", pathToVirtualEnv, EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("PYTHONPATH", $"{pathToVirtualEnv}\\Lib\\site-packages;{pathToVirtualEnv}\\Lib", EnvironmentVariableTarget.Process);
PythonEngine.PythonHome = pathToVirtualEnv;
PythonEngine.PythonPath = PythonEngine.PythonPath + ";" + Environment.GetEnvironmentVariable("PYTHONPATH", EnvironmentVariableTarget.Process);
As you can see above, you can reference PythonPath
while assigning a new value.
Answered By - Cardstdani Answer Checked By - Robin (WPSolving Admin)