You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Julia Genie路由报unexpected end of input错误求助

问题描述

######################### ERROR STACKTRACE #########################
Expected end of input
Line: 0
Around: ...11092×16 DataFrame Row...

使用Julia的Genie框架编写路由时触发上述错误,但将路由内的代码单独在终端运行时,可正常生成包含证券标的信息的DataFrame。目标是将/tickers作为API后端,/send用于桌面应用调用。

原代码如下:

using Genie, Genie.Renderer.Json, Genie.Requests
using HTTP, JSON
using DataFrames

route("/tickers", method = POST) do
  message = jsonpayload()
#  (:echo => (message["message"] * " ") ^ message["repeat"]) |> json
    syms = HTTP.request("GET","https://acre.iex.cloud/v1/data/CORE/REF_DATA?token=pk_79891f5cbcce4099ae063588956f937a")
    schema_req = HTTP.request("GET","https://acre.iex.cloud/v1/data/CORE/REF_DATA?schema=true&token=pk_79891f5cbcce4099ae063588956f937a")
    sbs = syms.body |> String |> JSON.parse
    smat = sbs .|> values .|> collect |> (x->reduce(hcat,x)) |> (x->permutedims(DataFrame(x,:auto)))
    schema = schema_req.body |> String |> JSON.parse |> first |> keys |> collect
    rename!(smat,Symbol.(schema))
end

route("/send") do
  response = HTTP.request("POST", "http://localhost:8000/tickers", [("Content-Type", "application/json")], """{"exchanges":"XNYS", "type":"cs"}""")
  response.body |> String |> JSON.parse
end

up(async = false)
解决方案
  • 核心错误原因:Genie路由处理函数必须返回可被HTTP响应序列化的内容,当前/tickers路由最后返回的是DataFrame对象,Genie无法直接将其转换为合法的HTTP响应体,导致解析出错。
  • 修复步骤:
    1. 在/tickers路由末尾,将DataFrame转换为JSON格式返回,使用Genie提供的json()函数完成序列化。
    2. 利用请求传入的exchanges和type参数,给API请求添加过滤条件,避免获取全量数据(原代码未使用传入参数,全量数据会增大响应体积)。
    3. 合并两次API请求为一次,直接从返回数据的第一个元素提取列名,减少冗余请求。

修改后的代码示例:

using Genie, Genie.Renderer.Json, Genie.Requests
using HTTP, JSON
using DataFrames

route("/tickers", method = POST) do
  # 获取请求参数,设置默认值避免参数缺失
  payload = jsonpayload()
  exchanges = get(payload, "exchanges", "")
  ticker_type = get(payload, "type", "")

  # 构造带过滤条件的API请求URL
  api_token = "pk_79891f5cbcce4099ae063588956f937a"
  query_params = Dict(
    "token" => api_token,
    "exchanges" => exchanges,
    "type" => ticker_type
  )
  # 拼接非空的查询参数
  query_str = join(["$k=$v" for (k,v) in query_params if !isempty(v)], "&")
  api_url = "https://acre.iex.cloud/v1/data/CORE/REF_DATA?$query_str"

  # 调用API并处理数据
  syms_response = HTTP.request("GET", api_url)
  sbs = syms_response.body |> String |> JSON.parse

  if !isempty(sbs)
    # 直接从返回数据提取列名并构造DataFrame
    df = DataFrame(sbs)
    # 返回JSON格式响应,自动设置正确的Content-Type头
    return json(df)
  else
    # 返回空数据的兜底响应
    return json(Dict("data" => []))
  end
end

route("/send") do
  response = HTTP.request("POST", "http://localhost:8000/tickers", [("Content-Type", "application/json")], """{"exchanges":"XNYS", "type":"cs"}""")
  # 将响应转换为JSON格式返回
  return json(response.body |> String |> JSON.parse)
end

up(async = false)
  • 额外说明:
    • json()函数是Genie的响应渲染工具,会自动处理序列化和HTTP头设置,确保客户端能正确解析。
    • 新增参数默认值,避免请求参数缺失时API调用出错。
    • 移除了单独请求schema的逻辑,直接从返回数据提取列名,提升效率。

内容的提问来源于stack exchange,提问作者Ethan Leonard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 06:02:03