Metadata-Version: 2.4
Name: snowland-qyweixin
Version: 0.1.0
Summary: toolkit for qyweixin. 企业微信开发SDK。
Home-page: https://gitee.com/snowlandltd/snowland-qyweixin-python
Author: A.Star
Author-email: astar@snowland.ltd
Maintainer: A.Star
Maintainer-email: astar@snowland.ltd
License: Apache v2.0
Platform: all
Classifier: Operating System :: OS Independent
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: Implementation
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Topic :: Software Development :: Libraries
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: snowland-smx
Requires-Dist: snowland-http>=0.2.0
Requires-Dist: easydict
Provides-Extra: requests
Requires-Dist: requests; extra == "requests"
Provides-Extra: httpx
Requires-Dist: httpx; extra == "httpx"
Provides-Extra: aiohttp
Requires-Dist: aiohttp; extra == "aiohttp"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license
Dynamic: license-file
Dynamic: maintainer
Dynamic: maintainer-email
Dynamic: platform
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: summary

# snowland-qyweixin-python

![version](https://img.shields.io/badge/version-0.1.0-blue)
![license](https://img.shields.io/badge/license-Apache--2.0-blue)
![python](https://img.shields.io/badge/python-3.8%2B-blue)
![platform](https://img.shields.io/badge/platform-win32%20%7C%20linux%20%7C%20macOS-lightgrey)
![backend](https://img.shields.io/badge/backend-requests%20%7C%20httpx%20%7C%20aiohttp-orange)
![tests](https://img.shields.io/badge/tests-unittest-blueviolet)

#### Description
Unofficial open-source SDK for WeCom (Enterprise WeChat), built on top of `snowland-http`.

This SDK provides a unified, rate-limited HTTP transport layer via `snowland-http`.
Every client exposes **both synchronous and asynchronous (asyncio)** APIs, backed by
`requests` / `httpx` respectively.

#### Installation

Core dependencies (no concrete HTTP library — only the `snowland-http` transport abstraction):

```bash
pip install -r requirements.txt
```

HTTP backends are all optional: you can `import` and use the SDK without any backend installed, but calling the corresponding sync/async request methods will raise a clear message at runtime. **Install only one of them as needed** (do not install all at once):

```bash
pip install snowland-qyweixin[requests]   # sync only
pip install snowland-qyweixin[httpx]      # sync + async (recommended, one library covers both)
pip install snowland-qyweixin[aiohttp]    # async only
# or install a single one manually:
pip install requests / httpx / aiohttp
```

#### Quick Start

Synchronous client:

```python
from qywechat import MessageClient

client = MessageClient(corpid="xxx", corpsecret="yyy", agentid=1000001)
client.send_text("hello", touser=["zhangsan", "lisi"])
```

Asynchronous client:

```python
import asyncio
from qywechat import MessageClient

async def main():
    client = MessageClient(corpid="xxx", corpsecret="yyy", agentid=1000001)
    await client.send_text_async("hello", touser="zhangsan")

asyncio.run(main())
```

Group robot (Webhook):

```python
from qywechat import Robot

robot = Robot("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxx")
robot.send_markdown("**hello**")
```

#### Modules

Each client class provides **both synchronous and asynchronous methods**: the synchronous
method uses the feature name (e.g. `send_text`), and the corresponding async method appends
the `_async` suffix (e.g. `send_text_async`).

| Module | Client Class | Features |
| --- | --- | --- |
| `message` | `MessageClient` | Application messages (text/markdown/image/voice/video/file/textcard/news), group chat management (create/update/get) and group chat message sending |
| `oa` | `OAClient` | Approval: get approval number list, approval detail, submit approval application |
| `contact` | `ContactClient` | Contacts: CRUD for members and departments |
| `external_contact` | `ExternalContactClient` | External contact (customer acquisition): follow-user list, customer list, customer detail |
| `robot` | `Robot` | Group robot: text/markdown/image/news/file messages and media upload |

#### Tests

```bash
python -m unittest discover -s qywechat/tests -p "test_*.py"
```

#### Notes
- `BaseClient` holds both a synchronous and an asynchronous `HttpClient`, and `access_token` is reused within its validity period.
- Synchronous methods only require **any one synchronous library** (candidates: `requests`, `httpx`); async methods only require **any one asynchronous library** (candidates: `httpx`, `aiohttp`). A missing library raises a clear message only when the corresponding method is actually used.
- Global token-bucket rate limiting can be enabled via `rate_limit=RateLimitConfig(...)`.
