如何获取 ndjson 响应流
How to get a stream of a ndjson response
我正在尝试连接到 http API。 API 以 ndjson 响应,这是一个换行符分隔的 json 字符串。在我全部下载它们之前,我需要一条一条地使用这些行(事实上,甚至在服务器知道它将在未来的行中输出什么之前)。
在 Python 中,我可以通过以下方式实现:
import requests, json
lines = requests.get("some url", stream=True).iter_lines()
for line in lines:
#parse line as JSON and do whatever
而且效果很好。
我想在 Nim 中完成相同的效果,但程序阻塞。例如,我试图只加载响应的第一行:
import httpclient, json, streams
var stream = newHttpClient().get("some url").bodyStream
var firstLine = ""
discard stream.readLine(firstLine )
echo firstLine
但运气不好 - 也就是说,程序从不回显。
我也尝试了 streams.lines
迭代器,但这也没有帮助。
有没有类似于 Python snipet 的习惯用法,可以让我轻松地逐行处理 http 响应流?
解决方案是使用@pietroppeter 链接的问题中的net
模块。这最初对我不起作用,因为我没有正确构造 HTTP 请求。
结果代码:
import net, json
const HOST = "host"
const TOKEN = "token"
iterator getNdjsonStream(path: string): JsonNode =
let s = newSocket()
wrapSocket(newContext(), s)
s.connect(HOST, Port(443))
var req = &"GET {path} HTTP/1.1\r\nHost:{HOST}\r\nAuthorization: {TOKEN}\r\n\r\n"
s.send(req)
while true:
var line = ""
while line == "" or line[0] != '{':
line = s.recvLine
yield line.parseJson
我认为使用 httpClient
模块无法实现这一点。异步版本可能看起来他们可以做到,但在我看来,你只能在 Future 完成后才能处理接收到的数据,即在所有数据下载之后。
事实上,这样一个简单的想法无法简单地完成,而且缺乏我能找到的例子,这导致了几天的挫败感,并且在 10 年的编程之后需要开设一个 Whosebug 帐户。
我正在尝试连接到 http API。 API 以 ndjson 响应,这是一个换行符分隔的 json 字符串。在我全部下载它们之前,我需要一条一条地使用这些行(事实上,甚至在服务器知道它将在未来的行中输出什么之前)。 在 Python 中,我可以通过以下方式实现:
import requests, json
lines = requests.get("some url", stream=True).iter_lines()
for line in lines:
#parse line as JSON and do whatever
而且效果很好。
我想在 Nim 中完成相同的效果,但程序阻塞。例如,我试图只加载响应的第一行:
import httpclient, json, streams
var stream = newHttpClient().get("some url").bodyStream
var firstLine = ""
discard stream.readLine(firstLine )
echo firstLine
但运气不好 - 也就是说,程序从不回显。
我也尝试了 streams.lines
迭代器,但这也没有帮助。
有没有类似于 Python snipet 的习惯用法,可以让我轻松地逐行处理 http 响应流?
解决方案是使用@pietroppeter 链接的问题中的net
模块。这最初对我不起作用,因为我没有正确构造 HTTP 请求。
结果代码:
import net, json
const HOST = "host"
const TOKEN = "token"
iterator getNdjsonStream(path: string): JsonNode =
let s = newSocket()
wrapSocket(newContext(), s)
s.connect(HOST, Port(443))
var req = &"GET {path} HTTP/1.1\r\nHost:{HOST}\r\nAuthorization: {TOKEN}\r\n\r\n"
s.send(req)
while true:
var line = ""
while line == "" or line[0] != '{':
line = s.recvLine
yield line.parseJson
我认为使用 httpClient
模块无法实现这一点。异步版本可能看起来他们可以做到,但在我看来,你只能在 Future 完成后才能处理接收到的数据,即在所有数据下载之后。
事实上,这样一个简单的想法无法简单地完成,而且缺乏我能找到的例子,这导致了几天的挫败感,并且在 10 年的编程之后需要开设一个 Whosebug 帐户。