Calling REST API with multipart/form-data - multipart

How to call a REST API from javascript with ajax or XMLHttpRequest to upload a file using
Content-Type: multipart/form-data.
File content is in binary format, but the API which I am calling has following request format:
Authorization: Bearer <>
Content-Type: multipart/form-data
I am using following code segment to upload the file content:
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("POST", requestUrl);
xmlHttp.setRequestHeader("Authorization", "Bearer " + token);
xmlHttp.setRequestHeader("Content-Type", "multipart/form-data");
xmlHttp.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xmlHttp.send(formData);
Where formData is the filecontent in binary format. Please suggest if this is the right way or should be handled differently.The file type I am using is an IFC file. And the error I am receiving is media-type not supported
Thanks!

For uploading files to Autodesk Forge (A360), the following curl command works in a Unix-like terminal:
curl -v 'https://developer.api.autodesk.com/oss/v2/buckets/$bucket_name/objects/$filename.ifc' \
-X 'PUT' \
-H 'Authorization: Bearer $token' \
-H 'Content-Type: text/plain; charset=UTF-8' \
-T '$filename.ifc'
since IFC files are text (ASCII) files and not binary files.
Using the same Content-Type might do the trick in your case.
Hope it helps.

Related

Authenticate using httr package when Making API Requests

I'm learning how to fetch data using an API in R. I understand that the aim of httr is to provide a wrapper for the curl package.
The documentation I'm following so that I make requests to the API has the following HTTP request format. This code below will be used to generate a token
curl -s \
-d "client_id=clientid” \
-d "username=user” \
-d "password=pwd” \
-d "grant_type=password" \
-d "scope=openid email" \
"https://auth.com/token"
Afterward, I'll use the token to now communicate with the API using this request
curl --header "Content-Type: application/json" \
--header "Accept: application/+json" \
--header "Authorization: Bearer token_goes_here“ \
--request GET \
--url "https://api-sitename.org/sections?parent_id=0"
Initially, I run these two requests in a terminal and they were successful, I got a response in JSON format. My question is, how do I run these requests in an R script such that I get a responses and they're it's stored in R studio global environment? My goal is to finally load the dataset from the API to the Rstudio working environment.
T
Here is something to get you started:
library(httr)
resp <- POST("https://auth.com/token",
body=list(client_id="clientid",
username="user",
password="pwd",
grant_type="password",
scope="openid email")
)
#parse for auth token here
content(resp, "text")
get_resp <- GET("https://api-sitename.org/sections?parent_id=0",
add_headers("Content-Type"="application/json",
Accept="application/+json",
"Authorization"=paste("Bearer", token))
I was able to successfully get my API call in R by replacing the content in header to body.
Here is my code
#' Th base url
base_url <- "your/url/endpoint/for/token"
# base64 encoded client id, my end-point requires to encone the client id to base64
c_id <- RCurl::base64(txt = "clinetid:sceret", mode = "character")
#' headers
headers <- httr::add_headers(
"Authorization" = paste("Basic",c_id, sep = " ")
)
# move everything else to the body. grant_type and password were requested by the endpoint
body <- list(
username = "your username",
password = "your password",
grant_type = "password",
scope = "read"
)
#' post call to get the token
httr::POST(
url = base_url,
body = body,
config = headers,
httr::accept_json()
)
When I had the user name and password in the body, I received 400 and 403 errors. Once I moved them o the body received 200 status and the token was successfully retrieved. If you can provide what you tried in R, can help you troubleshoot.

how to execute a https post request using curl in flutter

i am new to using curl and I am trying to execute a https post request using curl. and it doest seem to work like other json post requests so i was hoping someone can explain this to me
I am not sure if i understood your answer well enough but you can take a look at this Package or this one the latter one provides provides more flexibility and features like Interceptors etc.
You can use this package Curl https://pub.dev/packages/curl
example code
import 'package:curl/curl.dart';
import 'package:http/http.dart';
final req1 = new Request("GET", "https://exyui.com/endpoint");
print(toCurl(req1));
// will print out:
// curl 'https://exyui.com/endpoint' --compressed --insecure
final req2 = new Request("PUT", "https://exyui.com/endpoint");
req2.body = "This is the text of body😅, \\, \\\\, \\\\\\";
print(req2);
// will print out:
// curl 'https://exyui.com/endpoint' -X PUT -H 'content-type: text/plain; charset=utf-8' --data-binary \$'This is the text of body\\ud83d\\ude05, \\, \\\\, \\\\\\' --compressed --insecure
final req3 = new Request("POST", "https://exyui.com/endpoint");
final part1 = "This is the part one of content";
final part2 = "This is the part two of content😅";
final expectQuery = "part1=This%20is%20the%20part%20one%20of%20content&part2=This%20is%20the%20part%20two%20of%20content%F0%9F%98%85";
req3.bodyFields = {
"part1": part1,
"part2": part2,
};
print(toCurl(req3));

Retrieve API data with requests

I am trying to retrieve switch data via the Meraki API. Instructions and samples for the API's are here:
# https://dashboard.meraki.com/api_docs#return-a-switch-port
Sample Request
$ curl -L \
-H 'X-Cisco-Meraki-API-Key: <key>' \
-H 'Content-Type: application/json' \
-X GET 'https://dashboard.meraki.com/api/v0/devices/[serial]/switchPorts/[number]'
Sample Response
Successful HTTP Status: 200
{
"number": 1,
"name": "my port",
"tags": "dorm-room limited",
"enabled": true,
"type": "access",
"vlan": 10,
"voiceVlan": 20,
"poeEnabled": true,
"isolationEnabled": false,
"rstpEnabled": true,
"stpGuard": "disabled",
"accessPolicyNumber": "asdf1234",
"linkNegotiation": "Auto negotiate"
}
I am using Python's requests instead of curl. My code is: (NOTE I have altered the serial number and API key just for this post. I use the correct values when I run the code)
import requests
headers = {
'X-Cisco-Meraki-API-Key': '1111111111111111111111111111111111111111',
'Content-Type': 'application/json',
}
# response = requests.get('https://dashboard.meraki.com/api/v0/devices/[serial]/switchPorts/[number]', headers=headers)
response = requests.get('https://dashboard.meraki.com/api/v0/devices/1111-2222-3333/switchPorts/1', headers=headers)
print(response)
# <Response [200]>
I am getting back <Response [200]> instead of the JSON data that the API above shows.
My HTTP Status is correct, however. What am I missing in order to actually get back the JSON data?
Use print(response.content) instead of print(response).
If you want to save the data in a file, you can use:
content=response.content
data=open("name_you_want.json","wb")
data.write(content)
data.close()
use print (response.text)
instead of print(response)
because its printing response status code instead of body text and i guess you want to print response body
With .content & json.loads you should be able to parse JSON
import requests,json
response = requests.get('https://dashboard.meraki.com/api/v0/devices/1111-2222-3333/switchPorts/1')
json = json.loads(response.content)
print(json.get('name'))
To access curl using python, you can run this:
import requests
headers = {
'accept': 'text/html',
'Cookie': 'token=5e1a8b55b0249136a60423aa02b9120a845fa4122ac98ce4e771aec5d772d7d7a18ac22f18cd47727d00bddc2ebcc5cddf8a402d7a302ddffdeb7c6e15cb2a7005f857112',
}
response = requests.get("http://link-ui3.enter.com/data/1.0/auth/getUserByToken", headers=headers)
print(response.status_code)
print (r.json)
# You will get your json response

How do I make curl to POST a parameter, reading its value from a file?

I’m playing with GitHub web hooks and I want to use curl to post some sample JSON. The request is supposed to contain a payload POST parameter with the JSON string as a value. As an example, this works:
$ curl --form payload='{"foo":1}' http://somewhere
But I need to read the JSON from a file (say foo.json). Replacing the JSON string by #foo.json posts the payload in the request body:
--------------------------8d0c6d3f9cc7da97
Content-Disposition: form-data; name="payload"; filename="foo.json"
Content-Type: application/octet-stream
{'foo':1}
--------------------------8d0c6d3f9cc7da97--
That’s not really what I want, I need the payload to be passed as a parameter. How do I do that?
Maybe silly but try this:
cat foo.json | xargs -I % curl --form payload='%' http://example.com
Just wrote this little thing and it worked:
var=`cat some.json` && curl --form payload="$var" http://lvh.me/test/index.php
Here’s an alternative Perl testing script. Pass the target URL as the first argument, feed the JSON to STDIN:
#!/usr/bin/env perl
use strict;
use warnings;
use LWP;
my $target = shift #ARGV or die "Need a target URL";
my $ua = LWP::UserAgent->new;
my $payload = do { local $/; <STDIN> };
my $response = $ua->post($target, { payload => $payload });
print $response->as_string;

Put a custom http header in backbone

I am creating an API with Tastypie and I want to access to the API from Backbone.
To send credentials I use an user_id and a api_key. I do this in android and with curl and this work great, but I can set the http header from backbone.
In curl I use:
curl --dump-header - -H "Accept: application/json" -H "Content-Type: application/json" -H "user_id: 32" -H "api_key: 69950" -X DELETE "http://127.0.0.1:8000/api/v1/deletenote/66/?format=json"
and in android java I use:
HttpDelete requestDELETE = new HttpDelete();
requestDELETE.setHeader("Content-type", "application/json");
requestDELETE.setHeader("Accept", "application/json");
requestDELETE.setHeader(Constants.HEADER_USER_ID, user_id);
requestDELETE.addHeader(Constants.HEADER_API_KEY, key);
Both of them work great, but when I try this in Backbone following the responses that I found in other post from the page, this didn't work.
I am trying this:
var removeNote = new DeleteNoteModel({id:this.model.toJSON().id},{ query:this.model.toJSON().id});
removeNote.destroy({
headers: {'user_id':dataWeb.get("id"),'api_key':dataWeb.get("api_key")}
},{
async:false,
error: function(model, response){
console.log("KO_REMOVE_NOTE");
console.log(response);
},
success : function(model, response){
console.log("OK_REMOVE_NOTE");
console.log(response);
}
}
);
I'm putting the header when I call to the destroy call, but this don't send anithing to the server.
What I am doing in a wrong mode?
Thanks to all.
Tallmaris answer should fix it for you though I would recommend usign jQuery ajaxSetup method to setup the headers as default values for all ajax requests as I believe you need them all the time anyway right?
Somewhere where you launch the App put in
$.ajaxSetup({
headers: {
'user_id':dataWeb.get("id"),
'api_key':dataWeb.get("api_key")
}
});
Thanks to that you'll save yourself a lot of repeated code :) keep it DRY!
(obviously you'd need to ensure that dataWeb is available in the scope of where you launch the app :) )
It seems you are passing two parameters to destroy, pass only one containing the headers and the other options together, unless the brackets order is a typo. Try this:
removeNote.destroy({
headers: {
'user_id':dataWeb.get("id"),
'api_key':dataWeb.get("api_key")
}, // there was an extra close-open curly here...
async:false,
error: function(model, response){
console.log("KO_REMOVE_NOTE");
console.log(response);
},
success : function(model, response){
console.log("OK_REMOVE_NOTE");
console.log(response);
}
});

Resources