I was working with Python more extensively in the last years and really like the language and its rich ecosystem of libraries. Recently, I stumbled upon this fantastic .NET library [http://pythonnet.github.io(http://pythonnet.github.io)] offering a very tight coupling between the Python interpreter and the .NET clr. Looks like a good opportunity to introduced a Python region/editor(extension)/class into VL, so one can embed python code within a patch. What do you think? How should one approach this? I did some simple experiments with Visual Studio and C# and the interoperability layer works like a charm. There are also some examples of passing parameters to the Python script, getting results, multithreading handling, etc… any thoughts?
Interesting. How about approaching it like we did with shaders in Stride using VL’s node factories? I’m thinking one could have a subfolder called python containing python scripts whose interior gets made available as nodes - this assumes you can reflect over those scripts? Anything like that in there?
Yes, the implications of integrating Python3 are huge. I have a proof-of-concept that works, using an intermediate c# DLL, could not manage to make it work with just importing PythonNET.dll assembly and using pure VL. However, I would like to have the results from a PythonScript execution as native pins with the correct datatypes, which is handled gracefully by the PythonNet interoperability layer.
IIRC pythonNet objects are ‘dynamic’ types that need to convert to specific c# types. This was an issue a few years back that made using it in vl a little complicated, so the key step might be casting cleverly in vl by somehow checking the script. Because objects aren’t strongly typed in python this can be a little tricky.
Another way to look at it to think of wrapping particular python projects in c# and importing them to vl, a bit like tensorflow.net, though that’s quite an extreme case. Ideally, we have a minimal amount of c#
And of course VL.Stride, but probably a little hard to begin with. So take that one maybe for later when it’s about details like auto-reloading or exporting applications.
The steps on the C# side are:
Add a VL specific assembly initializer which will be called by the compiler when the assembly gets referenced by any document
In that intializer register your node factory
Your node factory must implement IVLNodeDescriptionFactory - you can either implement that yourself or (like done in Stride) use an implementation we provide which makes heavy use of delegates and closures, so that’s up to you.
That factory will be called back by our compiler when it looks up node references - you’ll need to spit out node descriptions which contains static information like name, category, pin names etc. - this is the stuff which will show up in the nodebrowser when your node factory is referenced (we come to that later)
Once the factory is referenced by a document it will also get another callback with the path of that document, where it can spit out another factory specific to that path - that’s what I meant above with having a subfolder called python.
The node description will later be called by the runtime to create the actual node - this is the next interface you’ll need to implement. There it’s finally about the real stuff.
The steps on the VL side are:
Reference your assembly. Once referenced you should see another entry in the dependencies menu where you can reference your node factory. Once you do that your nodes should show up.
In order to make it scale, and package it all up, you can build a full VL package and forward your node factory through the forwarding menu. Once the factory gets forwarded, any document referencing your nuget will also pick up any python subfolder beside it.
ooook, much to read. Thank you for the references and the clues!
I am currently making a simple c# app in VS that is loading arbitrary python class/script and is trying to get all necessary information for the reflection/node factory, such as classes, methods, parameters and functions, etc. If this works well, I see no reason why can not be done as you suggest. Thanks again!
Seems like a good idea to prototype it in a little console app first. And what @Hadasi said, that indeed could be problematic, as all pins would by typed dynamic. So I guess we need some idea here - does python have something like attributes?
Yes, exactly! I am doing a little c# app to inspect a given Python script. Now I can successfully extract all functions and classes/methods, and now trying to get the respective parameters, possibly with DataTypes, since in C#/VL we need to make the pins of specific type, right? Dynamic type pins are not possible.
@zeos really interesting I tried in the past many different ways to make python shell to comply with vvvv (beta and gamma) nothing really worked as I would like to. My main problems where the definitions and the different “pickle” approaches. Although nowadays there are some tables and libs to make it happen. @Elias in Python there are “decorators” and “class Attributes” which are working quite similar to C# Attributes but can you elaborate a bit more, how attributes would be useful for a Node Factory approach ?