[Python.NET] Embedding a Python interactive shell in a .NET application
Saparya K
spryify at gmail.com
Fri May 27 17:40:59 EDT 2016
Just in case someone stumbles on this post looking for an answer:
A solution that worked for me was redirecting the Python stdout/stderr to a
stream in Python. I was then able to route this stream into the .NET text
box.
private void button1_Click(object sender, EventArgs e){
using (Py.GIL())
{
// Redirect stdout to text box
dynamic sys = PythonEngine.ImportModule("sys");
string codeToRedirectOutput =
"import sys\n" +
"from io import StringIO\n" +
"sys.stdout = mystdout = StringIO()\n" +
"sys.stdout.flush()\n" +
"sys.stderr = mystderr = StringIO()\n" +
"sys.stderr.flush()\n";
PythonEngine.RunString(codeToRedirectOutput);
// Run Python code
string pyCode = "print(1 + 2)";
PyObject result = PythonEngine.RunString(pyCode); // null in
case of error
if (result != null)
{
string pyStdout = sys.stdout.getvalue(); // Get stdout
pyStdout = pyStdout.Replace("\n", "\r\n"); // To support
newline for textbox
textBox1.Text = pyStdout;
}
else
{
PythonEngine.PrintError(); // Make Python engine print errors
string pyStderr = sys.stderr.getvalue(); // Get stderr
pyStderr = pyStderr.Replace("\n", "\r\n"); // To support
newline for textbox
textBox1.Text = pyStderr;
}
}}
With this code, I was able to redirect the stdout (and stderr in the case
of an error) from the Python engine to a .NET text box.
On Wed, May 18, 2016 at 12:02 AM, Saparya K <spryify at gmail.com> wrote:
> Hi Denis,
> Thanks for pointing me to the new API. I am now able to embed Python in my
> C# code and access Python classes and methods from C#!
>
> Hi Nils,
> Your application looks very interesting and some of the features (e.g.
> matplotlib integration) are on the lines of what I have been thinking
> about. I am far from there though and will need to learn more before I can
> follow all the code in your wrapper!
>
> -----
>
> As of now, I am trying to redirect the output from the Python interpreter
> to a .NET text box. While I am able to redirect the output to a file, I am
> having trouble with routing the output to a text box.
>
> I first tried to redirect the console output to a custom TextWriter using
> Console.SetOut in C#:
>
> private void Form1_Load(object sender, EventArgs e)
> {
> _writer = new TextBoxWriter(this.textBox1);
> Console.SetOut(_writer); // Redirect stdout to custom TextWriter
> that writes to the text box
> }
>
> This did not work: while output from C# is routed to the text box, output
> from Python is not.
>
> -----
>
> I then thought that maybe I need to redirect the Python stdout instead of
> the C# standard output. The idea was to assign Python's sys.stdout to a
> .NET object that implements the same interface as a python stream (write(),
> writelines()...):
>
> *.NET class to mimic Python stream:*
>
> 1.
>
> public class TextBoxStream : PyObject // To assign to sys.stdout. Is this correct?{
> private TextBox _output = null;
>
> public TextBoxStream() {}
>
> public TextBoxStream(TextBox output) {
> _output = output;
> }
>
> void write(object value) {
> _output.AppendText(value.ToString());
> }}
>
> *In Form1.cs:*
>
> private void button1_Click(object sender, EventArgs e) {
> using (Py.GIL())
> {
> // Redirect stdout to text box
> dynamic sys = PythonEngine.ImportModule("sys");
> TextBoxStream textBoxStream = new TextBoxStream(textBox1);
> sys.stdout = textBoxStream; // This is probably not theright way?
> //sys.SetAttr("stdout", textBoxStream); // This did not work either
>
> string code =
> "import sys\n" +
> "print 'Message 1'\n" +
> "sys.stdout.write('Message 2')\n" +
> "sys.stdout.flush()";
>
> PyObject redirectPyObj = PythonEngine.RunString(code); // returns NULL
> sys.stdout.write("Message 3");
> // Exception thrown: 'Python.Runtime.PyObject' does not contain a definition for 'stdout'
> }}
>
>
> This does not work either: redirectPyObj is NULL. I tried using the old as
> well as the new Python.NET API (with dynamic). Neither the sys.stdout.write
> nor the print statements write to the text box.
>
> Any ideas on how to approach this would be very helpful.
> Thanks,
> Saparya
>
>
> On Tue, May 17, 2016 at 3:33 AM, Nils Becker <nilsc.becker at gmail.com>
> wrote:
>
>> Hey,
>>
>> a while ago I wrote something like a light wrapper around Python.NET to
>> embed CPython with numpy/scipy in a .NET GUI. It manages local/global
>> dictionaries, automatically converts simple data types and numpy
>> arrrays<->C# arrays and provides a plotting widget in C# that shows
>> matplotlib plots. It also has some other convenience functions.
>>
>> The code is by no means complete, fully tested or even nice. However, for
>> me it works.
>>
>> I uploaded it to github: https://github.com/Lodomir/PythonInterface
>> As it demonstrates some not-well documented use of Python.NET, I thought
>> it maybe nice to share the code.
>>
>> You will need to add the references to Python.NET to build the main
>> project (PythonInterface) and additionally to the PythonInterface-DLL to
>> build the examples.
>>
>> Cheers
>> Nils
>>
>> 2016-05-13 22:04 GMT+02:00 Denis Akhiyarov <denis.akhiyarov at gmail.com>:
>>
>>> for embedding look at c# embedding unit tests and also here:
>>>
>>> 1. Old API:
>>>
>>> http://pythonnet.github.io/readme.html
>>>
>>> 2. New simplified API using dynamic:
>>>
>>> https://github.com/pythonnet/pythonnet/blob/master/README.md
>>>
>>>
>>>
>>> On Thu, May 12, 2016 at 4:16 PM, Saparya K <spryify at gmail.com> wrote:
>>>
>>>> Thanks for your response, Denis.
>>>>
>>>> I had not come across Sho earlier. It looks very interesting. (If only
>>>> Python 3.x support was available, though it does look like they have added
>>>> support for their own math and visualization libraries).
>>>>
>>>> I am going over the demos and the unit tests and I was able to write a
>>>> simple console application to access .NET objects from Python. This is very
>>>> encouraging!
>>>> I am still figuring out how to embed Python code in my C# WinForms
>>>> application (instead of a console application).
>>>>
>>>> I will continue my experiments, but in the meantime if you or anyone
>>>> else has any ideas on how to redirect the result from the Python
>>>> interpreter (say, to a rich text box), I would love to hear them. That is
>>>> one part of the puzzle that is unclear to me.
>>>>
>>>> Thanks,
>>>> Saparya
>>>>
>>>> On Wed, May 11, 2016 at 4:01 PM, Denis Akhiyarov <
>>>> denis.akhiyarov at gmail.com> wrote:
>>>>
>>>>> This is definitely possible with WinForms or WPF. See the demo folder
>>>>> in pythonnet repo. One of the demo's is still in pull request.
>>>>>
>>>>> You should probably just try running previous IronPython attempts
>>>>> using pythonnet and report issues if any. Have a look at Sho from Microsoft.
>>>>>
>>>>> There is someone trying to embed ipython REPL using
>>>>> pythonnet/Excel-DNA or COM in Excel with Custom Task Pane (CTP) written
>>>>> in WinForms:
>>>>>
>>>>> https://groups.google.com/forum/#!topic/jupyter/CVht4orvQtc
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> On Wed, May 11, 2016 at 4:44 PM, Saparya K <spryify at gmail.com> wrote:
>>>>>
>>>>>> Hello PythonNet,
>>>>>>
>>>>>> I am looking to embed a Python interactive (REPL) shell in a .NET
>>>>>> WinForms application.
>>>>>> This C# application displays a graphical visualization of some data.
>>>>>> Methods to manipulate the data in the C# application would be exposed via a
>>>>>> Python API.
>>>>>> The idea is to be able to interact with the data from the Python
>>>>>> shell via the API, and thereby updating the graphical view.
>>>>>>
>>>>>> Ideally, the shell should support any valid Python syntax that is
>>>>>> required to use the API. This would involve:
>>>>>>
>>>>>> 1. Querying a collection of data from the application via the
>>>>>> Python API
>>>>>> 2. Then manipulating this collection in the Python shell
>>>>>> 3. Making API calls with the modified collection as an argument
>>>>>>
>>>>>> I came across a few examples where an interactive shell was developed
>>>>>> using IronPython. A limitation with this approach is the absence of *Python
>>>>>> 3.x* support (and other C-compiled libraries) in IronPython. For
>>>>>> this reason, I would prefer to use Python.NET if it is possible.
>>>>>>
>>>>>> Has anyone here tried something like this with Python.NET before?
>>>>>> Does it looks like what I am trying to achieve is feasible?
>>>>>>
>>>>>> Any direction would be very helpful!
>>>>>>
>>>>>> _________________________________________________
>>>>>> Python.NET mailing list - PythonDotNet at python.org
>>>>>> https://mail.python.org/mailman/listinfo/pythondotnet
>>>>>>
>>>>>
>>>>>
>>>>> _________________________________________________
>>>>> Python.NET mailing list - PythonDotNet at python.org
>>>>> https://mail.python.org/mailman/listinfo/pythondotnet
>>>>>
>>>>
>>>>
>>>> _________________________________________________
>>>> Python.NET mailing list - PythonDotNet at python.org
>>>> https://mail.python.org/mailman/listinfo/pythondotnet
>>>>
>>>
>>>
>>> _________________________________________________
>>> Python.NET mailing list - PythonDotNet at python.org
>>> https://mail.python.org/mailman/listinfo/pythondotnet
>>>
>>
>>
>> _________________________________________________
>> Python.NET mailing list - PythonDotNet at python.org
>> https://mail.python.org/mailman/listinfo/pythondotnet
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/pythondotnet/attachments/20160527/1d5e6857/attachment-0001.html>
More information about the PythonDotNet
mailing list