问题与目标
平台工作流发布后,Python 服务还要处理认证、输入映射、流式事件、错误和超时。本篇以 Dify Workflow Service API 为主实现一个流式客户端,再说明 Coze 的对应调用方式。令牌只从环境变量读取,不写进源码或日志。
核心概念
调用平台 API 时要区分三层契约:
- HTTP 契约:Endpoint、Bearer Token、超时和状态码;
- 工作流契约:
inputs的名称、类型和必填项; - 事件契约:开始、节点输出、结束和错误如何映射到本地事件。
SSE 是一条逐事件返回的 HTTP 响应。客户端不能把每个网络数据块当成一条完整 JSON,而应按空行分隔事件,并解析其中的 data: 行。
可运行实现
python -m pip install "httpx>=0.27,<1"
export DIFY_BASE_URL="https://api.dify.ai/v1"
export DIFY_API_KEY="替换为已发布应用的密钥"
import json
import os
from collections.abc import Iterator
import httpx
def iter_sse_data(lines: Iterator[str]) -> Iterator[dict]:
data_lines: list[str] = []
for line in lines:
if line == "":
if data_lines:
yield json.loads("\n".join(data_lines))
data_lines.clear()
continue
if line.startswith("data:"):
data_lines.append(line[5:].lstrip())
if data_lines:
yield json.loads("\n".join(data_lines))
def run_dify_workflow(inputs: dict, user_id: str) -> Iterator[dict]:
base_url = os.environ["DIFY_BASE_URL"].rstrip("/")
token = os.environ["DIFY_API_KEY"]
payload = {"inputs": inputs, "response_mode": "streaming", "user": user_id}
timeout = httpx.Timeout(connect=5, read=120, write=10, pool=5)
with httpx.Client(timeout=timeout) as client:
with client.stream(
"POST",
f"{base_url}/workflows/run",
headers={"Authorization": f"Bearer {token}"},
json=payload,
) as response:
response.raise_for_status()
for event in iter_sse_data(response.iter_lines()):
event_type = event.get("event", "unknown")
yield {"type": event_type, "data": event}
if event_type in {"workflow_finished", "error"}:
return
for item in run_dify_workflow(
{"device_id": "AX-3", "status": "offline", "temperature": 31},
user_id="user-17",
):
print(json.dumps(item, ensure_ascii=False))
不要只寻找文本片段。业务结果通常位于结束事件的输出字段中,应根据自己发布的工作流版本做 Schema 校验;未收到结束事件、收到 error 或流意外断开都算失败。
Coze 的中国站工作流 API 使用 https://api.coze.cn/v1/workflow/run 执行非流式调用,长任务可使用 /v1/workflow/stream_run。请求通常包含已发布的 workflow_id 和 parameters,同样使用 Bearer Token。两家平台字段不同,建议分别写适配器,再统一映射成本地事件:
{"type": "started|progress|completed|failed", "run_id": "...", "payload": {}}
常见问题与排查
返回 401 或 403
检查令牌是否属于目标工作空间、应用或工作流是否发布、令牌是否具备相应权限。不要把完整令牌打印到异常日志。
返回 200,但没有业务结果
流式响应的 200 只表示连接建立成功。继续读取到完成或错误事件,并验证结束输出。
中文或多行 JSON 解析失败
使用 UTF-8,并按 SSE 事件边界拼接所有 data: 行。不要对任意 TCP chunk 直接 json.loads()。
工作流字段更新后线上报错
为每次发布保存契约版本和回归样例。调用方对输入与结束输出做 Schema 校验,避免静默接受缺失字段。
小结
平台调用的稳定性来自契约和适配层,而不是一段 POST 请求。令牌外置、正确解析 SSE、识别终止事件并校验最终输出,才能把 Coze/Dify 工作流可靠接入 Python 服务。
许可协议:CC BY-NC 4.0
更新于 1 小时前
觉得文章有帮助?点个赞吧!
0 条评论


