workspace— step2

This commit is contained in:
2026-06-09 17:44:07 +08:00
parent 7eb3647539
commit 4e591b07eb
7 changed files with 29 additions and 28 deletions
+1 -1
View File
@@ -22,7 +22,7 @@ from app.models.scrape import (
SearchRequest, SearchRequest,
SearchResultData, TradeMonitorRequest, 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 ( from app.utils.parse_util import (
get_franchise_shipping_fee, get_franchise_shipping_fee,
get_handle_fee, get_handle_fee,
+1 -1
View File
@@ -24,8 +24,8 @@ from app.models.scrape import CategoryData, DetailRequest, ProductDetailData, Pr
from app.services.browser_pool import BrowserPool from app.services.browser_pool import BrowserPool
from app.services.cloudflare_session import CloudflareSessionManager from app.services.cloudflare_session import CloudflareSessionManager
from app.services.session_store import SessionStore 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 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__) logger = logging.getLogger(__name__)
+4 -5
View File
@@ -9,13 +9,12 @@ description = "Shared contracts (Redis keys, future models) for jp_surugaya serv
requires-python = ">=3.12" requires-python = ">=3.12"
dependencies = [ dependencies = [
"pydantic>=2.0.0,<3.0.0", "pydantic>=2.0.0,<3.0.0",
"redis>=5.0.0,<6.0.0", "redis==8.0.0",
] ]
[tool.hatch.build.targets.wheel] [tool.hatch.build.targets.wheel]
packages = ["src/surugaya_common"] packages = ["src/surugaya_common"]
# NOTE (deferred): redis pin here intentionally matches the API service (<6). # Keep surugaya_common light: stdlib + pydantic + redis only. redis is pinned to
# The worker's redis==8 requirement is NOT introduced in this increment, so there # ==8.0.0 to stay in lockstep with both the API service and the worker. Do not add
# is no conflict to resolve yet. Do not add fastapi/playwright/opencv/numpy/ # fastapi/playwright/opencv/numpy/pyautogui/pillow here.
# pyautogui/pillow here — surugaya_common must stay light.
@@ -1,8 +1,15 @@
"""通用字符串工具(stdlib only)。
app/utils/app_utils.py 迁移而来作为 surugaya_common 的共享实现
API 服务与 worker 复用
"""
def is_valid_str(s): def is_valid_str(s):
"""判断字符串是否有效,即非空且非空格。""" """判断字符串是否有效,即非空且非空格。"""
return isinstance(s, str) and len(s.strip()) > 0 return isinstance(s, str) and len(s.strip()) > 0
def is_empty_str(s): def is_empty_str(s):
"""判断字符串是否为空,即空或仅包含空格。""" """判断字符串是否为空,即空或仅包含空格。"""
return isinstance(s, str) and len(s.strip()) == 0 return isinstance(s, str) and len(s.strip()) == 0
@@ -1,3 +1,9 @@
"""HTTP 签名工具(stdlib only)。
app/utils/http_utils.py 迁移而来逻辑与 worker 端实现一致
作为 surugaya_common 的共享实现统一维护
"""
import json import json
import time import time
import hmac import hmac
@@ -5,6 +11,7 @@ import secrets
import hashlib import hashlib
from typing import Dict, Any 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]: 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)) timestamp = str(int(time.time() * 1000))
nonce = secrets.token_hex(16) nonce = secrets.token_hex(16)
+1 -1
View File
@@ -10,7 +10,7 @@ dependencies = [
"playwright-stealth>=1.0.0,<3.0.0", "playwright-stealth>=1.0.0,<3.0.0",
"pydantic>=2.0.0,<3.0.0", "pydantic>=2.0.0,<3.0.0",
"pydantic-settings>=2.4.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", "selectolax>=0.3.21,<1.0.0",
"starlette>=0.37.0,<1.0.0", "starlette>=0.37.0,<1.0.0",
"uvicorn[standard]>=0.30.0,<1.0.0", "uvicorn[standard]>=0.30.0,<1.0.0",
Generated
+5 -17
View File
@@ -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" }, { 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]] [[package]]
name = "pytest" name = "pytest"
version = "8.4.2" version = "8.4.2"
@@ -460,14 +451,11 @@ wheels = [
[[package]] [[package]]
name = "redis" name = "redis"
version = "5.3.1" version = "8.0.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ 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" }
{ 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" }
wheels = [ 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]] [[package]]
@@ -539,7 +527,7 @@ dependencies = [
[package.metadata] [package.metadata]
requires-dist = [ requires-dist = [
{ name = "pydantic", specifier = ">=2.0.0,<3.0.0" }, { 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]] [[package]]
@@ -576,7 +564,7 @@ requires-dist = [
{ name = "pydantic-settings", specifier = ">=2.4.0,<3.0.0" }, { name = "pydantic-settings", specifier = ">=2.4.0,<3.0.0" },
{ name = "pytest", marker = "extra == 'dev'", specifier = ">=8.3.0,<9.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 = "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 = "selectolax", specifier = ">=0.3.21,<1.0.0" },
{ name = "starlette", specifier = ">=0.37.0,<1.0.0" }, { name = "starlette", specifier = ">=0.37.0,<1.0.0" },
{ name = "surugaya-common", editable = "packages/surugaya_common" }, { name = "surugaya-common", editable = "packages/surugaya_common" },