Download app/utils/fe_version.py from bg5/zai: direct link, hf CLI and curl.
- Browser
- Download file 4.59 kB
-
https://huggingface.co/spaces/bg5/zai/resolve/main/app/utils/fe_version.py
- Command line
-
hf download hf://spaces/bg5/zai/app/utils/fe_version.py
-
curl -L -o fe_version.py https://huggingface.co/spaces/bg5/zai/resolve/main/app/utils/fe_version.py
4.59 kB
| #!/usr/bin/env python | |
| # -*- coding: utf-8 -*- | |
| """ | |
| Utility helpers for resolving the latest X-FE-Version value from chat.z.ai. | |
| The upstream service embeds the current front-end release identifier inside | |
| its landing page static asset URLs (e.g. `prod-fe-1.0.107`). The helpers in | |
| this module fetch the landing page, extract the version string, and cache it | |
| with a configurable TTL so the expensive network fetch only happens when | |
| necessary. | |
| """ | |
| from __future__ import annotations | |
| import asyncio | |
| import re | |
| import time | |
| from typing import Optional | |
| import httpx | |
| from app.core.httpx_errors import normalize_httpx_exception | |
| from app.utils.logger import logger, log_exception | |
| from app.utils.user_agent import get_random_user_agent | |
| # Base URL to probe for the version string. | |
| FE_VERSION_SOURCE_URL = "https://chat.z.ai" | |
| # Cache TTL in seconds (default: 30 minutes). | |
| CACHE_TTL_SECONDS = 1800 | |
| _version_pattern = re.compile(r"prod-fe-\d+\.\d+\.\d+") | |
| _cached_version: str = "" | |
| _cached_at: float = 0.0 | |
| _version_lock: Optional[asyncio.Lock] = None | |
| _version_lock_loop: Optional[asyncio.AbstractEventLoop] = None | |
| def _extract_version(page_content: str) -> Optional[str]: | |
| """Extract the version string from the page content.""" | |
| if not page_content: | |
| return None | |
| matches = _version_pattern.findall(page_content) | |
| if not matches: | |
| return None | |
| # Choose the highest lexical value to guard against mixed versions. | |
| return max(matches) | |
| def _should_use_cache(force_refresh: bool) -> bool: | |
| """Determine whether the cached value can be reused.""" | |
| if force_refresh: | |
| return False | |
| if not _cached_version: | |
| return False | |
| if _cached_at <= 0: | |
| return False | |
| return (time.time() - _cached_at) < CACHE_TTL_SECONDS | |
| async def get_latest_fe_version(force_refresh: bool = False) -> str: | |
| """ | |
| Resolve the latest X-FE-Version value from chat.z.ai. | |
| The lookup order is: | |
| 1. Cached value within TTL. | |
| 2. Remote fetch from chat.z.ai. | |
| Raises: | |
| Exception: If unable to fetch the version from the remote source. | |
| """ | |
| global _cached_version, _cached_at, _version_lock, _version_lock_loop | |
| if _should_use_cache(force_refresh): | |
| return _cached_version | |
| current_loop = asyncio.get_running_loop() | |
| if _version_lock is None or _version_lock_loop is not current_loop: | |
| _version_lock = asyncio.Lock() | |
| _version_lock_loop = current_loop | |
| async with _version_lock: | |
| if _should_use_cache(force_refresh): | |
| return _cached_version | |
| try: | |
| headers = {"User-Agent": get_random_user_agent("chrome")} | |
| except Exception: | |
| headers = { | |
| "User-Agent": ( | |
| "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " | |
| "AppleWebKit/537.36 (KHTML, like Gecko) " | |
| "Chrome/120.0.0.0 Safari/537.36" | |
| ) | |
| } | |
| try: | |
| async with httpx.AsyncClient( | |
| timeout=10.0, | |
| follow_redirects=True, | |
| trust_env=False, | |
| ) as client: | |
| response = await client.get(FE_VERSION_SOURCE_URL, headers=headers) | |
| response.raise_for_status() | |
| version = _extract_version(response.text) | |
| if version: | |
| if version != _cached_version: | |
| logger.debug("[Z.AI] Detected X-FE-Version update: %s", version) | |
| _cached_version = version | |
| _cached_at = time.time() | |
| return version | |
| logger.error("[Z.AI] Unable to locate X-FE-Version in landing page") | |
| raise Exception("Unable to locate X-FE-Version in landing page") | |
| except Exception as exc: | |
| log_exception( | |
| logger, | |
| "%s", | |
| normalize_httpx_exception( | |
| exc, | |
| method="GET", | |
| url=FE_VERSION_SOURCE_URL, | |
| context="fe_version.fetch", | |
| ), | |
| append_error=False, | |
| ) | |
| if _cached_version: | |
| return _cached_version | |
| raise Exception(f"Failed to fetch X-FE-Version: {exc}") | |
| async def refresh_fe_version() -> str: | |
| """Force refresh the cached version by bypassing the TTL.""" | |
| return await get_latest_fe_version(force_refresh=True) | |