Metadata-Version: 2.4
Name: pywecom-server
Version: 1.0.0
Summary: 企业微信API服务端SDK，提供企业微信API的基础服务封装，支持同步和异步两种模式。
Home-page: https://gitee.com/guolei19850528/pywecom_server
Author: guolei
Author-email: 174000902@qq.com
License: MIT
Keywords: 企业微信 服务端SDK
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx
Requires-Dist: jsonschema
Requires-Dist: decorator
Requires-Dist: jsonpath-ng
Requires-Dist: diskcache
Requires-Dist: redis
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: license-file
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# pywecom_server

企业微信API服务端SDK，提供企业微信API的基础服务封装，支持同步和异步两种模式。

## 功能特性

- **Access Token管理**: 自动获取、缓存和刷新Access Token
- **缓存支持**: 支持diskcache和Redis两种缓存后端
- **素材上传**: 支持图片、语音、视频、文件等媒体文件上传
- **消息发送**: 支持多种消息类型发送（文本、图片、语音、视频、文件、图文、Markdown等）
- **同步/异步支持**: 所有API均提供同步和异步版本
- **数据验证**: 基于Pydantic的数据模型验证

## 安装

```bash
pip install pywecom_server
```

### 可选依赖

如果需要使用缓存功能，需要安装额外依赖：

```bash
# 使用diskcache缓存
pip install diskcache

# 使用Redis缓存
pip install redis
```

## 快速开始

### 基本用法

```python
from pywecom_server import Server
from pywecom_server.message import Sender
from pywecom_server.msgtypes import Text

# 创建Server实例
server = Server(
    corpid="your_corpid",
    corpsecret="your_corpsecret",
    agentid="your_agentid"
)

# 刷新Access Token
server.refresh_access_token()

# 创建消息发送器
sender = Sender(
    corpid="your_corpid",
    corpsecret="your_corpsecret",
    agentid="your_agentid"
)
sender.refresh_access_token()

# 发送文本消息
content = Text(
    touser="@all",
    text={"content": "Hello, World!"}
)
result = sender.send_text(content)
print(result)
```

### 使用缓存

```python
import diskcache
import redis
from pywecom_server import Server

# 使用diskcache
cache = diskcache.Cache("/path/to/cache")
server = Server(
    corpid="your_corpid",
    corpsecret="your_corpsecret",
    agentid="your_agentid",
    cache_config={
        "instance": cache,
        "key": "pywecom_server_token",
        "expire": 7100
    }
)

# 使用Redis
redis_client = redis.Redis(host="localhost", port=6379, db=0)
server = Server(
    corpid="your_corpid",
    corpsecret="your_corpsecret",
    agentid="your_agentid",
    cache_config={
        "instance": redis_client,
        "key": "pywecom_server_token",
        "expire": 7100
    }
)
```

### 异步模式

```python
import asyncio
from pywecom_server import Server
from pywecom_server.message import Sender
from pywecom_server.msgtypes import Text


async def main():
    # 创建异步Server实例
    server = Server(
        corpid="your_corpid",
        corpsecret="your_corpsecret",
        agentid="your_agentid",
        is_async=True
    )

    # 异步刷新Access Token
    await server.async_refresh_access_token()

    # 创建异步消息发送器
    sender = Sender(
        corpid="your_corpid",
        corpsecret="your_corpsecret",
        agentid="your_agentid",
        is_async=True
    )
    await sender.async_refresh_access_token()

    # 异步发送消息
    content = Text(
        touser="@all",
        text={"content": "Hello, Async World!"}
    )
    result = await sender.async_send_text(content)
    print(result)


asyncio.run(main())
```

## 支持的消息类型

| 消息类型         | 说明                  | 对应类                 |
|:-------------|:--------------------|:--------------------|
| 文本消息         | 纯文本消息               | `Text`              |
| 图片消息         | 图片消息，需先上传获取media_id | `Image`             |
| 语音消息         | 语音消息，需先上传获取media_id | `Voice`             |
| 视频消息         | 视频消息，需先上传获取media_id | `Video`             |
| 文件消息         | 文件消息，需先上传获取media_id | `File`              |
| 文本卡片         | 带有标题、描述和链接的卡片       | `TextCard`          |
| 图文消息         | 图文消息，支持多篇文章         | `News`              |
| 图文消息(mpnews) | 更丰富样式的图文消息          | `MpNews`            |
| Markdown     | Markdown格式消息        | `Markdown`          |
| 小程序通知        | 小程序模板消息             | `MiniprogramNotice` |
| 模板卡片         | 模板卡片消息              | `TemplateCard`      |

## 素材上传

```python
from pywecom_server.material import Uploader

# 创建上传器
uploader = Uploader(
    corpid="your_corpid",
    corpsecret="your_corpsecret",
    agentid="your_agentid"
)
uploader.refresh_access_token()

# 上传图片
with open("image.jpg", "rb") as f:
    media_id = uploader.upload(file_type="image", files={"media": f})
print(f"Image media_id: {media_id}")

# 上传图片获取URL
with open("image.jpg", "rb") as f:
    url = uploader.uploadimg(files={"media": f})
print(f"Image URL: {url}")
```

## API参考

### Server类

#### 方法

| 方法                             | 说明                   |
|:-------------------------------|:---------------------|
| `gettoken()`                   | 获取Access Token       |
| `refresh_access_token()`       | 刷新Access Token（支持缓存） |
| `get_api_domain_ip()`          | 获取API域名IP列表          |
| `getcallbackip()`              | 获取回调IP列表             |
| `async_gettoken()`             | 异步获取Access Token     |
| `async_refresh_access_token()` | 异步刷新Access Token     |
| `async_get_api_domain_ip()`    | 异步获取API域名IP列表        |
| `async_getcallbackip()`        | 异步获取回调IP列表           |

### Sender类

#### 方法

| 方法                          | 说明           |
|:----------------------------|:-------------|
| `send()`                    | 通用消息发送       |
| `send_text()`               | 发送文本消息       |
| `send_image()`              | 发送图片消息       |
| `send_voice()`              | 发送语音消息       |
| `send_video()`              | 发送视频消息       |
| `send_file()`               | 发送文件消息       |
| `send_textcard()`           | 发送文本卡片消息     |
| `send_news()`               | 发送图文消息       |
| `send_mpnews()`             | 发送mpnews消息   |
| `send_markdown()`           | 发送Markdown消息 |
| `send_miniprogram_notice()` | 发送小程序通知      |
| `send_template_card()`      | 发送模板卡片消息     |

### Uploader类

#### 方法

| 方法            | 说明        |
|:--------------|:----------|
| `upload()`    | 上传媒体文件    |
| `uploadimg()` | 上传图片获取URL |

## 配置参数

### Server初始化参数

| 参数              | 类型      | 必填 | 默认值                           | 说明           |
|:----------------|:--------|:---|:------------------------------|:-------------|
| `base_url`      | str     | 否  | `https://qyapi.weixin.qq.com` | 企业微信API基础URL |
| `corpid`        | str     | 是  | -                             | 企业ID         |
| `corpsecret`    | str     | 是  | -                             | 应用密钥         |
| `agentid`       | str/int | 否  | -                             | 企业应用ID       |
| `cache_config`  | dict    | 否  | `{}`                          | 缓存配置         |
| `client_kwargs` | dict    | 否  | `{}`                          | HTTP客户端配置    |
| `is_async`      | bool    | 否  | `False`                       | 是否使用异步模式     |

### cache_config参数

| 参数         | 类型          | 必填 | 默认值                                 | 说明        |
|:-----------|:------------|:---|:------------------------------------|:----------|
| `instance` | Cache/Redis | 否  | `None`                              | 缓存实例      |
| `key`      | str         | 否  | `pywecom_server_{corpid}_{agentid}` | 缓存键名      |
| `expire`   | int         | 否  | `7100`                              | 缓存过期时间（秒） |

## 错误处理

当无法获取有效的Access Token时，会抛出`ValueError`异常：

```python
try:
    server.refresh_access_token()
except ValueError as e:
    print(f"获取Access Token失败: {e}")
```

## 企业微信官方文档

参考企业微信官方文档：[企业微信服务器端API](https://developer.work.weixin.qq.com/document/path/90664)

## 许可证

MIT License

## 作者

郭磊 <174000902@qq.com>
