I am new to python and I am trying to send a request to a python script with a machine learning model. I would like to get back the result of the model as a response in Ajax. My GUI is in basic HTML, CSS (no framework). How can I send the JSON data to python and get back the result in JavaScript? Below is my code...
My code
$(document).on('submit', '#form', function(e) {
e.preventDefault();
e.stopPropagation();
var form_data = new FormData(this);
form_data.append('subcounty', $('#subcounty_search').val());
form_data.append('area', $('#area').val());
$.ajax({
url: 'add.php',
type: 'post',
data: form_data,
contentType: false,
processData: false,
cache: false,
success: function(data) {
var xml = new XMLHttpRequest();
xml.open("POST", "tier match/run.py", true);
xml.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xml.onload = function() {
var dataReply = JSON.parse(this.responseText)
alert(dataReply)
}
var dataSend = JSON.stringify({
'home_type': $('input[name="home_type"]:checked').val(),
'residence_type': $('input[name="residence_type"]:checked').val(),
'bedrooms': $('#bedrooms').text(),
'bathrooms': $('#bathrooms').text(),
'occupancy': $('#occupancy').text(),
'swimming': encodeHomeFeatures($('input[name="swimming"]:checked').val()),
'wifi': encodeHomeFeatures($('input[name="wifi"]:checked').val()),
'tv': encodeHomeFeatures($('input[name="tv"]:checked').val()),
'workers': encodeHomeFeatures($('input[name="workers"]:checked').val()),
'wheelchair': encodeHomeFeatures($('input[name="wheelchair"]:checked').val()),
'parking': encodeHomeFeatures($('input[name="parking"]:checked').val()),
'gym': encodeHomeFeatures($('input[name="gym"]:checked').val()),
'kids': encodeHomeFeatures($('input[name="kids"]:checked').val()),
'security': encodeHomeFeatures($('input[name="security"]:checked').val()),
'garden': encodeHomeFeatures($('input[name="garden"]:checked').val()),
'ac': encodeHomeFeatures($('input[name="ac"]:checked').val()),
'pets': encodeHomeFeatures($('input[name="pets"]:checked').val()),
'smokers': encodeHomeFeatures($('input[name="smokers"]:checked').val())
});
xml.send(dataSend)
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="layer top">
<form method="POST" id="form">
<div class="content-wrap">
<div class="container p-lg-0">
<!-- start of description page-->
<div class="description-page">
<div class="row">
<div class="col-12">
<div class="section-heading ml-5">
<h4 class="heading-title"><span class="heading-circle green"></span> Give a good description of your home</h4>
</div>
</div>
</div>
<br>
<div class="section-wrapper ml-5">
<h6>Title</h6>
<div class="col-8">
<input type="text" class="form-control" id="title" name="title" placeholder="Christine's Spectacular Beach House" required>
</div>
<br>
<h6>Description</h6>
<div class="col-8">
<textarea id="description" class="form-control" name="description" rows="8" cols="30" required></textarea>
</div>
<br>
<h6>Insert an image of your house</h6>
<div class="col-6">
<input type="file" id="upload" name="upload" onchange="displayname(this,$(this))" />
<label for="upload" class="add-home-image">
<i class="fas fa-file-image"></i> Upload an image
</label>
</div>
</div>
<br><br>
<input type="hidden" name="where" id="where" value="home">
<input type="hidden" name="user" value="<?php echo $customer_id; ?>">
<div class="row">
<div class="col-6">
<div class="prev ml-5">
Previous
</div>
</div>
<div class="col-6">
<div class="submit">
<button type="submit" id="completeAddHome" style="background-color: #FD5555;" class="btn btn-danger rounded-pill ml-3">Complete</button>
</div>
</div>
</div>
</div>
</div>
</div>
<br>
</div>
</div>
<!-- end of description page-->
</div>
</div>
</form>
</div>
I was trying a Http request but it wasn't working for me. I don't know if that's an option. Don't worry about the data in the JSON, I passed it through another function. How can I send that JSON to the Python script below and get a response.
Python Script (run.py)
import ml
house_features = [0,0,0,0,1,1,2,1,4,0,0,0,0,0,0,0,0,1]
tier_prediction = ml.knn_prediction(house_features)
print(tier_prediction)
This script calls the ML model below which is a script called 'ml.py'
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import classification_report, confusion_matrix
def knn_prediction(features):
#house_features = [0,0,0,0,1,1,2,1,4,0,0,0,0,0,0,0,0,1]
data = pd.read_csv('/Users/Mariwa/.bitnami/stackman/machines/xampp/volumes/root/htdocs/HomeExchange/tier match/home_tier_dataset.csv')
X = data.iloc[:,:-1].values
Y = data.iloc[:, 18].values
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size = 0.9)
scaler = StandardScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
classifier = KNeighborsClassifier(n_neighbors=5)
classifier.fit(X_train,Y_train)
y_pred = classifier.predict(X_test)
check_value = np.array(features)
tier_prediction = classifier.predict([check_value])
tier = tier_prediction[0]
return tier
I've got a number of inputs in a form, created dynamically, and I'm trying to send them to the controller as an array using javascript.
Originally it was only one value and it was part of the Entity I pass in the model. Then, as it can be more than one, I added a Transient field to the entity as a List and also created another class in java with just a List. However, I still don't know how to add these values from javascript to the th:object in the form.
<form id="selectform" th:object="${systemIdListForm}" th:action="#{/myController}" method="get">
<div class="box-body">
<label>System Id:</label>
<div id="fields">
<div class="form-group col-md-1">
<input class="form-control" name ="systemIdInput" type="text" style="width: 90%;" maxlength="8" onkeypress="return isNumber(event)"/>
</div>
</div>
<a id="addMore" href="#"><i class="fa fa-plus"></i><span>Add</span></a>
</div>
<div class="box-footer">
<button type="submit" class="btn btn-primary">Select</button>
</div>
</form>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function () {
$("#addMore").click(function() {
var html = '<div class="form-group col-md-1"><input class="form-control" name="systemIdInput" type="text" style="width: 90%;" maxlength="8" onkeypress="return isNumber(event)"/></div>';
$('#fields').append(html);
});
$("#selectform").submit(function(){
var values = $(this).serialize();
});
});
/*]]>*/
</script>
At the moment I can see that the variable values have the right information but nothing is sent to the controller. I realize that the formatting of these values is probably not want I need but I'm not sure what to do.
Any help is much appreciated
What data type have you used in Model ?
Make sure you have taken String [] for that field.
If not taken String [] then use that and let me know whether it works or not.
Also you can take help of below code.It is for your case only.
$("#selectform").submit(function (event) {
// form redirect stop
event.preventDefault();
var status = jbf.form.validate('#selectform');
if (!status) {
return;
}
// get form data
var data = {};
data["enrollmentNumber"] = $("#enrollmentNumber").val();
data["systemIdInput"] = jQuery("#selectform input[name=systemIdInput]").val();
var url = "/yourURL";
$.ajax({
type: "POST",
url: url,
data: JSON.stringify(data),
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function (response) {
var message = response.message;
//success notification
if(response.success === true){
alert(message);
}else{
error(message);
}
},
error: function (e) {
console.log("ERROR: ", e);
error("Add failed");
}
});
});
I managed to get the list of values from all the inputs in the form using a hidden input. I added a transient field in my entity (systemIds) where I've got all the values.
<form id="selectform" th:object="${myEntiry}" th:action="#{/crops/singlecroplabeloffinsp/list/1}" method="get">
<input class="form-control" id="systemIdList" th:field="*{systemIds}" type="hidden"/>
<div class="box-body">
<label>System Id:</label>
<div id="fields">
<div class="form-group col-md-1">
<input class="form-control" name ="systemIdInput" type="text" style="width: 90%;" maxlength="8" onkeypress="return isNumber(event)"/>
</div>
</div>
<a id="addMore" href="#"><i class="fa fa-plus"></i><span>Add</span></a>
</div>
<div class="box-footer">
<button type="submit" class="btn btn-primary">Select</button>
</div>
</form>
...
$("#selectform").submit(function(){
//get all the system ids
var x = document.getElementsByName("systemIdInput");
var systemIds = [];
for (i = 0; i < x.length; i++ ) {
if (x[i].type ='text') {
systemIds.push(x[i].value);
}
}
$("#systemIdList").val(systemIds);
this.submit();
});
Added to the entity with getter & setter:
#Transient
private List<Integer> systemIds;
I used some sample code from the Wiki API docs but when I enter a search item, nothing happens. No errors in the console, just nothing. The URL itself works if I enter it into a browser so I think something with the code is not passing in the proper value. Is there an issue with how I'm calling the API? Below is the relevant code:
$(document).ready(function(){
$('#search-submit').click(function() {
getWiki($('#searchVal').val());
});
/*add code for get lucky function*/
});
function getWiki(searchParam) {
$.ajax( {
url: 'http://en.wikipedia.org/w/api.php?action=parse&format=json&prop=text§ion=0&page='+searchParam+'&callback=?',
dataType: 'json',
type: 'POST',
headers: { 'Api-User-Agent': 'Example/1.0' },
success: function(data) {
var result = data;
pageTitle = result.title;
$(".search-box").html(pageTitle);
}
});
};
Here is the HTML:
<body>
<div class="container">
<div class="col-lg-12 header">
<h1>Search Wiki</h1>
</div>
<div class="row search-box">
<div class="col-lg-10">
<input placeholder=" Search" class="input" type="text" id="searchVal" name="searchVal"/></div>
<div class="col-lg-2"><button type="submit" id="search-submit" name="search-submit" class="btn-default">
<i class="fa fa-search fa-2x"></i>
</button></div>
</div>
<div class="row button-box text-center">
<div class="col-lg-12">
<button type="button" class="btn btn-primary" id="random">I'm Feeling Lucky</button></div>
</div>
</div>
</body>
The returned JSON has a parse property before the result, so it has to be data.parse.title to get the title etc.
$(document).ready(function() {
$('#search-submit').click(function() {
getWiki($('#searchVal').val());
});
/*add code for get lucky function*/
});
function getWiki(searchParam) {
$.ajax({
url: 'http://en.wikipedia.org/w/api.php?action=parse&format=json&prop=text§ion=0&page=' + searchParam + '&callback=?',
dataType: 'json',
type: 'POST',
headers: {
'Api-User-Agent': 'Example/1.0'
},
success: function(data) {
var result = data.parse;
var pageTitle = result.title;
$(".search-box").html('The title is : ' + pageTitle);
}
});
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Search for something : <input id="searchVal"><button id="search-submit">Search</button>
<br /><br /><br />
<div class="search-box"></div>
I have the following form created in my HTML, this will be submitted to "url 'submitrecord'". This will work fine for single entry per HTML. How can I add multiple entries of this type and submit at once.
Code:
<form method='POST' action="{% url 'submitrecord' %}">
<div class="row">
<div class = "col-md-1 form-group">
<input type="text" class="form-control" name="EntryNo" placeholder="EntryNo"/>
</div>
<div class = "col-md-2 form-group">
<input type="text" class="form-control" name="MedicineName" placeholder="MedicineName"/>
</div>
<button type="submit" class="btn btn-default">Done</button>
</div>
</form>
I found this answer but still it isnot sending the request to my URL.
<script>
$(document).ready(function(){
var called = 0;
ajax_recaller = function(forms){
$.ajax({
type: "POST",
data: forms[called].serialize(),
url: forms[called].attr('action'),
success: function(data) {
called++;
if(called < forms.length) {
ajax_recaller(forms);
} else {
called=0; // set called value to 0 again
alert('All forms has been submitted!');
}
}
});
}
$(document).on('click','.submitforms',function(){
var x=0;
$('.ajax_form').each(function(){
forms[x] = $(this);
x++;
});
ajax_recaller(forms);
});
});
</script>
Thought to test something like this to get the values of fields that precede a repeating UpdateButton's click, but it logs undefined values in the browser console
var $prevID = $(this).prevAll('.UpdateStory').first(".storyID");
var $prevStory = $(this).prevAll('.UpdateStory').first(".currentStory");
var id = $prevID.val();
var story = $prevStory.val();
Here's the HTML (client-side + server-side handlebars.js)
<div id="allStories" class="allStories"> </div><!--/allStories-->
<script id="storyTemplate" type="text/x-handlebars-template">
<div class="thisness">
<div class="stories">
<div class="new" id="new">
\{{#each stories}}
<div class="container-fluid">
<div class="row">
<div class="col-sm-4 col-sm-offset-4">
<form class="updateNewStoryForm">
<div class="input-group">
<span class="input-group-addon">
<input type="checkbox">
</span>
<input type="hidden" class="storyID" value="\{{ _id }}"/>
<input type="text" class="currentStory" value="\{{ story }}">
<span class="input-group-addon">
<input type="button" class="UpdateStory">
</span>
</div><!-- /input-group -->
</form>
</div><!-- /.col-lg-6 -->
</div><!-- /.row -->
</div><!-- /.container-fluid -->
\{{/each}}
</div>
</div> <!--/stories-->
</div> <!--/thisness-->
</script>
And here's the ajax .put that otherwise only updates the first story
// UpdateStory button clicks
$(".allStories").on('click','.UpdateStory',function(e) {
e.preventDefault();
console.log('UpdateStory clicked');
// story elements for API that work for only the first item,
// regardless of whichever UpdateStory button is clicked
var id = $( ".storyID" ).val();
var story = $( ".currentStory" ).val();
console.log(id);
console.log(story);
var AjaxPostData = {
id : id,
story : story
};
// if the story field has content
if (story.length != 0) {
console.log('there is a story: ' + story);
// make an ajax call
$.ajax({
dataType: 'json',
data: AjaxPostData,
type: 'put',
url:"http://localhost:4200/api/v1/stories/" + id,
success: refreshNewStories,
error: foundAllNewFailure
});
};
}); // UPDATE
It should be:
var group = $(this).closest(".input-group-addon");
var id = group.prevAll(".storyID").val();
var story = group.prevAll(".currentStory").val();