How can I upload a file with JSON data to django rest api? - python

I am using angular as the front-end scope and Django Rest as the back-end. Now I am facing a situation where I want to create a Model. The structure of a model is really complex in nature, I could use some other simple way outs but using JSON and passing the files with that can really simplify the logic and also make process really efficient.
I am have been trying a lot but none of the ways seem to work.
Can some someone help me with a standard way or tell me even it is possible or not.
This the structure of my Typescript which I want to upload.
import { v4 as uuid4 } from 'uuid';
export interface CompleteReport{
title: string;
description: string;
author: string;
article_upload_images: Array<uuid4>,
presentation_upload_images: Array<uuid4>,
report_article: ReportArticle,
report_image: ReportImage,
report_podcast: ReportPodcast,
report_presentation: ReportPresentation,
report_video: ReportVideo,
}
export interface ReportArticle{
file: File;
body: string;
}
export interface ReportPodcast{
file: any;
}
export interface ReportVideo{
file: Array<File>;
}
export interface ReportImage{
file: File;
body: string;
}
export interface ReportPresentation{
body: string;
}
export interface UploadImage{
file: File;
}

I don't see how you wanna send data, but if you wanna send data with multipart/data-form, I think you should make small changes to your report structure.
JSON doesn't supports binary. So, you can't put files on it. You need to split file and report JSON.
(async () => {
let formData = new FormData();
// here's how to send file on multipart/data-form via fetch
let reportFile = document.querySelector('#file');
formData.append("file", imagefile.files[0]);
// here's your report json
let report = {
...
};
formData.append("report", JSON.stringify(report));
// send request and upload
let response = await fetch(url, {
method: 'POST',
body: formData
});
// do something with response
let responseText = await response.text();
console.log(responseText)
})();
And I see UUID on your frontend code, I think it's better to put that kinda stuff on backend to prevent manipulated request. I think it's better to put complicated stuff, and any server data related on your backend. Just my opinion.

Related

How to send file from Nodejs to Flask Python?

Hope you are doing well.
I'm trying to send pdfs file from Nodejs to Flask using Axios.
I read files from a directory (in the form of buffer array) and add them into formData (an npm package) and send an Axios request.
const existingFile = fs.readFileSync(path)
console.log(existingFile)
const formData = new nodeFormData()
formData.append("file", existingFile)
formData.append("fileName", documentData.docuName)
try {
const getFile = await axios.post("http://127.0.0.1:5000/pdf-slicer", formData,
{
headers: {
...formData.getHeaders()
}
})
console.log(getFile)} catch (e) {console.log(e, "getFileError")}
On flask side:
I'm trying to get data from the request.
print(request.files)
if (request.method == "POST"):
file=request.form["file"]
if file:
print(file)
in request.file, I'm getting ImmutableMultiDict([])
but in request.form["file"], I'm getting data something like this:
how can I handle this type of file format or how can I convert this file format to python fileObject.
I solved this issue by updating my Nodejs code.
We need to convert formData file into octet/stream format.
so I did minor change in my formData code :
before: formData.append("file", existingFile)
after: formData.append("file", fs.createReadStream(existingFile)
Note: fs.createReadStream only accepts string or uint8array
without null bytes. we cannot pass the buffer array.

how to get json object from a webservice

i have the below posted json response.as shown below in json section, the parametersobject is emitted in this line (this is an angular application)
this._FromInsToSiteDataService.emitOnSubmitButtonClikedBroadcast(parameters)
and it is received in
this.subscriptionBroadcastEmitterOnSubmitButtonClicked = this._FromInsecticidesToSiteMapDataService.getBroascastEmitterOnSubmitButtonClicked().subscribe((response:Object)=>{
response['siteGeometry'] = this.selectedSite.geometry
console.log("response: ", response)
this.sSProvider.startWebServiceFor(response)
});
in the latter code i want to pass the response which is in json format to the webservice and receive it as show in the websrvicepostedbelow`
when i run the code, i expected to see the contents of the json object which is
{
"dist1": d1,
"dist2": d2,
"date1": date1,
"date2": date2,
"ingredient": activeIngredient
}
but i get NONE
please let me know how can i correctly get a json object from a webservice
json
private submit() {
let parameters = {
"dist1": d1,
"dist2": d2,
"date1": date1,
"date2": date2,
"ingredient": activeIngredient
}
this._FromInsToSiteDataService.emitOnSubmitButtonClikedBroadcast(parameters)
receiving the json object
this.subscriptionBroadcastEmitterOnSubmitButtonClicked = this._FromInsecticidesToSiteMapDataService.getBroascastEmitterOnSubmitButtonClicked().subscribe((response:Object)=>{
response['siteGeometry'] = this.selectedSite.geometry
console.log("response: ", response)
this.sSProvider.startWebServiceFor(response)
});
webservice:
#app.route("/insSpecifications/<parameters>", methods=['GET'] )
def insSpecifications(parameters):
# print(request.json())
print(request.get_json())//returns NONE
return "OK"
Intro
There are two parts to your question -
Making a request from JS
Creating a Flask API to handle the request
Both these have extensively answered on SO hence I will only summarize it here, please follow the links for more information
Answer
REST Method:
When sending JSON data from the front end to the backend, you need to make a POST request or PUT depending on the need. Please read up on REST API concepts to understand the methods and purposes.
https://www.w3schools.in/restful-web-services/rest-methods/
Making a request
Depending on which library you use in the front end, the request might look different, but essentially you need to send a request with JSON in the body and HEADERS set appropriately i.e. Content-Type: application/json
Using FETCH this can be achieved by (auto-generated from postman)
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
var raw = JSON.stringify({
"username": "Sample1",
"email": "test2#test.com"
});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("localhost:5000/sample", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
But most libraries would have wrappers around this, please look into making a POST request for your respective JS library
Creating Flask API
Finally, you need a Flask API to consume this request. Assuming it's a POST request. You need to create a route with method as POST and get the JSON data using get_json() : https://stackoverflow.com/a/20001283/5236575
So once the HEADERS are correctly set and a post request is made, your code should work fine by changing GET to POST
Note: The parameters field is captured correctly hence I'm leaving it as is, but that is not where your JSON body comes from
#app.route("/insSpecifications/<parameters>", methods=['POST'] )
def insSpecifications(parameters):
# print(request.json())
print(request.get_json())
return "OK"
Testing
You can test your API using Postman or any other API testing tool to see how the API behaves and validate if the issue you have is in the API or in the front-end code.

Javascript long polling a json file - angularjs/jquery

Wishing you a Happy New year.!
I am having trouble when i am trying to load a json file from my web server. Actually i do not know java script. I just need this code to work. I am developing a website using Django. One of the django views, serves the client side java script and at the back end on a separate thread, it process some modules and generates a json output.
Now i am accessing this json using the below code.
<script type="text/javascript">
function addmsg(msg) {
document.getElementById("messages").innerHTML = msg;
}
function waitForMsg() {
$.ajax({
type: "GET",
url: "{% static ""%}tmp/{{url_hash}}/{{url_json}}",
cache: false,
timeout: 50000,
success: function (data) {
addmsg(data);
if (!data) {
setTimeout(
waitForMsg,
1500
);
};
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
addmsg("error");
setTimeout(waitForMsg, 15000);
}
});
};
$(document).ready(function () {
waitForMsg();
addmsg("loading");
});
</script>
When i run this, javascript gets served and then it queries for the json file every 1.5 sec.
What happens is, once the file is available on the server, this script loads the file and redirects the page to something like this ,
localhost:8000/+e+/
I dono from where this is getting redirected. I am not redirecting on any views or urls.py is clean.
Please help me with a code which will load this json from webserver when its available and then print the contents.
Thanks
===========update------------------
can anyone please suggest me angular js script for achieving the same ? thanks
==================== Update =====================================
Found the error, Actually the json dict has javascript, which has } { and quotes. Which breaks it.
I suggest looking beyond a lack of knowledge about JavaScript and stepping through all the parts of your problem. For example, use chrome and open the developer tools tab. Reload the page. Look at the url the JavaScript is testing to open. I suspect it is not the url you intend.
This code looks odd:
{% static ""%
Why is there the quote in the middle of the django directive? This isn't a JavaScript issue, just a quoting issue. It's also a warning sign because your JavaScript is using template directives - not an impossible or illegal thing, but a concern that some teams wouldn't allow.
In any case, track down the url that is actually bring invoked, see if it is the one you intend, and check the quoting issue in the httpcall.

Calling a python function using dojo/request

Firstly, I'm very new to the world of web development, so sorry if this question is overly simple. I'm trying to use python to handle AJAX requests. From reading the documentation it seems as though Dojo/request should be able to do this form me, however I've not found any examples to help get this working.
Assuming I've got a Python file (myFuncs.py) with some functions that return JSON data that I want to get from the server. For this call I'm interested in a particular function inside this file:
def sayhello():
return simplejson.dumps({'message':'Hello from python world'})
What is not clear to me is how to call this function using Dojo/request. The documentation suggests something like this:
require(["dojo/dom", "dojo/request", "dojo/json", "dojo/domReady!"],
function(dom, request, JSON){
// Results will be displayed in resultDiv
var resultDiv = dom.byId("resultDiv");
// Request the JSON data from the server
request.get("../myFuncs.py", {
// Parse data from JSON to a JavaScript object
handleAs: "json"
}).then(function(data){
// Display the data sent from the server
resultDiv.innerHTML = data.message
},
function(error){
// Display the error returned
resultDiv.innerHTML = error;
});
}
);
Is this even close to what I'm trying to achieve? I don't understand how to specify which function to call inside myFuncs.py?
What you could also do is to create a small jsonrpc server and use dojo to do a ajax call to that server and get the json data....
for python side you can follow this
jsonrpclib
for dojo you could try something like this..
<script>
require(['dojox/rpc/Service','dojox/rpc/JsonRPC'],
function(Service,JsonRpc)
{
function refreshContent(){
var methodParams = {
envelope: "JSON-RPC-2.0",
transport: "POST",
target: "/jsonrpc",
contentType: "application/json-rpc",
services:{}
};
methodParams.services['myfunction'] = { parameters: [] };
service = new Service(methodParams);
function getjson(){
dojo.xhrGet({
url: "/jsonrpc",
load : function(){
var data_list = [];
service.myfunction().then(
function(data){
dojo.forEach(data, function(dat){
data_list.push(dat);
});
console.log(data_list)
},
function(error) {
console.log(error);
}
);
}
});
}
getjson();
}
refreshContent();
});
});
</script>
I've used this approach with django where i am not creating a different server for the rpc calls but using django's url link to forward the call to my function.. But you can always create a small rpc server to do the same..

$.ajax function : send json data : parse at serverside function

I am using $.ajax function to send json data to serverside function.
var jsonObjects = [{id:1, name:"amit"}, {id:2, name:"ankit"},{id:3,name:"atin"},{id:1, name:"puneet"}];
$.ajax({
url: "{{=URL('myControllerName')}}",
type: "POST",
context: document.body,
data: {students: JSON.stringify(jsonObjects) },
dataType: "json",
success: function(){
alert('ok');
}
});
In the serverside function, how do I access the data?
Somebody has give the code for grails as :---
//this code is written in grails
import grails.converters.JSON;
List<JSON> students = JSON.parse(params.students) //students in request params is parsed to json objects and stored in the List
println "Student id: " + students[0].studentId //first element of the students list is accessed as a map holding a key studentId
I want to do this in a python web framework viz. web2py.
Tried to access it as params.students and request.students, but no luck.
What is the correct syntax to access the data sent? (I checked the jQuery API, but couldn't find the same).
Thanks,
Vineet
You are confused.
"How to access the data on the serverside" has nothing to do with jquery, and everything to do with your server-side web framework.
You need to extract the data from the request object; the web2py documentation for that is here: http://web2py.com/book/default/chapter/04#request

Categories