Scripting C# with Iron Python
February 15, 2017
I wanted to integrate IronPython into one of my C# applications. The following code is a proof of concept for this.
This python script is defined in the file script.py
def process(pString, pAgreement): if float(pAgreement.balance) > 100.0: return pAgreement.agreementNumber else: return pAgreement.product txt = process(txt, agreement)
Here's the C# code involved.
using IronPython.Hosting; using Microsoft.Scripting; using Microsoft.Scripting.Hosting; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace IronPythonTest {
First we define a data structure which we'll pass through to the script. Note the virtual
keyword here - without this the script won't be able to see the attributes on the object.
public class Agreement { virtual public string agreementNumber { get; set; } virtual public string balance { get; set; } virtual public string product { get; set; } }
Next we create a console application and run the execute
method
class Program { private ScriptEngine m_engine = Python.CreateEngine(); private ScriptScope m_scope = null; static void Main(string[] args) { Program lProgram = new Program(); lProgram.execute(); }
This method creates a scope for the script execution, then creates a string which is passed to the script as variable txt
.
private void execute() { this.m_scope = this.m_engine.CreateScope(); String lText = "Quick Brown Fox Lazy Dog"; this.m_scope.SetVariable("txt", lText);
We then create a new Agreement instance, populate it, and pass that through to the script as agreement
Agreement lAgreement = new Agreement(); lAgreement.agreementNumber = "ABC123"; lAgreement.balance = "123.45"; lAgreement.product = "UPL"; this.m_scope.SetVariable("agreement", lAgreement);
Now we read in the script.py
file, and execute it. Note the SourceCodeKind.AutoDetect
here - I initially had this set to SourceCodeKind.SingleStatement
which caused all sorts of problems when I was passing a multiline script. The execution failed because it didn't expect the second line of code.
string lCode = System.IO.File.ReadAllText("script.py"); ScriptSource source = m_engine.CreateScriptSourceFromString(lCode, SourceCodeKind.AutoDetect); source.Execute(m_scope);
Finally, we get the value of the variables after our script has completed.
var lUpdatedText = m_scope.GetVariable<string>("txt"); var lUpdatedAgreement = m_scope.GetVariable<Agreement>("agreement"); Console.WriteLine(lUpdatedText); } } }