fix: stabilize API routing and simplify delivery reports

This commit is contained in:
zeroerr.th51
2026-10-16 11:02:03 +08:00
parent bc3dda55ff
commit d5eef9de57
9 changed files with 215 additions and 14 deletions

View File

@@ -17,7 +17,9 @@ truststore.inject_into_ssl()
DEFAULT_BASE_URL = os.getenv("ZEROERR_AGENT_BASE_URL", "https://api.zeroerr-agent.com").rstrip("/")
DEFAULT_ENDPOINT = "/api/SaleAgent/DeliveryPrediction/WithTransit"
APPROVED_SKIP_TLS_HOSTNAME = "api.zeroerr-agent.com"
APPROVED_API_HOSTNAME = "api.zeroerr-agent.com"
APPROVED_SKIP_TLS_HOSTNAME = APPROVED_API_HOSTNAME
PROXY_MODE_ENV = "ZEROERR_AGENT_PROXY_MODE"
API_KEY_ENV = "ZEROERR_AGENT_API_KEY"
PROJECT_ROOT = Path(__file__).resolve().parents[3]
LOCAL_API_KEY_FILE = PROJECT_ROOT / "configs" / "delivery_api_key.local"
@@ -66,6 +68,23 @@ def get_api_key() -> str:
return ""
def build_api_opener(url: str, *, skip_tls_verify: bool = False) -> urllib.request.OpenerDirector:
"""Keep the approved API independent of the desktop's changing proxy route."""
mode = os.getenv(PROXY_MODE_ENV, "direct").strip().lower()
if mode not in {"direct", "system"}:
raise ValueError("invalid API proxy mode: expected direct or system")
target = urllib.parse.urlsplit(url)
if mode == "direct" and (
target.scheme != "https" or target.hostname != APPROVED_API_HOSTNAME
):
raise ValueError("direct API connection requires the approved HTTPS hostname")
# An explicit empty proxy map disables both environment and macOS proxies
# for this opener only. Never alter the process-wide urllib opener or env.
proxy = urllib.request.ProxyHandler({}) if mode == "direct" else urllib.request.ProxyHandler()
context = ssl._create_unverified_context() if skip_tls_verify else ssl.create_default_context()
return urllib.request.build_opener(proxy, urllib.request.HTTPSHandler(context=context))
def main() -> int:
args = parse_args()
product = args.product.strip()
@@ -110,9 +129,13 @@ def main() -> int:
}
request = urllib.request.Request(url, headers=headers, method="GET")
context = ssl._create_unverified_context() if args.skip_tls_verify else None
try:
with urllib.request.urlopen(request, timeout=30, context=context) as response:
opener = build_api_opener(url, skip_tls_verify=args.skip_tls_verify)
except ValueError as exc:
emit_error(str(exc))
return 2
try:
with opener.open(request, timeout=30) as response:
raw_body = response.read().decode("utf-8")
except urllib.error.HTTPError as exc:
body = exc.read().decode("utf-8", errors="replace")