Metadata-Version: 2.3
Name: leap-beisen-sdk
Version: 0.1.2
Summary: 面向北森 Beisen OpenAPI 的异步 Python 迷你 SDK
Keywords: beisen,italent,openapi,sdk,async
Author: Llugaes
Author-email: Llugaes <249094896@qq.com>
License: MIT License
         
         Copyright (c) 2026 Llugaes
         
         Permission is hereby granted, free of charge, to any person obtaining a copy
         of this software and associated documentation files (the "Software"), to deal
         in the Software without restriction, including without limitation the rights
         to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         copies of the Software, and to permit persons to whom the Software is
         furnished to do so, subject to the following conditions:
         
         The above copyright notice and this permission notice shall be included in all
         copies or substantial portions of the Software.
         
         THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
         SOFTWARE.
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Dist: python-dotenv>=1.2.1
Requires-Dist: httpx>=0.27.2
Requires-Python: >=3.13
Project-URL: Homepage, https://github.com/Llugaes/leap-beisen-sdk
Project-URL: Issues, https://github.com/Llugaes/leap-beisen-sdk/issues
Project-URL: Repository, https://github.com/Llugaes/leap-beisen-sdk
Description-Content-Type: text/markdown

# leap-beisen-sdk

面向北森 (Beisen / iTalent) OpenAPI 的异步 Python 迷你 SDK。

PyPI 包名是 `leap-beisen-sdk`，Python import 包名保持为
`beisen_custom_sdk`。当前聚焦三个能力：

- access token 获取、缓存和自动刷新。
- 报表表头查询与报表数据分页查询。
- 应聘者原始简历文件地址获取。

## 环境要求

- Python >= 3.13
- 推荐使用 [uv](https://docs.astral.sh/uv/) 管理项目

## 安装

```bash
pip install leap-beisen-sdk
```

使用 uv：

```bash
uv add leap-beisen-sdk
```

## 配置

复制 `.env.template` 为 `.env` 并填入北森应用凭证：

```dotenv
BEISEN_KEY=你的 app_key
BEISEN_SECRET=你的 app_secret
```

SDK 解析凭证的优先级是：**显式传参 > 环境变量**。
两者都未提供时，构造客户端会立即抛出 `BeisenError`。

## 快速开始

```python
import asyncio

from beisen_custom_sdk import BeisenClient


async def main() -> None:
    async with BeisenClient() as client:
        header = await client.get_report_header("报表ID")
        for col in header.columns:
            print(f"{col.title} -> {col.id}")

        page = await client.get_report_data("报表ID", page=1, page_size=100)
        print(f"总记录数: {page.total_records}")
        print(page.rows[0])

        readable_page = await client.get_report_data(
            "报表ID",
            page=1,
            page_size=100,
            readable=True,
        )
        print(readable_page.rows[0])

        resume = await client.get_resume_url("应聘者ID")
        print(resume.download_url)
        print(resume.preview_url)


asyncio.run(main())
```

也可以显式传入凭证：

```python
async with BeisenClient(app_key="your_key", app_secret="your_secret") as client:
    ...
```

## API 参考

### `BeisenClient`

```python
BeisenClient(
    app_key: str | None = None,
    app_secret: str | None = None,
    *,
    base_url: str = "https://openapi.italent.cn",
    header_cache_ttl: float = 600,
    timeout: float = 30,
    max_retries: int = 10,
    retry_base_delay: float = 1.0,
    retry_max_delay: float = 30.0,
)
```

| 参数 | 说明 |
|---|---|
| `app_key` | 北森应用 Key；为 `None` 时从 `BEISEN_KEY` 读取 |
| `app_secret` | 北森应用 Secret；为 `None` 时从 `BEISEN_SECRET` 读取 |
| `base_url` | API 基础地址，默认北森生产环境 |
| `header_cache_ttl` | 报表表头缓存有效期，单位秒 |
| `timeout` | HTTP 请求超时时间，单位秒 |
| `max_retries` | 遇到 429 / 5xx 时的最大重试次数 |
| `retry_base_delay` | 指数退避基础延迟 |
| `retry_max_delay` | 单次退避等待上限 |

使用 `async with` 管理生命周期，退出时会自动关闭 HTTP 连接。

### 报表接口

#### `get_report_header(report_id) -> ReportHeader`

获取分析报表或定制报表的表头数据。

```python
header = await client.get_report_header("80c0b3b2-858b-46ff-a509-d553d5a68496")
mapping = header.id_to_title_map()
```

#### `get_report_data(report_id, page, page_size, *, readable=False) -> ReportPage`

获取报表单页数据。SDK 不封装全量分页遍历，业务层自行控制分页。

```python
page = await client.get_report_data("报表ID", page=1, page_size=100)

readable_page = await client.get_report_data(
    "报表ID",
    page=1,
    page_size=100,
    readable=True,
)
```

`readable=True` 时，SDK 会自动获取并缓存表头，把返回行里的 column_id
替换为 column_title。同一报表的后续请求不会重复调用表头接口，直到缓存过期。

### 简历接口

#### `get_resume_url(applicant_id) -> ResumeInfo`

获取应聘者原始简历文件地址。若北森返回的是 `//...` 地址，SDK 会自动补成
`http://...`。

```python
resume = await client.get_resume_url("8b5ad780-6968-476d-b7e8-9226d6d8ff2e")
print(resume.download_url)
print(resume.preview_url)
print(resume.dfs_path)
```

## 数据模型

| 类 | 说明 |
|---|---|
| `ReportColumn` | 报表列，含 `title`、`id`、`sub_columns` |
| `ReportHeader` | 报表表头，含 `is_complex`、`columns`，提供 `id_to_title_map()` |
| `ReportPage` | 单页数据，含 `total_records`、`rows` |
| `ResumeInfo` | 简历信息，含 `download_url`、`preview_url`、`dfs_path`、`raw` |

## 异常处理

```python
from beisen_custom_sdk import BeisenAPIError, BeisenAuthError, BeisenError

try:
    header = await client.get_report_header("bad-id")
except BeisenAuthError:
    # Token 获取或刷新失败
    ...
except BeisenAPIError as exc:
    # 北森 API 业务错误
    print(exc.code)
    print(exc.api_message)
except BeisenError:
    # 其他 SDK 异常
    ...
```

## 开发

```bash
uv sync --dev
uv run ruff check src tests
uv run pyright src
uv run pytest tests/ -v
uv run python -m compileall -q src
```

## 许可证

MIT
