Get data via Netatmo API within R - r

I tried to get data from a netatmo station I have access to via API. The following code I used in R.
myapp <- oauth_app("my_netatmo",key="my_netatmo_client_id",secret="my_netatmo_client_secret")
ep <- oauth_endpoint(authorize = "http://api.netatmo.net/oauth2/authorize",access = "http://api.netatmo.net/oauth2/token")
sig_tok <- oauth2.0_token(ep,myapp, scope="read_station")
#after that I get redirected to my browser to log in and after that sig_tok contains an access token
sig <- config(token = sig_tok)
html_get<-GET("http://api.netatmo.net/api/devicelist",sig)
html_get contains this:
html_get
Response [http://api.netatmo.net/api/devicelist]
Status: 400
Content-type: application/json; charset=utf-8
{"error":{"code":1,"message":"Access token is missing"}}
What am I doing wrong since "sig" seems to contain a token:
sig$token$credentials$access_token
[1] "5**********************f|3**********************a"
There are two tokens or am I wrong (because of "|" in between)?

The '|' inside the access_token is part of it, it is only one access token.
From the documentation: http://dev.netatmo.com/doc/methods/devicelist,
the parameter name is: "access_token". I don't know the R language, but it seems you are sending "token" as a parameter, and not "access_token". It may explain the issue.

Related

Authorization in R API, specifically for League of Legends

I am learning how to use API in R and it is going well for the most part, but I am having trouble getting any data from the league of legends API.
For reference, I used this article as a start (https://www.dataquest.io/blog/r-api-tutorial/) and cop
res <- GET("http://api.open-notify.org/astros.json")
res
This worked just fine and has a 200 status, but I am not interested in that data.
What I want is data about league of legends, so I am trying to use:
base.url <- "https://na1.api.riotgames.com"
path <- "/lol/champion-mastery/v4/champion-masteries/by-summoner/"
API_Key <- read.table("riotkey.txt")
API_KEY <- API_Key$V1
Summoner_ID <- read.table("summonerID.txt")
SUMMONER_ID <- Summoner_ID$V1
path <- paste0(path,SUMMONER_ID)
LoL_API_Test <- GET(base.url, path = path,
add_headers(Authorization = API_KEY))
LoL_API_Test
This is Riot's explanation for the 403 error - Forbidden. "This error indicates that the server understood the request but refuses to authorize it. There is no distinction made between an invalid path or invalid authorization credentials (e.g., an API key)"
I am certain that my API key and summoner ID are correct.
So I assume the issue has to be with how I am requesting the data.
What am I doing wrong?
This particular API expects the API key to be passed in a header called "X-Riot-Token", not "Authorization". Change your call to
LoL_API_Test <- GET(base.url, path = path,
add_headers("X-Riot-Token" = API_KEY))

How do I translate my CLI curl POST api create user call to R httr?

I want to add users to groups on nextcloud via their API.
I succeeded with adding one user (ncuser) to Group1 and Group2 from my CLI, by running this request:
curl -X POST https://adminuser:'admin pass phrase'#cloud.example.org/ocs/v1.php/cloud/users/ncuser/groups -d groupid="Group1" -d groupid="Group2" -H "OCS-APIRequest: true"
With the following response:
<?xml version="1.0"?>
<ocs>
<meta>
<status>ok</status>
<statuscode>100</statuscode>
<message>OK</message>
<totalitems></totalitems>
<itemsperpage></itemsperpage>
</meta>
<data/>
</ocs>
I attempted to run the request in Rstudio with this code:
library(curl)
library(httr)
call <- POST("https://adminuser:'admin pass phrase'#cloud.example.org/ocs/v1.php/cloud/users/ncuser/groups",
body = list(groupid = "Group1", groupid = "Group2"),
add_headers('OCS-APIRequest' = "true", 'Content-Type' = "application/x-www-form-urlencoded"))
But this isn't successful. I get this response in R:
Response [https://adminuser:'admin pass phrase'#cloud.example.org/ocs/v1.php/cloud/users/ncuser/groups]
Date: 2020-03-22 15:43
Status: 401
Content-Type: application/json; charset=utf-8
Size: 140 B
Here is the content of my R POST request:
content(call)
$ocs
$ocs$meta
$ocs$meta$status
[1] "failure"
$ocs$meta$statuscode
[1] 997
$ocs$meta$message
[1] "Current user is not logged in"
$ocs$meta$totalitems
[1] ""
$ocs$meta$itemsperpage
[1] ""
$ocs$data
list()
It seems like I wasn't able to login through the POST() url, and need to add adminuser and 'admin pass phrase' in some other way, but i am not sure how.
Also, the nextcloud API documentation states that OCS-APIRequest and the content type needs to be specified in the header, but I am not sure if i did that correctly.
All calls to OCS endpoints require the OCS-APIRequest header to be set to true.
All POST requests require the Content-Type: application/x-www-form-urlencoded header. (Note: Some libraries like cURL set this header automatically, others require setting the header explicitly.)
How should my POST request be written in R so that I can successfully add my nextcloud users to groups?
Any help would be highly appreciated.
Maybe try
call <- POST("https://cloud.example.org/ocs/v1.php/cloud/users/ncuser/groups",
body = list(groupid = "Group1", groupid = "Group2"),
add_headers('OCS-APIRequest' = "true"),
authenticate("adminuser", "admin pass phrase"),
encode = "form")
This will make sure POST encode the body properly and will more safely pass the username/password. You can also try adding in verbose() to get more output. It's not going to be easy to help you without some sort of reproducible example we can use for testing.

Using HTTR POST to Create a Azure Devops Work Item

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)

Scraping Data using R - Form with List in POST

I am trying to scrape some web data using the API that I can see is being called by viewing the Safari Network Tab.
Either the API doesn't seem to get the form parameters correctly if passed as json or I get an error from R if I try to pass them as URLEncoded. I can't see what am I doing wrong? I suspect part of the problem is that my form is a list containing a list.
Request Data as shown in Safari Network Tab
MIME Type: application/x-www-form-urlencoded; charset=UTF-8
method: POST
section[]: 1
section[]: 4
period[]: 20170501
HTTR Post to mimic the above
form <- list(
section = list(1,4),
period = 20170501
)
resp<-POST(URL, body=form, encode="json", verbose())
Then the code runs without error and the API does return results but seems to have ignored the specific parameters.
The output from verbose suggests the parameters are being included:
{"section":[1,4],"period":20170501}
Adjustment for Form Type
I can see the above is not using the correct form type, so I change encode to "form" to so that the form is sent as x-www-form-urlencoded. However, I then get the following error.
Error in vapply(elements, encode, character(1)) :
values must be length 1,
but FUN(X[[1]]) result is length 2
Fixed! I had to use Query instead of Body and add the [] after each item.
query <- list(
"section[]" = 1,
"section[]" = 4,
"period[]" = 20170501
)
resp<-POST(URL, query=query, verbose())

R API Connection (Localytics) with getURL and RCurl Error

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.

Resources