2026-03-11 12:26:29 +00:00
|
|
|
|
# @clawd/auth-runtime-py
|
|
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
Python 版本的 OpenClaw Auth Runtime。
|
2026-03-11 12:26:29 +00:00
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
**注意**: 本模块**不加载 .env 文件**,只从环境变量读取配置。
|
2026-03-11 12:26:29 +00:00
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
加载 `.env.local` 应该在具体的 skill 中实现。
|
2026-03-11 12:26:29 +00:00
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
## 项目结构
|
2026-03-11 12:26:29 +00:00
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
```
|
|
|
|
|
|
your-skill/
|
|
|
|
|
|
├── .env.local # 敏感配置(不提交到 git)
|
|
|
|
|
|
├── scripts/
|
|
|
|
|
|
│ ├── main.py # 加载 .env.local 并调用 auth_runtime
|
|
|
|
|
|
│ └── load_env.py # 从 python_auth_runtime 复制
|
|
|
|
|
|
└── pyproject.toml
|
2026-03-11 12:26:29 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
## 安装
|
2026-03-11 12:26:29 +00:00
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-03-11 12:29:29 +00:00
|
|
|
|
uv pip install /path/to/python_auth_runtime
|
2026-03-11 12:26:29 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 使用方式
|
|
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
### 步骤 1: 在具体 skill 中加载 .env.local
|
2026-03-11 12:26:29 +00:00
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
参考 `~/clawd/skills/1688-product-master/scripts/run.ts` 的 `loadEnvLocal()` 实现:
|
|
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
|
# your-skill/scripts/main.py
|
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
import os
|
|
|
|
|
|
|
|
|
|
|
|
def load_env_local():
|
|
|
|
|
|
"""加载 .env.local 文件到环境变量"""
|
|
|
|
|
|
script_dir = Path(__file__).parent
|
|
|
|
|
|
env_local_path = script_dir.parent / ".env.local"
|
|
|
|
|
|
|
|
|
|
|
|
if env_local_path.exists():
|
|
|
|
|
|
with open(env_local_path, "r", encoding="utf-8") as f:
|
|
|
|
|
|
for line in f:
|
|
|
|
|
|
line = line.strip()
|
|
|
|
|
|
if not line or line.startswith("#"):
|
|
|
|
|
|
continue
|
|
|
|
|
|
eq_index = line.find("=")
|
|
|
|
|
|
if eq_index > 0:
|
|
|
|
|
|
key = line[:eq_index].strip()
|
|
|
|
|
|
value = line[eq_index + 1:].strip()
|
|
|
|
|
|
# 去除引号
|
|
|
|
|
|
if (value.startswith('"') and value.endswith('"')) or \
|
|
|
|
|
|
(value.startswith("'") and value.endswith("'")):
|
|
|
|
|
|
value = value[1:-1]
|
|
|
|
|
|
# 只设置尚未存在的环境变量
|
|
|
|
|
|
if key not in os.environ:
|
|
|
|
|
|
os.environ[key] = value
|
|
|
|
|
|
|
|
|
|
|
|
# 在 main() 函数开始时调用
|
|
|
|
|
|
load_env_local()
|
2026-03-11 12:26:29 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
### 步骤 2: 使用 auth_runtime
|
2026-03-11 12:26:29 +00:00
|
|
|
|
|
|
|
|
|
|
```python
|
2026-03-11 12:29:29 +00:00
|
|
|
|
from python_auth_runtime import create_env_config, request_api_with_auto_refresh
|
2026-03-11 12:26:29 +00:00
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
# 创建配置(自动从环境变量读取)
|
2026-03-11 12:26:29 +00:00
|
|
|
|
config = create_env_config()
|
|
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
# 调用 API
|
2026-03-11 12:26:29 +00:00
|
|
|
|
response = request_api_with_auto_refresh(
|
|
|
|
|
|
method="POST",
|
|
|
|
|
|
url=f"{config.auth_base}/ecom/tasks/scrape",
|
|
|
|
|
|
dry_run=False,
|
|
|
|
|
|
config=config,
|
|
|
|
|
|
body={"url": "https://detail.1688.com/offer/123.html"},
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
if response.status == 200:
|
|
|
|
|
|
import json
|
|
|
|
|
|
data = json.loads(response.body)
|
|
|
|
|
|
print("商品价格:", data["price"])
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
### 完整示例
|
2026-03-11 12:26:29 +00:00
|
|
|
|
|
|
|
|
|
|
```python
|
2026-03-11 12:29:29 +00:00
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
# your-skill/scripts/main.py
|
2026-03-11 12:26:29 +00:00
|
|
|
|
import os
|
2026-03-11 12:29:29 +00:00
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
from python_auth_runtime import create_env_config, request_api_with_auto_refresh
|
|
|
|
|
|
|
|
|
|
|
|
def load_env_local():
|
|
|
|
|
|
"""加载 .env.local 文件到环境变量"""
|
|
|
|
|
|
script_dir = Path(__file__).parent
|
|
|
|
|
|
env_local_path = script_dir.parent / ".env.local"
|
|
|
|
|
|
|
|
|
|
|
|
if env_local_path.exists():
|
|
|
|
|
|
with open(env_local_path, "r", encoding="utf-8") as f:
|
|
|
|
|
|
for line in f:
|
|
|
|
|
|
line = line.strip()
|
|
|
|
|
|
if not line or line.startswith("#"):
|
|
|
|
|
|
continue
|
|
|
|
|
|
eq_index = line.find("=")
|
|
|
|
|
|
if eq_index > 0:
|
|
|
|
|
|
key = line[:eq_index].strip()
|
|
|
|
|
|
value = line[eq_index + 1:].strip()
|
|
|
|
|
|
if (value.startswith('"') and value.endswith('"')) or \
|
|
|
|
|
|
(value.startswith("'") and value.endswith("'")):
|
|
|
|
|
|
value = value[1:-1]
|
|
|
|
|
|
if key not in os.environ:
|
|
|
|
|
|
os.environ[key] = value
|
2026-03-11 12:26:29 +00:00
|
|
|
|
|
|
|
|
|
|
def main():
|
2026-03-11 12:29:29 +00:00
|
|
|
|
# 加载 .env.local
|
|
|
|
|
|
load_env_local()
|
|
|
|
|
|
|
|
|
|
|
|
# 创建配置
|
2026-03-11 12:26:29 +00:00
|
|
|
|
config = create_env_config()
|
|
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
# 调用 API
|
2026-03-11 12:26:29 +00:00
|
|
|
|
response = request_api_with_auto_refresh(
|
|
|
|
|
|
method="POST",
|
|
|
|
|
|
url=f"{config.auth_base}/ecom/tasks/scrape",
|
|
|
|
|
|
dry_run=False,
|
|
|
|
|
|
config=config,
|
|
|
|
|
|
body={"url": "https://detail.1688.com/offer/123.html"},
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
print(f"状态:{response.status}")
|
|
|
|
|
|
print(f"响应:{response.body}")
|
2026-03-11 12:26:29 +00:00
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
main()
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
## 环境变量
|
|
|
|
|
|
|
|
|
|
|
|
| 变量 | 默认值 | 说明 |
|
|
|
|
|
|
|------|--------|------|
|
|
|
|
|
|
| `CLIENT_KEY` | **必需** | 客户端密钥 |
|
|
|
|
|
|
| `AUTH_BASE` | `https://api-gw-test.yuanwei-lnc.com` | 认证基础 URL |
|
|
|
|
|
|
| `AUTH_CACHE_DIR` | `/tmp/skill-auth-cache` | 缓存目录 |
|
|
|
|
|
|
| `AUTH_MIN_TTL_SEC` | `60` | 最小令牌 TTL(秒) |
|
|
|
|
|
|
|
|
|
|
|
|
## 命令行参数覆盖
|
2026-03-11 12:26:29 +00:00
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
可以在命令行设置环境变量,优先级高于 `.env.local`:
|
2026-03-11 12:26:29 +00:00
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-03-11 12:29:29 +00:00
|
|
|
|
CLIENT_KEY="override-key" python scripts/main.py
|
2026-03-11 12:26:29 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
## 测试
|
2026-03-11 12:26:29 +00:00
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
```bash
|
|
|
|
|
|
cd /Users/xiaolongxia/Documents/ai-build-app/skills/excel-toolkit/python_auth_runtime
|
|
|
|
|
|
uv run python scripts/example_usage.py
|
2026-03-11 12:26:29 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
## 与 TypeScript 版本对比
|
2026-03-11 12:26:29 +00:00
|
|
|
|
|
2026-03-11 12:29:29 +00:00
|
|
|
|
| 特性 | TypeScript | Python |
|
|
|
|
|
|
|------|-----------|--------|
|
|
|
|
|
|
| 模块 | `@clawd/auth-runtime` | `python_auth_runtime` |
|
|
|
|
|
|
| .env 加载 | skill 自己实现 (`loadEnvLocal()`) | skill 自己实现 (`load_env_local()`) |
|
|
|
|
|
|
| 环境变量 | `process.env` | `os.getenv()` |
|
|
|
|
|
|
| 缓存 | `/tmp/skill-auth-cache` | `/tmp/skill-auth-cache` |
|