workspace— step2
This commit is contained in:
@@ -9,13 +9,12 @@ description = "Shared contracts (Redis keys, future models) for jp_surugaya serv
|
||||
requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
"pydantic>=2.0.0,<3.0.0",
|
||||
"redis>=5.0.0,<6.0.0",
|
||||
"redis==8.0.0",
|
||||
]
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["src/surugaya_common"]
|
||||
|
||||
# NOTE (deferred): redis pin here intentionally matches the API service (<6).
|
||||
# The worker's redis==8 requirement is NOT introduced in this increment, so there
|
||||
# is no conflict to resolve yet. Do not add fastapi/playwright/opencv/numpy/
|
||||
# pyautogui/pillow here — surugaya_common must stay light.
|
||||
# Keep surugaya_common light: stdlib + pydantic + redis only. redis is pinned to
|
||||
# ==8.0.0 to stay in lockstep with both the API service and the worker. Do not add
|
||||
# fastapi/playwright/opencv/numpy/pyautogui/pillow here.
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
"""通用字符串工具(stdlib only)。
|
||||
|
||||
从 app/utils/app_utils.py 迁移而来,作为 surugaya_common 的共享实现,
|
||||
供 API 服务与 worker 复用。
|
||||
"""
|
||||
|
||||
|
||||
def is_valid_str(s):
|
||||
"""判断字符串是否有效,即非空且非空格。"""
|
||||
return isinstance(s, str) and len(s.strip()) > 0
|
||||
|
||||
|
||||
def is_empty_str(s):
|
||||
"""判断字符串是否为空,即空或仅包含空格。"""
|
||||
return isinstance(s, str) and len(s.strip()) == 0
|
||||
@@ -0,0 +1,45 @@
|
||||
"""HTTP 签名工具(stdlib only)。
|
||||
|
||||
从 app/utils/http_utils.py 迁移而来,逻辑与 worker 端实现一致,
|
||||
作为 surugaya_common 的共享实现统一维护。
|
||||
"""
|
||||
|
||||
import json
|
||||
import time
|
||||
import hmac
|
||||
import secrets
|
||||
import hashlib
|
||||
from typing import Dict, Any
|
||||
|
||||
|
||||
def generate_signed_headers(app_id: str, app_secret: str, data: Dict[str, Any], method: str = "POST") -> Dict[str, str]:
|
||||
timestamp = str(int(time.time() * 1000))
|
||||
nonce = secrets.token_hex(16)
|
||||
|
||||
payload_str = json.dumps(data, ensure_ascii=False)
|
||||
payload_bytes = payload_str.encode("utf-8")
|
||||
actual_body_hash = hashlib.sha256(payload_bytes).hexdigest()
|
||||
|
||||
string_to_sign = "\n".join([
|
||||
method.upper(),
|
||||
app_id,
|
||||
timestamp,
|
||||
nonce,
|
||||
actual_body_hash
|
||||
])
|
||||
|
||||
signature = hmac.new(
|
||||
app_secret.encode("utf-8"),
|
||||
string_to_sign.encode("utf-8"),
|
||||
hashlib.sha256
|
||||
).hexdigest()
|
||||
|
||||
headers = {
|
||||
"X-Ca-Appid": app_id,
|
||||
"X-Ca-Timestamp": timestamp,
|
||||
"X-Ca-Nonce": nonce,
|
||||
"X-Ca-Signature": signature,
|
||||
"Content-Type": "application/json; charset=utf-8"
|
||||
}
|
||||
|
||||
return headers
|
||||
Reference in New Issue
Block a user