# TopStack Python SDK
TopStack Python SDK 是一个用于与 TopStack 平台交互的 Python 客户端库,提供了完整的 API 封装和便捷的使用接口。
## 功能特性
- 🚀 **完整的 API 支持** - 支持 IoT、告警、资产管理、能源管理等所有模块
- 🔧 **易于使用** - 简洁的 API 设计,快速上手
- 🛡️ **类型安全** - 使用 Pydantic 进行数据验证
- 📦 **标准包结构** - 采用现代 Python 包结构,支持 src 布局
- 🧪 **完整测试** - 包含单元测试和集成测试
- 📚 **详细文档** - 提供完整的使用示例和 API 文档
- 🔄 **实时数据** - 支持 NATS 消息总线,实时接收设备数据、状态和告警信息
## 项目结构
```
topstack-sdk-python/
├── LICENSE
├── pyproject.toml # 项目配置
├── README.md # 项目说明
├── src/ # 源代码目录
│ └── topstack_sdk/ # SDK 包
│ ├── __init__.py
│ ├── client.py # 核心客户端
│ ├── alert/ # 告警模块
│ ├── asset/ # 资产管理模块
│ ├── datav/ # 数据可视化模块
│ ├── ems/ # 能源管理模块
│ ├── iot/ # IoT 模块
│ └── nats.py # NATS 消息总线模块
├── tests/ # 测试目录
│ ├── __init__.py
│ ├── test_client.py
│ └── test_iot.py
├── examples/ # 示例代码
│ ├── basic_usage.py
│ └── nats_example.py # NATS 消息总线示例
└── scripts/ # 工具脚本
├── explore_apis.py
└── diagnose_connection.py
```
## 快速开始
### 安装
#### 从 PyPI 安装(推荐)
```bash
pip install topstack-sdk
```
#### 本地安装
```bash
# 克隆仓库
git clone https://github.com/topstack/topstack-sdk-python.git
cd topstack-sdk-python
# 开发模式安装(推荐)
pip install -e .
```
### 基本使用
```python
from topstack_sdk import TopStackClient
from topstack_sdk.iot import IotApi
# 创建客户端
client = TopStackClient(
base_url="http://localhost:8000",
api_key="your-api-key",
project_id="your-project-id"
)
# 使用 IoT API
iot_api = IotApi(client)
# 查询实时数据
data = iot_api.find_last_data("device-id", "point-id")
print(f"当前值: {data.data['value']}")
# 查询设备列表
devices = client.get("/iot/open_api/v1/device/query")
print(f"设备数量: {len(devices.data.items)}")
```
## API 模块
### IoT 模块
```python
from topstack_sdk.iot import IotApi
iot_api = IotApi(client)
# 查询单点实时数据
data = iot_api.find_last_data("device-id", "point-id")
# 批量查询实时数据
points = [{"deviceID": "dev1", "pointID": "point1"}]
batch_data = iot_api.find_last_batch_data(points)
# 设置点位值
iot_api.set_value("device-id", "point-id", 123.45)
# 查询历史数据
history = iot_api.query_history_data(
points=[{"deviceID": "dev1", "pointID": "point1"}],
start="2023-01-01T00:00:00Z",
end="2023-01-01T23:59:59Z"
)
```
### 告警模块
```python
from topstack_sdk.alert import AlertApi
alert_api = AlertApi(client)
# 查询告警级别
alert_levels = alert_api.query_alert_levels()
# 查询告警类型
alert_types = alert_api.query_alert_types()
# 查询告警记录
alert_records = alert_api.query_alert_records(
start="2023-01-01T00:00:00Z",
end="2023-01-01T23:59:59Z",
pageNum=1,
pageSize=10
)
```
### 资产管理模块
```python
from topstack_sdk.asset import AssetApi
asset_api = AssetApi(client)
# 查询工单
work_orders = asset_api.query_work_orders(pageSize=10, pageNum=1)
# 获取工单详情
work_order_detail = asset_api.get_work_order_detail("work-order-id")
```
### 能源管理模块
```python
from topstack_sdk.ems import EmsApi
ems_api = EmsApi(client)
# 查询电表
meters = ems_api.query_meters(pageNum=1, pageSize=10)
# 查询用能单元
sectors = ems_api.query_sectors(pageNum=1, pageSize=10)
```
### NATS 消息总线模块
```python
import asyncio
from topstack_sdk import NatsConfig, create_nats_bus
# 创建 NATS 配置
config = NatsConfig(
addr="nats://localhost:4222", # NATS 服务器地址
token="your_token_here", # 认证令牌(可选)
username="your_username", # 用户名(可选)
password="your_password" # 密码(可选)
)
async def point_data_handler(point_data):
"""处理测点数据"""
print(f"收到测点数据: 设备={point_data.device_id}, 测点={point_data.point_id}, 值={point_data.value}")
async def device_state_handler(device_state):
"""处理设备状态数据"""
status = "在线" if device_state.state == 1 else "离线"
print(f"设备状态变化: 设备={device_state.device_id}, 状态={status}")
async def alert_info_handler(alert_info):
"""处理告警信息"""
print(f"收到告警: ID={alert_info.alert_id}, 标题={alert_info.title}")
async def main():
# 创建 NATS 总线
nats_bus = await create_nats_bus(config)
# 订阅设备测点数据
point_sub = await nats_bus.subscribe_point_data(
"project_id", "device_id", "point_id", point_data_handler
)
# 订阅设备状态数据
device_state_sub = await nats_bus.subscribe_device_state(
"project_id", "device_id", device_state_handler
)
# 订阅告警信息
alert_sub = await nats_bus.subscribe_alert_info(
"project_id", alert_info_handler
)
# 保持连接运行
try:
while True:
await asyncio.sleep(1)
except KeyboardInterrupt:
# 取消订阅并关闭连接
await point_sub.unsubscribe()
await device_state_sub.unsubscribe()
await alert_sub.unsubscribe()
await nats_bus.close()
# 运行
asyncio.run(main())
```
#### 支持的消息类型
- **设备测点数据** (`PointData`): 实时设备测点值
- **设备状态数据** (`DeviceState`): 设备在线/离线状态
- **网关状态数据** (`GatewayState`): 网关在线/离线状态
- **数据通道状态** (`ChannelState`): 数据通道运行状态
- **告警信息** (`AlertInfo`): 实时告警消息
#### 订阅方法
```python
# 订阅设备测点数据
await nats_bus.subscribe_point_data(project_id, device_id, point_id, callback)
# 订阅同设备模型下的测点数据
await nats_bus.subscribe_device_type_data(project_id, device_type_id, point_id, callback)
# 订阅设备状态数据
await nats_bus.subscribe_device_state(project_id, device_id, callback)
# 订阅网关状态数据
await nats_bus.subscribe_gateway_state(project_id, callback)
# 订阅数据通道状态数据
await nats_bus.subscribe_channel_state(project_id, callback)
# 订阅全部告警消息
await nats_bus.subscribe_alert_info(project_id, callback)
# 订阅设备告警信息
await nats_bus.subscribe_device_alert_info(project_id, device_id, callback)
```
## 开发
### 运行测试
```bash
# 安装开发依赖
pip install -e ".[dev]"
# 运行测试
pytest
# 运行测试并生成覆盖率报告
pytest --cov=src/topstack_sdk --cov-report=html
```
### 代码格式化
```bash
# 格式化代码
black src/ tests/
# 排序导入
isort src/ tests/
```
### 类型检查
```bash
# 运行类型检查
mypy src/
```
## 发布到 PyPI
### 构建包
```bash
# 安装构建工具
pip install build twine
# 构建包
python -m build
```
### 发布
```bash
# 检查包
python -m twine check dist/*
# 发布到测试 PyPI
python -m twine upload --repository testpypi dist/*
# 发布到正式 PyPI
python -m twine upload dist/*
```
## 本地使用(不发布到 PyPI)
### 方法一:直接使用源码
```bash
# 克隆仓库
git clone https://github.com/topstack/topstack-sdk-python.git
cd topstack-sdk-python
# 开发模式安装
pip install -e .
# 在代码中使用
python examples/basic_usage.py
```
### 方法二:开发模式安装
```bash
# 在 SDK 目录下执行
pip install -e .
```
### 方法三:构建本地包
```bash
# 构建包
python -m build
# 安装本地包
pip install dist/topstack_sdk-1.0.0-py3-none-any.whl
```
## 配置
### 环境变量
```bash
export TOPSTACK_BASE_URL="http://localhost:8000"
export TOPSTACK_API_KEY="your-api-key"
export TOPSTACK_PROJECT_ID="your-project-id"
```
### 配置文件
```python
# config.py
TOPSTACK_CONFIG = {
"base_url": "http://localhost:8000",
"api_key": "your-api-key",
"project_id": "your-project-id"
}
```
## 故障排除
### 常见问题
1. **模块找不到**
```bash
# 检查 Python 路径
python -c "import sys; print('\n'.join(sys.path))"
# 检查模块是否可导入
python -c "import topstack_sdk; print('SDK 导入成功')"
```
2. **依赖问题**
```bash
# 检查依赖
pip list | grep -E "(requests|pydantic|python-dateutil)"
# 重新安装依赖
pip install . --force-reinstall
```
3. **API 端点问题**
```bash
# 运行 API 探索脚本
python scripts/explore_apis.py
# 运行连接诊断
python scripts/diagnose_connection.py
```
## 贡献
欢迎贡献代码!请遵循以下步骤:
1. Fork 项目
2. 创建功能分支 (`git checkout -b feature/amazing-feature`)
3. 提交更改 (`git commit -m 'Add some amazing feature'`)
4. 推送到分支 (`git push origin feature/amazing-feature`)
5. 打开 Pull Request
## 许可证
本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情。
## 支持
- 📧 邮箱:support@topstack.com
- 🐛 问题反馈:[GitHub Issues](https://github.com/topstack/topstack-sdk-python/issues)
- 📖 文档:[GitHub Wiki](https://github.com/topstack/topstack-sdk-python/wiki)
Raw data
{
"_id": null,
"home_page": "https://github.com/topstack/topstack-sdk-python",
"name": "topstack-sdk",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "TopStack Team <support@topstack.com>",
"keywords": "topstack, iot, api, client, sdk",
"author": "TopStack Team",
"author_email": "TopStack Team <support@topstack.com>",
"download_url": "https://files.pythonhosted.org/packages/e3/26/db46fd6c9bf9629637f179df43a9e52f0cb15f13fe3ca58fd521a0f342cc/topstack_sdk-1.0.2.tar.gz",
"platform": null,
"description": "# TopStack Python SDK\n\nTopStack Python SDK \u662f\u4e00\u4e2a\u7528\u4e8e\u4e0e TopStack \u5e73\u53f0\u4ea4\u4e92\u7684 Python \u5ba2\u6237\u7aef\u5e93\uff0c\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684 API \u5c01\u88c5\u548c\u4fbf\u6377\u7684\u4f7f\u7528\u63a5\u53e3\u3002\n\n## \u529f\u80fd\u7279\u6027\n\n- \ud83d\ude80 **\u5b8c\u6574\u7684 API \u652f\u6301** - \u652f\u6301 IoT\u3001\u544a\u8b66\u3001\u8d44\u4ea7\u7ba1\u7406\u3001\u80fd\u6e90\u7ba1\u7406\u7b49\u6240\u6709\u6a21\u5757\n- \ud83d\udd27 **\u6613\u4e8e\u4f7f\u7528** - \u7b80\u6d01\u7684 API \u8bbe\u8ba1\uff0c\u5feb\u901f\u4e0a\u624b\n- \ud83d\udee1\ufe0f **\u7c7b\u578b\u5b89\u5168** - \u4f7f\u7528 Pydantic \u8fdb\u884c\u6570\u636e\u9a8c\u8bc1\n- \ud83d\udce6 **\u6807\u51c6\u5305\u7ed3\u6784** - \u91c7\u7528\u73b0\u4ee3 Python \u5305\u7ed3\u6784\uff0c\u652f\u6301 src \u5e03\u5c40\n- \ud83e\uddea **\u5b8c\u6574\u6d4b\u8bd5** - \u5305\u542b\u5355\u5143\u6d4b\u8bd5\u548c\u96c6\u6210\u6d4b\u8bd5\n- \ud83d\udcda **\u8be6\u7ec6\u6587\u6863** - \u63d0\u4f9b\u5b8c\u6574\u7684\u4f7f\u7528\u793a\u4f8b\u548c API \u6587\u6863\n- \ud83d\udd04 **\u5b9e\u65f6\u6570\u636e** - \u652f\u6301 NATS \u6d88\u606f\u603b\u7ebf\uff0c\u5b9e\u65f6\u63a5\u6536\u8bbe\u5907\u6570\u636e\u3001\u72b6\u6001\u548c\u544a\u8b66\u4fe1\u606f\n\n## \u9879\u76ee\u7ed3\u6784\n\n```\ntopstack-sdk-python/\n\u251c\u2500\u2500 LICENSE\n\u251c\u2500\u2500 pyproject.toml # \u9879\u76ee\u914d\u7f6e\n\u251c\u2500\u2500 README.md # \u9879\u76ee\u8bf4\u660e\n\u251c\u2500\u2500 src/ # \u6e90\u4ee3\u7801\u76ee\u5f55\n\u2502 \u2514\u2500\u2500 topstack_sdk/ # SDK \u5305\n\u2502 \u251c\u2500\u2500 __init__.py\n\u2502 \u251c\u2500\u2500 client.py # \u6838\u5fc3\u5ba2\u6237\u7aef\n\u2502 \u251c\u2500\u2500 alert/ # \u544a\u8b66\u6a21\u5757\n\u2502 \u251c\u2500\u2500 asset/ # \u8d44\u4ea7\u7ba1\u7406\u6a21\u5757\n\u2502 \u251c\u2500\u2500 datav/ # \u6570\u636e\u53ef\u89c6\u5316\u6a21\u5757\n\u2502 \u251c\u2500\u2500 ems/ # \u80fd\u6e90\u7ba1\u7406\u6a21\u5757\n\u2502 \u251c\u2500\u2500 iot/ # IoT \u6a21\u5757\n\u2502 \u2514\u2500\u2500 nats.py # NATS \u6d88\u606f\u603b\u7ebf\u6a21\u5757\n\u251c\u2500\u2500 tests/ # \u6d4b\u8bd5\u76ee\u5f55\n\u2502 \u251c\u2500\u2500 __init__.py\n\u2502 \u251c\u2500\u2500 test_client.py\n\u2502 \u2514\u2500\u2500 test_iot.py\n\u251c\u2500\u2500 examples/ # \u793a\u4f8b\u4ee3\u7801\n\u2502 \u251c\u2500\u2500 basic_usage.py\n\u2502 \u2514\u2500\u2500 nats_example.py # NATS \u6d88\u606f\u603b\u7ebf\u793a\u4f8b\n\u2514\u2500\u2500 scripts/ # \u5de5\u5177\u811a\u672c\n \u251c\u2500\u2500 explore_apis.py\n \u2514\u2500\u2500 diagnose_connection.py\n```\n\n## \u5feb\u901f\u5f00\u59cb\n\n### \u5b89\u88c5\n\n#### \u4ece PyPI \u5b89\u88c5\uff08\u63a8\u8350\uff09\n\n```bash\npip install topstack-sdk\n```\n\n#### \u672c\u5730\u5b89\u88c5\n\n```bash\n# \u514b\u9686\u4ed3\u5e93\ngit clone https://github.com/topstack/topstack-sdk-python.git\ncd topstack-sdk-python\n\n# \u5f00\u53d1\u6a21\u5f0f\u5b89\u88c5\uff08\u63a8\u8350\uff09\npip install -e .\n```\n\n### \u57fa\u672c\u4f7f\u7528\n\n```python\nfrom topstack_sdk import TopStackClient\nfrom topstack_sdk.iot import IotApi\n\n# \u521b\u5efa\u5ba2\u6237\u7aef\nclient = TopStackClient(\n base_url=\"http://localhost:8000\",\n api_key=\"your-api-key\",\n project_id=\"your-project-id\"\n)\n\n# \u4f7f\u7528 IoT API\niot_api = IotApi(client)\n\n# \u67e5\u8be2\u5b9e\u65f6\u6570\u636e\ndata = iot_api.find_last_data(\"device-id\", \"point-id\")\nprint(f\"\u5f53\u524d\u503c: {data.data['value']}\")\n\n# \u67e5\u8be2\u8bbe\u5907\u5217\u8868\ndevices = client.get(\"/iot/open_api/v1/device/query\")\nprint(f\"\u8bbe\u5907\u6570\u91cf: {len(devices.data.items)}\")\n```\n\n## API \u6a21\u5757\n\n### IoT \u6a21\u5757\n\n```python\nfrom topstack_sdk.iot import IotApi\n\niot_api = IotApi(client)\n\n# \u67e5\u8be2\u5355\u70b9\u5b9e\u65f6\u6570\u636e\ndata = iot_api.find_last_data(\"device-id\", \"point-id\")\n\n# \u6279\u91cf\u67e5\u8be2\u5b9e\u65f6\u6570\u636e\npoints = [{\"deviceID\": \"dev1\", \"pointID\": \"point1\"}]\nbatch_data = iot_api.find_last_batch_data(points)\n\n# \u8bbe\u7f6e\u70b9\u4f4d\u503c\niot_api.set_value(\"device-id\", \"point-id\", 123.45)\n\n# \u67e5\u8be2\u5386\u53f2\u6570\u636e\nhistory = iot_api.query_history_data(\n points=[{\"deviceID\": \"dev1\", \"pointID\": \"point1\"}],\n start=\"2023-01-01T00:00:00Z\",\n end=\"2023-01-01T23:59:59Z\"\n)\n```\n\n### \u544a\u8b66\u6a21\u5757\n\n```python\nfrom topstack_sdk.alert import AlertApi\n\nalert_api = AlertApi(client)\n\n# \u67e5\u8be2\u544a\u8b66\u7ea7\u522b\nalert_levels = alert_api.query_alert_levels()\n\n# \u67e5\u8be2\u544a\u8b66\u7c7b\u578b\nalert_types = alert_api.query_alert_types()\n\n# \u67e5\u8be2\u544a\u8b66\u8bb0\u5f55\nalert_records = alert_api.query_alert_records(\n start=\"2023-01-01T00:00:00Z\",\n end=\"2023-01-01T23:59:59Z\",\n pageNum=1,\n pageSize=10\n)\n```\n\n### \u8d44\u4ea7\u7ba1\u7406\u6a21\u5757\n\n```python\nfrom topstack_sdk.asset import AssetApi\n\nasset_api = AssetApi(client)\n\n# \u67e5\u8be2\u5de5\u5355\nwork_orders = asset_api.query_work_orders(pageSize=10, pageNum=1)\n\n# \u83b7\u53d6\u5de5\u5355\u8be6\u60c5\nwork_order_detail = asset_api.get_work_order_detail(\"work-order-id\")\n```\n\n### \u80fd\u6e90\u7ba1\u7406\u6a21\u5757\n\n```python\nfrom topstack_sdk.ems import EmsApi\n\nems_api = EmsApi(client)\n\n# \u67e5\u8be2\u7535\u8868\nmeters = ems_api.query_meters(pageNum=1, pageSize=10)\n\n# \u67e5\u8be2\u7528\u80fd\u5355\u5143\nsectors = ems_api.query_sectors(pageNum=1, pageSize=10)\n```\n\n### NATS \u6d88\u606f\u603b\u7ebf\u6a21\u5757\n\n```python\nimport asyncio\nfrom topstack_sdk import NatsConfig, create_nats_bus\n\n# \u521b\u5efa NATS \u914d\u7f6e\nconfig = NatsConfig(\n addr=\"nats://localhost:4222\", # NATS \u670d\u52a1\u5668\u5730\u5740\n token=\"your_token_here\", # \u8ba4\u8bc1\u4ee4\u724c\uff08\u53ef\u9009\uff09\n username=\"your_username\", # \u7528\u6237\u540d\uff08\u53ef\u9009\uff09\n password=\"your_password\" # \u5bc6\u7801\uff08\u53ef\u9009\uff09\n)\n\nasync def point_data_handler(point_data):\n \"\"\"\u5904\u7406\u6d4b\u70b9\u6570\u636e\"\"\"\n print(f\"\u6536\u5230\u6d4b\u70b9\u6570\u636e: \u8bbe\u5907={point_data.device_id}, \u6d4b\u70b9={point_data.point_id}, \u503c={point_data.value}\")\n\nasync def device_state_handler(device_state):\n \"\"\"\u5904\u7406\u8bbe\u5907\u72b6\u6001\u6570\u636e\"\"\"\n status = \"\u5728\u7ebf\" if device_state.state == 1 else \"\u79bb\u7ebf\"\n print(f\"\u8bbe\u5907\u72b6\u6001\u53d8\u5316: \u8bbe\u5907={device_state.device_id}, \u72b6\u6001={status}\")\n\nasync def alert_info_handler(alert_info):\n \"\"\"\u5904\u7406\u544a\u8b66\u4fe1\u606f\"\"\"\n print(f\"\u6536\u5230\u544a\u8b66: ID={alert_info.alert_id}, \u6807\u9898={alert_info.title}\")\n\nasync def main():\n # \u521b\u5efa NATS \u603b\u7ebf\n nats_bus = await create_nats_bus(config)\n \n # \u8ba2\u9605\u8bbe\u5907\u6d4b\u70b9\u6570\u636e\n point_sub = await nats_bus.subscribe_point_data(\n \"project_id\", \"device_id\", \"point_id\", point_data_handler\n )\n \n # \u8ba2\u9605\u8bbe\u5907\u72b6\u6001\u6570\u636e\n device_state_sub = await nats_bus.subscribe_device_state(\n \"project_id\", \"device_id\", device_state_handler\n )\n \n # \u8ba2\u9605\u544a\u8b66\u4fe1\u606f\n alert_sub = await nats_bus.subscribe_alert_info(\n \"project_id\", alert_info_handler\n )\n \n # \u4fdd\u6301\u8fde\u63a5\u8fd0\u884c\n try:\n while True:\n await asyncio.sleep(1)\n except KeyboardInterrupt:\n # \u53d6\u6d88\u8ba2\u9605\u5e76\u5173\u95ed\u8fde\u63a5\n await point_sub.unsubscribe()\n await device_state_sub.unsubscribe()\n await alert_sub.unsubscribe()\n await nats_bus.close()\n\n# \u8fd0\u884c\nasyncio.run(main())\n```\n\n#### \u652f\u6301\u7684\u6d88\u606f\u7c7b\u578b\n\n- **\u8bbe\u5907\u6d4b\u70b9\u6570\u636e** (`PointData`): \u5b9e\u65f6\u8bbe\u5907\u6d4b\u70b9\u503c\n- **\u8bbe\u5907\u72b6\u6001\u6570\u636e** (`DeviceState`): \u8bbe\u5907\u5728\u7ebf/\u79bb\u7ebf\u72b6\u6001\n- **\u7f51\u5173\u72b6\u6001\u6570\u636e** (`GatewayState`): \u7f51\u5173\u5728\u7ebf/\u79bb\u7ebf\u72b6\u6001\n- **\u6570\u636e\u901a\u9053\u72b6\u6001** (`ChannelState`): \u6570\u636e\u901a\u9053\u8fd0\u884c\u72b6\u6001\n- **\u544a\u8b66\u4fe1\u606f** (`AlertInfo`): \u5b9e\u65f6\u544a\u8b66\u6d88\u606f\n\n#### \u8ba2\u9605\u65b9\u6cd5\n\n```python\n# \u8ba2\u9605\u8bbe\u5907\u6d4b\u70b9\u6570\u636e\nawait nats_bus.subscribe_point_data(project_id, device_id, point_id, callback)\n\n# \u8ba2\u9605\u540c\u8bbe\u5907\u6a21\u578b\u4e0b\u7684\u6d4b\u70b9\u6570\u636e\nawait nats_bus.subscribe_device_type_data(project_id, device_type_id, point_id, callback)\n\n# \u8ba2\u9605\u8bbe\u5907\u72b6\u6001\u6570\u636e\nawait nats_bus.subscribe_device_state(project_id, device_id, callback)\n\n# \u8ba2\u9605\u7f51\u5173\u72b6\u6001\u6570\u636e\nawait nats_bus.subscribe_gateway_state(project_id, callback)\n\n# \u8ba2\u9605\u6570\u636e\u901a\u9053\u72b6\u6001\u6570\u636e\nawait nats_bus.subscribe_channel_state(project_id, callback)\n\n# \u8ba2\u9605\u5168\u90e8\u544a\u8b66\u6d88\u606f\nawait nats_bus.subscribe_alert_info(project_id, callback)\n\n# \u8ba2\u9605\u8bbe\u5907\u544a\u8b66\u4fe1\u606f\nawait nats_bus.subscribe_device_alert_info(project_id, device_id, callback)\n```\n\n## \u5f00\u53d1\n\n### \u8fd0\u884c\u6d4b\u8bd5\n\n```bash\n# \u5b89\u88c5\u5f00\u53d1\u4f9d\u8d56\npip install -e \".[dev]\"\n\n# \u8fd0\u884c\u6d4b\u8bd5\npytest\n\n# \u8fd0\u884c\u6d4b\u8bd5\u5e76\u751f\u6210\u8986\u76d6\u7387\u62a5\u544a\npytest --cov=src/topstack_sdk --cov-report=html\n```\n\n### \u4ee3\u7801\u683c\u5f0f\u5316\n\n```bash\n# \u683c\u5f0f\u5316\u4ee3\u7801\nblack src/ tests/\n\n# \u6392\u5e8f\u5bfc\u5165\nisort src/ tests/\n```\n\n### \u7c7b\u578b\u68c0\u67e5\n\n```bash\n# \u8fd0\u884c\u7c7b\u578b\u68c0\u67e5\nmypy src/\n```\n\n## \u53d1\u5e03\u5230 PyPI\n\n### \u6784\u5efa\u5305\n\n```bash\n# \u5b89\u88c5\u6784\u5efa\u5de5\u5177\npip install build twine\n\n# \u6784\u5efa\u5305\npython -m build\n```\n\n### \u53d1\u5e03\n\n```bash\n# \u68c0\u67e5\u5305\npython -m twine check dist/*\n\n# \u53d1\u5e03\u5230\u6d4b\u8bd5 PyPI\npython -m twine upload --repository testpypi dist/*\n\n# \u53d1\u5e03\u5230\u6b63\u5f0f PyPI\npython -m twine upload dist/*\n```\n\n## \u672c\u5730\u4f7f\u7528\uff08\u4e0d\u53d1\u5e03\u5230 PyPI\uff09\n\n### \u65b9\u6cd5\u4e00\uff1a\u76f4\u63a5\u4f7f\u7528\u6e90\u7801\n\n```bash\n# \u514b\u9686\u4ed3\u5e93\ngit clone https://github.com/topstack/topstack-sdk-python.git\ncd topstack-sdk-python\n\n# \u5f00\u53d1\u6a21\u5f0f\u5b89\u88c5\npip install -e .\n\n# \u5728\u4ee3\u7801\u4e2d\u4f7f\u7528\npython examples/basic_usage.py\n```\n\n### \u65b9\u6cd5\u4e8c\uff1a\u5f00\u53d1\u6a21\u5f0f\u5b89\u88c5\n\n```bash\n# \u5728 SDK \u76ee\u5f55\u4e0b\u6267\u884c\npip install -e .\n```\n\n### \u65b9\u6cd5\u4e09\uff1a\u6784\u5efa\u672c\u5730\u5305\n\n```bash\n# \u6784\u5efa\u5305\npython -m build\n\n# \u5b89\u88c5\u672c\u5730\u5305\npip install dist/topstack_sdk-1.0.0-py3-none-any.whl\n```\n\n## \u914d\u7f6e\n\n### \u73af\u5883\u53d8\u91cf\n\n```bash\nexport TOPSTACK_BASE_URL=\"http://localhost:8000\"\nexport TOPSTACK_API_KEY=\"your-api-key\"\nexport TOPSTACK_PROJECT_ID=\"your-project-id\"\n```\n\n### \u914d\u7f6e\u6587\u4ef6\n\n```python\n# config.py\nTOPSTACK_CONFIG = {\n \"base_url\": \"http://localhost:8000\",\n \"api_key\": \"your-api-key\",\n \"project_id\": \"your-project-id\"\n}\n```\n\n## \u6545\u969c\u6392\u9664\n\n### \u5e38\u89c1\u95ee\u9898\n\n1. **\u6a21\u5757\u627e\u4e0d\u5230**\n ```bash\n # \u68c0\u67e5 Python \u8def\u5f84\n python -c \"import sys; print('\\n'.join(sys.path))\"\n \n # \u68c0\u67e5\u6a21\u5757\u662f\u5426\u53ef\u5bfc\u5165\n python -c \"import topstack_sdk; print('SDK \u5bfc\u5165\u6210\u529f')\"\n ```\n\n2. **\u4f9d\u8d56\u95ee\u9898**\n ```bash\n # \u68c0\u67e5\u4f9d\u8d56\n pip list | grep -E \"(requests|pydantic|python-dateutil)\"\n \n # \u91cd\u65b0\u5b89\u88c5\u4f9d\u8d56\n pip install . --force-reinstall\n ```\n\n3. **API \u7aef\u70b9\u95ee\u9898**\n ```bash\n # \u8fd0\u884c API \u63a2\u7d22\u811a\u672c\n python scripts/explore_apis.py\n \n # \u8fd0\u884c\u8fde\u63a5\u8bca\u65ad\n python scripts/diagnose_connection.py\n ```\n\n## \u8d21\u732e\n\n\u6b22\u8fce\u8d21\u732e\u4ee3\u7801\uff01\u8bf7\u9075\u5faa\u4ee5\u4e0b\u6b65\u9aa4\uff1a\n\n1. Fork \u9879\u76ee\n2. \u521b\u5efa\u529f\u80fd\u5206\u652f (`git checkout -b feature/amazing-feature`)\n3. \u63d0\u4ea4\u66f4\u6539 (`git commit -m 'Add some amazing feature'`)\n4. \u63a8\u9001\u5230\u5206\u652f (`git push origin feature/amazing-feature`)\n5. \u6253\u5f00 Pull Request\n\n## \u8bb8\u53ef\u8bc1\n\n\u672c\u9879\u76ee\u91c7\u7528 MIT \u8bb8\u53ef\u8bc1 - \u67e5\u770b [LICENSE](LICENSE) \u6587\u4ef6\u4e86\u89e3\u8be6\u60c5\u3002\n\n## \u652f\u6301\n\n- \ud83d\udce7 \u90ae\u7bb1\uff1asupport@topstack.com\n- \ud83d\udc1b \u95ee\u9898\u53cd\u9988\uff1a[GitHub Issues](https://github.com/topstack/topstack-sdk-python/issues)\n- \ud83d\udcd6 \u6587\u6863\uff1a[GitHub Wiki](https://github.com/topstack/topstack-sdk-python/wiki) \n",
"bugtrack_url": null,
"license": "MIT",
"summary": "TopStack Python SDK - \u7528\u4e8e\u4e0e TopStack \u5e73\u53f0\u4ea4\u4e92\u7684 Python \u5ba2\u6237\u7aef\u5e93",
"version": "1.0.2",
"project_urls": {
"Bug Tracker": "https://github.com/topstack/topstack-sdk-python/issues",
"Documentation": "https://github.com/topstack/topstack-sdk-python/blob/main/README.md",
"Homepage": "https://github.com/topstack/topstack-sdk-python",
"Repository": "https://github.com/topstack/topstack-sdk-python"
},
"split_keywords": [
"topstack",
" iot",
" api",
" client",
" sdk"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "f5ebabe135eb9f79e88b4a24c22e9f9e96bf22806b197976c6bae0852e82a474",
"md5": "39ac93be65fa916e16e83b94425fad74",
"sha256": "e2c36c03a77ce7ede83137db514d53755731bb74ea0b394bb8836ac4627a9752"
},
"downloads": -1,
"filename": "topstack_sdk-1.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "39ac93be65fa916e16e83b94425fad74",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 21594,
"upload_time": "2025-08-05T07:53:32",
"upload_time_iso_8601": "2025-08-05T07:53:32.918583Z",
"url": "https://files.pythonhosted.org/packages/f5/eb/abe135eb9f79e88b4a24c22e9f9e96bf22806b197976c6bae0852e82a474/topstack_sdk-1.0.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "e326db46fd6c9bf9629637f179df43a9e52f0cb15f13fe3ca58fd521a0f342cc",
"md5": "2ed1cf0854a29f2e1dbce92a769a1913",
"sha256": "1f742442bb69aa7c8fc67b30aacbac280d0d4881b31fcd2f9b8b9a77e36b9b8d"
},
"downloads": -1,
"filename": "topstack_sdk-1.0.2.tar.gz",
"has_sig": false,
"md5_digest": "2ed1cf0854a29f2e1dbce92a769a1913",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 23576,
"upload_time": "2025-08-05T07:53:34",
"upload_time_iso_8601": "2025-08-05T07:53:34.311444Z",
"url": "https://files.pythonhosted.org/packages/e3/26/db46fd6c9bf9629637f179df43a9e52f0cb15f13fe3ca58fd521a0f342cc/topstack_sdk-1.0.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-05 07:53:34",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "topstack",
"github_project": "topstack-sdk-python",
"github_not_found": true,
"lcname": "topstack-sdk"
}