【问题标题】:Issue with API callAPI调用问题
【发布时间】:2018-09-28 10:30:03
【问题描述】:

我正在尝试使用以下方法将一些数据点发送到 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 命令中使用它。有什么解决这个问题的建议吗?

【问题讨论】:

    标签: r post httr


    【解决方案1】:

    我没有 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 接口的包时传递它们。

    【讨论】:

    • 感谢您的 cmets。我喜欢卷曲转换器的想法。
    【解决方案2】:

    找到了解决办法。这是对 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****")
    )
    

    感谢您的帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-31
      • 2016-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多