1

How do I execute and return the results of a python script in c#?

I am trying to run a python script from my controller.

I have python.exe setup in a virtual environment folder created with the virtualenv command.

So just for testing purposes at the moment I would like to just return resulting string from my phython script:

# myscript.py
print "test"

And display that in a view in my asp.net mvc app.

I got the run_cmd function from a related stackoverflow question. I've tried adding the -i option to force interactive mode and calling process.WaitForExit() with no luck.

namespace NpApp.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index(string returnUrl)
        {
            ViewBag.ReturnUrl = returnUrl;

            ViewBag.textResult = run_cmd("-i C:/path/to/virtualenv/myscript.py", "Some Input");

            return View();
        }

        private string run_cmd(string cmd, string args)
        {
            ProcessStartInfo start = new ProcessStartInfo();
            start.FileName = @"C:/path/to/virtualenv/Scripts/python.exe";
            start.CreateNoWindow = true;
            start.Arguments = string.Format("{0} {1}", cmd, args);
            start.UseShellExecute = false;
            start.RedirectStandardOutput = true;
            using (Process process = Process.Start(start))
            {
                using (StreamReader reader = process.StandardOutput)
                {
                    string result = reader.ReadToEnd();
                    //Console.Write(result);
                    process.WaitForExit();
                    return result;
                }
            }
        }
    }
}

It seems like myscript.py never even runs. But I get no errors, just a blank variable in my view.

Edit:

I had tried to simplify the above stuff because I thought it would be easier to explain and get an answer. Eventually I do need to use a package called "nameparser" and store the result of passed name argument into a database. But if I can just get the run_cmd to return a string I think I can take care of the rest of it. This is why I think the rest api and IronPython mentioned in the comments may not work for me here.

Community
  • 1
  • 1
ooXei1sh
  • 3,459
  • 2
  • 27
  • 47
  • You can host python as REST API and invoke that using `webclient` - https://myadventuresincoding.wordpress.com/2011/01/02/creating-a-rest-api-in-python-using-bottle-and-mongodb/ -- ignore the word mongodb, it has nothing to do with this, just look at rest api part. – Arindam Nayak Nov 16 '14 at 06:41
  • Give IronPython a try: http://www.codeproject.com/Articles/15579/Call-Ironpython-in-C It's designed for .NET. – B.K. Nov 16 '14 at 06:54
  • I don't know python, but you can receive the `errorlevel` value with `ExitCode` method, try process.ExitCode – AsfK Nov 16 '14 at 07:10
  • Do you see a `python.exe` process start when running this code? – Yuval Itzchakov Nov 16 '14 at 08:28
  • @B.K: I attempted to used IronPython but it seems like it has issues dealing with packages. Plus I got IO errors when running ipy from VisualStudio. – ooXei1sh Nov 16 '14 at 12:25
  • @Yuval Itzchakov I tried just creating a file in the python script to see if it is even running. No file was created. I search in debug Output from VisualStudio doesn't mention my script name. I can run the script from command line without issue and everything works fine. – ooXei1sh Nov 16 '14 at 12:36
  • @AsfK I added `return process.ExitCode.ToString();` that actually returns the number 2 and displays in my page. I'm guess anything that's higher than zero means there is an issue. – ooXei1sh Nov 16 '14 at 12:38

1 Answers1

2

Ok, I figured out what the issue was thanks to some leads from the comments. Mainly it was the spaces in the path to the python.exe and the myscript.py. Turns out I didn't need -i or process.WaitForExit(). I just moved the python virtual environment into a path without spaces and everything started working. Also made sure that the myscript.py file was executable.

This was really helpful:

string stderr = process.StandardError.ReadToEnd();
string stdout = process.StandardOutput.ReadToEnd();
Debug.WriteLine("STDERR: " + stderr);
Debug.WriteLine("STDOUT: " + stdout);

That shows the python errors and output in the Output pane in Visual Studio.

ooXei1sh
  • 3,459
  • 2
  • 27
  • 47