Call python script from .Net Core using pythonnet

MrCalvin picture MrCalvin · Dec 5, 2018 · Viewed 8.1k times · Source

I'm trying to get pythonnet to work in my .Net Core app running on Linux.

I've made a reference to Python.Runtime.dll (which I got from nuget) in my .Net Core project.

My code is:

using System;
using Python.Runtime;
namespace pythonnet_w
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Start");
            using (**Py.GIL()**) {
            //     blabla
            }
            Console.WriteLine("End");
        }
    }
}

I get this runtime error:

 Unhandled Exception: System.MissingMethodException: Method not found:     'System.Reflection.Emit.AssemblyBuilder      
 System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName, System.Reflection.Emit.AssemblyBuilderAccess)'.
    at Python.Runtime.CodeGenerator..ctor()
    at Python.Runtime.DelegateManager..ctor()
    at Python.Runtime.PythonEngine.Initialize(IEnumerable`1 args, Boolean setSysArgv)
    at Python.Runtime.PythonEngine.Initialize(Boolean setSysArgv)
    at Python.Runtime.PythonEngine.Initialize()
    at Python.Runtime.Py.GIL()
    at pythonnet_w.Program.Main(String[] args) in D:\Development\~.Net libraries (3.part)\phytonnet\.Net Core test (phytonnet)\c#\pythonnet_test\Program.cs:line 10
 /usr/sbin/pythonnet_w: line 5: 19487 Aborted                 dotnet "/usr/share/pythonnet_wit/pythonnet_w.dll"

Tried to find a solution in these threads but without any luck:

How do I run a py file in C#?

Call Python from .NET

UPDATE:

I tried to open \pythonnet-master\src\runtime**Python.Runtime.csproj** in Visual Studio to see if I can compile it to .Net or .Core, but I can only compile to .Net framework. I found this article "How to port from .net framework to .net standard" Is that what I have to do?

Answer

MP24 picture MP24 · May 11, 2019

I finally had success by using a self-compiled Python.Runtime.dll as of version 2.4.0. There are two options to create a working DLL:

  • Remove the other target framework net461 from the respective project file (leaving only netstandard2.0).
  • Run dotnet build using the appropriate options

For option 2, the following works(in Windows, Mac and Linux):

  1. Clone the pythonnet repo (https://github.com/pythonnet/pythonnet)
  2. In the pythonnet folder, cd src\runtime
  3. Run dotnet build -c ReleaseWinPY3 -f netstandard2.0 Python.Runtime.15.csproj in Windows(in Mac/Linux, replace ReleaseWinPY3 with ReleaseMonoPY3 because the former use python37 and the later use python3.7)
  4. Set DYLD_LIBRARY_PATH in Mac or LD_LIBRARY_PATH in linux(Windows skip):
export DYLD_LIBRARY_PATH=/Library/Frameworks/Python.framework/Versions/3.7/lib
  1. Use the built DLL bin\netstandard2.0\Python.Runtime.dll as DLL reference in your Visual Studio .NET Core project (mine targets netcoreapp2.2, netcoreapp3.1 is also tested ok), e.g. in conjunction with the following code,
using System;
using Python.Runtime;

namespace Python_CSharp
{
    class Program
    {
        static void Main(string[] args)
        {
            using (Py.GIL())
            {
                dynamic os = Py.Import("os");
                dynamic dir = os.listdir();
                Console.WriteLine(dir);

                foreach (var d in dir)
                {
                    Console.WriteLine(d);
                }
            }
        }
    }
}