From 4e591b07eb9344a13725884833e7fed135818965 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Tue, 9 Jun 2026 17:44:07 +0800 Subject: [PATCH] =?UTF-8?q?workspace=E2=80=94=20step2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/routes/scrape.py | 2 +- app/services/surugaya_client.py | 2 +- packages/surugaya_common/pyproject.toml | 9 ++++---- .../src/surugaya_common}/app_utils.py | 7 ++++++ .../src/surugaya_common}/http_utils.py | 13 ++++++++--- pyproject.toml | 2 +- uv.lock | 22 +++++-------------- 7 files changed, 29 insertions(+), 28 deletions(-) rename {app/utils => packages/surugaya_common/src/surugaya_common}/app_utils.py (62%) rename {app/utils => packages/surugaya_common/src/surugaya_common}/http_utils.py (82%) diff --git a/app/api/routes/scrape.py b/app/api/routes/scrape.py index 8e785a8..8f24fe0 100644 --- a/app/api/routes/scrape.py +++ b/app/api/routes/scrape.py @@ -22,7 +22,7 @@ from app.models.scrape import ( SearchRequest, SearchResultData, TradeMonitorRequest, ) -from app.utils.http_utils import generate_signed_headers +from surugaya_common.http_utils import generate_signed_headers from app.utils.parse_util import ( get_franchise_shipping_fee, get_handle_fee, diff --git a/app/services/surugaya_client.py b/app/services/surugaya_client.py index c98917c..7525c88 100644 --- a/app/services/surugaya_client.py +++ b/app/services/surugaya_client.py @@ -24,8 +24,8 @@ from app.models.scrape import CategoryData, DetailRequest, ProductDetailData, Pr from app.services.browser_pool import BrowserPool from app.services.cloudflare_session import CloudflareSessionManager from app.services.session_store import SessionStore -from app.utils.app_utils import is_empty_str from app.utils.parse_util import format_price, get_shipping_fee, surugaya_photo_url_to_cdn +from surugaya_common.app_utils import is_empty_str logger = logging.getLogger(__name__) diff --git a/packages/surugaya_common/pyproject.toml b/packages/surugaya_common/pyproject.toml index c039223..7704be2 100644 --- a/packages/surugaya_common/pyproject.toml +++ b/packages/surugaya_common/pyproject.toml @@ -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. diff --git a/app/utils/app_utils.py b/packages/surugaya_common/src/surugaya_common/app_utils.py similarity index 62% rename from app/utils/app_utils.py rename to packages/surugaya_common/src/surugaya_common/app_utils.py index c97aec4..73e2052 100644 --- a/app/utils/app_utils.py +++ b/packages/surugaya_common/src/surugaya_common/app_utils.py @@ -1,8 +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 diff --git a/app/utils/http_utils.py b/packages/surugaya_common/src/surugaya_common/http_utils.py similarity index 82% rename from app/utils/http_utils.py rename to packages/surugaya_common/src/surugaya_common/http_utils.py index 377e8d6..c0e32e2 100644 --- a/app/utils/http_utils.py +++ b/packages/surugaya_common/src/surugaya_common/http_utils.py @@ -1,3 +1,9 @@ +"""HTTP 签名工具(stdlib only)。 + +从 app/utils/http_utils.py 迁移而来,逻辑与 worker 端实现一致, +作为 surugaya_common 的共享实现统一维护。 +""" + import json import time import hmac @@ -5,10 +11,11 @@ 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() @@ -34,5 +41,5 @@ def generate_signed_headers(app_id: str, app_secret: str, data: Dict[str, Any], "X-Ca-Signature": signature, "Content-Type": "application/json; charset=utf-8" } - - return headers \ No newline at end of file + + return headers diff --git a/pyproject.toml b/pyproject.toml index e5baad7..6d2c3bc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ dependencies = [ "playwright-stealth>=1.0.0,<3.0.0", "pydantic>=2.0.0,<3.0.0", "pydantic-settings>=2.4.0,<3.0.0", - "redis>=5.0.0,<6.0.0", + "redis==8.0.0", "selectolax>=0.3.21,<1.0.0", "starlette>=0.37.0,<1.0.0", "uvicorn[standard]>=0.30.0,<1.0.0", diff --git a/uv.lock b/uv.lock index 5666dc7..6ba2eb0 100644 --- a/uv.lock +++ b/uv.lock @@ -366,15 +366,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, ] -[[package]] -name = "pyjwt" -version = "2.12.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c2/27/a3b6e5bf6ff856d2509292e95c8f57f0df7017cf5394921fc4e4ef40308a/pyjwt-2.12.1.tar.gz", hash = "sha256:c74a7a2adf861c04d002db713dd85f84beb242228e671280bf709d765b03672b", size = 102564, upload-time = "2026-03-13T19:27:37.25Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/7a/8dd906bd22e79e47397a61742927f6747fe93242ef86645ee9092e610244/pyjwt-2.12.1-py3-none-any.whl", hash = "sha256:28ca37c070cad8ba8cd9790cd940535d40274d22f80ab87f3ac6a713e6e8454c", size = 29726, upload-time = "2026-03-13T19:27:35.677Z" }, -] - [[package]] name = "pytest" version = "8.4.2" @@ -460,14 +451,11 @@ wheels = [ [[package]] name = "redis" -version = "5.3.1" +version = "8.0.0" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pyjwt" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/6a/cf/128b1b6d7086200c9f387bd4be9b2572a30b90745ef078bd8b235042dc9f/redis-5.3.1.tar.gz", hash = "sha256:ca49577a531ea64039b5a36db3d6cd1a0c7a60c34124d46924a45b956e8cf14c", size = 4626200, upload-time = "2025-07-25T08:06:27.778Z" } +sdist = { url = "https://files.pythonhosted.org/packages/53/ae/ed461cca5780b5fc8b9fe8ca0ed98d89508645fb9d880c24cc42c087678f/redis-8.0.0.tar.gz", hash = "sha256:a00c5355432051ac14e593b8b197fc76c887ee12d55a0984f69328a1115fdc49", size = 5101591, upload-time = "2026-05-28T12:45:13.5Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/26/5c5fa0e83c3621db835cfc1f1d789b37e7fa99ed54423b5f519beb931aa7/redis-5.3.1-py3-none-any.whl", hash = "sha256:dc1909bd24669cc31b5f67a039700b16ec30571096c5f1f0d9d2324bff31af97", size = 272833, upload-time = "2025-07-25T08:06:26.317Z" }, + { url = "https://files.pythonhosted.org/packages/27/e3/b519734372d305bd547534a9f32e4ce9f98552af753dce72cf3483a0ff0b/redis-8.0.0-py3-none-any.whl", hash = "sha256:c938c18338585009f0bc310f4c7e4e4b4d37639356c4ac072cedf3af570c8dc7", size = 499870, upload-time = "2026-05-28T12:45:11.697Z" }, ] [[package]] @@ -539,7 +527,7 @@ dependencies = [ [package.metadata] requires-dist = [ { name = "pydantic", specifier = ">=2.0.0,<3.0.0" }, - { name = "redis", specifier = ">=5.0.0,<6.0.0" }, + { name = "redis", specifier = "==8.0.0" }, ] [[package]] @@ -576,7 +564,7 @@ requires-dist = [ { name = "pydantic-settings", specifier = ">=2.4.0,<3.0.0" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.3.0,<9.0.0" }, { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=0.24.0,<1.0.0" }, - { name = "redis", specifier = ">=5.0.0,<6.0.0" }, + { name = "redis", specifier = "==8.0.0" }, { name = "selectolax", specifier = ">=0.3.21,<1.0.0" }, { name = "starlette", specifier = ">=0.37.0,<1.0.0" }, { name = "surugaya-common", editable = "packages/surugaya_common" },