I am trying to get data from the mobile analytics service Localytics via their API (https://api.localytics.com/docs#query). In particular I would like to translate the following cURL command in R:
curl --get 'https://api.localytics.com/v1/query' \
--user 'API_KEY:API_SECRET' \
--data 'app_id=APP_ID' \
--data 'metrics=users' \
--data 'dimensions=day' \
--data-urlencode 'conditions={"day":["between","2013-04-01","2013-04-07"]}'
My R code looks like this at the moment. APIKey and API secret are of course replaced by the actual keys. However, I receive an error stating that at least a dimension or a metric has to be specified.
object <- getURL('https://api.localytics.com/v1/query', userpwd = "API_Key:API_Secret", httpheader=list(app_id = "app_id=03343434353534",
metrics = "metrics=users",
dimensions = "dimensions=day",
conditions = toJSON('conditions={"day":["between","2014-07-01","2014-07-10"]}')), ssl.verifypeer = FALSE)
What changes would be necessary to get it to work.
Thanks in advance for helping me out,
Peter
This is particular easy with the dev version of httr:
library(httr)
r <- POST('https://api.localytics.com/v1/query',
body = list(
app_id = "APP_ID",
metrics = "users",
dimensions = "day",
conditions = list(
day = c("between", "2014-07-01", "2004-07-10")
)
),
encode = "json",
authenticate("API_key", "API_secret")
)
stop_for_status(r)
content(r)
(I converted the request to a POST and used json encoding for everything, as describe in the API docs).
If you want to see exactly what's being sent to the server, use the verbose() config.
It looks like getURL passes the parameters you quested as HTTP headers and not as querystring data as your curl call does. You should use getForm instead. Also, I wasn't sure from which library your toJSON function came form, but that's at least not the right syntax for the one from rsjon.
Anyway, here's a call from R which should produce the same HTTP call are your curl command
library(rjson)
library(RCurl)
object <- getForm('https://api.localytics.com/v1/query',
app_id = "APP_ID",
metrics = "users",
dimensions = "day",
conditions = toJSON(list(day=c("between","2014-07-01","2004-07-10"))),
.opts=curlOptions(
userpwd = "API_Key:API_Secret", httpauth = 1L)
)
I found that using the site http://requestb.in/ is very helpful in debugging these problems (and that's exactly what I used to create this solution). You can send requests to their site and they record the exact HTTP message that was sent so you can compare different methods.
The httpauth part was from this SO question which seemed to be required to trigger authentication for the test site; you may not need it for the "real" site.
Related
I am trying to pass some text to the UberDuck API but I can't seem to get my credentials to process correctly.
What is the correct structure I need to pass? In the terminal I get:
matt#UNKNOWN:~> curl -u pub_vworsdasdssd3242ds3bfzc:pk_sa8f07saf-4e7c-dsfasd989ds7dfds5f2b6 'https://api.uberduck.ai/speak'
{"detail":"Method Not Allowed"}matt#UNKNOWN:~>
matt#UNKNOWN:~> \ --data-raw '{"speech":"This is just a test.","voice":"zwf"}'
API key and secret has been changed:
Curl:
curl -u pub_jutyrreufnrhzbfzc:pk_999999999-1f3b-4e7c-iu54-6c358525f2b6 'https://api.uberduck.ai/speak'
\ --data-raw '{"speech":"This is just a test.","voice":"zwf"}'
Code in R:
library(httr)
c("\n\nWe gon' fight for the people\nThat's why we came, that's why we came\nWe gon' fight for the poor\nGon' fight for the have-nots\nGonna make sure that they get a piece of the pie\nAnd we'll never give up, never give in\n'Til we see justice for every single one\n\nAnd it's not just a black and white issue\nIt's everybody's issue\nWe all need to stand up\nAnd demand that the government does right\nBy the people, all the people\nNot just the ones with the most power and money\n\nSo come on, join the fight\nIt's time to take a stand\nFor social justice, for equality\nFor human rights, for humanity\nAnd we'll never give up, never give in\n'Til we see justice for every single one")
url <- "https://api.uberduck.ai/speak"
singer <- "2pac"
payload <- list(voice = singer, pace = 1, speech = generated_song)
headers <- list("accept" = "application/json", "content-type" = "application/json", "authorization" = "Basic XXXXXXXXXXXXXXXXXXXXXXXXXXX")# this is just the encoded version of your Uberduck API credentials. You can have it directly on the Uberduck website
}
response <- POST(url, body = payload, add_headers(headers))
print(content(response))
i am experimenting with R and i wonder how could i GET some data from API using library httr or rcurl..
for example with curl in terminal i can do this and it gets me the data i want:
curl -X GET "https://some.webpage.com/api/v1/accounts/self/profile" -H "accept: application/json" -H "token-auth: 72124asfin393483feifefi92835w345"
note: token key is random set of chars
Unfortunately when i try to reproduce this in R i fail, i tried using something like:
> library(httr)
> c <- GET("https://some.webpage.com/api/v1/accounts/self/profile?token- auth=72124asfin393483feifefi92835w345"
or this:
> url = "https://some.webpage.com/api/v1/accounts/self/profile"
> key = "{72124asfin393483feifefi92835w345}"
> a <- GET(url, add_headers(Authorization = paste("Bearer", key, sep = " ")))
Unfortunately when i try this in Rstudio i always get this error:
[1] "'token-auth' has to be provided for authentication."
More info about this particular API call:
This is the documentation
So i guess i obviously do something wrong with the url composition, how would i get this to work with R? I am baffled, i found some documentation on API in R, but nothing to explain how to work with a token. Thanks
Correct solution is what MrFlick said:
Then try a <- GET(url, add_headers("token-auth" = key)). And make sure you don't have the braces in your key string.
Im attempting to setup some R code to create a new work item task in Azure Devops. Im okay with a mostly empty work item to start with if thats okay to do (my example code is only trying to create a work item with a title).
I receive a 203 response but the work item doesn't appear in Devops.
Ive been following this documentation from Microsoft, I suspect that I might be formatting the body incorrectly.
https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/work%20items/create?view=azure-devops-rest-5.1
Ive tried updating different fields and formatting the body differently with no success. I have attempted to create either a bug or feature work item but both return the same 203 response.
To validate that my token is working I can GET work item data by ID but the POST continues to return a 203.
require(httr)
require(jsonlite)
url <- 'https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/$bug?api-version=5.1'
headers = c(
'Authorization' = sprintf('basic %s',token),
'Content-Type' = 'application/json-patch+json',
'Host' = 'dev.azure.com'
)
data <- toJSON(list('body'= list("op"= "add",
"path"= "/fields/System.AreaPath",
"value"= "Sample task")), auto_unbox = TRUE, pretty = TRUE)
res <- httr::POST(url,
httr::add_headers(.headers=headers),
httr::verbose(),
body = data)
Im expecting a 200 response (similar to the example in the link above) and a work item task in Azure DevOps Services when I navigate to the website.
Im not the best with R so please be detailed. Thank you in advanced!
The POST continues to return a 203.
The HTTP response code 203 means Non-Authoritative Information, it should caused by your token format is converted incorrectly.
If you wish to provide the personal access token through an HTTP
header, you must first convert it to a Base64 string.
Refer to this doc described, if you want to use VSTS rest api, you must convert your token to a Base64 string. But in your script, you did not have this script to achieve this convert.
So, please try with the follow script to convert the token to make the key conformant with the requirements(load the base64enc package first):
require(base64enc)
key <- token
keys <- charToRaw(paste0(key,":token"))
auth <- paste0("Basic ",base64encode(keys))
Hope this help you get 200 response code
I know this question is fairly old, but I cannot seem to find a good solution posted yet. So, I will add my solution in case others find themselves in this situation. Note, this did take some reading through other SO posts and trial-and-error.
Mengdi is correct that you do need to convert your token to a Base64 string.
Additionally, Daniel from this SO question pointed out that:
In my experience with doing this via other similar mechanisms, you have to include a leading colon on the PAT, before base64 encoding.
Mengdi came up big in another SO solution
Please try with adding [{ }] outside your request body.
From there, I just made slight modifications to your headers and data objects. Removed 'body' from your json, and made use of paste to add square brackets as well. I found that the Rcurl package made base64 encoding a breeze. Then I was able to successfully create a blank ticket (just titled) using the API! Hope this helps someone!
library(httr)
library(jsonlite)
library(RCurl)
#user and PAT for api
userid <- ''
token= 'whateveryourtokenis'
url <- 'https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/$bug?api-version=5.1'
#create a combined user/pat
#user id can actually be a blank string
#RCurl's base64 seemed to work well
c_id <- RCurl::base64(txt = paste0(userid,
":",
devops_pat
),
mode = "character"
)
#headers for api call
headers <- c(
"Authorization" = paste("Basic",
c_id,
sep = " "
),
'Content-Type' = 'application/json-patch+json',
'Host' = 'dev.azure.com'
)
#body
data <- paste0("[",
toJSON(list( "op"= "add",
"path"= "/fields/System.Title",
"value"= "API test - please ignore"),
auto_unbox = TRUE,
pretty = TRUE
),
"]"
)
#make the call
res <- httr::POST(url,
httr::add_headers(.headers=headers),
httr::verbose(),
body = data
)
#check status
status <- res$status_code
#check content of response
check <- content(res)
I have this working curl statement to post a file to Nokia's HERE batch geocoding service...
curl -X POST -H 'Content-Type: multipart/form-data;boundary=----------------------------4ebf00fbcf09' \
--data-binary #example.txt \
'http://batch.geocoder.cit.api.here.com/6.2/jobs?action=run&mailto=test#gmail.com&maxresults=1&language=es-ES&header=true&indelim=|&outdelim=|&outcols=displayLatitude,displayLongitude,houseNumber,street,district,city,postalCode,county,state,country,matchLevel,relevance&outputCombined=false&app_code=AJKnXv84fjrb0KIHawS0Tg&app_id=DemoAppId01082013GAL'
I have tried this:
library(RCurl)
url <- "http://batch.geocoder.cit.api.here.com/6.2/jobs? action=run&mailto=test#gmail.com&maxresults=1&language=es-ES&header=true&indelim=|&outdelim=|&outcols=displayLatitude,displayLongitude,houseNumber,street,district,city,postalCode,county,state,country,matchLevel,relevance&outputCombined=false&app_code=AJKnXv84fjrb0KIHawS0Tg&app_id=DemoAppId01082013GAL'"
postForm(url, file=fileUpload(filename="example.txt",
contentType="multipart/form-data;boundary=----------------------------4ebf00fbcf09"))
And this:
library(httr)
a <- POST(url, body=upload_file("example.txt", type="text/plain"),
config=c(add_headers("multipart/form-data;boundary=----------------------------4ebf00fbcf09")))
content(a)
Using this file as example.txt: https://gist.github.com/corynissen/4f30378f11a5e51ad9ad
Is there any way to do this property in R?
I'm not a Nokia developer, and I'm assuming those are not your real API creds. This should help you get further with httr:
url <- "http://batch.geocoder.cit.api.here.com/6.2/jobs"
a <- POST(url, encode="multipart", # this will set the header for you
body=list(file=upload_file("example.txt")), # this is how to upload files
query=list(
action="run",
mailto="test#example.com",
maxresults="1",
language="es-ES", # this will build the query string
header="true",
indelim="|",
outdelim="|",
outcols="displayLatitude,displayLongitude", # i shortened this for the example
outputCombined="false",
app_code="APPCODE",
app_id="APPID"),
verbose()) # this lets you verify what's going on
But, I can't be sure w/o registering (and no time to do that).
This is the solution based on hrbrmstr's solution
bod <- paste(readLines("example.txt", warn=F), collapse="\n")
a <- POST(url, encode="multipart", # this will set the header for you
body=bod, # this is how to upload files
query=list(
action="run",
mailto="test#gmail.com",
maxresults="1",
language="es-ES", # this will build the query string
header="true",
indelim="|",
outdelim="|",
outcols="displayLatitude,displayLongitude,houseNumber,street,district,city,postalCode,county,state,country,matchLevel,relevance", # i shortened this for the example
outputCombined="false",
app_code="AJKnXv84fjrb0KIHawS0Tg",
app_id="DemoAppId01082013GAL"),
#config=c(add_headers("multipart/form-data;boundary=----------------------------4ebf00fbcf09")),
verbose()) # this lets you verify what's going on
content(a)
The problem I had to get around was that the normal upload process strips line breaks... but I needed them in there for the API to work (--data-binary option in curl does this). To get around this, I insert the data as a string after reading it via readLines().
I am trying to create an OAuth token from the command line using the instructions here. I am able to use curl from the command line, and get the correct response
curl -u 'username:pwd' -d '{"scopes":["user", "gist"]}' \
https://api.github.com/authorizations
Now, I want to replicate the same in R using RCurl or httr. Here is what I tried, but both commands return an error. Can anyone point out what I am doing wrong here?
httr::POST(
'https://api.github.com/authorizations',
authenticate('username', 'pwd'),
body = list(scopes = list("user", "gist"))
)
RCurl::postForm(
uri = 'https://api.github.com/authorizations',
.opts = list(
postFields = '{"scopes": ["user", "gist"]}',
userpwd = 'username:pwd'
)
)
The question is ages old, but maybe still helpfull to some: The problem should be that the opts arguments are passed in the wrong way (lacking a curlOptions function call). The following worked for me in a different context:
result <- getURL(url,.opts=curlOptions(postfields=postFields))
(and yes, as far as I know you can use getURL function for POST requests).