Files

50 lines
2.1 KiB
Python

# requires: fastapi, pydantic
"""给 Dify / Coze 当“自定义工具”的后端接口:提供 OpenAPI 描述 + API Key 鉴权。
在 Dify 中:工具 → 自定义 → 创建自定义工具 → 填入 http://<你的地址>/openapi.json 导入,
鉴权方式选 API Key(请求头 Authorization: Bearer <key>)。具体界面以 Dify 官方文档为准。
本地运行:uvicorn app:app --port 8100(直接 python app.py 只做导入检查)
"""
from __future__ import annotations
import os
import secrets
from fastapi import Depends, FastAPI, HTTPException
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from pydantic import BaseModel, Field
API_KEY = os.environ.get("TOOL_API_KEY", "dev-only-key") # 生产环境从密钥管理读取
app = FastAPI(
title="订单查询工具",
version="1.0.0",
description="供低代码平台调用的订单查询接口。只读,按调用方的店铺隔离数据。",
servers=[{"url": "http://127.0.0.1:8100"}], # Dify 导入时需要 servers 字段,部署后改成实际地址
)
bearer = HTTPBearer()
ORDERS = {"A1001": {"shop": "s1", "status": "已发货", "eta": "明天"},
"A1002": {"shop": "s2", "status": "待支付", "eta": None}}
def auth(cred: HTTPAuthorizationCredentials = Depends(bearer)) -> str:
if not secrets.compare_digest(cred.credentials, API_KEY):
raise HTTPException(401, "无效的 API Key")
return "s1" # 示例:一个 Key 对应一个店铺;真实项目查表
class OrderStatus(BaseModel):
order_id: str
status: str = Field(description="订单状态")
eta: str | None = Field(default=None, description="预计送达时间")
@app.get("/orders/{order_id}", operation_id="getOrderStatus", response_model=OrderStatus,
summary="查询订单状态", description="根据订单号查询订单状态和预计送达时间。订单号形如 A1001。")
def get_order_status(order_id: str, shop: str = Depends(auth)) -> OrderStatus:
o = ORDERS.get(order_id)
if not o or o["shop"] != shop:
raise HTTPException(404, "订单不存在")
return OrderStatus(order_id=order_id, status=o["status"], eta=o["eta"])