> ## Documentation Index
> Fetch the complete documentation index at: https://docs.textin.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Python SDK

> 使用 xparse-client Python SDK 快速集成文档解析能力

`xparse-client` 是 TextIn xParse 的官方 Python SDK，提供同步解析、异步任务管理、类型安全的响应模型和完善的错误处理，基于[最新版 API](/api-reference/endpoint/xparse/v1/parse-sync) 封装。

* PyPI: [xparse-client](https://pypi.org/project/xparse-client/)

## 安装

<CodeGroup>
  ```bash pip theme={null}
  pip install xparse-client
  ```

  ```bash uv theme={null}
  uv add xparse-client
  ```
</CodeGroup>

**系统要求：** Python >= 3.9

## 认证与初始化

SDK 支持多种认证方式（优先级：构造参数 > 环境变量 > .env 文件）：

<CodeGroup>
  ```python 环境变量（推荐） theme={null}
  import os
  os.environ["TEXTIN_APP_ID"] = "your-app-id"
  os.environ["TEXTIN_SECRET_CODE"] = "your-secret-code"

  from xparse_client import XParseClient
  client = XParseClient()
  ```

  ```python 直接传参 theme={null}
  from xparse_client import XParseClient
  client = XParseClient(
      app_id="your-app-id",
      secret_code="your-secret-code",
  )
  ```

  ```python .env 文件 theme={null}
  # 需要安装 dotenv 扩展: pip install xparse-client[dotenv]
  # .env 文件内容:
  # TEXTIN_APP_ID=your-app-id
  # TEXTIN_SECRET_CODE=your-secret-code

  from xparse_client import XParseClient
  client = XParseClient()
  ```
</CodeGroup>

<Tip>
  推荐使用环境变量方式，避免在代码中硬编码密钥。
</Tip>

## API 概览

| 方法                          | 说明         | 返回类型                |
| --------------------------- | ---------- | ------------------- |
| `client.parse.run()`        | 同步解析文档     | `ParseResponse`     |
| `client.parse.create_job()` | 创建异步解析任务   | `AsyncJobResponse`  |
| `client.parse.get_job()`    | 查询异步任务状态   | `JobStatusResponse` |
| `client.parse.wait_job()`   | 轮询等待异步任务完成 | `JobStatusResponse` |

## 同步解析

适用于一般大小的文档，直接返回解析结果。

```python theme={null}
from xparse_client import XParseClient, ParseConfig, Capabilities, Scope

client = XParseClient()

with open("document.pdf", "rb") as f:
    result = client.parse.run(
        file=f,
        filename="document.pdf",
        config=ParseConfig(
            capabilities=Capabilities(
                include_table_structure=True,  # 返回表格详细结构
                include_image_data=True,       # 返回图片数据
                title_tree=True,               # 返回目录树
                pages=True,                    # 返回页面元信息
            ),
            scope=Scope(page_range="1-10"),     # 指定解析页面范围
        ),
    )

# 输出 Markdown
print(result.markdown)

# 遍历元素
for el in result.elements:
    print(f"[{el.type}] p{el.page_number}: {el.text[:60]}")
```

### 解析配置参数

`ParseConfig` 支持以下配置：

| 参数                                     | 类型                       | 说明                      |
| -------------------------------------- | ------------------------ | ----------------------- |
| `capabilities.include_hierarchy`       | bool                     | 返回元素父子关系                |
| `capabilities.include_inline_objects`  | bool                     | 返回行内对象（公式、手写体、复选框）      |
| `capabilities.include_char_details`    | bool                     | 返回字符级坐标和置信度             |
| `capabilities.include_image_data`      | bool                     | 返回图片 URL、MIME 类型、OCR 文本 |
| `capabilities.include_table_structure` | bool                     | 返回表格行/列/单元格详细结构         |
| `capabilities.pages`                   | bool                     | 返回页面元信息列表               |
| `capabilities.title_tree`              | bool                     | 返回文档目录树                 |
| `capabilities.table_view`              | `"markdown"` \| `"html"` | 表格视图格式                  |
| `scope.page_range`                     | string                   | 解析页面范围，如 `"1-10"`       |
| `document.password`                    | string                   | 加密 PDF 的密码              |

## 异步解析

适用于大文件或批量处理场景。

### 创建任务并等待结果

```python theme={null}
client = XParseClient()

# 创建异步任务
with open("large_document.pdf", "rb") as f:
    job = client.parse.create_job(
        file=f,
        filename="large_document.pdf",
        webhook="https://example.com/callback",  # 可选：完成后回调通知
    )

print(f"任务已创建: {job.job_id}")

# 等待任务完成（自动轮询）
result = client.parse.wait_job(
    job_id=job.job_id,
    timeout=300.0,       # 超时时间（秒）
    poll_interval=5.0,   # 轮询间隔（秒）
)

if result.is_completed:
    # 异步任务返回 result_url，需单独下载获取解析结果
    import httpx
    resp = httpx.get(result.result_url)
    print(resp.json())
```

### 手动查询任务状态

```python theme={null}
status = client.parse.get_job(job_id="your-job-id")

print(f"状态: {status.status}")  # pending | in_progress | completed | failed
```

## 错误处理

SDK 提供了完善的错误分类，方便您精确处理不同的异常情况。

### 错误类型

| 错误类                        | 说明                            |
| -------------------------- | ----------------------------- |
| `XParseClientError`        | 基础错误类，捕获所有 SDK 错误             |
| `ValidationError`          | 客户端参数校验失败                     |
| `AuthenticationError`      | 认证失败（app-id 或 secret-code 错误） |
| `PermissionDeniedError`    | IP 不在白名单                      |
| `InsufficientBalanceError` | 余额不足                          |
| `InvalidParameterError`    | 参数错误                          |
| `UnsupportedFileTypeError` | 不支持的文件类型                      |
| `FileSizeError`            | 文件超过 500MB 限制                 |
| `CorruptedFileError`       | 文件损坏                          |
| `PasswordProtectedError`   | PDF 需要密码                      |
| `ServerError`              | 服务端错误（HTTP 5xx）               |
| `ServiceUnavailableError`  | 服务暂时不可用                       |

### 错误处理示例

```python theme={null}
from xparse_client.exceptions import (
    XParseClientError,
    BusinessError,
    AuthenticationError,
    APIError,
)

try:
    with open("document.pdf", "rb") as f:
        result = client.parse.run(file=f, filename="document.pdf")
except AuthenticationError as e:
    print(f"认证失败: {e.message}")
except BusinessError as e:
    print(f"业务错误 [{e.business_code}]: {e.message}")
    print(f"请求ID: {e.x_request_id}")  # 用于技术支持排查
except APIError as e:
    print(f"API错误 [HTTP {e.status_code}]: {e.message}")
except XParseClientError as e:
    print(f"SDK错误: {e.message}")
```

### 获取请求 ID

每个 API 请求都会返回 `x_request_id`，可用于联系技术支持排查问题：

```python theme={null}
result = client.parse.run(file=f, filename="document.pdf")
print(f"请求ID: {result.x_request_id}")
```

## 高级配置

### 超时与重试

```python theme={null}
client = XParseClient(
    timeout=120.0,    # 请求超时（秒），默认 630
    max_retries=3,    # 最大重试次数，默认 3
)
```

### 自定义 API 地址

```python theme={null}
client = XParseClient(
    server_url="https://custom-api.example.com"
)
```

### 自定义 HTTP 客户端

支持代理、自定义 SSL 证书等场景：

```python theme={null}
import httpx

http_client = httpx.Client(
    proxy="http://proxy.example.com:8080",
    verify="/path/to/custom-ca.pem",
)

client = XParseClient(
    app_id="your-app-id",
    secret_code="your-secret-code",
    http_client=http_client,
)
```

### 资源管理

使用上下文管理器自动关闭连接：

```python theme={null}
with XParseClient() as client:
    result = client.parse.run(...)
    # 退出时自动关闭连接
```

## 调试日志

启用 DEBUG 级别日志查看请求详情：

```python theme={null}
import logging
logging.getLogger("xparse_client").setLevel(logging.DEBUG)
```

## 常见问题

| 问题                    | 解决方案                                           |
| --------------------- | ---------------------------------------------- |
| `AuthenticationError` | 检查 `TEXTIN_APP_ID` 和 `TEXTIN_SECRET_CODE` 是否正确 |
| `FileSizeError`       | 文件大小限制为 500MB                                  |
| `TimeoutException`    | 增大超时时间：`XParseClient(timeout=300.0)`           |

## 相关链接

* [PyPI 主页](https://pypi.org/project/xparse-client/)
* [API 参考：同步解析](/api-reference/endpoint/xparse/v1/parse-sync)
* [API 参考：异步解析](/api-reference/endpoint/xparse/v1/parse-async)
