I'm using Xamarin Forms to create a chatbot-like messaging app and I've created a simple chatbot model using TensorFlow and python. The model executes as a console app and after some testing, I've been able to run the python chatbot script in C# console using Pythonnet. I would now like to integrate it into the Xamarin app wherein the users text is taken in as the input and the output is from the chatbot. How would I use this python file as a backend?
Chatbot.py
#MODULE IMPORTS
import nltk
from nltk.stem.lancaster import LancasterStemmer
import numpy
import tflearn
import tensorflow
import random
import json
import pickle
stemmer = LancasterStemmer()
with open("C:/Users/PAVILION/Desktop/Trial3/Conversations/intents.json") as file:
data = json.load(file)
try:
with open("data.pickle", "rb") as f:
words, labels, training, output = pickle.load(f)
except:
words = []
labels = []
docs_x = []
docs_y = []
for intent in data["intents"]:
for pattern in intent["patterns"]:
#STEMMING OF WORDS
stemmedWords = nltk.word_tokenize(pattern)
words.extend(stemmedWords)
docs_x.append(stemmedWords)
docs_y.append(intent["tag"])
if intent["tag"] not in labels:
labels.append(intent["tag"])
words = [stemmer.stem(w.lower()) for w in words if w != "?"]
words = sorted(list(set(words)))
labels = sorted(labels)
training = []
output = []
out_empty = [0 for _ in range(len(labels))]
for x, doc in enumerate(docs_x):
bag = []
stemmedWords = [stemmer.stem(w) for w in doc]
for w in words:
if w in stemmedWords:
bag.append(1)
else:
bag.append(0)
output_row = out_empty[:]
output_row[labels.index(docs_y[x])] = 1
training.append(bag)
output.append(output_row)
training = numpy.array(training)
output = numpy.array(output)
with open("data.pickle", "wb") as f:
pickle.dump((words, labels, training, output), f)
tensorflow.reset_default_graph()
net = tflearn.input_data(shape = [None, len(training[0])])
net = tflearn.fully_connected(net, 8)
net = tflearn.fully_connected(net, 8)
net = tflearn.fully_connected(net, len(output[0]), activation="softmax")
net = tflearn.regression(net)
model = tflearn.DNN(net)
try:
model.load("model.tflearn")
except:
model.fit(training, output, n_epoch=1000, batch_size=8, show_metric=True)
model.save("model.tflearn")
def bagOfWords(s, words):
bag = [0 for _ in range(len(words))]
s_words = nltk.word_tokenize(s)
s_words = [stemmer.stem(word.lower()) for word in s_words]
for s2 in s_words:
for i, w in enumerate(words):
if w == s2:
bag[i] = (1)
return numpy.array(bag)
def chat():
print("Start talking with the bot")
while True:
userInput = input("You: ")
if userInput.lower() == "quit":
break
results = model.predict([bagOfWords(userInput, words)])[0]
results_index = numpy.argmax(results)
tag = labels[results_index]
if results[results_index] > 0.6:
for tg in data["intents"]:
if tg["tag"] == tag:
responses = tg["responses"]
print(random.choice(responses))
else:
print("Dont understand")
chat()
Chatbot.xaml in Xamarin
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="clr-namespace:BluePillApp.Controls"
xmlns:renderers="clr-namespace:BluePillApp.CustomRenderers"
xmlns:local="clr-namespace:BluePillApp"
xmlns:helpers="clr-namespace:BluePillApp.Helpers"
xmlns:xamEffects="clr-namespace:XamEffects;assembly=XamEffects"
xmlns:pancake="clr-namespace:Xamarin.Forms.PancakeView;assembly=Xamarin.Forms.PancakeView"
mc:Ignorable="d"
x:Class="BluePillApp.Views.ChatbotPage">
<ContentPage.Resources>
<ResourceDictionary>
<helpers:TemplateSelector x:Key="MessageTemplateSelector"/>
</ResourceDictionary>
</ContentPage.Resources>
<Grid RowSpacing="0" ColumnSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="1"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!--Chat Views-->
<!--Chat Messages Area-->
<ListView Grid.Row="1"
ItemTemplate="{StaticResource MessageTemplateSelector}"
ItemsSource="{Binding Messages}"
Margin="0"
HasUnevenRows="True"
VerticalOptions="FillAndExpand"
SeparatorColor="Transparent" >
</ListView>
<!--A simple separater-->
<BoxView BackgroundColor="LightGray"
HorizontalOptions="FillAndExpand"
Grid.Row="2"/>
<!--Chat Entry and Send Button-->
<StackLayout Orientation="Horizontal"
Margin="0"
Grid.Row="3"
Padding="5,10,10,10">
<!--Chat Entry-->
<renderers:RoundedEntry Text="{Binding TextToSend}"
x:Name="ChatEntry"
Placeholder="Type your message"
CornerRadius="30"
BackColor="White"
BackgroundColor="Transparent"
BorderColor="#999999"
BorderWidth="5"
FontSize="16"
PlaceholderColor="#b3b3b3"
Keyboard="Chat"
WidthRequest="280"/>
<!--Send Button-->
<pancake:PancakeView BackgroundColor="#0f8df4"
CornerRadius="100"
xamEffects:TouchEffect.Color="White"
xamEffects:Commands.Tap="{Binding SendCommand}"
HeightRequest="47"
WidthRequest="47"
HorizontalOptions="EndAndExpand">
<Image Source="sendarrow1.png"
HeightRequest="30"
WidthRequest="30"
Margin="5,0,0,0"
HorizontalOptions="Center"
VerticalOptions="Center"/>
</pancake:PancakeView>
</StackLayout>
<!--Chatbot Header and Back Button-->
<pancake:PancakeView BackgroundColor="#f7f7f7" Grid.Row="0" HasShadow="True" Padding="0,10,0,10">
<StackLayout Orientation="Horizontal">
<!--Back Arrow Button-->
<renderers:FontAwesomeIcon Text="{x:Static helpers:IconsFA.BackArrow}"
HorizontalOptions="Start"
TextColor="Black"
FontSize="20"
VerticalTextAlignment="Center"
Margin="15,0,0,0">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="BacktoMain_Button"/>
</Label.GestureRecognizers>
</renderers:FontAwesomeIcon>
<!--Fleming Image-->
<StackLayout Orientation="Horizontal">
<Frame BackgroundColor="Gray"
Padding="0"
CornerRadius="100"
HasShadow="False"
IsClippedToBounds="True"
HeightRequest="40"
WidthRequest="40">
<Image HorizontalOptions="Center"
VerticalOptions="Center"/>
</Frame>
<!--Fleming Text-->
<Label Text="Fleming"
TextColor="Black"
FontAttributes="Bold"
FontSize="18"
VerticalOptions="Center"/>
</StackLayout>
</StackLayout>
</pancake:PancakeView>
</Grid>
</ContentPage>
Chatbot.xaml ViewModel
public class ChatbotPageViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// A collection.list of chat message items
/// </summary>
public ObservableCollection<ChatMessageModel> Messages { get; set; } = new ObservableCollection<ChatMessageModel>();
/// <summary>
/// The text that the user inputs
/// </summary>
public string TextToSend { get; set; }
/// <summary>
/// A command for sending the users messages
/// </summary>
public ICommand SendCommand { get; set; }
/// <summary>
/// ChatPageViewModel Constructor
/// </summary>
public ChatbotPageViewModel()
{
Messages.Add(new ChatMessageModel() { Text = "Hi" });
Messages.Add(new ChatMessageModel() { Text = "How are you?" });
SendCommand = new RelayCommand(Send);
}
/// <summary>
/// This function sends a message
/// </summary>
private void Send()
{
if (!string.IsNullOrEmpty(TextToSend))
{
//This adds the following to the messages collection
Messages.Add(new ChatMessageModel() { Text = TextToSend, User = App.User});
if(TextToSend == "Hey")
{
Messages.Add(new ChatMessageModel() { Text = "Hey yourself"});
}
}
}
}