Metadata-Version: 2.4
Name: ubox-py-sdk
Version: 0.2.27
Summary: 用于操作优测设备的python-sdk
Author-email: lainxxu <lainxxu@tencent.com>
Keywords: python,sdk,ubox,优测
Requires-Python: <3.12,>=3.10
Requires-Dist: cryptography>=41.0.0
Requires-Dist: lxml>=6.0.0
Requires-Dist: numpy~=1.23.0
Requires-Dist: openai>=2.9.0
Requires-Dist: opencv-python-headless==4.11.0.86
Requires-Dist: pillow==11.3.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: pyjwt>=2.8.0
Requires-Dist: requests>=2.31.0
Requires-Dist: textdistance==4.6.3
Provides-Extra: dev
Requires-Dist: black>=23.0.0; extra == 'dev'
Requires-Dist: flake8>=6.0.0; extra == 'dev'
Requires-Dist: isort>=5.12.0; extra == 'dev'
Requires-Dist: mypy>=1.0.0; extra == 'dev'
Provides-Extra: docs
Requires-Dist: sphinx-rtd-theme>=1.2.0; extra == 'docs'
Requires-Dist: sphinx>=6.0.0; extra == 'docs'
Description-Content-Type: text/markdown

# 优测 Python UBox SDK

![Python Version](https://img.shields.io/badge/python-%3E%3D3.10%2C%3C3.12-blue.svg)
![Version](https://img.shields.io/badge/version-0.2.23-green.svg)

用于操作优测设备的 Python SDK，提供简单易用的 API 接口来与优测设备进行交互，支持 Android、iOS、HarmonyOS 三大平台。

## ✨ 功能特性

| 类别 | 能力 |
|------|------|
| 🚀 **设备管理** | 设备初始化/释放、连通性探测、设备列表查询、多设备并发管理 |
| 📱 **基础操作** | 点击、滑动、输入、按键、双指缩放、长按、双击 |
| 🔍 **智能识别** | UI控件定位、OCR文字识别、CV图像匹配、多模式综合查找 |
| 📸 **截图录制** | 截图（支持裁剪）、Base64截图、屏幕录制 |
| 📊 **性能监控** | 应用性能数据采集与分析 |
| 📝 **日志采集** | Logcat日志采集与过滤（Android/鸿蒙） |
| 🚨 **ANR/Crash监控** | 应用ANR和Crash问题检测，自动截图和日志收集 |
| 🤖 **AI Agent** | 基于大模型的探索性测试，自然语言驱动设备操作 |
| 🔧 **应用管理** | 安装/卸载/启动/停止/清理应用 |
| 🌐 **网络代理** | 全局HTTP代理设置与管理 |
| 📋 **剪贴板** | 剪贴板读写操作 |
| ⚡ **事件处理** | Watcher模式自动处理弹窗和事件 |

## 📦 安装

### 使用 uv 安装（推荐）

```bash
# 安装 uv（如果还没有安装）
curl -LsSf https://astral.sh/uv/install.sh | sh
# 或 Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

# 创建虚拟环境
uv venv

# 安装包
uv pip install -U ubox-py-sdk --index-url https://pypi.tuna.tsinghua.edu.cn/simple \
  --extra-index-url https://mirrors.tencent.com/repository/pypi/tencent_pypi/simple
```

### 使用 pip 安装

```bash
python -m pip install ubox-py-sdk \
  --index-url https://pypi.tuna.tsinghua.edu.cn/simple \
  --extra-index-url https://mirrors.tencent.com/repository/pypi/tencent_pypi/simple
```

> ⚠️ 确保 Python 版本 >= 3.10, < 3.12

---

## 🚀 快速开始

### 三种运行模式

SDK 支持三种运行模式，适用于不同场景：

| 模式 | 说明 | 适用场景                |
|------|------|---------------------|
| `RunMode.NORMAL` | 正常模式（默认），自动管理设备占用、释放和续期 | 日常自动化测试（推荐）         |
| `RunMode.LOCAL` | 本地模式，直连本地 `127.0.0.1:26000` | 本地调试自动化脚本（特殊场景使用）   |
| `RunMode.CLI` | CLI模式，无状态，不续期不释放 | 一次性脚本/命令行工具（特殊场景使用） |

### 正常模式（推荐）

```python
from ubox_py_sdk import UBox, OSType, RunMode

# 使用 with 语句自动管理连接和释放
with UBox(secret_id="your_sid", secret_key="your_skey") as ubox:
    # 初始化设备（自动占用）
    device = ubox.init_device(udid="DEVICE_SERIAL", os_type=OSType.ANDROID)
    
    # 执行操作
    device.click_pos([0.5, 0.5])       # 点击屏幕中心
    device.screenshot("test", "./img")  # 截图保存
    
# 退出 with 块时自动释放所有设备
```

### CLI模式（快捷函数）

```python
from ubox_py_sdk import connect_device, create_device, OSType

# 一步连接设备
device = connect_device(
    udid="DEVICE_SERIAL",
    os_type=OSType.ANDROID,
    auth_token="your_auth_token"
)

# 获取连接信息，后续可复用
conn_info = device.connection_info

# 后续直接用连接信息创建设备实例，无需重新连接
device2 = create_device(conn_info, auth_token="your_auth_token")
device2.click_pos([0.5, 0.5])
```


### 设备连通性探测

在占用设备前，可以先探测设备是否可用（不会占用设备）：

```python
with UBox(secret_id="sid", secret_key="skey") as ubox:
    is_ok = ubox.probe_device(udid="DEVICE_SERIAL", os_type=OSType.ANDROID)
    if is_ok:
        print("✅ 设备可连接")
        device = ubox.init_device(udid="DEVICE_SERIAL", os_type=OSType.ANDROID)
    else:
        print("❌ 设备不可用")
```

### 获取设备列表

```python
from ubox_py_sdk import UBox, PhonePlatform

with UBox(secret_id="sid", secret_key="skey") as ubox:
    # 获取在线的 Android 设备
    result = ubox.device_list(
        page_num=1,
        page_size=20,
        phone_platform=[PhonePlatform.ANDROID],
        online_status=1
    )
    
    for dev in result.list:
        print(f"设备: {dev.udid} | 型号: {dev.modelKind} | 状态: {'在线' if dev.onlineStatus == 1 else '离线'}")
    print(f"共 {result.total} 台设备")
```

### 常用操作示例

```python
# ---- 基础操作 ----
device.click_pos([0.5, 0.5])                          # 坐标点击
device.click_pos([0.5, 0.5], duration=2)               # 长按2秒
device.click_pos([0.5, 0.5], times=2)                  # 双击
device.slide_pos([0.5, 0.8], [0.5, 0.2])              # 上滑
device.input_text("Hello World")                        # 输入文本
device.press(DeviceButton.HOME)                         # 按Home键
device.press(DeviceButton.BACK)                         # 按返回键

# ---- 智能点击 ----
device.click("确定", by=DriverType.OCR)                 # OCR识别文字并点击
device.click("./icon.png", by=DriverType.CV)            # 图像匹配并点击
device.click("//*[@text='登录']", by=DriverType.UI)     # UI控件定位并点击

# ---- 截图录制 ----
img_path = device.screenshot("demo", "./screenshots")   # 截图
img_b64 = device.screenshot_base64()                     # Base64截图
device.record_start("./videos")                          # 开始录制
device.record_stop()                                     # 停止录制

# ---- 应用管理 ----
device.install_app(app_url="https://example.com/app.apk")
device.start_app("com.example.app")
device.stop_app("com.example.app")
device.uninstall_app("com.example.app")

# ---- 性能监控 ----
device.perf_start(container_bundle_identifier="com.example.app")
# ... 执行测试操作 ...
device.perf_stop("./perf_output")

# ---- Logcat日志采集（仅Android/鸿蒙）----
task = device.logcat_start(file="./logs/app.txt", clear=True, re_filter=".*MyApp.*")
# ... 执行测试操作 ...
task.stop()

# ---- ANR/Crash监控（仅Android/鸿蒙）----
device.anr_start(package_name="com.example.app")
# ... 执行测试操作 ...
result = device.anr_stop(output_directory="./anr_output")
print(f"ANR: {result['anr_count']}, Crash: {result['crash_count']}")
```

### AI Agent 探索测试

```python
from ubox_py_sdk import UBox, OSType
from ubox_py_sdk.phone_agent import AgentModelConfig, ModelType, ModelConfig

# 配置AI模型
model_config = AgentModelConfig(
    model=ModelType.QWEN_VL,  # 选择模型
    configs={
        ModelType.QWEN_VL: ModelConfig(
            api_key="your_api_key",
            base_url="https://your-model-endpoint/v1",
        )
    }
)

with UBox(
    secret_id="sid", secret_key="skey",
    agent_model_config=model_config
) as ubox:
    device = ubox.init_device(udid="DEVICE_SERIAL", os_type=OSType.ANDROID)
    
    # 流式获取AI执行过程
    for update in device.explore("打开微信并搜索'优测'"):
        print(f"[{update.update_type}] {update.content}")
    
    # 主动停止Agent
    device.stop_agent()
```

### 事件处理（Watcher模式）

```python
# 创建watcher自动处理弹窗
device.handler.watcher("permission").when("允许").click()
device.handler.watcher("update").when("稍后更新").click()

# 自定义处理函数
def handle_ad(device, xml_element, smart_click):
    smart_click("关闭")

device.handler.watcher("ad").when("广告").call(handle_ad)

# 启动后台监控
device.handler.start(interval=2.0)

# ... 执行测试操作 ...

# 停止监控
device.handler.stop()
```

### 日志配置

```python
# 默认配置（仅控制台输出）
ubox = UBox(secret_id="sid", secret_key="skey")

# 调试模式
ubox = UBox(secret_id="sid", secret_key="skey", log_level="DEBUG")

# 文件日志
ubox = UBox(
    secret_id="sid", secret_key="skey",
    log_level="INFO",
    log_to_file=True,
    log_file_path="logs/ubox.log"
)

# 生产环境
ubox = UBox(
    secret_id="sid", secret_key="skey",
    log_level="WARNING",
    log_to_file=True,
    log_file_path="logs/production.log"
)
```

---

## 📖 完整 API 参考

SDK 提供了丰富的 API 接口，包括客户端管理和设备操作两大类。

👉 **[查看完整 API 参考文档](./API_REFERENCE.md)**

---

## 🛠️ 开发者指南

### 项目结构

```
ubox-py-sdk/
├── src/                        # 源代码目录
│   └── ubox_py_sdk/           # 主包目录
│       ├── __init__.py         # 包初始化，导出公开API
│       ├── client.py           # UBox客户端类，管理连接和认证
│       ├── device.py           # Device设备类，封装设备操作接口
│       ├── device_operations.py # 设备操作实现（Operation模式）
│       ├── handler.py          # EventHandler事件处理器
│       ├── phone_agent/        # AI Agent探索测试模块
│       ├── exceptions.py       # 异常定义
│       ├── models.py           # 数据模型（Pydantic）
│       ├── logger.py           # 日志工具
│       └── utils/              # 工具类（JWT、图像处理等）
├── examples/                   # 使用示例
│   ├── example.py             # 基础功能演示
│   ├── event_handler_example.py # 事件处理示例
│   └── device_list_example.py # 设备列表示例
├── pyproject.toml             # 项目配置
├── version.log                # 版本变更日志
├── Makefile                   # 构建脚本
└── uv.lock                   # 依赖锁定文件
```

### 架构设计

SDK 采用分层架构设计：

```
┌─────────────────────────────────────────┐
│              用户代码                     │
├─────────────────────────────────────────┤
│  UBox (client.py)                       │  ← 客户端层：认证、连接管理、设备生命周期
├─────────────────────────────────────────┤
│  Device (device.py)                     │  ← 设备层：统一操作接口
├─────────────────────────────────────────┤
│  DeviceOperation (device_operations.py) │  ← 操作层：具体操作实现（策略模式）
├─────────────────────────────────────────┤
│  HTTP Session (requests)                │  ← 传输层：HTTP请求、连接池、重试
└─────────────────────────────────────────┘
```

- **UBox** 负责认证（JWT Token管理）、设备占用/释放/续期、连接路由（直连/代理自动切换）
- **Device** 通过组合模式持有 UBox 引用，封装所有设备操作的统一入口
- **DeviceOperation** 使用策略模式，每种操作独立实现，便于扩展

### 环境搭建

```bash
# 克隆项目
git clone <repo_url>
cd ubox-py-sdk

# 安装 uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# 安装依赖
uv sync

# 运行示例
uv run python examples/example.py
```

### 编译与发布

```bash
# 编译
uv build

# 发布到内部仓库
uv publish --publish-url https://mirrors.tencent.com/repository/pypi/tencent_pypi/simple
```

### 异常体系

所有异常继承自 `UBoxError`，异常信息会自动附带 `traceId`、`authCode`、`debugId`、`udid` 等调试信息：

| 异常类 | 说明 |
|--------|------|
| `UBoxError` | 基础异常类 |
| `UBoxConnectionError` | 连接异常（无法连接设备或连接中断） |
| `UBoxAuthenticationError` | 认证异常（密钥错误或权限不足） |
| `UBoxValidationError` | 数据验证异常（参数格式错误） |
| `UBoxTimeoutError` | 超时异常 |
| `UBoxDeviceError` | 设备异常（设备返回错误或状态异常） |

### 枚举类型

| 枚举 | 值 | 说明 |
|------|-----|------|
| `OSType.ANDROID` | `"android"` | Android设备 |
| `OSType.IOS` | `"ios"` | iOS设备 |
| `OSType.HM` | `"hm"` | HarmonyOS设备 |
| `RunMode.NORMAL` | `"normal"` | 正常模式 |
| `RunMode.LOCAL` | `"local"` | 本地模式 |
| `RunMode.CLI` | `"cli"` | CLI模式 |
| `PhonePlatform.ANDROID` | `1` | Android平台 |
| `PhonePlatform.IOS` | `2` | iOS平台 |
| `PhonePlatform.HARMONYOS` | `3` | 鸿蒙平台 |
| `PhonePlatform.HARMONYOS_NEXT` | `4` | 鸿蒙NEXT平台 |
