Metadata-Version: 2.5
Name: py-chanjet-toolkit
Version: 4.1.1
Summary: 畅捷通 T+ Python 扩展包
Project-URL: HomePage, https://gitee.com/guolei19850528/py_chanjet_toolkit
Project-URL: Repository, https://gitee.com/guolei19850528/py_chanjet_toolkit
Author-email: 郭磊 <174000902@qq.com>
License: MIT
License-File: LICENSE
Keywords: T+云API,畅捷通,畅捷通T+
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
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.9
Requires-Dist: httpx<1.0,>=0.24.0
Requires-Dist: pydantic<3.0,>=2.0.0
Provides-Extra: all
Requires-Dist: mkdocs-material>=9.0.0; extra == 'all'
Requires-Dist: mkdocs>=1.5.0; extra == 'all'
Requires-Dist: mypy>=1.10.0; extra == 'all'
Requires-Dist: pre-commit>=3.7.0; extra == 'all'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'all'
Requires-Dist: pytest-cov>=5.0.0; extra == 'all'
Requires-Dist: pytest>=8.0.0; extra == 'all'
Requires-Dist: python-dotenv>=1.0.0; extra == 'all'
Requires-Dist: respx>=0.21.0; extra == 'all'
Requires-Dist: ruff>=0.8.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: mypy>=1.10.0; extra == 'dev'
Requires-Dist: pre-commit>=3.7.0; extra == 'dev'
Requires-Dist: python-dotenv>=1.0.0; extra == 'dev'
Requires-Dist: ruff>=0.8.0; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.0.0; extra == 'docs'
Requires-Dist: mkdocs>=1.5.0; extra == 'docs'
Provides-Extra: test
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'test'
Requires-Dist: pytest-cov>=5.0.0; extra == 'test'
Requires-Dist: pytest>=8.0.0; extra == 'test'
Requires-Dist: python-dotenv>=1.0.0; extra == 'test'
Requires-Dist: respx>=0.21.0; extra == 'test'
Description-Content-Type: text/markdown

# py-chanjet-toolkit

[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

[中文](./README.md) | [English](./README.en.md)

## 功能

- **畅捷通 T+ ZKHB Web Service**：通过 SOAP `GetDataSet` 执行 SQL 查询，支持同步和异步客户端，均支持上下文管理器以自动关闭 HTTP 连接，并提供缴费/退款记录过滤。
- **类型模型**：基于 Pydantic 定义响应模型。

## 安装

```bash
pip install py-chanjet-toolkit
```

使用 uv：

```bash
uv add py-chanjet-toolkit
```

需要开发与测试工具时，从仓库安装：

```bash
uv sync --extra dev --extra test
```

## 包结构

```text
py_chanjet_toolkit/
├── pyproject.toml
├── README.md
├── LICENSE
├── src/
│   └── py_chanjet_toolkit/
│       ├── __init__.py
│       ├── py.typed
│       └── tplus/
│           ├── __init__.py
│           └── zkhb/
│               ├── __init__.py
│               ├── _clients.py      # 内部实现：同步与异步 ZKHB 客户端
│               └── _models.py       # 内部实现：ZKHB 异常、请求构建与响应模型
├── examples/
│   └── tplus/
│       └── zkhb/
│           ├── .env.example
│           ├── get_dataset_async.py     # GetDataSet 异步调用示例
│           └── get_dataset_sync.py      # GetDataSet 同步调用示例
└── tests/
    └── tplus/
        └── zkhb/
            ├── .env.example
            ├── conftest.py
            ├── test_get_dataset_async.py
            └── test_get_dataset_sync.py
```

包根导出 `tplus` 模块，`tplus` 导出 `zkhb` 模块。各模块对外公开的名称带有 `Zkhb` 前缀，避免名称冲突；`_` 开头的文件是内部实现模块。

## 使用

### 1. zkhb 模块 - 畅捷通 T+ ZKHB Web Service

畅捷通 T+ ZKHB 模块通过 `base_url` 和 `endpoint_path` 初始化客户端。`get_dataset` 支持发送 SQL 查询。

#### 1.1 同步查询

```python
from py_chanjet_toolkit.tplus.zkhb import ZkhbClient

with ZkhbClient(
    base_url="https://your-server.example",
    endpoint_path="/estate/webService/ForcelandEstateService.asmx",
) as client:
    response = client.get_dataset("select 1")
    print(response.model_dump())
    print("查询成功:", response.ok)
```

#### 1.2 异步查询

```python
import asyncio

from py_chanjet_toolkit.tplus.zkhb import ZkhbAsyncClient


async def main() -> None:
    async with ZkhbAsyncClient(
        base_url="https://your-server.example",
        endpoint_path="/estate/webService/ForcelandEstateService.asmx",
    ) as client:
        response = await client.get_dataset("select 1")
        print(response.model_dump())
        print("查询成功:", response.ok)


asyncio.run(main())
```

同步客户端可用 `with` 管理连接；异步客户端可用 `async with` 管理连接。也可以分别调用 `ZkhbClient.close()` 和 `ZkhbAsyncClient.aclose()` 手动关闭。

#### 1.3 客户端配置

同步客户端 `ZkhbClient` 和异步客户端 `ZkhbAsyncClient` 使用相同的构造参数：

| 参数 | 必填 | 默认值 | 说明 |
|------|------|--------|------|
| `base_url` | 是 | — | 服务主机地址，包含协议和可选端口。 |
| `endpoint_path` | 是 | — | ASMX 服务接口路径。 |

#### 1.4 GetDataSet 查询参数及响应

`get_dataset(sql)` 支持以下参数：

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `sql` | `str` | 是 | 要执行的 SQL 语句。 |

接口返回 `ZkhbGetDataSetResponse`，其属性 `ok`、`data` 与响应一致；`response.ok` 在查询成功时为 `True`。`response.data` 为 `ZkhbGetDataSetResult`，可调用 `to_dict_list()` 将 XML 行数据转为字典列表。

#### 1.5 构造缴费明细查询

`zkhb_build_query_charge_fee_items_sql` 构造缴费明细查询 SQL，支持可选的列、条件和排序子句。请仅在可信来源构造 SQL 条件；示例中对房间号中的单引号进行 SQL 字符串转义。

#### 1.6 过滤配对的缴费和退款记录

`zkhb_filter_offset_charge_fee_items` 按 `SDate`、`EDate` 对记录分组，并在同一期间内按金额绝对值一一匹配正、负金额记录。成功配对的缴费和退款记录都会从结果中移除；未匹配记录、金额为零或金额无法解析的记录会保留。

#### 1.7 完整示例脚本

项目提供 [GetDataSet 演示脚本](examples/tplus/zkhb/)，支持同步/异步模式、SQL 查询及缴费/退款过滤。可通过环境变量或命令行参数传入服务配置。

```bash
python examples/tplus/zkhb/get_dataset_sync.py
```

```bash
python examples/tplus/zkhb/get_dataset_async.py
```

也可以设置 `BASE_URL`、`ENDPOINT_PATH`、`TEST_ROOM_NO` 和 `START_DATE` 环境变量。

#### 1.8 异常处理

客户端配置无效时会产生 `ValueError`；HTTP 网络请求失败时会产生 `ConnectionError`；SOAP 响应异常时会产生 `RuntimeError`。调用方可根据需要显式处理：

```python
try:
    # 在此处初始化客户端并调用 get_dataset。
    ...
except (ValueError, ConnectionError, RuntimeError) as exc:
    print(f"ZKHB 请求失败：{exc}")
```

## 配置示例与测试

示例脚本读取环境变量；仓库提供 [examples/tplus/zkhb/](examples/tplus/zkhb/) 作为调用示例，支持通过环境变量传入服务配置。

测试配置位于 [tests/tplus/zkhb/.env.example](tests/tplus/zkhb/.env.example)。复制到对应测试目录的 `.env` 并填入有效凭证。配置包含 `BASE_URL`、`ENDPOINT_PATH`、`TEST_ROOM_NO` 和 `START_DATE`。

```bash
pytest
```

测试配置在缺少必需环境变量时会跳过相应测试。pytest 默认配置会输出终端、HTML 和 XML 覆盖率报告。

> **注意：**默认集成测试会向真实 T+ ZKHB 服务发送请求。只有在 `.env` 中配置有效凭据时才会运行真实请求；否则 pytest 会跳过测试。请勿在不适合的环境中执行。

## 开发

```bash
ruff check .
ruff format --check .
python -m compileall -q src examples tests
```

项目支持 Python 3.9 及以上版本。核心依赖包括 httpx 和 Pydantic；开发、测试、文档工具可通过 `pyproject.toml` 中的可选依赖组安装。

## 作者信息

- 作者：郭磊
- 邮箱：174000902@qq.com

## 许可证

本项目基于 [MIT 许可证](LICENSE) 开源。
