mock_receipt_api.py 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. """
  2. 双模式契约测试用 Mock API(S5 采购收货样板)。
  3. 严格对齐 MdpApiPullExecutor.cs 现有实现:
  4. - GET,单次请求,不分页;
  5. - Bearer Token 鉴权(api_auth_type='TOKEN',token 见环境变量 MOCK_TOKEN);
  6. - 响应数组位于 data.list(对应 mdp_entity.response_data_path='data.list');
  7. - 每行去重键 bizKey(对应 dedup_key_path='bizKey');
  8. - 可选 ?cursor=<上批最后一行 bizKey>,用于演示增量:仅返回 bizKey 大于该游标的行。
  9. 启动:
  10. pip install -r requirements.txt
  11. set MOCK_TOKEN=uat-mock-token # bash: export MOCK_TOKEN=uat-mock-token
  12. uvicorn mock_receipt_api:app --host 127.0.0.1 --port 8018
  13. """
  14. import json
  15. import os
  16. from pathlib import Path
  17. from fastapi import FastAPI, Header, HTTPException, Query
  18. app = FastAPI(title="AIDOP Mock Receipt API", version="1.0.0")
  19. _TOKEN = os.environ.get("MOCK_TOKEN", "uat-mock-token")
  20. _SAMPLE_PATH = Path(__file__).with_name("sample_receipt.json")
  21. def _load_rows() -> list[dict]:
  22. with _SAMPLE_PATH.open("r", encoding="utf-8") as f:
  23. return json.load(f)
  24. def _check_auth(authorization: str | None) -> None:
  25. expected = f"Bearer {_TOKEN}"
  26. if authorization != expected:
  27. raise HTTPException(status_code=401, detail="invalid or missing bearer token")
  28. @app.get("/api/receipt")
  29. def get_receipt(
  30. cursor: str | None = Query(default=None, description="上批最后一行 bizKey(增量游标)"),
  31. authorization: str | None = Header(default=None),
  32. ):
  33. _check_auth(authorization)
  34. rows = _load_rows()
  35. # 按 bizKey 稳定排序,保证「最后一行 bizKey」作为游标可复现
  36. rows.sort(key=lambda r: r["bizKey"])
  37. if cursor:
  38. rows = [r for r in rows if r["bizKey"] > cursor]
  39. return {"code": 0, "message": "ok", "data": {"list": rows}}
  40. @app.get("/health")
  41. def health():
  42. return {"status": "UP"}