【免费下载链接】ade-python
Python library for Agentic Document Extraction (ADE).
ade-python 是 LandingAI Agentic Document Extraction(ADE)服务的官方 Python SDK:把 PDF、图片解析为带坐标的 Markdown,再按 Pydantic 模型提取结构化字段。它的价值在于全类型化请求 + Pydantic 响应模型、同步/异步双客户端、自动重试与异步 Job 等待。本文带你沿真实代码走一遍:一次client.v2.parse(...)调用,是如何从参数校验一路走到带类型的响应对象的。
一、先看全局:一张图看懂分层架构
整个库采用典型的"分层 SDK"设计,自下而上共四层:
| 层 | 代表文件 | 职责 |
|---|---|---|
| 业务方法层 | _client.py、resources/v2/ | 暴露parse/extract等用户方法,拼装 body、文件与请求选项 |
| 传输层 | _base_client.py | 构造httpx.Request、发送、重试、异常映射 |
| 响应层 | _response.py | 包装原始响应,按需惰性解析、缓存解析结果 |
| 模型层 | _models.py、types/ | 请求参数 TypedDict + 响应 Pydantic 模型(由 OpenAPI 生成) |
一个关键设计:v1 与 v2 走不同的 API 主机。构造函数里通过环境映射表解析双 base URL,client.v2子客户端复用同一套传输设施(认证、重试、httpx 连接池),只是路由到 v2 主机,见 _resolve_v2_base_url 与 ENVIRONMENTS / V2_ENVIRONMENTS。
二、链路第 1 步:方法入口——把参数组装成"最终请求选项"
以 v1 的client.parse为例(v2 同构),入口做了三件事:
- 本地文件路径转上传参数:
convert_url_to_file_if_local把本地Path转成可上传的文件对象,见 lib/url_utils.py; - 抽取文件字段:
extract_files从 body 中剥离出document等文件项,其余标量参数交给maybe_transform按 TypedDict 参数模型做校验转换,见 _client.py 的 parse 方法; - 生成
FinalRequestOptions:post()把 method、url、json_data、files 打包进一个 Pydantic 模型,这是贯穿整条链路的"请求信封",定义在 _models.py。
v2 的 Pydantic schema 参数还有额外一步:client.v2.extract(schema=Invoice)接受 Pydantic 模型类时,由 lib/schema_utils.py 的pydantic_to_json_schema将其转为扁平 JSON Schema(自动展开$ref/$defs)后再发送,所以你可以直接传业务模型类。
三、链路第 2 步:request()主循环——发送、重试与异常映射
真正的 HTTP 传输发生在 SyncAPIClient.request,核心是一个"最多重试 N 次"的 for 循环:
- 构造请求:
_build_request合并默认头与自定义头(含Authorization: Bearer <apikey>、结构化 User-Agent、X-Source: sdk等身份头),序列化 query,组装 multipart/form-data,见 _build_request; - 非 GET 请求自动附幂等键:每次重试用同一个
idempotency_key,避免重试造成重复计费,见 request 循环; - 失败即重试:连接超时、网络异常、408/409/429/5xx 都进入重试,退避策略为"指数退避 + 抖动",优先尊重服务端
Retry-After响应头,见 _calculate_retry_timeout 与 _should_retry; - 默认参数:默认超时 8 分钟(连接 5 秒)、默认重试 2 次,集中定义在 _constants.py。
若重试耗尽,状态码会被逐一映射为具体异常(400→BadRequestError、401→AuthenticationError、429→RateLimitError…),映射逻辑在 _make_status_error,异常类层级见 _exceptions.py。v2 特有的V2SyncTimeoutError、JobWaitTimeoutError、JobFailedError则独立成体系,定义在 lib/v2_errors.py。
💡 细节:请求日志在 debug 级别下会经过
_redact_for_logging脱敏——文件内容替换为<N bytes>、password字段替换为<redacted>,见 脱敏实现。
四、链路第 3 步:_process_response——从 httpx.Response 到类型化对象
拿到 2xx 响应后,_process_response负责"最后一公里",见 实现:
- 包一层
APIResponse:原始httpx.Response被封装为 _response.py 中的APIResponse对象,保留headers、status_code、elapsed等原始信息,并支持.with_raw_response场景下按需.parse(); - 惰性读取 + 缓存:
.parse()才真正读取 body;同一类型重复 parse 会命中_parsed_by_type缓存,见 parse 方法; - JSON 解析与类型构建:先按
Content-Type判断是否 JSON,再交给_process_response_data——宽松模式下用construct_type按目标 Pydantic 模型"宽松构造"(未知字段保留、缺失字段容忍),严格模式下用validate_type强校验,见 _process_response_data 与 construct_type。
到这里,一段 JSON 字符串就成了V2ParseResponse这样的强类型对象。
五、模型层:响应模型从何而来
所有响应模型由OpenAPI 规范自动生成并随仓库提交快照:
- 规范源文件:specs/v1-ade.json、specs/v2-aide.json
- 生成产物:specs/_generated/v1_models.py、specs/_generated/v2_models.py,最终落入 types/ 目录
以 V2ParseResponse 为例:markdown、structure(document→page→element 的带坐标树)、metadata(页数、耗时、计费)都是带文档字符串的 Pydantic 字段;structure中每个节点内联grounding(页码 + Markdown 字符范围 + 归一化坐标 box)。生成脚本与规范同步流水线见 scripts/spec-sync/ 与 docs/design/stainless-exit-and-v2.md。
请求侧则相反:嵌套参数是TypedDict(如 client_parse_params.py),只描述、不校验;响应侧是 Pydantic 模型,可.to_dict()/.to_json()。
六、异步 Job 的等待器:复用同一条链路
大文档走client.v2.parse_jobs:create返回标准化Job(含job_id、status、progress、is_terminal),wait()只是带退避地轮询get(job_id),直到终态或抛出JobWaitTimeoutError/JobFailedError,见 wait 实现。它没有新的传输逻辑——每次轮询依旧完整走一遍"第二章 → 第四章"的链路。
七、链路速查:关键文件一张表
| 环节 | 文件 | 关键符号 |
|---|---|---|
| 方法入口 / 双环境路由 | src/landingai_ade/_client.py | LandingAIADE、_resolve_v2_base_url |
| 请求构造 / 重试 / 异常映射 | src/landingai_ade/_base_client.py | SyncAPIClient.request、_should_retry |
| 请求信封与类型构建 | src/landingai_ade/_models.py | FinalRequestOptions、construct_type |
| 响应包装与解析 | src/landingai_ade/_response.py | APIResponse.parse |
| 默认超时 / 重试参数 | src/landingai_ade/_constants.py | DEFAULT_TIMEOUT、DEFAULT_MAX_RETRIES |
| 异常体系 | src/landingai_ade/_exceptions.py、src/landingai_ade/lib/v2_errors.py | APIStatusError、V2SyncTimeoutError |
| 响应 Pydantic 模型 | src/landingai_ade/types/v2/parse_response.py | V2ParseResponse |
总结:ade-python 的链路可以概括为一句话——"方法层组装 → 传输层发送重试 → 响应层包装 → 模型层定型"。理解这条从 HTTP 请求到 Pydantic 响应模型的完整链路后,你就能快速定位重试、超时、字段缺失等各类问题的归属层,也能明白save_to、extra_headers、with_raw_response等高级能力分别插入在链路的哪个位置。
【免费下载链接】ade-python
Python library for Agentic Document Extraction (ADE).
相关推荐
bearparser与PE-bear:构建专业PE分析工具的完美组合
bearparser与PE bear:构建专业PE分析工具的完美组合 bearparser是一款功能强大的Portable Executable(PE)解析库,
应用安全PostgREST 架构深度解析:从 HTTP 请求到 PostgreSQL 查询的完整链路
PostgREST 架构深度解析:从 HTTP 请求到 PostgreSQL 查询的完整链路 PostgREST 将 PostgreSQL 数据库自动转化为 R
后端API网关深度解析:SQLAlchemy ORM性能优化的5大实战技巧
深度解析:SQLAlchemy ORM性能优化的5大实战技巧 SQLAlchemy作为Python生态系统中最强大的数据库工具包,为开发者提供了灵活而高效的数据
后端数据库ORM关系型数据库
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考