Retrieve API data with requests - python-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

Related

Has anyone tried the Piwik PRO api in R?

I would like to use the Piwik PRO api in R, but cannot find an example for the code.
Does anyone know how to format this into R code? (Or can help me point to a source which will help me to do this myself?)
curl -X POST 'https://<domain>/auth/token' -H "Content-Type: application/json" --data '{
"grant_type": "client_credentials",
"client_id": "your_generated_client_id",
"client_secret": "your_generated_client_secret"
}'
I would suggest using the httr package.
Authentication code should look something like this:
library(httr)
url <- ""
payload <- "{ \"grant_type\": \"client_credentials\", \"client_id\": \"\", \"client_secret\": \"\" }"
encode <- "json"
response <- VERB("POST", url, body = payload, add_headers(Content_Type = 'application/json'), content_type("application/json"), encode = encode)
content(response, "text")

Sending headers to post request

I have this python code that does not work as expected.
import requests
import json
API_ENDPOINT = "https://lkokpdvhc4.execute-api.us-east-1.amazonaws.com/mycall"
data = {'mnumber':'9819838466'}
r = requests.post(url = API_ENDPOINT, data = json.dumps(data))
print (r.text)
This will return an error:
{"stackTrace": [["/var/task/index.py", 5, "handler", "return
mydic[code]"]], "errorType": "KeyError", "errorMessage": "''"}
When I test the API using Amazon console's gateway, I get the expected output (i.e. string like "mumbai"). It means this is client side issue. I have confirmed this by using "postman" as well that returns the same error as mentioned above. How do I send correct headers to post request?
You can create a dictionary with the headers such as
headers = {
"Authorization": "Bearer 12345",
"Content-Type": "application/json",
"key" : "value"
}
Then at the point of making the request pass it as a keyword argument to the request method i.e .post() or .get() or .put
This will be
response = requests.post(API_ENDPOINT, data=json.dumps(data), headers=headers)

Convert cURL to Google Apps Script

I am trying to convert a cURL command to a Google Apps Script PUT request.
I came up with the below google script but it does not seem to work. When I change the URL of both of these to RequestBin in order to probe what the server side is getting, RequestBin shows that the raw source of both of these come through as exactly the same. Yet, only the cURL command is able to perform the desired action (update a file on github) when I change it back to the github URL.
curl -i -X PUT -H 'Authorization: token yadayda' -d '{"path":"mygeojson.json","message":"Initial Commit","committer":{"name":"Sidd","email":"siddsubra#gmail.com"},"content":"bXkgbmV3IGZpbGUgY29udGVudHM=","sha":"0d5a690c8fad5e605a6e8766295d9d459d65de42","branch":"master"}' https://api.github.com/repos/teku45/GeoJSON-Update/contents/mygeojson.json
cURL Command
And this is the Google Script
function mainscript() {
var sha = getSHA();
var authenticationToken = "yadayada";
var url = "http://api.github.com/repos/teku45/GeoJSON-Update/contents/mygeojson.json";
var headers = {
"Authorization" : "token " + authenticationToken,
};
var payload = {
"path": "mygeojson.json",
"message": "Initial Commit",
"committer":{
"name": "Sidd",
"email": "siddsubra#gmail.com"
},
"content": "bXkgbmV3IGZpbGUgY29udGVudHM=",
"sha": sha,
"branch": "master"
};
var options = {
"headers" : headers,
"method" : "PUT",
"payload" : JSON.stringify(payload)
};
Logger.log(options);
Logger.log(UrlFetchApp.fetch(url, options));
}
Google Apps Script
I recently did a script that call a request to a API from scrapy cloud, and had a dificulty to convert curl to App Script request too.
I noticed that payload doesn't worked when i used JSON.stringify, so try remove it from payload:
"payload" : payload
Other observation was the need to use Utilities.base64Encode in authentication token:
headers = {"Authorization":"Basic " + Utilities.base64Encode(authenticationToken + ":" + "")}
See this sample:
url = "https://app.scrapinghub.com/api/run.json"
headers = {"Authorization":"Basic " + Utilities.base64Encode("myToken" + ":" + "")}
payload = {"project":"327107", "spider":"pmp"}
options = {"headers":headers, "payload":payload}
response = UrlFetchApp.fetch(url, options)
data = JSON.parse(response.getContentText())

Uber API - requests endpoint cannot read read json

I am trying to generate a POST request for the requests endpoint in the following python code:
import requests
...
response = requests.post(
'https://sandbox-api.uber.com/v1/requests',
headers = {
'Authorization': 'Bearer %s' % access_token,
'Content-Type': 'application/json'
},
params={"start_latitude":"37.334381","start_longitude":"-121.89432","end_latitude":"37.77703","end_longitude":"-122.419571","product_id":"a1111c8c-c720-46c3-8534-2fcdd730040d"})
data = response.json()
The access_token was obtained using request scope during authorization. The response json is :
{"message": "Unable to parse JSON in request body.", "code": "invalid_json"}
Need help in formatting the request properly. Thanks.
Figured out the problem - had to replace the params field with a data field and wrap the dict with json.dumps() before sending it off.

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