跳到主要内容

Python SDK 概述

Darra AI SDK 的 Python 绑定。只翻译 C ABI 的类型和错误码,零密码学、零容器格式逻辑。cffi 只走 ABI 模式ffi.dlopen),不编译任何 C 扩展。

权威契约:Core/include/darra_ai.h。语义冲突时以头文件为准。包版本 1.0.0,与 __version__ / pyproject.toml 一致。

from darra_ai import Session

import darra_ai 加载 native。第一次调用碰 Core 的 API(Session.open / runtime.ensure / diagnostics.collect / version() / authoring.*)才 dlopen

安装

pip install darra-ai
分发名与导入名

PyPI 分发名为 darra-aipip install 用此名),代码内导入名为 darra_aifrom darra_ai import Session)。两者是独立概念(PEP 427),不要混用。

开发树(Darra.AI.Studio.SDK/Python/):

pip install -e .

依赖 cffi>=1.15。wheel 按平台内嵌 darra_ai/_native/<plat>/darraai_core.dll|so。本仓库此时尚未发布 native,get_lib() 会抛 DarraLoadError

找不到库时按顺序找:

  1. 包内 _native/<平台>/
  2. 环境变量 DARRA_AI_CORE_PATH(文件或目录)
  3. 系统加载器搜索路径

平台目录名:win_amd64 / linux_x86_64 / linux_aarch64

Windows 库名候选:darraai_core.dllDarraAI.Core.dll。Linux:darraai_core.solibdarraai_core.so

加载后立即核 ABI:darra_version() 的 major 必须等于 1,不等抛 DarraLoadError,禁止继续调用。

环境要求

项目要求
操作系统Windows x64 / Linux x86_64 / Linux ARM64(RK3588)
Python≥ 3.10(cffi ABI 模式,同一份纯 Python 不按解释器版本拆 wheel)
依赖cffi ≥ 1.15
nativeDarraAI.Core(wheel 内嵌或 DARRA_AI_CORE_PATH
不在 v1macOS、32 位

快速开始

from darra_ai import Session, runtime

runtime.ensure() # None = 按硬件自动选 Provider 包

with Session.open("model.darmodel", key_path="model.darmkey") as s:
print(s.meta())
jpg = open("photo.jpg", "rb").read()
print(s.infer_image(jpg))

明文 ONNX(Studio 试跑 / 客户自有未加密模型)走同一推理路径:

with Session.open_plain("model.onnx") as s:
print(s.infer_image(jpg))

工业相机裸缓冲:

from darra_ai import IMAGE_BGR888

result = s.infer_image(frame, format=IMAGE_BGR888, width=1920, height=1080)

Session 可作上下文管理器,退出 with 块时自动 close()。完整脚本见 SDK 树 examples/infer_image.py

类别与访问

数据用属性,不用 get_xxx()。下表覆盖 darra_ai 公开符号(__all__ + 三个子模块函数)。_ffi / _util 不是公开 API。

类别成员类型访问说明
图像格式IMAGE_AUTOint(0)常量编码图自动嗅探
IMAGE_ENCODEDint(1)常量已编码 JPG/PNG/BMP 字节流
IMAGE_RGB888int(2)常量裸 RGB888 像素
IMAGE_BGR888int(3)常量裸 BGR888 像素
版本version()tuple[int, int, int]方法(major, minor, patch)。会加载 native
version_string()str方法形如 1.0.0+runtime / 1.0.0+authoring。会加载 native
会话打开Session.openSession方法打开加密容器 .darmodel(DARM1)
Session.open_plainSession方法打开明文 .onnx;跳过容器解码与验票
Session.open_exSession方法可扩展入口,当前翻译到 open
Session.closeNone方法关闭会话。重复 close / 未打开均为 no-op
会话元信息meta()dict方法会话元信息 JSON 对象(有缓存)
taskstr | None只读detect / classify / segment / pose / ocr / anomaly。缺席为 None
labelslist[str]只读类别标签。缺席或非数组则为空列表
input_widthint只读模型输入宽。未知为 0
input_heightint只读模型输入高。未知为 0
channelsint只读模型输入通道数。未知为 0
layoutstr | None只读张量布局(如 NCHW / NHWC)。先读 input.layout,再读顶层 layout
payload_kindstr | None只读onnx / trt-engine / openvino / rknn
provider_idstr | None只读实际选中的 Provider ID(不是 prefer 入参)
encryptedbool只读是否加密容器会话。明文 ONNX 为 False
推理infer_imagedict方法对一张图跑推理,返回结果 JSON 对象
会话选项SessionOptions.key_pathstr | None读写授权文件路径。构造本对象不加载 native
SessionOptions.passwordstr | None读写密码通道
SessionOptions.prefer_providerstr | None读写指名 Provider;None = 自动选
运行时runtime.ensureNone方法确保 Provider / profile 已装好
runtime.cancelNone方法取消当前在飞的 ensure。无在飞操作为 no-op
诊断diagnostics.collectdict方法本机环境自检 JSON。禁止在 PLC 扫描周期等实时路径调用
authoringauthoring.encrypt_onnxNone方法明文 .onnx.darmodel。仅 authoring 构建
authoring.issue_keyNone方法签发 .darmkey。仅 authoring 构建
authoring.fingerprint_perturbNone方法逐客户权重扰动。仅 authoring 构建
错误DarraError.codeint | None只读darra_error_code;绑定侧错误为 None
DarraError.messagestr只读错误描述
DarraError.hintstr只读修复建议,与 错误码目录 一致

只读属性全部从 meta() 的附录 B JSON 派生。

会话

Session.open

@classmethod
def open(
cls,
container_path: str,
*,
key_path: str | None = None,
password: str | None = None,
prefer_provider: str | None = None,
) -> Session

打开加密容器(.darmodel,DARM1)建会话。

参数类型默认说明
container_pathstr容器路径,不能为空
key_pathstr | NoneNone授权文件
passwordstr | NoneNone密码通道
prefer_providerstr | NoneNone指名 Provider

key_pathpassword 至少给一个;都给则 key 文件优先验票。prefer_provider 为 None 时按 载荷 × 硬件 × 已装包 自动选;指名但不可用 = fail-closed,绝不静默降级。

Session.open_plain

@classmethod
def open_plain(
cls,
onnx_path: str,
*,
prefer_provider: str | None = None,
) -> Session

打开明文 .onnx 建会话。与 open 同一推理路径,只跳过容器解码与验票。训练格式(.pt / .pth / Paddle)不是运行时载荷,Core 报 DARRA_UNSUPPORTED_PAYLOAD

Session.open_ex

@classmethod
def open_ex(
cls,
container_path: str,
options: SessionOptions | None = None,
) -> Session

可扩展入口,对齐 C# OpenExoptions 为 None 时等同全部可选通道为空。当前翻译到 open;Core 追加 darra_session_open_ex 后只换调用点。

Session.infer_image

def infer_image(
self,
image_bytes: bytes | bytearray | memoryview,
*,
format: int = IMAGE_AUTO,
width: int = 0,
height: int = 0,
stride: int = 0,
) -> dict
参数类型默认说明
image_bytesbytes / bytearray / memoryview图像字节
formatintIMAGE_AUTO见图像格式常量
widthint0裸缓冲必须 >0
heightint0裸缓冲必须 >0
strideint00 = 紧凑排列(width × 3)

IMAGE_AUTO / IMAGE_ENCODEDimage_bytes 为 JPG/PNG/BMP 编码字节流,忽略宽高。IMAGE_RGB888 / IMAGE_BGR888:裸像素,必须给 width/height;缺宽高或未知 format 抛 InternalError(码 18)。

返回结果 JSON 对象。会话已关闭再调抛 InternalError

Session.close

def close(self) -> None

关闭会话并释放全部资源。重复 close / 未打开均为 no-op。也实现 __enter__ / __exit__

运行时

runtime.ensure

def ensure(
profile_or_provider_id: str | None = None,
offline_zip: str | None = None,
progress: Callable[[float, str], None] | None = None,
) -> None

确保指定 Provider / profile 已装好;没装就探测→选包→下载→校验→解压登记。已装且清单匹配 → 直接成功。进程内互斥串行。取消或失败不留半成品。

参数类型默认说明
profile_or_provider_idstr | NoneNone细包 ID 或场景整合包名;None = 按硬件自动选
offline_zipstr | NoneNone本地离线整合包 zip;None = 在线下载
progress回调 | NoneNone(percent, stage)。percent 为 0..100;stage 为 probe / manifest / download / verify / install / done

进度回调在 SDK 工作线程触发,回调内禁止再调任何 Darra AI API(含 cancel)。回调异常被吞掉,以免穿越 C 边界崩进程。

runtime.cancel

def cancel() -> None

请求取消当前在飞的 ensure(任意线程可调;进度回调内禁止)。没有在飞的 ensure 时为 no-op。被取消的 ensureCancelledError

诊断

diagnostics.collect

def collect() -> dict

采集本机环境诊断,返回 JSON 对象。尽力而为:单个字段采不到时为 null 或缺席,整体不失败。去敏:不含密钥 / 密码 / token / 机器指纹字节。可能触发 WMI / NVML / sysfs,耗时数百毫秒,禁止在 PLC 扫描周期等实时路径调用

authoring

encrypt_onnx / issue_key / fingerprint_perturb 只随 AI Studio 的 authoring 构建导出。客户机 runtime 包物理上没有这些符号;访问时 cffi 抛 AttributeError,由 authoring.py 包装成 DarraErrorcode 为 None)。不是权限开关,是物理隔离。

调用顺序:fingerprint_perturbencrypt_onnxissue_key。扰动必须发生在加密前。

authoring.encrypt_onnx

def encrypt_onnx(onnx_path: str, out_container_path: str) -> None

明文 .onnx 加密打包成 .darmodel(DARM1)。

authoring.issue_key

def issue_key(
container_path: str,
out_key_path: str,
*,
password: str | None = None,
bind_machine: bool = False,
trial_runs: int = 0,
) -> None

为容器签发 .darmkey(DARMK2)。password 为 None = 本授权不启用密码通道。bind_machine=True 绑定签发时的机器指纹。trial_runs>0 为试用计次;0 = 永久授权。

authoring.fingerprint_perturb

def fingerprint_perturb(
onnx_path: str,
out_onnx_path: str,
customer_seed: int,
) -> None

逐客户权重扰动指纹(盗版溯源,不是防 dump)。同一 customer_seed 永远产出同一份扰动结果。必须在 encrypt_onnx 之前调用。

错误

失败时抛 DarraError 子类(code / message / hint)。hint 文案与 错误码目录 一致,可原样展示给最终用户。native 找不到或 ABI 主版本不是 1 时抛 DarraLoadErrorcode 为 None)。

exception_for_code(code, message, hint="") 按码构造对应子类;未知新码兜底为 DarraError 基类,code 原样保留。

异常说明
DarraError基类。绑定侧错误 code 为 None
DarraLoadErrorNonenative 加载失败或 ABI 不匹配
IoNotFoundError1文件不存在
IoDeniedError2文件存在但读写被拒
BadContainerError3.darmodel 损坏 / 非 DARM1
BadLicenseError4.darmkey 损坏或与容器不配对
PasswordRequiredError5需要密码但没给
PasswordWrongError6密码错误
MachineMismatchError7绑机授权用在非目标机器
TrialExhaustedError8试用计次已用完
UnsupportedPayloadError9载荷类型当前平台/Provider 不支持
UnsupportedPlatformError10OS/架构不在支持矩阵
ProviderMissingError11运行时 Provider 包未安装
ProviderAbiMismatchError12Provider 包与 Core ABI 不匹配
HardwareMissingError13未探测到所需硬件
DriverTooOldError14驱动版本低于 Provider 要求(SDK 不代装)
NetworkFailedError15清单 / 运行时包下载失败
ChecksumMismatchError16下载包或离线包 sha256 校验不过
CancelledError17ensure 被取消
InternalError18SDK 内部错误;也用于调用方参数契约违反
try:
with Session.open("model.darmodel", key_path="model.darmkey") as s:
s.infer_image(jpg)
except DarraError as ex:
print(ex) # [码] 描述 | 建议: hint

诚实边界

  • 不承诺 dump 免疫:授权机 + 管理员级调试器在会话存活期暂停 dump 挡不住。本 SDK 防的是静态拷走 / 转发 / 无授权运行 / 常规 dump 工具。
  • 加密单向:官方不提供解回明文的通道;永久密码只用于无限次推理。
  • 驱动 / OS 级依赖不自动装:NVIDIA 驱动过旧、RK3588 板镜像缺 NPU 驱动,SDK 只诊断不代劳。
  • macOS 不在 v1;rknn 载荷只在 linux-arm64 板端,Windows 上如实拒绝。
  • 推理不承诺硬实时。