Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add version check caching, fix version comparison #1835

Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bittensor/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,8 @@ def __init__(
# If no_version_checking is not set or set as False in the config, version checking is done.
if not self.config.get("no_version_checking", d=True):
try:
bittensor.utils.version_checking()
except:
bittensor.utils.check_version()
except bittensor.utils.VersionCheckError:
# If version checking fails, inform user with an exception.
raise RuntimeError(
"To avoid internet-based version checking, pass --no_version_checking while running the CLI."
Expand Down
30 changes: 1 addition & 29 deletions bittensor/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@

import bittensor
import hashlib
import requests
import torch
import scalecodec

from .wallet_utils import * # noqa F401
from .version import version_checking, check_version, VersionCheckError

RAOPERTAO = 1e9
U16_MAX = 65535
Expand Down Expand Up @@ -59,34 +59,6 @@ def unbiased_topk(values, k, dim=0, sorted=True, largest=True):
return topk, permutation[indices]


def version_checking(timeout: int = 15):
try:
bittensor.logging.debug(
f"Checking latest Bittensor version at: {bittensor.__pipaddress__}"
)
response = requests.get(bittensor.__pipaddress__, timeout=timeout)
latest_version = response.json()["info"]["version"]
version_split = latest_version.split(".")
latest_version_as_int = (
(100 * int(version_split[0]))
+ (10 * int(version_split[1]))
+ (1 * int(version_split[2]))
)

if latest_version_as_int > bittensor.__version_as_int__:
print(
"\u001b[33mBittensor Version: Current {}/Latest {}\nPlease update to the latest version at your earliest convenience. "
"Run the following command to upgrade:\n\n\u001b[0mpython -m pip install --upgrade bittensor".format(
bittensor.__version__, latest_version
)
)

except requests.exceptions.Timeout:
bittensor.logging.error("Version check failed due to timeout")
except requests.exceptions.RequestException as e:
bittensor.logging.error(f"Version check failed due to request failure: {e}")


def strtobool_with_default(
default: bool,
) -> Callable[[str], Union[bool, Literal["==SUPRESS=="]]]:
Expand Down
103 changes: 103 additions & 0 deletions bittensor/utils/version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
from typing import Optional
from pathlib import Path
import time
from packaging.version import Version

import bittensor
import requests

VERSION_CHECK_THRESHOLD = 86400


class VersionCheckError(Exception):
pass


def _get_version_file_path() -> Path:
return Path.home() / ".bittensor" / ".last_known_version"


def _get_version_from_file(version_file: Path) -> Optional[str]:
try:
mtime = version_file.stat().st_mtime
bittensor.logging.debug(f"Found version file, last modified: {mtime}")
diff = time.time() - mtime

if diff >= VERSION_CHECK_THRESHOLD:
bittensor.logging.debug("Version file expired")
return None

return version_file.read_text()
except FileNotFoundError:
bittensor.logging.debug("No bitensor version file found")
return None
except OSError:
bittensor.logging.exception("Failed to read version file")
return None


def _get_version_from_pypi(timeout: int = 15) -> str:
bittensor.logging.debug(
f"Checking latest Bittensor version at: {bittensor.__pipaddress__}"
)
try:
response = requests.get(bittensor.__pipaddress__, timeout=timeout)
latest_version = response.json()["info"]["version"]
return latest_version
except requests.exceptions.RequestException:
bittensor.logging.exception("Failed to get latest version from pypi")
raise


def get_and_save_latest_version(timeout: int = 15) -> str:
version_file = _get_version_file_path()

if last_known_version := _get_version_from_file(version_file):
return last_known_version

latest_version = _get_version_from_pypi(timeout)

try:
version_file.write_text(latest_version)
except OSError:
bittensor.logging.exception("Failed to save latest version to file")

return latest_version


def check_version(timeout: int = 15):
"""
Check if the current version of Bittensor is up to date with the latest version on PyPi.
Raises a VersionCheckError if the version check fails.
"""

try:
latest_version = get_and_save_latest_version(timeout)

if Version(latest_version) > Version(bittensor.__version__):
print(
"\u001b[33mBittensor Version: Current {}/Latest {}\nPlease update to the latest version at your earliest convenience. "
"Run the following command to upgrade:\n\n\u001b[0mpython -m pip install --upgrade bittensor".format(
bittensor.__version__, latest_version
)
)
except Exception as e:
raise VersionCheckError("Version check failed") from e


def version_checking(timeout: int = 15):
"""
Deprecated, kept for backwards compatibility. Use check_version() instead.
"""

from warnings import warn

warn(
"version_checking() is deprecated, please use check_version() instead",
DeprecationWarning,
)

try:
check_version(timeout)
except VersionCheckError:
bittensor.logging.exception("Version check failed")
1 change: 1 addition & 0 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ hypothesis==6.81.1
flake8==7.0.0
mypy==1.8.0
types-retry==0.9.9.4
freezegun==1.5.0
1 change: 1 addition & 0 deletions requirements/prod.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ netaddr
numpy
msgpack-numpy-opentensor==0.5.0
nest_asyncio
packaging
pycryptodome>=3.18.0,<4.0.0
pyyaml
password_strength
Expand Down
Loading