net - run python library in c#




Running Python Code in.NET Environment without Installing Python (4)

Is it possible to productionize Python code in a .NET/C# environment without installing Python and without converting the Python code to C#, i.e. just deploy the code as is?

I know installing the Python language would be the reasonable thing to do but my hesitation is that I just don't want to introduce a new language to my production environment and deal with its testing and maintenance complications, since I don't have enough manpower who know Python to take care of these issues.

I know IronPython is built on CLR, but don't know how exactly it can be hosted and maintained inside .NET. Does it enable one to treat PYthon code as a "package" that can be imported into C# code, without actually installing Python as a standalone language? How can IronPython make my life easier in this situation? Can python.net give me more leverage?


As I mentioned in the comments, the right and better way to do it is to create Restful services over your Python code and make http-requests from the C# code. I don't know how much you know about web-frameworks in Python but there are tons of them that you can use. For your need, I would suggest Flask which is light-weight micro web-framework to create Restful web services.

This is very simple Flask web-service for the example: (you can check a running version of it here , I hosted it on pythonOnEverywhere)

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello from Flask!'

@app.route('/math/add/<int:num1>/<int:num2>')
def add(num1, num2):
    return '%d' % (num1+num2)

This simple service, adds two number and returns the sum of them.

And C# Code:

using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

public class Program
{
    // Always use HttpClient as a singleton object
    public static HttpClient _httpClient = new HttpClient() { BaseAddress = new Uri("http://al1b.pythonanywhere.com") } ;
    public async static Task Main()
    {

        var num1 = 1;
        var num2 = 4;

        Console.WriteLine("Making http-request wait ...\r\n");      

        var mathAddResult = await _httpClient.GetAsync($"/math/add/{num1}/{num2}");

        // 200 = OK
        if(mathAddResult.StatusCode == HttpStatusCode.OK)
        {   
            Console.WriteLine(await mathAddResult.Content.ReadAsStringAsync());
        }
    }
}

The output:

Making http-request wait ... 

5

The running version of code above is now runnable on .NET Fiddle .

TL;DR:

For understanding and learning Flask, take a look on its documentions . (It's short and well). I'm sure you will have complex web-services, such as accepting complex or pocco objects as your web-service inputs and returning complex objects (as json) as web-serivce results.

In that case you need to know how Flask jsonify works, This link will tell you how .

Ok, on the other hand, in your C# application you will have those complex objects and scenarios as well. You need to know how to serialize, deseriaze and etc.

Microsoft did a great job for its tutorials here:

https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client

and

https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=netframework-4.8


I really do not understand the question. You do not want to install python, you do not want to introduce it to your system since it has an additional maintance cost and your team lacks the basic knowledge of it. Still, you want to "productionize" it without anyone knowing.

My assumption you want to have a scripting language, and for some reason you decided on python. My answer is based on this assumption.

IronPython is why we have dynamic keyword and DLR in .net world. You can host it you application and make it compile some python code to .net compatible types.

IronPython's own documentation mentions it https://ironpython.net/documentation/dotnet/dotnet.html#accessing-python-code-from-other-net-code

Also there is an MSDN blog post showing how to do that. https://blogs.msdn.microsoft.com/seshadripv/2008/06/30/how-to-invoke-a-ironpython-function-from-c-using-the-dlr-hosting-api/

Hope it helps


If you must run some Python code from a .NET and you don't want to ship Python with the app then you should just compile the Python code down to an EXE using something like https://cython.org/

You can pass variables in to it on the command line and receive answers back from a Python function by writing to the console from Python and capturing the output of the process you spawned from .NET. This way it would work just like calling any other Sub or Function, the only difference is each procedure is a new process to .NET. This could get really complicated if you want to pass complex objects back and forth as you would have to unwrap and wrap them as they flow, as text, between the components.

Ultimately, you would be better off just rewriting your Python code in .NET and not going down this path at all. Use a converter tool like https://github.com/uxmal/pytocs to convert all the Python code to C#. It likely won't be perfect but it will give you a codebase to work on replacing the Python functions you want to use. It will take you less time to clean up the translated procedures than it would to try to maintain both languages and inter-op functions between them.


IronPython is limited compared to running Python with C based libraries needing the Python Interpreter, not the .NET DLR. I suppose it depends how you are using the Python code, if you want to use a lot of third party python libraries, i doubt that IronPython will fit your needs.

What about building a full Python application but running it all from Docker?

That would require your environments to have Docker installed, but you could then also deploy your .NET applications using Docker too, and they would all be isolated and not dirty your 'environment'.

There are base docker images out there that are specifically for Building Python and .NET Project and also for running.





python.net