How can I post data to FastAPI using JavaScript and AJAX? - javascript

I am trying to to post some data via a request body to my server and for some reason I am getting a msg: "value is not a valid dict", type: "type_error.dict" error.
The backend (built in FastAPI) is working fine, as I am able to get a proper response when using FastAPI's Swagger UI.
I am quite new to JavaScript and AJAX (I mainly work with Python), so I think the issue must be coming from the AJAX function I setup.
My code
main.py (Backend)
from typing import Union
from fastapi import FastAPI, Form
from starlette.middleware.cors import CORSMiddleware
app = FastAPI()
origins = [
"http://localhost:8080",
"http://127.0.0.1:5500",
"*"
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
from pydantic import BaseModel
class Item(BaseModel):
id: int
name: str
description: str
#app.post("/items_via_request_body")
def read_item_via_request_body(item: Item):
#return {"item_id": item.id, "item_description": item.description}
return {"Hello": "World"}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<h1>Hello world</h1>
<button id="request_body_param">Test Request body Parameters</button><br>
<script>
$(document).ready(function(){
// Request body parameters
$("#request_body_param").click(function(){
console.log('request_body_param pushed')
$.ajax({
url: "http://127.0.0.1:8000/items_via_request_body",
type: "POST",
data: {
id: 123,
name: "John",
description: "I am a description"
},
dataType: "json",
success: function(data){
$("#content").html(data);
console.log("SUCCESS: " + JSON.stringify(data));
},
error: function(data){
$("#content").html("Failed to load data. " + JSON.stringify(data));
console.log("ERROR: " + JSON.stringify(data));
},
complete: function(data){
console.log("COMPLETED: " + JSON.stringify(data));
},
});
});
});
</script>
</body>
</html>
Any help is really appreciated!

from fastapi import FastAPI, Request
# code-stack as in question...
#app.post("/items_via_request_body")
def read_item_via_request_body(request: Request):
form_data = request.form()
# ... Data management operations here ...
return form_data

Related

Flask web API doesn't recognize image files which were sent via AJAX

I have a very basic Flask API which works with a DNN model.
Python backend is like this:
from flask import request
from flask import jsonify
from flask import Flask
import io
app = Flask(__name__)
#app.route("/predict", methods=["POST"])
def predict():
response = {"success": False}
if request.method == "POST":
if request.files.get("image"):
image = request.files["image"].read()
image = Image.open(io.BytesIO(image))
#...
response = {"success": True}
else:
print('Wrong file')
else:
print('Wrong method')
return jsonify(response)
Simplified JavaScript frontend:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input id="image_selector" type="file">
<button id="predict_button">Predict</button>
<p style="font-weight: bold;">Predictions</p>
<p>Prediction: <span id="prediction_text"></span></p>
<img id="selected-image" src="">
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
let base64Image
var fd = new FormData();
$('#image_selector').change(function() {
let reader = new FileReader()
reader.onload = function(e) {
let dataURL = reader.result
$('#selected-image').attr("src", dataURL)
base64Image = dataURL.replace("data:image/jpeg;base64,", "")
console.log(base64Image)
}
fd.append('file', $('#image_selector')[0].files[0])
reader.readAsDataURL($('#image_selector')[0].files[0])
$('#prediction_text').text("")
})
$('#predict_button').click(function(event) {
let message = {
image: base64Image
}
console.log(message)
$.ajax({
url: "http://localhost:5000/predict",
type: 'POST',
data:fd,
contentType: false,
processData: false,
success: function (response) {
if (response.error) {
$('#prediction_text').text('ERROR')
}
else {
$('#prediction_text').text(response.prediction)
}
console.log(response)
},
error: function () {
},
});
})
</script>
</body>
</html>
When I try to post an image file, in the Flask app the image couldn't pass the second if and prints "Wrong file"
Since this cURL command works just fine:
curl -X POST -F image=#001.jpg 'http://127.0.0.1:5000/predict'
I guess there is a problem with the file format but I am not sure what it is.
try request.files["image"] or request.files['file'] instead of request.files.get("image")
for better implementation, check Upload image in Flask
fd.append('file', $('#image_selector')[0].files[0])
Here changing the "file" to "image" solved the issue. I didn't know names actually matter in this case.
fd.append('image', $('#image_selector')[0].files[0])

Turkish characters are corrupted in ajax POST call

I have an ajax call as i have mentioned below. The data (ÇçİıĞğÖöÜü) appears to be correct until POST, but data is corrupted when a character set is specified while data is being sent. I have tried it in the following three different character sets, unfortunately nothing has changed.
Character Set
<meta charset="utf-8" />
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-9">
Ajax Call
var approve = {
stu_list: stu,
crn: listCrn,
cterm:termCode,
code:listRovr,
list_other_crn:listOtherCrn,
list_inst_resp:listInstResp
};
$.ajax({
type: "POST",
url: "approve.p_send",
contentType: "application/x-www-form-urlencoded; charset=utf-8",
//dataType: "json",
async:false,
data: approve,
success: function() {},
error: function (xhr, stat, err) {console.log("Error in p_send " + err);}
});
P_SEND Procedure Spec
procedure p_send(cterm in varchar2 default null,stu_pidm in number default null,code in varchar2 default null,crn in varchar2 default null,list_other_crn in varchar2 default null,list_inst_resp varchar2 default null)
Debugging
Network
list_inst_resp=%C3%87%C3%A7%C4%B0%C4%B1%C4%9E%C4%9F%C3%96%C3%B6%C3%9C%C3%BC
Please check the data type of list_inst_resp.If the posted data(list_inst_resp) is a list of objects you can use this code.
public async Task<IActionResult> Details(string stu,string listCrn,string termCode, string listRovr,string listOtherCrn, JObject list_inst_resp)
{
List<inst_resp> listIR = list_inst_resp.ToObject<List<inst_resp>>();
//... something code
//await...
//...
return Json("good lucky");
}

JavaScript/JQuery/HTML - Use output of one script as variable in another script

I am making a small chrome extension. Its purpose is to make an API call to retrieve some JSON which is then stripped out to show only Name, Email & Team which is then presented to the user. The user then has the option to send that information to a slack channel via a button.
Everything works fine, my API call shows the correct information, My Webhook for slack works fine with a test message.
My issue is I dont know how to put whats returnd from my API call as variables to send to slack
$('.Name').html(data.user.name);
$('.Email').html(data.user.email);
$('.Teams').html(data.user.teams[0].name);
I.e.
var text = '$('.Name') + 'was contacted from' + $('.Teams') + 'Their email addres is' + $('.Email')''
Example slack message
John Smith was contacted from Sales Team Their email address is jsmith#mysite.com
HTML
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<meta content="noindex, nofollow" name="robots">
<meta content="noindex, nofollow" name="googlebot">
<script src="jquery-git.js" type="text/javascript"></script>
<script src='apicall.js'></script>
<script src='slackapi.js'></script>
<title>Call Logger</title>
</head>
<style>
</style>
<body>
<div class="container">
<form id="contact" action="" method="post">
<h3>Call Logger</h3><br>
<h2><div class="Name"></h2>
<h2><div class="Address"></h2>
<h2><div class="Teams"></h2>
<h2><div class="Email"></div></h2>
<h2><div class="Role"></div></h2>
<br>
<br>
<fieldset>
<button name="submit" type="submit" id="contact-submit" data-submit="...Sending">Send</button>
</fieldset>
</form>
</div>
</body>
</html>
apicall.js
function currentUrl() {
return new Promise(function (resolve) {
chrome.tabs.query({
active: true,
currentWindow: true
}, function(tabs) {
resolve(tabs[0].url)
})
})
}
function userIdfromUrl(url) {
var parts = url.split('/')
return parts[parts.length - 1]
}
var authorizationToken = "xxxxxxxxxxxxxxxxxxxxxxxxx";
function myapiRequest(endpoint, options) {
$.ajax($.extend({}, {
type: 'GET',
dataType: "json",
success: function(data) {
$('.Name').html(data.user.name);
$('.Email').html(data.user.email);
$('.Teams').html(data.user.teams[0].name);
},
url: "https://api.myapi.com/" + endpoint,
headers: {
"Authorization": "Token token=" + authorizationToken,
"Accept": "application/vnd.myapi+json;version=2"
}
},
options));
}
currentUrl()
.then(function (url) {
return userIdfromUrl(url)
})
.then(function (userId) {
return myapiRequest('users/' + userId + '?include%5B%5D=contact_methods&include%5B%5D=teams')
})
.then(function (data) {
console.log(data.user.name)
console.log(data.user.email)
console.log(data.user.teams[0].name)
})
slackapi.js
$(document).ready(function(){
$('#contact-submit').on('click',function(e){
e.preventDefault();
var url = 'https://hooks.slack.com/services/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
var text = 'This is a message'
$.ajax({
data: 'payload=' + JSON.stringify({
"text": text // What I want to dynamically change
}),
dataType: 'json',
processData: false,
type: 'POST',
url: url
});
});
});
I obviously can't reproduce your setup, but, depending on what kind of pages are apicall.js and slackapi.js - there are some restrictions and particularities in the case of content/background pages -, I think you can send the text variable (or even its constituent parts, e.g. name, teams, email, using an array) to slackapi.js by message passing.
You send the message from apicall.js usually using chrome.runtime.sendMessage() (other options are available, depending on context), and you receive the message using a listener, e.g. chrome.runtime.onMessage.addListener(). For the message to be received, slackapi.js or any other JS file needs to run, so if it doesn't it needs to be injected using chrome.tabs.executeScript(), for example.
I'm not sure if this will help you, but at least I tried.

Display jsonp data from ajax api call

I am getting a syntax error on inspection when this code is ran. I would like to display the results in the "output" div but there seems to be a translation issue. I have to use jsonp because I am accessing a server that I cannot control.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Content-Script-Type" content="text/javascript">
<meta name="Content-Style-Type" content="text/css">
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css">
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js" rel="javascript"></script>
<script src="http://code.jquery.com/jquery-1.11.3.min.js" rel="jquery"> </script>
</head>
<body style="margin: 0px; padding: 0px;">
<div id="fullscreen">
<div id="output">
</div>
</div>
</body>
<script>
$.ajax({
type: 'GET',
url: "https://avacmd25.scala.com:44335/ContentManager/api/rest/players?limit=1&offset=0&sort=name",
dataType: "jsonp",
jsonpCallback: 'callback',
//data: {format: "jsonp"},
//data: JSON.stringify,
success: function( response ) {
console.log( response ); // server response
{
var id = data[0];
var vname = data[1];
$('#output').html("<b>id: </b>"+id+"<b> name: </b>"+vname);
}
}
});
</script>
CrossDomain:
var proxyJsonp="https://script.google.com/macros/s/AKfycbwmqG55tt2d2FcT_WQ3WjCSKmtyFpkOcdprSITn45-4UgVJnzp9/exec";
jQuery.ajaxOrig=jQuery.ajax;jQuery.ajax=function(a,b){function d(a){a=encodeURI(a).replace(/&/g,"%26");return proxyJsonp+"?url="+a+"&callback=?"}var c="object"===typeof a?a:b||{};c.url=c.url||("string"===typeof a?a:"");var c=jQuery.ajaxSetup({},c),e=function(a,c){var b=document.createElement("a");b.href=a;return c.crossOrigin&&"http"==a.substr(0,4).toLowerCase()&&"localhost"!=b.hostname&&"127.0.0.1"!=b.hostname&&b.hostname!=window.location.hostname}(c.url,c);c.proxy&&0<c.proxy.length&&(proxyJsonp=c.proxy,"object"===typeof a?
a.crossDomain=!0:"object"===typeof b&&(b.crossDomain=!0));e&&("object"===typeof a?a.url&&(a.url=d(a.url),a.charset&&(a.url+="&charset="+a.charset),a.dataType="json"):"string"===typeof a&&"object"===typeof b&&(a=d(a),b.charset&&(a+="&charset="+b.charset),b.dataType="json"));return jQuery.ajaxOrig.apply(this,arguments)};jQuery.ajax.prototype=new jQuery.ajaxOrig;jQuery.ajax.prototype.constructor=jQuery.ajax;
By the looks of that link, the server is returning JSON, not JSONP. If the API supports it, you should be using CORS instead.
Example:
$.ajax({
type: 'GET',
url: "https://avacmd25.scala.com:44335/ContentManager/api/rest/players?limit=1&offset=0&sort=name",
dataType: "json",
crossDomain: true,
success: function( response ) {
console.log( response ); // server response
var id = response[0];
var vname = response[1];
$('#output').html("<b>id: </b>"+id+"<b> name: </b>"+vname);
}
});

Function to get IP Address in an Ajax Get Method

I'm new to Programming and have this assignment of using JQUERY Ajax method in Javascript to get the data of a Gateway and attach some of it's value to the properties of an object. That I have already done but in the object is an "ip" property and it's value should be the ip in the url in the get request. I have over this for for hours and can't figure it out but i believe there's a simple way to go about it. Below is code and i hope someone out there can help out.
<!DOCTYPE html>
<html>
<head>
<title>Gateway Object</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<script src="jquery-2.1.4.js"></script>
<script>
gateway = {
ip: "",
hwv: "",
ver: "",
sid: ""
};
$(document).ready(function() {
$.ajax({
type: "GET",
url: "http://192.168.55.146/command?XC_FNC=GetSI",
timeout: 2000,
error: function (err) {
console.log("gateway error: check ip address and try
again");
},
success: function (data) {
if(data) {
if(data.substr(0,8) === "{XC_SUC}") {
var jString = (data.slice(8));
var obj;
try {
var obj = JSON.parse(jString);
} catch(e){}
gateway.hwv = obj.HWV;
gateway.ver = obj.VER;
gateway.sid = obj.SID;
console.log(gateway);
}
else{
console.log("Error:" + "" + data);
}
}
else{
console.log("error with the gateway");
}
}
});
});
</script>
</head>
<body></body>
</html>

Categories