欢迎回到 dora
教程!到目前为止,我们已经学习了
数据流 作为应用程序蓝图
事件流 作为其通信通道
数据消息/Arrow Data 作为高效数据传输的格式。
现在,我们来谈谈如何实际编写这些节点和操作符的代码 ,让它们完成各自的工作。你用 Python
或 Rust
编写的自定义逻辑如何连接到 dora 运行时
来接收输入并发送输出?这时, API Binding
绑定 就派上用场了。
假设你用 Python
设计了一个很棒的物体检测算法。你想把它包装在一个 dora
节点中,这样它就可以从摄像头节点接收图像,并将检测结果发送到绘图节点,所有这些都按照你的 Dataflow YAML
文件中的定义进行。
您的 Python
代码需要特定的工具来:
dora
运行时它已准备好启动。INPUT
事件。dora
运行时发送了 STOP
信号,则知道何时停止。这些工具以库或模块的形式提供给不同的编程语言,它们被称为 API 绑定
。它们是连接自定义应用程序逻辑和 dora 运行时
环境的软件层。
将 API 绑定
视为:
dora
运行时可以理解的低级消息和协议。send_output
、 next
、 on_event
等),简化与 dora
核心机制(如事件流和数据消息处理)的交互。dora
为多种语言提供了 API 绑定
,包括 Rust
、Python
、C
和 C++
。因此,您可以在同一个数据流中混合搭配使用不同语言编写的节点,只要它们使用各自语言的 dora API 绑定
进行通信即可。
API 绑定
提供的核心功能无论使用哪种语言, dora API 绑定
通常都会提供用于以下基本任务的函数或方法:
Node/Operator
代码连接到正在运行的 dora
数据流实例的函数。此步骤对于运行时识别组件并设置其通信通道至关重要。INPUT
、 STOP
、 InputClosed
等)。Apache Arrow
进行结构化)。event["value"]
)和可选 metadata
( event["metadata"]
)。STOP
等控制事件的内置处理或清晰的通知机制。API 绑定
:代码示例让我们看一下使用 Python API
绑定( dora-rs
库)的简化示例,这是 AI
和数据处理任务的常见选择。
API
的简单 Python
节点这与我们在Node
中看到的结构类似,但现在重点关注 API
调用本身:
from dora import Node
:从 API 绑定
导入必要的类。node = Node()
:初始化与 dora
运行时的连接。运行时使用启动期间设置的环境变量(基于你的 Dataflow YAML
)来识别此节点。for event in node
: 这是接收事件的核心。API
会处理阻塞,直到下一个事件在事件流中可用,并以结构化格式(类似 Python
字典)提供。event["type"]
, event["id"]
, event["value"]
:访问已接收事件的详细信息。API
提供以下标准键。node.send_output("my_output", processed_data)
:调用 API
函数发送数据。您需要指定 Dataflow YAML
中定义的输出 ID 和数据负载。API
负责格式化数据(如果需要,例如,格式化为 Arrow
格式),可能还会使用共享内存 ,并通知运行时。API
的简单 Python
运算符操作符使用稍微不同的 API
结构,专门设计用于 dora-runtime
进程。
from dora import DoraStatus
:导入必要的状态值来向运行时发出信号(例如, DoraStatus.CONTINUE
, DoraStatus.STOP
)。class Operator
: 在 Python
中定义运算符的标准方法。on_event(self, dora_event, send_output)
: dora-runtime
期望此特定的方法签名。运行时调用此方法,并传递事件详情( dora_event
)以及特定于此运算符实例的 send_output
函数。dora_event["type"] 、 dora_event["id"] 、 dora_event["value"]
:访问事件详细信息,类似于 Node API
,但通常直接作为参数提供或嵌套在事件对象中。send_output("operator_output", processed_data, dora_event["metadata"])
:调用提供的函数来从此特定运算符发送输出数据。然后,运行时会根据数据流 YAML
将此输出路由到同一节点内的其他运算符,或者路由到节点外的其他运算符。return DoraStatus.CONTINUE / DoraStatus.STOP
:操作符在处理事件后明确向运行时返回状态,指示它们是否应该继续或停止。您可以在 Rust
绑定( dora-node-api
、 dora-operator-api
)和 C/C++
绑定(通过 CXX
和原始 C FFI
公开,参见 apis/rust/node/src/lib.rs
、 apis/c++/node/src/lib.rs
、 apis/c/node/src/lib.rs
)中看到类似的 API
结构和概念。它们提供了针对特定语言范式定制的相同基本功能(初始化、接收、发送、处理信号)。
API
绑定那么,当您调用 node.send_output(...)
或 send_output(...)
时会发生什么?
API 绑定库
本身并不实现整个 dora
通信逻辑。相反,它与启动节点或操作员的 dora
运行时进程( Dora Daemon/Coordinator
)进行通信。
当你的 Node/Operator
进程启动时, dora 运行时
会设置高效的通信渠道:
dora 运行时
向你的 Node/Operator
发送事件的地方(即事件流 )。API
绑定的事件循环( for event in node
)正在监听此通道。dora 运行时
发送命令的地方(例如“发送此输出”、“我已完成此共享内存块的操作”)。API
绑定的 send_output
函数使用此通道。这是一个简化的序列图:
API 绑定
隐藏了这些通道和协议的复杂性,让您可以专注于应用程序逻辑。它将您语言的数据类型转换为适合 dora
的格式(例如 Arrow
),并管理高效通信所需的低级交互。
Rust
和 C++ API 绑定
通常会暴露底层细节或允许更细粒度的控制以提高性能,而 Python
绑定则优先考虑易用性。但它们的根本目的都是为你的自定义代码提供一种结构化的方式,以便与 dora
运行时进行通信。
API 绑定
是必不可少的软件库,它使您能够使用熟悉的编程语言(例如 Python
、Rust
、C
和 C++
)为自定义 dora
节点和操作符编写核心逻辑。它们提供了标准化的函数工具包( init
、 send_output
、事件循环/回调
),这些函数抽象了进程间通信、共享内存和事件处理的复杂性,使您可以专注于特定的应用程序任务,同时无缝集成到 dora
数据流中。
现在您已经了解了如何使用 API 绑定
为各个组件编写代码,让我们缩小范围并查看用于管理和运行整个数据流的主要工具: Dora CLI 命令行
。