cua fleet Python 契约绑定详解:UniFFI 生成的 SDK 绑定与离线契约测试运行机制
cua fleet Python 契约绑定详解UniFFI 生成的 SDK 绑定与离线契约测试运行机制【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua本文围绕 Python 契约绑定说明 展开讲清楚 cua 仓库中fleet服务面向 Python 的 SDK 绑定是如何从 Rust 核心经 UniFFI 生成的、run-python-sdk-binding.sh启动器如何“一次构建 cdylib、临时装配 Python 包、退出即清理”地运行契约测试以及fleet_sdk包内部加载原生库、校验契约版本与 API 校验和的底层机制。读完后你可以独立完成 Python 绑定的构建与契约验证并理解生成代码与手写测试之间的边界。Python 契约绑定在 fleet SDK 中的位置fleet的 SDK 以 Rust 为原生 API 与规范实现libs/fleet/sdk是 Rust cratelibs/fleet/sdk-schema提供规范化的 schema 源而 sdk-bindings 总目录 提交了多种语言的生成源码使 code review 与漂移检查可复现原生库、Cargo 产物、语言运行时目录均不入库。Python 目标目录结构如下fleet_sdk 包对外门面由_schema与_sdk两个生成模块重组导出并补充ClaimSpec、OSGymSandboxClaimStatus、OSGymSandboxTemplateSpec、OSGymSandboxWarmPoolSpec、OSGymSandboxWarmPoolStatus等记录类型的 FFI 转换器UniFFI 生成的 FFI 层约 6400 行包含 ctypes 函数声明、Rust 缓冲区/流式编解码、handle map、异步 future 回调等全部脚手架契约测试 与 手写测试夹具test_builders.py、test_async_client.py、test_public_package.py验证生成表面contract_fixture.py提供脚本化 HTTP 客户端等离线设施。按 多语言绑定总 README 的划分Python 与 Kotlin、Swift、Ruby 一样由generate-sdk-bindings.sh钉住 UniFFI0.31.0的工作区包装脚本统一生成与--check漂移校验Go、Node.js 则是第三方生成器的独立兼容快照不属于这条四语言管线。需要说明路径映射Python README 中的命令前缀写作cyclops-cs/...如$REPO_ROOT/cyclops-cs/scripts/run-python-sdk-binding.sh而当前 checkout 中对应的实体位于libs/fleet/下例如 启动脚本 实际存放在libs/fleet/scripts/。从仓库结构看这是目录改名后的旧前缀残留阅读文档时应把cyclops-cs前缀按当前布局对应到libs/fleet。运行 Python 契约绑定README 给出的标准流程Python 绑定 README 给出的核心操作是先设置REPO_ROOT指向本 clone 的绝对路径然后从任意工作目录调用启动器REPO_ROOT/path/to/clone $REPO_ROOT/cyclops-cs/scripts/run-python-sdk-binding.sh $REPO_ROOT/cyclops-cs/sdk-bindings/python/tests/test_async_client.py -v $REPO_ROOT/cyclops-cs/scripts/run-python-sdk-binding.sh $REPO_ROOT/cyclops-cs/sdk-bindings/examples/python/app_controlled.py按当前 checkout 布局两条命令分别对应异步客户端契约测试与确定性生命周期示例。总 README 还补充了第三条常用入口——构建器契约测试$REPO_ROOT/cyclops-cs/scripts/run-python-sdk-binding.sh \ $REPO_ROOT/cyclops-cs/sdk-bindings/python/tests/test_builders.py -v其中-v只是透传给python3的额外参数见下文启动器分析。运行前提摘自总 READMERust1.97.0工具链、Python3.11用于 Python 契约夹具与源码检查器、宿主机 C 编译器/链接器产物库名为 Linux 上的libcyclops_sdk.somacOS 为libcyclops_sdk.dylib。启动器脚本逐行解析一次构建、临时装配、退出清理run-python-sdk-binding.sh 全文只有十几行却完整实现了 README 所承诺的“从不把原生库复制进生成源码”的隔离策略repo_root$(cd $(dirname ${BASH_SOURCE[0]})/../.. pwd) bindings$repo_root/cyclops-cs/sdk-bindings/python library$($repo_root/cyclops-cs/scripts/build-sdk-bindings-native.sh) runtime$(mktemp -d ${TMPDIR:-/tmp}/cyclops-python-sdk.XXXXXX) trap rm -rf $runtime EXIT cp -R $bindings/fleet_sdk $runtime/fleet_sdk cp $library $runtime/fleet_sdk/$(basename $library) target$1 case $target in /*) ;; *) target$repo_root/$target ;; esac shift PYTHONPATH$runtime:$bindings${PYTHONPATH::$PYTHONPATH} python3 $target $关键机制逐条对应 README 描述构建 cdylib 一次library$(... build-sdk-bindings-native.sh)捕获构建脚本输出的库路径。build-sdk-bindings-native.sh 默认把产物放到$workspace/target/sdk-bindings-native并支持通过CYCLOPS_SDK_NATIVE_TARGET_DIR覆盖目标目录使多条命令Python、Kotlin、Ruby 等共享同一份原生构建。装配临时 Python 包mktemp -d创建一次性目录把仓库中的fleet_sdk生成源码整体拷入再把构建出的libcyclops_sdk.so拷到$runtime/fleet_sdk/下——这正是生成绑定运行时按“与 .py 同目录”找库的约定见下一节的_uniffi_load_indirect。退出即删trap rm -rf $runtime EXIT保证无论测试成功、失败还是被中断临时包与临时复制的原生库都会被清理仓库内sdk-bindings/python/fleet_sdk/中的生成源码永远不会被注入二进制。参数处理第一个参数是目标脚本相对路径会补全为$repo_root/前缀shift之后剩余参数如-v原样透传给python3。PYTHONPATH同时包含临时运行目录与仓库内bindings目录后者让contract_fixture等测试辅助模块可被导入。生成绑定的加载与契约校验读 _sdk.py 的关键段落fleet_sdk/_sdk.py 顶部即声明“本文件由unifficrate 自动生成的脚手架产出”并解释了为什么辅助代码要内联在绑定里而不是拆成独立模块Python 侧对 FFI 缓冲区、内置类型的序列化细节必须与编译 Rust 组件的确切 UniFFI 版本严格一致。原生库定位L449-L472 的_uniffi_load_indirect按平台选择lib{}.dylibmacOS、lib{}.so其他 ELF 平台或{}.dllWindows直接按完整路径加载库名固定为cyclops_sdk加载位置是绑定文件自身所在目录——这解释了启动器为何必须把.so放进临时fleet_sdk/包内而不是指望动态链接器搜索路径。双重一致性防护契约版本检查L474-L480调用ffi_cyclops_sdk_uniffi_contract_version与绑定侧写死的bindings_contract_version 30比对不一致即抛出“UniFFI contract version mismatch: try cleaning and rebuilding your project”API 校验和检查L482 起对每个暴露的函数/构造器如create_pool、wait_claim、connect_with_access_token、各 builder 的 setter逐一比对uniffi_cyclops_sdk_checksum_*的哈希常量任何表面偏差都会以InternalError形式在导入期暴露。这意味着“改了 Rust API 却忘了重新生成 Python 绑定”不会悄悄工作而是在包导入时立刻失败——漂移检查在 CI 层generate-sdk-bindings.sh --check与运行层各设了一道闸。此外脚手架还包含_UniffiRustBuffer/_UniffiRustBufferStream/_UniffiRustBufferBuilder三大端结构体与大端序读写原语L38-L245_UniffiHandleMapL343-L388用带锁的 handle 表在 Python 与 Rust 间传递对象引用Python 生成的 handle 恒置最低位以便区分以及按返回类型特化的ffi_cyclops_sdk_rust_future_poll_*/cancel_*/complete_*/free_*一组函数声明支撑 Rustasync方法在 Python 侧以await形式被回调完成。契约测试在验证什么tests/test_async_client.py 基于unittest.IsolatedAsyncioTestCase全部通过 contract_fixture.py 提供的ScriptedHttpClient脚本化离线传输与offline_sandbox等夹具运行不依赖真实部署完整类型化生命周期run_lifecycle(ScriptedHttpClient(expected_lifecycle()))断言 pool、claim、sandbox、service 的元数据与状态码202精确匹配预期验证“Python 构造记录 → UniFFI 序列化 → Rust 客户端 → 回调 PythonHttpClient.execute”的完整往返错误传播契约令execute抛出HttpError.Transport(offline transport)断言其透传为SdkError.Transport且reason字段保持——证明跨 FFI 的异常类型与消息保真请求/响应体的三态区分对同一接口连续提交None无 body、b空 body、b\x00\xff二进制 body三组用例验证原生回调在“缺席 / 空 / 二进制”之间不混淆——这是总 README 强调的“preserve request/response body semantics”的直接可执行证据。test_builders.py面向七个 sandbox-pool 记录VmTemplate、SandboxService、OSGymSandboxTemplateSpec、CreateTemplateRequest、SandboxTemplateRef、OSGymSandboxWarmPoolSpec、CreatePoolRequest生成的不可变 builder每个 setter 返回新的 builder 对象对应 Rust 侧self - ArcSelf形态build()返回既有记录类型遗漏必填字段时经由稳定的SdkBuildError/SchemaBuildError变体报错。总 README 给出的 Python 形态示例可对照理解vm (fleet_sdk.VmTemplateBuilder().container_disk_image(image) .image_pull_secret(secret).cpu_cores(4).memory(8Gi) .services([service]).build())test_public_package.py则约束fleet_sdk公共面的导出稳定性配合 check-sdk-binding-contract-sources.sh含--self-test证明“仅靠注释不满足源码要求”构成对生成与手写边界的静态检查。与多语言绑定体系的衔接及常见故障排查总 README 的“Build once and run bindings”章节定义了跨语言共享原生构建的约定export CYCLOPS_SDK_NATIVE_TARGET_DIR$REPO_ROOT/cyclops-cs/target/sdk-bindings-native $REPO_ROOT/cyclops-cs/scripts/build-sdk-bindings-native.sh之后 Python、KotlinCYCLOPS_SDK_NATIVE_DIR指向 staging 目录、Ruby 各自的 runner 复用同一 cdylib。CI 映射方面Linux 工作流跑格式、锁定 clippy/测试、原始 CRD 漂移、绑定漂移、生成器回归、源码检查器与 Python/Kotlin/Ruby 契约及示例钉住 Rust1.97.0、Python3.11、Ruby3.3、JDK21、Gradle8.10.2macOS 工作流单独验证 Swift 绑定。针对 Python 目标排查要点均来自总 README Troubleshootingcargo must be available on PATH安装 Rust1.97.0并激活工作区工具链后重试CRD 或绑定漂移运行对应生成命令并只提交原始生成源码不做后处理libcyclops_sdk无法加载运行build-sdk-bindings-native.sh、导出文档规定的 native 目标变量并使用宿主平台正确的.so/.dylib文件名需要对外网真实部署做端到端验证时总 README 的 “Live examples” 提供live_app_controlled系列示例需CUA_BASE_URL、CUA_TOKEN_URL、CUA_CLIENT_ID、CUA_CLIENT_SECRET等变量且会创建计费资源与本文讨论的确定性、离线app_controlled示例形成对照示例脚本按语言位于 sdk-bindings/examples 目录树内。适用前提与小结适用前提本机具备 Rust1.97.0工具链与 C 编译器、Python3.11并能在libs/fleet工作区下执行cargo阅读命令时需将文档中cyclops-cs前缀对应当前 checkout 的libs/fleet位置。小结Python 契约绑定是 fleet SDK“Rust 单一真源 多语言生成表面”策略的落地切片。生成层负责 FFI 细节并以契约版本加 API 校验和双保险锁定表面run-python-sdk-binding.sh以临时装配的方式保证“仓库内只有源码、运行时才有二进制”而contract_fixture.py驱动的离线契约测试让绑定表面的每一项关键语义生命周期、错误传播、请求体三态、不可变 builder都成为可执行断言。【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →