我正在尝试使用以下方法将一些数据点发送到Web api。 (不确定是否要共享密钥,因此我将其中的一部分遗漏了。)
library(jsonlite)
library(httr)
url = "https://api.marketcycles.online/api/CycleScanner"
t <- 1:101
val <- 2*sin(2*pi*t/25) + 5*cos(2*pi*t/50)
val[1:3]
body.list <- list(datapoints = val)
query.list <- list(api_Key = "wtt****")
res <- POST(url = url, query = query.list, body = body.list,
encode = "json")
a <- content(res, as = "text")
b <- fromJSON(a)
b[[2]]
这将导致错误“对象引用未设置为对象的实例”
以下curl命令有效(我已经编辑了大部分数据点)
curl -X POST --header 'Content-Type: application/json' \
--header 'Accept: application/json' \
-d '[5.458,5.8064,6.018,....5,5.458]' \
'https://api.marketcycles.online/api/CycleScanner?api_Key=wtt****'
关于使POST命令起作用的任何建议吗?
感谢您的回答hrbrmstr。非常感激。 我尝试了以下
httr::POST(
url = "https://api.marketcycles.online/api/CycleScanner",
httr::content_type_json(),
httr::accept_json(),
encode = "json",
body = jsonlite::toJSON(val),
query = list(
amplitudeMulti = "1.0",
bartelsLimit = "49",
minCycleLength = "5",
maxCycleLength = "300",
sortByStrength = "true",
includeSpectrum = "false",
humanReadableText = "false",
api_Key = "wtt****")
)
带有和不带有content_type_jason()的行,并且在两种情况下都收到以下错误
b[[1]]
[1] "The request contains an entity body but no Content-Type header. The
inferred media type 'application/octet-stream' is not supported for this
resource."
b[[2]]
[1] "No MediaTypeFormatter is available to read an object of type
'Double[]' from content with media type 'application/octet-stream'."
b[[3]]
[1] "System.Net.Http.UnsupportedMediaTypeException"
据我了解,当主体是列表时,encode()提供列表元素的格式。我不清楚在不这样做时该怎么办。我查看了httr源,其中有一个未记录的函数body_config,但不确定在POST命令中使用它。有解决此问题的建议吗?
答案 0 :(得分:0)
我没有API密钥(并且您100%正确地不共享您的密钥),但是他们的Swagger API Docs有点说谎他们期望作为输入。
我在他们提供的在线Swagger测试器中对该端点使用了伪造的API密钥(知道它会失败,但仍显示curl
行),并填充了默认值,以全面了解端点的期望并把它退了回来(格式化是我的,它回来了整整一行):
curl
-X POST
--header 'Content-Type: application/json'
--header 'Accept: application/json'
-d '[5.458,5.8064,6.018,6.0702,5.9472,5.6409,5.1517,4.4888,3.6699,2.7207,1.6732,0.5646,-0.5646,-1.6732,-2.7207,-3.6699,-4.4888,-5.1517,-5.6409,-5.9472,-6.0702,-6.018,-5.8064,-5.458,-5,-4.4632,-3.8794,-3.2798,-2.6929,-2.143,-1.6488,-1.2225,-0.8695,-0.5879,-0.3695,-0.2007,-0.0633,0.0633,0.2007,0.3695,0.5879,0.8695,1.2225,1.6488,2.143,2.6929,3.2798,3.8794,4.4632,5,5.458,5.8064,6.018,6.0702,5.9472,5.6409,5.1517,4.4888,3.6699,2.7207,1.6732,0.5646,-0.5646,-1.6732,-2.7207,-3.6699,-4.4888,-5.1517,-5.6409,-5.9472,-6.0702,-6.018,-5.8064,-5.458,-5,-4.4632,-3.8794,-3.2798,-2.6929,-2.143,-1.6488,-1.2225,-0.8695,-0.5879,-0.3695,-0.2007,-0.0633,0.0633,0.2007,0.3695,0.5879,0.8695,1.2225,1.6488,2.143,2.6929,3.2798,3.8794,4.4632,5,5.458]'
'https://api.marketcycles.online/api/CycleScanner?amplitudeMulti=1.0&bartelsLimit=49&minCycleLength=5&maxCycleLength=300&sortByStrength=true&includeSpectrum=false&humanReadableText=false&api_Key=aaaa'
这表明文档在暗示datapoints
值被命名时在撒谎。不是。这可能是导致您出错的原因。
我通过curlconverter
运行了生成的原始curl
命令行,并将其作为httr
模板提供了>
httr::VERB(
verb = "POST",
url = "https://api.marketcycles.online/api/CycleScanner",
httr::add_headers(Accept = "application/json"),
body = "[5.458,5.8064,6.018,6.0702,5.9472,5.6409,5.1517,4.4888,3.6699,2.7207,1.6732,0.5646,-0.5646,-1.6732,-2.7207,-3.6699,-4.4888,-5.1517,-5.6409,-5.9472,-6.0702,-6.018,-5.8064,-5.458,-5,-4.4632,-3.8794,-3.2798,-2.6929,-2.143,-1.6488,-1.2225,-0.8695,-0.5879,-0.3695,-0.2007,-0.0633,0.0633,0.2007,0.3695,0.5879,0.8695,1.2225,1.6488,2.143,2.6929,3.2798,3.8794,4.4632,5,5.458,5.8064,6.018,6.0702,5.9472,5.6409,5.1517,4.4888,3.6699,2.7207,1.6732,0.5646,-0.5646,-1.6732,-2.7207,-3.6699,-4.4888,-5.1517,-5.6409,-5.9472,-6.0702,-6.018,-5.8064,-5.458,-5,-4.4632,-3.8794,-3.2798,-2.6929,-2.143,-1.6488,-1.2225,-0.8695,-0.5879,-0.3695,-0.2007,-0.0633,0.0633,0.2007,0.3695,0.5879,0.8695,1.2225,1.6488,2.143,2.6929,3.2798,3.8794,4.4632,5,5.458]",
encode = "json",
query = list(
amplitudeMulti = "1.0",
bartelsLimit = "49",
minCycleLength = "5",
maxCycleLength = "300",
sortByStrength = "true",
includeSpectrum = "false",
humanReadableText = "false",
api_Key = "aaaa"
)
)
它比以编程方式生成的必需b / c更为冗长。使其适合您的原始代码:
httr::POST(
url = "https://api.marketcycles.online/api/CycleScanner",
httr::accept_json()
encode = "json",
body = jsonlite::toJSON(val),
query = list(
amplitudeMulti = "1.0",
bartelsLimit = "49",
minCycleLength = "5",
maxCycleLength = "300",
sortByStrength = "true",
includeSpectrum = "false",
humanReadableText = "false",
api_Key = "aaaa"
)
)
可能有效。同样,我只是经过Swagger而无法对其进行测试。您也可以在query
位中删除所有默认值。我喜欢在构建与API接口的软件包时传递它们。
答案 1 :(得分:0)
找到了解决方案。这是hrbrmstr建议的代码的几处调整。 以下代码有效
httr::POST(
url = "https://api.marketcycles.online/api/CycleScanner",
httr::content_type_json(), # needed to add this
httr::accept_json(),
body =jsonlite::toJSON(val),
# encode = "json", # needed to delete this
query = list(
amplitudeMulti = "1.0",
bartelsLimit = "49",
minCycleLength = "5",
maxCycleLength = "300",
sortByStrength = "true",
includeSpectrum = "false",
humanReadableText = "false",
api_Key = "wtt****")
)
感谢您的帮助。