fix(vedastro): pin SDK at install and cap free-tier wait
Independent Staging Quality Gate / validate (push) Successful in 9m36s
Independent Staging Quality Gate / publish (push) Successful in 18m18s

Image build patches vedastro.check_for_update to a no-op after pip install so import cannot hit pypi or upgrade the pin. Free-tier queue waits are capped to VEDASTRO_TIMEOUT_SECONDS and fail fast as free_tier_rate_limited. Gateway status exposes runtime mode as booleans without secrets. BUG-719 resolved; BUG-720 stays investigating until production env is filled in.
This commit is contained in:
jesse-ux
2026-09-16 00:25:15 +08:00
parent 62be52dacf
commit 6b3248bf53
9 changed files with 323 additions and 3 deletions
+17
View File
@@ -29,6 +29,14 @@ def _official_network_enabled() -> bool:
return os.environ.get("VEDASTRO_ENABLE_NETWORK", "1").strip().lower() in {"1", "true", "yes", "on"}
def _sdk_version() -> str | None:
try:
import importlib.metadata
return importlib.metadata.version("vedastro")
except Exception:
return None
def _int_env(name: str, default: int = 0) -> int:
raw = os.environ.get(name, "").strip()
if not raw:
@@ -271,7 +279,16 @@ def gateway_status() -> dict[str, Any]:
"self_host_configured": config["self_host_endpoint_configured"],
"official_configured": config["official_endpoint_configured"],
"credential_configured": bool(os.environ.get("VEDASTRO_API_KEY", "").strip()),
"endpoint_configured": bool(config["official_endpoint_configured"] or config["self_host_endpoint_configured"]),
"fanout_enabled": os.environ.get("VEDASTRO_FULL_SNAPSHOT_FANOUT_ENABLED", "1").strip().lower() in {"1", "true", "yes", "on"},
"range_scan_network_enabled": os.environ.get("VEDASTRO_RANGE_SCAN_NETWORK_ENABLED", "").strip().lower() in {"1", "true", "yes", "on"},
"free_tier_queue_active": bool(
config["official_endpoint_configured"]
and not os.environ.get("VEDASTRO_API_KEY", "").strip()
),
"sdk_version": _sdk_version(),
"cache_ttl_seconds": config["cache_ttl_seconds"],
"official_full_snapshot_cache_ttl_seconds": _int_env("VEDASTRO_OFFICIAL_FULL_SNAPSHOT_CACHE_TTL_SECONDS", 0),
"queue_enabled": config["queue_enabled"],
"fail_open_local": config["fail_open_local"],
"official_readiness": {
+36 -1
View File
@@ -350,6 +350,7 @@ ALLOW_NETWORK_ENV = "VEDASTRO_ENABLE_NETWORK"
CACHE_TTL_ENV = "VEDASTRO_CACHE_TTL_SECONDS"
FREE_TIER_MAX_REQUESTS_ENV = "VEDASTRO_FREE_TIER_MAX_REQUESTS"
FREE_TIER_WINDOW_SECONDS_ENV = "VEDASTRO_FREE_TIER_WINDOW_SECONDS"
FREE_TIER_WAIT_BUDGET_ENV = "VEDASTRO_FREE_TIER_WAIT_BUDGET_SECONDS"
DEFAULT_CACHE_TTL_SECONDS = 86400.0
DEFAULT_FREE_TIER_MAX_REQUESTS = 5
DEFAULT_FREE_TIER_WINDOW_SECONDS = 60.0
@@ -505,6 +506,17 @@ def _free_tier_window_seconds() -> float:
return DEFAULT_FREE_TIER_WINDOW_SECONDS
def _free_tier_wait_budget_seconds() -> float:
timeout = _timeout_seconds()
raw = os.environ.get(FREE_TIER_WAIT_BUDGET_ENV, "").strip()
if not raw:
return timeout
try:
return max(0.0, min(float(raw), timeout))
except ValueError:
return timeout
def schema() -> dict[str, Any]:
request_example = {
**PARITY_CASES["beijing_first_use_demo"],
@@ -1903,6 +1915,7 @@ def _acquire_free_tier_slot(request_url: str) -> dict[str, Any]:
}
waited_seconds = 0.0
budget = _free_tier_wait_budget_seconds()
with _FREE_TIER_REQUEST_LOCK:
while True:
now = time.monotonic()
@@ -1913,6 +1926,16 @@ def _acquire_free_tier_slot(request_url: str) -> dict[str, Any]:
_FREE_TIER_REQUEST_TIMESTAMPS.append(now)
break
sleep_seconds = max(window_seconds - (now - _FREE_TIER_REQUEST_TIMESTAMPS[0]), 0.0)
if waited_seconds + sleep_seconds > budget:
return {
"mode": "free_tier_budget_exceeded",
"queue_active": False,
"waited_seconds": round(waited_seconds, 6),
"window_seconds": window_seconds,
"max_requests": max_requests,
"wait_budget_seconds": budget,
"degraded_reason": "free_tier_rate_limited",
}
waited_seconds += sleep_seconds
if sleep_seconds > 0:
time.sleep(sleep_seconds)
@@ -1963,6 +1986,15 @@ def _post_json_with_retry(endpoint: str, request_preview: dict[str, Any]) -> tup
for attempt in range(1, max_attempts + 1):
try:
rate_limit_metadata = _acquire_free_tier_slot(request_url)
if rate_limit_metadata.get("mode") == "free_tier_budget_exceeded":
return {
"Status": "Fail",
"Payload": {"reason": "free_tier_rate_limited"},
"source_metadata": {
"free_tier_rate_limit": rate_limit_metadata,
"degraded_reason": "free_tier_rate_limited",
},
}, attempt, retry_error_codes
payload = _post_json(endpoint, request_preview)
if not isinstance(payload, dict):
return {}, attempt, retry_error_codes
@@ -2176,9 +2208,12 @@ def _official_snapshot_budget_exhausted_bundle(reason: str) -> dict[str, Any]:
def _payload_status(payload: dict[str, Any]) -> str:
if not isinstance(payload, dict):
return "invalid"
metadata = payload.get("source_metadata") if isinstance(payload.get("source_metadata"), dict) else {}
if metadata.get("degraded_reason") == "free_tier_rate_limited":
return "rate_limited"
if str(payload.get("Status") or "").lower() == "fail":
failure_text = json.dumps(payload.get("Payload"), ensure_ascii=False).lower()
if "rate limit" in failure_text or "calls/minute" in failure_text or "too many requests" in failure_text:
if "rate limit" in failure_text or "calls/minute" in failure_text or "too many requests" in failure_text or "free_tier_rate_limited" in failure_text:
return "rate_limited"
return "ok" if payload.get("Status") == "Pass" else "fail"