How to Deploy Machine Learning Models to a .NET Environment

Python and R are among the most popular programming languages for data-centric engineers. However, they are not always the languages that the rest of an application is built on. This is why you sometimes need to find a way to deploy machine-learning models written in Python or R into an environment based on a language such as .NET.

In this article, I show how to use Web APIs to integrate machine learning models into applications written in .NET.

Enter Flask

We can use Flask as a way to share and host our machine learning predictions. Let’s use the well-known Titanic data set from the infamous Kaggle competition. First, create a new file and call it, or whatever name you want. Import and initialize the Flask app, and launch the server at the bottom. Leave room in the middle to add in your model and routes later on.

import flask
app = flask.Flask(__name__)
#-------- MODEL GOES HERE -----------#
#-------- ROUTES GO HERE -----------#
if __name__ == '__main__':
	'''Connects to the server'''
	HOST = ''
	PORT = 4000      	#make sure this is an integer, PORT)

Note that we specified the host and port we want the app to run on.

Create and Train a Model

Load in the Titanic dataset and create a model on it:

#-------- MODEL GOES HERE -----------#
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
df = pd.read_csv('data/titanic.csv')
include = ['Pclass', 'Sex', 'Age', 'Fare', 'SibSp', 'Survived']
# Create dummies and drop NaNs
df['Sex'] = df['Sex'].apply(lambda x: 0 if x == 'male' else 1)
df = df[include].dropna()
X = df['Pclass', 'Sex', 'Age', 'Fare', 'SibSp']
y = df['Survived']
PREDICTOR = RandomForestClassifier(n_estimators=100).fit(X, y)

Make a Simple API

Here's the fun part. Now that we have a PREDICTOR, we need to get some values to make our predictions. One way to do this is to get information from the URL parameters which are the key:value pairs that appear after the ? in a URL. For example, if you navigate to: http://localhost:4000/predict?pclass=1&sex=1&age=18&fare=500&sibsp=0 then Flask can retrieve that data for you.

Let's write a route to do just that:

#-------- ROUTES GO HERE -----------#
@app.route('/predict', methods=["GET"])
def predict():
	pclass = flask.request.args['pclass']
	sex = flask.request.args['sex']
	age = flask.request.args['age']
	fare = flask.request.args['fare']
	sibsp = flask.request.args['sibsp']
	item = [pclass, sex, age, fare, sibsp]
	score = PREDICTOR.predict_proba(item)
	results = {'survival chances': score[0,1], 'death chances': score[0,0]}
	return flask.jsonify(results)

Save the file and launch your app. You now have a simple API for your model.

Deploying to a .NET environment

There are numerous options for deployment of Flask in to your .NET environment, and they will depend greatly on your infrastructure choices. To give you an idea of the process let’s take a look at deploying to an IIS environment by utilizing Microsoft Azure.

I will assume that you have already created an Azure Cosmos Database (which is outside of the scope of this article, but for details see the Azure documentation) and a Flask Web Application (as we walked through above), and are familiar with Azure and Visual Studio.

If you have set up your environment correctly, you will be ready to deploy your web application to Azure. This can be done by creating a web.config file to update the files on the web server to match the files in your instance. To do this, perform the following steps:

  • In Visual Studio Solution Explorer, right-click the project and select Add > New Item. In the dialog that appears, select the Azure web.config (Fast CGI) template and select OK. This creates a web.config file in your project root.
  • Modify the section in web.config so that the path matches the Python installation. For example, for Python 2.7 x64 the entry should appear as follows:
              <add name="PythonHandler" path="*" verb="*" modules="FastCgiModule" scriptProcessor="D:\home\Python27\python.exe|D:\home\Python27\" resourceType="Unspecified" requireAccess="Script"/>
  • Set the WSGI_HANDLER entry in web.config to to match your project name, as below:
    <!-- Flask apps only: change the project name to match your app -->
    <add key="WSGI_HANDLER" value=""/>
  • In Visual Studio Solution Explorer, expand the tutorial folder, right-click the static folder, select Add > New Item, select the "Azure static files web.config" template, and select OK. This action creates another web.config in the static folder that disables Python processing for that folder. This configuration sends requests for static files to the default web server rather than using the Python application.
  • Save the files, then right-click the project in Solution Explorer (make sure you're not still running it locally) and select Publish.
  • In the Publish dialog box, select Microsoft Azure App Service, select Create New, and then click Publish.
  • In the Create App Service dialog box, enter the name for your web app along with your Subscription, Resource Group, and App Service Plan. Then click Create.
  • In a few seconds, Visual Studio finishes copying your files to the server and displays the following error message on the page: "The page cannot be displayed because an internal server error has occurred."
  • In the Azure portal, open your new App Service account. In the navigation menu, scroll down to the Development Tools section, select Extensions, then click Add.
  • In the Choose Extension page, scroll down to the most recent Python 2.7 installation and select the x86 or x64 bit option, then click OK to accept the legal terms.
  • Use the Kudu console, which you can find at, to install the packages listed in your app's requirements.txt file. To do this, in the Kudu Diagnostic Console, navigate to your Python folder at D:\home\Python27, then run the following command as described in the Kudu console section: D:\home\Python27>python -m pip install --upgrade -r /home/site/wwwroot/requirements.txt
  • Restart the App Service in the Azure portal after installing the new packages by pressing the Restart button.
  • Once you've fully configured the server environment, refresh the page in the browser and the web app should appear.

For more information, check out the following links:

Flask Documentation
Flask Configuration Handling
Flask Deployment Options

For a quick way to start using Python, download ActivePython. It includes a number of useful libraries and packages, such as Flask, to get you started on your machine learning journey.

Download ActivePython