Metadata-Version: 2.4
Name: py_wisharetec_toolkit
Version: 3.0.0
Summary: 浙江慧享科技有限公司 - 善数・慧享云运营平台 Python 扩展包，提供接口调用封装
Author-email: guolei <174000902@qq.com>
License: MIT
Project-URL: Homepage, https://gitee.com/guolei19850528/py_wisharetec_toolkit
Keywords: wisharetec,wisharetec_toolkit,shanshu,saas.wisharetec.com,saas toolkit
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
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: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.24.0
Requires-Dist: pydantic>=2.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
Requires-Dist: black; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Provides-Extra: cache
Requires-Dist: diskcache>=5.0; extra == "cache"
Requires-Dist: redis>=5.0; extra == "cache"

# py_wisharetec_toolkit

浙江慧享科技有限公司 - 善数・慧享云运营平台 Python 扩展包。

本包封装了善数・慧享云运营平台 (https://saas.wisharetec.com/) 的各类 API 接口，提供同步客户端 `ShanshuClient` 和异步客户端 `AsyncShanshuClient`，供他人调用。

**作者**：guolei <174000902@qq.com>  
**项目主页**：https://gitee.com/guolei19850528/py_wisharetec_toolkit

## 安装

```bash
pip install py_wisharetec_toolkit
```

或从本地源码安装（开发模式）：

```bash
pip install -e .
```

带缓存依赖安装（diskcache / redis）：

```bash
pip install py_wisharetec_toolkit[cache]
```

或从本地源码安装（开发模式，带缓存依赖）：

```bash
pip install -e ".[cache]"
```

## 快速开始

### 同步客户端

```python
from py_wisharetec_toolkit.shanshu.client import ShanshuClient
from py_wisharetec_toolkit.shanshu.auth import DiskCacheTokenCache

# 从环境变量读取账号和密码（不建议在代码中硬编码）
import os

account = os.environ.get("SHANSHU_TEST_ACCOUNT", "")
password = os.environ.get("SHANSHU_TEST_PASSWORD", "")

# 创建客户端（token 自动缓存到 diskcache）
token_cache = DiskCacheTokenCache(cache_dir=".runtime/cache/diskcache", table="token")
client = ShanshuClient(
    account=account,
    password=password,
    token_cache=token_cache,
)

# 登录
client.login(account, password)

# 查询园区档案
from py_wisharetec_toolkit.shanshu.models import PageQueryParams
params = PageQueryParams(
    conditions={
        "fields": [
            {"map": {}, "method": 1, "name": "spaceTreeId", "value": "73"},
            {"map": {}, "method": 1, "name": "flag", "value": 0},
        ]
    },
    page_num=1,
    page_size=20,
)
resp = client.query_community_with_paginator(params=params)
print(resp.ok, resp.total, len(resp.records))

client.close()
```

### 异步客户端

```python
import asyncio
import os
from py_wisharetec_toolkit.shanshu.auth import DiskCacheTokenCache
from py_wisharetec_toolkit.shanshu.client import AsyncShanshuClient
from py_wisharetec_toolkit.shanshu.models import PageQueryParams

async def main():
    token_cache = DiskCacheTokenCache(cache_dir=".runtime/cache/diskcache", table="token")
    account = os.environ.get("SHANSHU_TEST_ACCOUNT", "")
    password = os.environ.get("SHANSHU_TEST_PASSWORD", "")
    
    async with AsyncShanshuClient(
        account=account,
        password=password,
        token_cache=token_cache,
    ) as client:
        await client.async_login(account, password)
        
        params = PageQueryParams(
            conditions={
                "fields": [
                    {"map": {}, "method": 1, "name": "spaceTreeId", "value": "73"},
                    {"map": {}, "method": 1, "name": "flag", "value": 0},
                ]
            },
            page_num=1,
            page_size=20,
        )
        resp = await client.async_query_community_with_paginator(params=params)
        print(resp.ok, resp.total, len(resp.records))

asyncio.run(main())
```

## 已实现的接口

| 接口 | 方法 | 路径 | 返回模型 |
|------|------|------|----------|
| 登录 | `login` / `async_login` | `/api/user/loginInteractive` | `LoginResponse` |
| 园区档案 | `query_community_with_paginator` / `async_query_community_with_paginator` | `/api/space/community/v2/frontPage` | `CommunityPageResponse` |
| 房产档案 | `query_property_with_paginator` / `async_query_property_with_paginator` | `/api/space/property/propertyPage` | `PropertyPageResponse` |
| 车场档案 | `query_yard_archive_with_paginator` / `async_query_yard_archive_with_paginator` | `/api/space/space/yardArchivePage` | `YardArchivePageResponse` |
| 楼幢档案 | `query_building_with_paginator` / `async_query_building_with_paginator` | `/api/space/property/getSpaceBuildingPage` | `BuildingPageResponse` |
| 用户档案 | `query_resident_with_paginator` / `async_query_resident_with_paginator` | `/api/user/residentInfo/getResidentPage` | `ResidentPageResponse` |
| 业主档案 | `query_archive_with_paginator` / `async_query_archive_with_paginator` | `/api/space/archive/examine/page` | `ArchivePageResponse` |
| 车辆档案 | `query_car_manage_with_paginator` / `async_query_car_manage_with_paginator` | `/api/space/carManage/pageCarManage` | `CarManagePageResponse` |
| 车位档案 | `query_parking_with_paginator` / `async_query_parking_with_paginator` | `/api/space/parking/parkingPage` | `ParkingPageResponse` |
| 工单档案 | `query_work_order_with_paginator` / `async_query_work_order_with_paginator` | `/api/woreport/task/query/page` | `WorkOrderPageResponse` |
| 商城订单 | `query_mall_order_with_paginator` / `async_query_mall_order_with_paginator` | `/api/retailmall/order/pageFront` | `MallOrderPageResponse` |
| 服务订单 | `query_service_order_with_paginator` / `async_query_service_order_with_paginator` | `/api/houseserve/order/pageFront` | `ServiceOrderPageResponse` |
| 审批数据 | `query_approval_with_paginator` / `async_query_approval_with_paginator` | `/api/bpm/process/approval` | `ApprovalPageResponse` |
| 审批详情 | `query_approval_detail` / `async_query_approval_detail` | `/api/bpm/process/progress/{instance_id}/{node_id}` | `ApprovalDetailRecord` |
| 业主详情 | `query_owner_detail` / `async_query_owner_detail` | `/api/space/archive/archive/detailSensitive` | `OwnerDetailRecord` |

所有分页接口均使用 `PageQueryParams` 模型封装查询参数，包含 `conditions`、`count`、`last`、`order_by`、`page_num`、`page_size` 字段。

## Token 缓存

客户端支持三种 Token 缓存后端：

- `MemoryTokenCache`：进程内内存缓存（默认，无需额外依赖）
- `DiskCacheTokenCache`：基于 diskcache 的持久化缓存（默认依赖）
- `RedisTokenCache`：基于 redis 的缓存（默认依赖）

缓存 key 格式：`py_wisharetec_toolkit:shanshu:authorization_token:{account}`，便于缓存不同用户的登录 token。

## 目录结构

```text
src/py_wisharetec_toolkit/
├── __init__.py          # 顶层包
├── py.typed             # PEP 561 类型标记
└── shanshu/             # 子包，供他人调用
    ├── __init__.py
    ├── client.py        # 同步客户端 ShanshuClient
    ├── async_client.py  # 异步客户端 AsyncShanshuClient（已合并到 client.py）
    ├── auth.py          # Token 缓存与认证
    ├── models.py        # pydantic 响应模型
    └── hello.py         # 示例模块
```

## 参数说明

所有分页查询接口均使用 `PageQueryParams` 模型：

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| conditions | dict\|None | None | 查询条件 |
| count | bool | True | 是否返回总记录数 |
| last | bool | True | 是否返回 last 标志 |
| order_by | list\|None | None | 排序字段列表 |
| page_num | int | 1 | 页码 |
| page_size | int | 20 | 每页大小 |

## 许可证

MIT License
