I am trying to "translate" the curl call below, so that I can make an API call with R (using httr), with no luck. I have tried curlconverter and using the suggestion here. However, the API I want to access has multiple layers, and parenthesis are all over the place, which complicate conversion. Any suggestions for a function that will translate this recurring logic dynamically?
curl call:
curl -X POST 'https://api.notion.com/v1/databases/897e5a76ae524b489fdfe71f5945d1af' \
-H 'Authorization: Bearer '"$NOTION_API_KEY"'' \
-H 'Notion-Version: 2021-05-13' \
-H "Content-Type: application/json" \
--data '{
"filter": {
"or": [
{
"property": "In stock",
"checkbox": {
"equals": true
}
},
{
"property": "Cost of next trip",
"number": {
"greater_than_or_equal_to": 2
}
}
]
},
"sorts": [
{
"property": "Last ordered",
"direction": "ascending"
}
]
}'
Desired outcome (function)
api_call(page, token, filters)
This question is a bit difficult to answer, since you have the access key and therefore nobody can test code to make sure it works. However, in terms of simply translating the curl call to httr code, I think the following code will do so.
library(httr)
library(jsonlite)
# Create the body of the POST request
json_body <- list(
"filter" = list(
"or" = list(
list(
"property" = "In stock",
"checkbox" = list(
"equals" = "true"
)
),
list(
"property" = "Cost of next trip",
"number" = list(
"greater_than_or_equal_to" = 2
)
)
)
),
"sorts" = list(
list(
"property" = "Last ordered",
"direction" = "ascending"
)
)
)
# Make post request
request <- POST(
url = "https://api.notion.com/v1/databases/897e5a76ae524b489fdfe71f5945d1af",
add_headers("Authorization" = paste("Bearer", notion_api_key),
"Notion-Version" = "2021-05-13"),
body = json_body,
encode = "json"
)
In terms of defining a function that creates the body dynamically, that's simply a question of formatting the filters similarly to the above example.
Related
I am using R and have one question on how to pass parameter to the REST API REQUEST.
I already got the token and I am using R, and need to retrieve data from REST API service, by passing some parameters. Here is my code:
library(httr)
r <- POST("https://XXXXXXXX/api/locationhazardInfo",
add_headers("Content-Type"="text/plain; charset=UTF-8",
Accept="text/plain",
"Authorization"=paste("Bearer", tok)),
body = list(
"Latitude":40.738269,
"Longitude":-74.02826,
"CountryCode":"USA",
"HazardLayers":[
{
"LayerId":"18",
"Description":""
},
{
"LayerId":"6",
"Description":""
}
],
"Distances":[
{
"Value":1,
"Unit":"miles"
}
]
)
)
The tok is the token I got from previous step. And I got the systax errors (seem all syntax errors) as shown below,
Any input is greatly appreciated.
here is the screenshot of the error
Your body isn't a list. (I don't think!). I also think you have a rogue ) at the end (second last) which should be a }
A list would look like:
body = list(x = "A simple text string", y="Another String")
Your body is JSON encoded text.
body = '{"a":1,"b":{}}', encode = "raw")
So your code might look like this:
library(httr)
r <- POST(
"https://XXXXXXXX/api/locationhazardInfo",
add_headers(
"Content-Type"="text/plain; charset=UTF-8",
Accept="text/plain",
"Authorization"=paste("Bearer", tok)
),
body = '{
"Latitude":40.738269,
"Longitude":-74.02826,
"CountryCode":"USA",
"HazardLayers":[
{
"LayerId":"18",
"Description":""
},
{
"LayerId":"6",
"Description":""
}
],
"Distances":[
{
"Value":1,
"Unit":"miles"
}
]
}',
encode = "raw" )
An update, here is the solution at least it fixed my problem:
rg <- POST(url,
# add_headers("Content-Type"="text/plain; charset=UTF-8",
add_headers("Content-Type"="application/json",
Accept="text/plain",
"Authorization"=paste("Bearer", tok)),
body = '{
"Latitude":40.738269,
"Longitude":-74.02826,
"CountryCode":"USA",
"HazardLayers":[
{
"LayerId":"18",
"Description":""
},
{
"LayerId":"6",
"Description":""
}
],
"Distances":[
{
"Value":1,
"Unit":"miles"
}
]
}' ,
encode = "raw" #### , verbose()
)
I am new to this topic and reviewed several SO answers before, but still cannot figure it out.
Trying to access API, using R:
curl -X POST "http://api.spending.gov.ua/api/rest/1.0/transactions" -H "accept: application/json" -H
"Content-Type: application/json" -d "{ \"payers_edrpous\": [ \"string\" ], \"recipt_edrpous\": [
\"string\" ], \"startdate\": \"string\", \"enddate\": \"string\", \"regions\": [ 0 ]}"
My current stage
library(httr)
r <- GET("http://api.spending.gov.ua/api/rest/1.0/transactions")
status_code(r)
This works, I have 200 response.
But how to write a query to get data in json format? Appreciate any tips.
The link from #dcruvolo was helpful.
In order get to this to work, you need to start with some valid values. From the API link in the question, there is a test page to order to test the submittal:
One can substitute in test values and then press the "Execute" button submit values. Attempted values from the comments above, valid enough not to cause an error but also did not return any valid results.
To perform the POST in R here is an example:
posting<-'{
"payers_edrpous": [
"00013534"
],
"recipt_edrpous": [
""
],
"startdate": "2020-03-01",
"enddate": "2020-03-28",
"regions": [
0
]
}'
library(httr)
r <- POST("http://api.spending.gov.ua/api/rest/1.0/transactions", body=posting,
httr::add_headers(`accept` = 'application/json'),
httr::content_type('application/json')) #encode="json"
content(r)
Posting is the JSON body to pass, edit this as necessary. All variables are strings except "regions" where it is an integer, not sure what the valid range is.
Sorry this is the best I can do. Good luck.
I am trying to connect directly to a BI tool's API from within R. The API Documentation lists the curl command below to obtain an authentication token:
curl -X POST -H "Content-Type: application/json" -d
'{
"email": "your#email.com",
"password": "your_password"
}'
https://app.datorama.com/services/auth/authenticate
Further, below is an example of a JSON query that can be used to query data:
{
"brandId": "9999",
"dateRange": "CUSTOM",
"startDate": "2016-01-01",
"endDate": "2016-12-31",
"measurements": [
{
"name": "Impressions"
}
],
"dimensions": [
"Month"
],
"groupDimensionFilters": [],
"stringDimensionFilters": [],
"stringDimensionFiltersOperator": "AND",
"numberDimensionFiltersOperator": "AND",
"numberMeasurementFilter": [],
"sortBy": "Month",
"sortOrder": "DESC",
"topResults": "50",
"groupOthers": true,
"topPerDimension": true,
"totalDimensions": []
}
I'm trying to 1) translate the curl command above into R so as to obtain the authentication token required, and 2) query the data through the JSON script above.
So far i've attempted using the httr library as follows:
library(httr)
r <- POST('https://app.datorama.com/services/auth/authenticate',
body = list(
brandId = "9999",
dateRange = "CUSTOM",
measurements = list(name="Impressions"),
dimensions = list(name="Month"),
startDate = "2016-01-01",
endDate = "2016-12-31"
),
encode = "json",
authenticate("username", "password"))
to no avail.
The API documentation is behind a password protected page and as such i'm unable to link it. Let me know if additional information is required.
hrbrmstr is totally right! you should generate two api calls, the first one is to authenticate the user and the second one is to query the data.
Below is a fully working example of using the Datorama query API from R. feel free to contact the Datorama support for any additional questions.
library(httr)
res <- POST("https://app.datorama.com/services/auth/authenticate",
body=list(email="your#email.com",
password="your_password"),
encode="json")
token <- content(res)$token
res_query <- POST(paste("https://app.datorama.com/services/query/execQuery?token=",token, sep=""),
body = list(
brandId = "9999",
dateRange = "CUSTOM",
measurements = list(list(name = "Impressions")),
dimensions = list("Month"),
startDate = "2016-01-01",
endDate = "2016-12-31"
),
encode = "json")
cat(content(res_query, "text"), "\n")
I don't have access to their API and would have prbly written a small wrapper pkg to this service if they had a free tier. Having said that,
curl -X POST \
-H "Content-Type: application/json" \
-d '{ "email": "your#email.com",
"password": "your_password" }'
translates to:
library(httr)
res <- POST("https://app.datorama.com/services/auth/authenticate",
body=list(email="your#email.com",
password="your_password"),
encode="json")
They don't have their app API documentation online for free either but I'm going to assume it sends back a JSON response with some type of authorization_token and encoded string.
You then—most likely—need to pass that result with every subsequent API call (and there is probably a timeout where the initial auth will need to be re-upped).
authenticate() is used for HTTP basic auth, not for this type of in-API JSON/REST auth.
Your actual API call looks fine apart from using the token auth.
This curl call works to create a new droplet on Digital Ocean
curl -X POST "https://api.digitalocean.com/v2/droplets" \
-d '{"name":"test3","region":"nyc2","size":"512mb","image":5562742,"ssh_keys":[89103]}' \
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
However, I'm having trouble getting an httr::POST() request to work only when the parameter ssh_keys is given. In the above method the ssh_keys parameter, if given, has to be an array.
I assumed the list of parameters could be passed to the body as, e.g., where the ssh_keys parameter is inside a list
args <- list(name="test3", region="nyc2", size="512mb", image="5562742", ssh_keys=list(891111))
POST(url, config=auth, body=args)
I assume this is what's happening on the inside:
jsonlite::toJSON(args)
[1] "{ \"name\" : [ \"test3\" ], \"region\" : [ \"nyc2\" ], \"size\" : [ \"512mb\" ], \"image\" : [ \"5562742\" ], \"ssh_keys\" : [ [ 89103 ] ] }"
Which I imagine would work, but perhaps that's not what's happening? Fiddling with the encode parameter in POST doesn't seem to help.
The curl call works from terminal, but using httr::POST() I keep getting the error message
You specified invalid ssh key ids for Droplet creation.
In this specific case,
x <- jsonlite::toJSON(args, auto_unbox=TRUE)
cat(x)
seems to return the correct format (assuming the problem is not with the headers) so them
POST(url, config=auth, body=x)
should send the correct request.
Maybe something like:
req <- POST(
url = "https://api.digitalocean.com/v2/droplets",
body = toJSON(args, auto_unbox=TRUE),
add_headers (
"Content-Type" = "application/json",
"Authorization" = paste("Bearker", TOKEN)
)
)
Given this URL
http://localhost:8080/alfresco/service/api/sites/test-3
I get back:
{
"url": "\/alfresco\/service\/api\/sites\/test-3",
"sitePreset": "site-dashboard",
"shortName": "test-3",
"title": "Test 3",
"description": "",
"node": "\/alfresco\/service\/api\/node\/workspace\/SpacesStore\/0352afea-797f-4b9e-be27-3bf37e54a2f1",
"tagScope": "\/alfresco\/service\/api\/tagscopes\/workspace\/SpacesStore\/0352afea-797f-4b9e-be27-3bf37e54a2f1",
"siteManagers":
[
"admin"
],
"isPublic": true,
"visibility": "PUBLIC"
}
How to I use that info to get the list of folders in the site?
You need to use a different API. Look at this shell session:
$ curl -u admin:admin -i -H "Accept: application/json" -H "Content-Type: application/json" -X POST -d "{'shortName':{'values':['test'], 'match':'foo'}}" http://localhost:8080/alfresco/service/api/sites/query
{
"url" : "\/alfresco\/service\/api\/sites\/test",
"sitePreset" : "wcmqs-site-dashboard",
"shortName" : "test",
"title" : "test",
"description" : "",
"node" : "\/alfresco\/service\/api\/node\/workspace\/SpacesStore\/e597e4c2-d307-46e3-ba4d-b911262e7261",
"tagScope" : "\/alfresco\/service\/api\/tagscopes\/workspace\/SpacesStore\/e597e4c2-d307-46e3-ba4d-b911262e7261",
"isPublic" : false,
"visibility" : "PRIVATE",
"siteManagers" :
[
"admin"
]
}
// see the 'node' property up there
$ curl -u admin:admin http://p01:8080/alfresco/service/api/node/workspace/SpacesStore/e597e4c2-d307-46e3-ba4d-b911262e7261/children
[..cmis response here..]
One option is to use CMIS. Depending on your exact needs though, you can use some built in webscripts to do the listings too
Within the root of a site, you have Containers, such as documentLibrary and wiki. You can get a list of the containers for a site from the container.get webscript. Take a look at org/alfresco/slingshot/documentlibrary/container.get.desc.xml for the details. The URL pattern for it, as shown in that file, is /slingshot/doclib/containers/{site}
curl -u admin:admin http://localhost:8080/alfresco/service/slingshot/doclib/containers/test
{
"containers":
[
{
"name": "documentLibrary",
"description": "Document Library",
"nodeRef": "workspace://SpacesStore/973338a0-db39-458e-a10d-396f00cb16a3",
"type": "cm:folder"
}
]
}
Next, when you know what container or folder within a container you want to use, the treenode.get webscript can let you list that, eg
curl -u admin:admin http://localhost:8080/alfresco/service/slingshot/doclib/treenode/site/test/documentLibary
{
"totalResults": 0,
"resultsTrimmed": false,
"parent":
{
"nodeRef": "workspace://SpacesStore/92e4f8de-b919-4540-a27a-16c4e53a57bc",
"userAccess":
{
"create": true,
"edit": true,
"delete": true
}
},
"items":
[
]
}
I can also recommend you use http://localhost:8080/alfresco/service/index to view what webscripts are present in your system, and get information on them, it helps a lot for situations like this
Load a site: http://localhost:8080/alfresco/service/api/sites/test-3
{
"url": "\/alfresco\/service\/api\/sites\/test-3",
"sitePreset": "site-dashboard",
"shortName": "test-3",
"title": "test 3",
"description": "",
"node": "\/alfresco\/service\/api\/node\/workspace\/SpacesStore\/0352afea-797f-4b9e-be27-3bf37e54a2f1",
"tagScope": "\/alfresco\/service\/api\/tagscopes\/workspace\/SpacesStore\/0352afea-797f-4b9e-be27-3bf37e54a2f1",
"siteManagers":
[
"admin"
],
"isPublic": true,
"visibility": "PUBLIC"
}
Get the site contents using the ID extracted from the node property: http://localhost:8080/alfresco/service/api/node/workspace/SpacesStore/0352afea-797f-4b9e-be27-3bf37e54a2f1/children
Inside that is a node with the title "documentLibrary". Using its ID GUID, you can fetch some more children
http://localhost:8080/alfresco/service/cmis/s/workspace:SpacesStore/i/b68db1eb-547d-4b2c-b5eb-ba207a275789/children
If you have custom properties, they will appear on the child items using this API call.
Using the ID of the child item, you can get its content.
http://localhost:8080/alfresco/service/cmis/s/workspace:SpacesStore/i/2d53f464-bea0-46f3-aa0c-10b3302e661c/content
Use this url to get folder list.
http://localhost:8080/alfresco/service/api/node/workspace:SpacesStore/store_id/b0697dd1-ae94-4bf6-81c8-5e2fa098ddfa/children