Skip to main content

node-api-python

Use for Python dora node development questions. Triggers on: dora.Node, python node, dora-rs python, event type, INPUT, STOP, send_output, for event in node, python dataflow, Python节点, Python API, dora python

معلومات المصدر

المستودع
ZhangHanDong/dora-skills
آخر نشاط في المصدر
٢١ يناير ٢٠٢٦ في ١٦:١٦
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٧
التفرعات
١

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
node-api-python
description
Use for Python dora node development questions. Triggers on: dora.Node, python node, dora-rs python, event type, INPUT, STOP, send_output, for event in node, python dataflow, Python节点, Python API, dora python
globs
["**/*.py"]
source
https://dora-rs.ai/docs/guides/getting-started/conversation_py/
# Python Node API > Complete guide to building dora nodes in Python ## Installation ```bash pip install dora-rs ``` ## Basic Usage ```python from dora import Node node = Node() for event in node: if event["type"] == "INPUT": input_id = event["id"] data = event["value"] # numpy array or pyarrow array metadata = event["metadata"] # Process data... # Send output node.send_output("output_id", data) elif event["type"] == "STOP": break ``` ## Event Types ```python event = { "type": "INPUT" | "STOP" | "INPUT_CLOSED" | "ERROR", "id": "input_name", # For INPUT events "value": data, # numpy/pyarrow array "metadata": {...}, # Timestamp, type info "error": "message", # For ERROR events } ``` ### Handling Events ```python from dora import Node node = Node() for event in node: match event["type"]: case "INPUT": handle_input(event["id"], event["value"]) case "INPUT_CLOSED": print(f"Input {event['id']} closed") case "STOP": print("Stopping...") break case "ERROR": print(f"Error: {event['error']}") ``` ## Sending Outputs ### NumPy Arrays ```python import numpy as np # Integer array data = np.array([1, 2, 3], dtype=np.int32) node.send_output("numbers", data) # Float array data = np.array([1.0, 2.5, 3.14], dtype=np.float64) node.send_output("floats", data) # Image (HWC format) image = np.zeros((480, 640, 3), dtype=np.uint8) node.send_output("image", image) ``` ### PyArrow Arrays ```python import pyarrow as pa # String array data = pa.array(["hello", "world"]) node.send_output("text", data) # Struct array (for complex data) data = pa.array([{ "x": 1.0, "y": 2.0, "label": "point" }]) node.send_output("point", data) ``` ### With Metadata ```python metadata = { "watermark": 1000, "deadline": 5000, } node.send_output("data", array, metadata) ``` ## Complete Examples ### Camera Node ```python # camera_node.py import cv2 import numpy as np from dora import Node node = Node() cap = cv2.VideoCapture(0) for event in node: if event["type"] == "INPUT" and event["id"] == "tick": ret, frame = cap.read() if ret: # Convert BGR to RGB frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) node.send_output("image", frame_rgb) elif event["type"] == "STOP": break cap.release() ``` ### Processing Node ```python # processor_node.py import numpy as np from dora import Node node = Node() for event in node: if event["type"] == "INPUT": if event["id"] == "image": image = event["value"] # Process image gray = np.mean(image, axis=2).astype(np.uint8) node.send_output("processed", gray) elif event["type"] == "STOP": break ``` ### Detection Node ```python # detector_node.py import numpy as np import pyarrow as pa from dora import Node from ultralytics import YOLO node = Node() model = YOLO("yolov8n.pt") for event in node: if event["type"] == "INPUT" and event["id"] == "image": image = event["value"] # Run detection results = model(image) # Convert to bounding boxes boxes = [] for r in results: for box in r.boxes: boxes.append({ "x1": float(box.xyxy[0][0]), "y1": float(box.xyxy[0][1]), "x2": float(box.xyxy[0][2]), "y2": float(box.xyxy[0][3]), "confidence": float(box.conf[0]), "class": int(box.cls[0]), }) node.send_output("bbox", pa.array(boxes)) elif event["type"] == "STOP": break ``` ## Dataflow Configuration ```yaml nodes: - id: camera path: camera_node.py inputs: tick: dora/timer/millis/33 outputs: - image - id: processor path: processor_node.py inputs: image: camera/image outputs: - processed - id: detector path: detector_node.py inputs: image: camera/image outputs: - bbox ``` ## Async Python (Experimental) ```python import asyncio from dora import Node async def main(): node = Node() async for event in node: if event["type"] == "INPUT": # Async processing result = await process_async(event["value"]) node.send_output("result", result) elif event["type"] == "STOP": break asyncio.run(main()) ``` ## Environment Variables Access environment variables from dataflow config: ```python import os model_path = os.environ.get("MODEL_PATH", "default.pt") device = os.environ.get("DEVICE", "cpu") ``` ## Best Practices 1. **Use NumPy for numerical data** - Native support, zero-copy when possible 2. **Use PyArrow for structured data** - Complex types, nested structures 3. **Handle STOP events** - Clean up resources properly 4. **Check input IDs** - Multiple inputs may arrive 5. **Use environment variables** - Keep config in YAML ## Debugging ### Interactive Mode Run node directly for testing: ```bash python my_node.py ``` Without `DORA_NODE_CONFIG` set, the node enters interactive mode where you can manually provide inputs. ### Logging ```python import logging logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) for event in node: logger.debug(f"Received event: {event['type']}") ``` ## Related Skills - **dataflow-config** - YAML configuration - **node-api-rust** - Rust alternative - **hub-nodes** - Pre-built Python nodes
عرض على GitHub