I am in the process of building a wrapper package for a web-based API.
library(httr)
path <- "datapoint/timeseries"
query <- list(onData = "Variable")
devsite_api <- function(path, query = NULL) {
url <- httr::modify_url("https://api.devsite.com/v1/", path = path, query = query)
return(url)
}
devsite_api(path = path, query = query)
The result of this is
"https://api.devsite.com/datapoint/timeseries?onData=Variable"
I'd like for the result to be
"https://api.devsite.com/v1/datapoint/timeseries?onData=Variable"
When I looked into the modify_url it function it seems to turn the url into a URL object which identifies hostnames, paths, etc. How can I make this function work without introducing something like:
devsite_api <- function(path, query = NULL) {
path_changed <- paste("v1", path, sep = "/")
url <- httr::modify_url("https://api.devsite.com", path = path_changed, query = query)
return(url)
}
Thanks.
I am trying to fetch all my mailinglists contacts using the following custom function, but contact lists didn't download all the records inside them. Idk what I am doing wrong?
get_all_contacts<-function(mailingListID){
directoryId<-"POOL_XXXXXXXXXX"
apiToken<-"XXXXXXXXXX"
fetch_url<- VERB(verb = "GET", url = paste("https://iad1.qualtrics.com/API/v3/directories/", directoryId,
"/mailinglists/",mailingListID ,"/contacts",sep = ""),
add_headers(`X-API-TOKEN` = apiToken), encode = "json")
fetch_url<-content(fetch_url, "parse",encoding = "UTF-8")
fetch_url<-fetch_url$result$nextPage
elements <- list()
while(!is.null(fetch_url)){
res<- VERB(verb = "GET", url = fetch_url,
add_headers(`X-API-TOKEN` = apiToken),
encode = "json")
res<-content(res, "parse",encoding = "UTF-8")
elements <- append(elements,res$result$elements)
fetch_url <- res$result$nextPage
}
return(elements)
}
I need to run following code
library(curl)
user= "GEAS"
password= "878282193100310"
content = paste("username=", user, "&password=", password, sep="")
h <- new_handle(copypostfields = content)
handle_setheaders(h,
"Content-Type" = "application/x-www-form-urlencoded"
)
handle_setopt(h, ssl_verifypeer = FALSE, ssl_verifyhost = FALSE)
However, this code stops at line when new_handle function is applied. When running this line I have following output
> h
<curl handle> (empty)
How can I make new_handle function work properly?
How would one set up logging each request to a different json file with RestRserve?
I tried using the lgr package (referred to in RestRserve's doc on logging) like so:
library(RestRserve)
library(lgr)
app = Application$new(content_type = "text/plain")
# RestRserve logger
app$logger = RestRserve::Logger$new(level = "trace", name = "mylogger",
printer=function(timestamp, level, logger_name, pid, message, ...)
{
lgr$log(level=tolower(level), msg=message, ...)
}
)
# JSON appender in lgr
tf <- tempfile(tmpdir="D:/temp", fileext=".log")
lgr$add_appender(AppenderJson$new(tf), name = "json")
# Endpoint
app$add_get("/sqrt", function(request, response) {
on.exit({
# Next log file
tf <- tempfile(tmpdir="D:/temp", fileext=".log")
lgr$appenders$json$set_file(tf)
})
app$logger$info(msg="", context=list(request_id = request$id, message="Process start"))
response$body = sqrt(x)
app$logger$info(msg="", context=list(request_id = request$id, message="Process end"))
})
# Submit request
request = Request$new(path = "/sqrt", method = "GET", parameters_query = list(x = "10"))
response = app$process_request(request)
But this splits up a request's log info across two files. I'm also quite sure it wouldn't work for simultaneous requests.
I believe you even don't need any special logger - just use writeLines. Also you can rely on req$id to name files since it is unique.
library(RestRserve)
req = Request$new()
res = Response$new()
fl = file.path(tempdir(), paste0(req$id, ".log"))
con = file(fl, open = "at")
writeLines("Process start", con)
res$set_body(sqrt(10))
writeLines("Process end", con)
close(con)
readLines(fl)
unlink(fl)
I used to code like this :
inets:start(),
ssl:start(),
ParaUrl = io_lib:format("http://xxx/passport?accessn=~s",[Access]),
ParaStr = io_lib:format("id=~p",[Id]),
RegUsr = httpc:request(post,{ParaUrl, [],"application/x-www-form-urlencoded", list_to_binary(ParaStr)},[],[])
but it's just for string not binary file, can anyone tell me how to post binary file with httpc:request?
It works for me:
{ok, F} = file:read_file("warning.gif"),
httpc:request(post,{Url, [],"multipart/form-data", F},[],[]).
I recieved on cowboy web server with function cowboy_req:body(Req):
{ok,<<71,73,70,56,57,97,11,0,11,0,230,64,0............>>,
{http_req,#Port<0.65562>,ranch_tcp,keepalive,<0.8736.0>,<<"POST">>,
'HTTP/1.1',
{{127,0,0,1},58154},
<<"localhost">>,undefined,8000,<<"/test1">>,
[<<"test1">>],
<<>>,undefined,[],
[{<<"content-type">>,<<"multipart/form-data">>},
{<<"content-length">>,<<"516">>},
{<<"te">>,<<>>},
{<<"host">>,<<"localhost:8000">>},
{<<"connection">>,<<"keep-alive">>}],
[{<<"content-length">>,516},
{<<"expect">>,undefined},
{<<"content-length">>,516},
{<<"connection">>,[<<"keep-alive">>]}],undefined,[],done,undefined,<<>>,true,waiting,[],<<>>,
undefined}}
Inspired by ActiveState recipe 146306 (and PYTHON HTTP POST BINARY FILE UPLOAD WITH PYCURL (PYTHON RECIPE)), altered by Formatting Multipart Formdata in Erlang. Thanks!
format_multipart_formdata(Boundary, Fields, Files) ->
FieldParts = lists:map(fun({FieldName, FieldContent}) ->
[lists:concat(["--", Boundary]),
lists:concat(["Content-Disposition: form-data; name=\"",atom_to_list(FieldName),"\""]),
"", FieldContent]
end, Fields),
FieldParts2 = lists:append(FieldParts),
FileParts = lists:map(fun({FieldName, FileName, FileContent}) ->
[lists:concat(["--", Boundary]),
lists:concat(["Content-Disposition: form-data; name=\"",atom_to_list(FieldName),"\"; filename=\"",FileName,"\""]),
lists:concat(["Content-Type: ", "application/octet-stream"]), "", FileContent]
end, Files),
FileParts2 = lists:append(FileParts),
EndingParts = [lists:concat(["--", Boundary, "--"]), ""],
Parts = lists:append([FieldParts2, FileParts2, EndingParts]),
string:join(Parts, "\r\n").
Usage:
{ok,BinStream} = file:read_file("./images/avatar.png"),
Data = binary_to_list(BinStream),
Boundary = "------WebKitFormBoundaryUscTgwn7KiuepIr1",
ReqBody = format_multipart_formdata(Boundary, [{uid,"123"}], [{avatar, "avatar", Data}]),
ContentType = lists:concat(["multipart/form-data; boundary=", Boundary]),
ReqHeader = [{"Content-Length", integer_to_list(length(ReqBody))}],
inets:start(),
ParaUrl = string:join(["http://www.example.com/avatar?access_token=",binary_to_list(token)],""),
RegUsr = httpc:request(post,{ParaUrl, ReqHeader,ContentType, ReqBody},[],[])