Metadata-Version: 2.4
Name: zc-center-sdk-python
Version: 1.0.2
Summary: ZC Center SAPI Python SDK (HMAC-SHA256, AES-256-GCM, exam notice push)
Author-email: liujunlin <ljl763606865@gmail.com>
Maintainer-email: liujunlin <ljl763606865@gmail.com>
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/763606865/zc-center-sdk-python
Project-URL: Documentation, https://github.com/763606865/zc-center-sdk-python#readme
Project-URL: Repository, https://github.com/763606865/zc-center-sdk-python
Project-URL: Issues, https://github.com/763606865/zc-center-sdk-python/issues
Project-URL: Changelog, https://github.com/763606865/zc-center-sdk-python/releases
Keywords: zc-center,sapi,sdk,hmac,aes-gcm,exam-notice,flask
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.31.0
Requires-Dist: cryptography>=42.0.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Dynamic: license-file

# ZC Center Python SDK

适用于 Python 3.10+ 的中台 SAPI 服务端 SDK，提供 HMAC-SHA256 请求签名、AES-256-GCM 加解密、响应验签，以及招考公告推送封装。

协议与中台 [`docs/sapi/`](../../docs/sapi/README.md)、ThinkPHP / Spring Boot SDK 保持一致。许可证：Apache-2.0。

`app_secret` 只能保存在爬虫/服务端，禁止写入前端或客户端。

## 安装

PyPI（发布后）：

```bash
pip install zc-center-sdk
```

源码开发（推荐虚拟环境，避免 macOS `externally-managed-environment`）：

```bash
cd sdk/python
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -U pip
python -m pip install -e ".[dev]"
pytest -q
```

发布到 PyPI 的完整步骤见 [PUBLISH.md](./PUBLISH.md)。

## 配置

| 环境变量 | 说明 |
| --- | --- |
| `ZC_CENTER_BASE_URL` | 中台根地址，如 `https://zc-center.example.com` |
| `ZC_CENTER_APP_KEY` | 中台应用 `app_key` |
| `ZC_CENTER_APP_SECRET` | 中台应用 `app_secret` |
| `ZC_CENTER_ENCRYPTION` | `1`/`0`，须与中台 `SAPI_ENCRYPTION_ENABLED` 一致 |

联调可关闭加密；生产必须开启。

## 爬虫推荐流程

1. 在中台「业务管理 → 应用管理」为爬虫创建生态应用，拿到 `app_key` / `app_secret`，配置 IP 白名单。
2. 爬虫抓取并组合数据后，**不要依赖中台扫盘读 JSON**；直接调用 `exam_notice.report_batch`。
3. 每条至少传 `title`、`collect_source`；强烈建议再传稳定幂等键之一：
   - `uuid`（来源系统 UUID v4）
   - 或 `collect_ref`（来源站点内唯一 ID）
   - 或稳定的 `official_url` / `collect_url`
4. 单次最多 100 条；示例脚本会自动分批。

### 代码示例

```python
from zc_center import Client

client = Client(
    base_url="https://zc-center.example.com",
    app_key="...",
    app_secret="...",
    encryption=True,
)

client.ping().send("crawler-ready")

result = client.exam_notice().report_batch([
    {
        "title": "某市事业单位招聘公告",
        "collect_source": "某市人社局",
        "collect_ref": "src-2026-001",
        "official_url": "https://example.com/notices/1",
        "publish_time": 1788888888,
        "content": "<p>公告正文</p>",
    }
]).data()

print(result["created"], result["exists"], result["failed"])
```

Flask 等框架无特殊依赖，在服务端任务里直接 `from zc_center import Client` 即可。

### 一键推送 JSON 文件

```bash
export ZC_CENTER_BASE_URL=https://zc-center.example.com
export ZC_CENTER_APP_KEY=...
export ZC_CENTER_APP_SECRET=...

python examples/push_exam_notices.py /data/crawler/notices-2026-09-09.json
```

JSON 支持数组，或 `{"items":[...]}` / `{"list":[...]}`。

## 字段约定（招考公告）

| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `title` | 是 | 公告标题 |
| `collect_source` | 是 | 采集来源站点/单位名 |
| `uuid` | 推荐 | UUID v4，来源稳定 ID |
| `collect_ref` | 推荐 | 来源侧业务主键 |
| `official_url` / `collect_url` | 推荐 | 用于排重 |
| `code` / `exam_type` / `area_code` | 否 | 业务编码、招考类型、地区码 |
| `publisher_name` / `summary` / `content` | 否 | 发布单位、摘要、正文 |
| `publish_time` 等时间字段 | 否 | Unix 秒；也可传可解析时间字符串 |

排重优先级见 [`docs/sapi/招考公告.md`](../../docs/sapi/招考公告.md)。

## 与「扫盘导入」的关系

## 简历增量同步

```python
page = client.resume().list({"updated_after": 0, "last_id": 0, "limit": 100})
client.resume().update({"uuid": resume_uuid, "job_status": "actively_looking"})
```

每页都应保存 `next_updated_after` 与 `next_last_id`，下次请求同时回传。

## 职位库 / 职位

```python
client.job_bank().list({"page": 1, "page_size": 20})
page = client.job().list({"updated_after": 0, "last_id": 0, "limit": 100})
client.job().report({
    "bank_code": "default_center",
    "company_credit_code": "91110000MA01234567",
    "code": "JD-001",
    "title": "后端工程师",
    "employment_type": 1,
    "status": 1,
})
client.job().update({"uuid": job_uuid, "status": 2, "remark": "协助暂停"})
```

游标与权限见中台 [`docs/sapi/职位.md`](../../docs/sapi/职位.md)。

本 SDK 走推模式：爬虫写完即上报。中台无需再为「几点读哪个目录」建配置表；若仍保留本地 JSON，仅作备份或对账即可。
