diff --git a/setup.py b/setup.py index 57dde5c..3441a0d 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,5 @@ from setuptools import setup, find_packages -from _version import version +from smsdk._version import version with open("README.md", "r") as fh: long_description = fh.read() diff --git a/smsdk/_version.py b/smsdk/_version.py index 18880fe..8bb4da1 100644 --- a/smsdk/_version.py +++ b/smsdk/_version.py @@ -1,12 +1,13 @@ # """ -Track version information for factorytx-core module here. +Track version information for sightmachine-sdk module here. """ import typing import itertools import requests import warnings import functools +import re class VersionInfo(typing.NamedTuple): @@ -30,49 +31,79 @@ def __str__(self) -> str: version = str(f"v{version_info}") +def sort_releases_descending( + releases: typing.List[typing.Dict[str, typing.Any]] +) -> typing.List[typing.Dict[str, typing.Any]]: + def version_key( + release: typing.Dict[str, typing.Any] + ) -> typing.Union[typing.Tuple[int, int, int, str], typing.Tuple[()]]: + version = release["tag_name"] + # Use regular expression to extract numerical and string parts + match = re.match(r"(?i)v(\d+)\.(\d+)\.(\d+)(\D*)", version) + if match: + major, minor, patch, suffix = map(match.group, (1, 2, 3, 4)) + return int(major), int(minor), int(patch), suffix + else: + return () + + return ( + sorted(releases, key=version_key, reverse=True) + if len(releases) > 1 + else releases + ) + + +def get_latest_release_version( + releases: typing.List[typing.Dict[str, typing.Any]] +) -> typing.Optional[typing.Any]: + if releases: + sorted_releases = sort_releases_descending(releases) + return sorted_releases[0]["tag_name"] + return None + + def get_latest_sdk_release() -> typing.Optional[typing.Any]: api_url = f"https://api.github.com/repos/{owner}/{repo}/releases" try: - response = requests.get(api_url) - - # To raise an HTTPError for any bad responses - response.raise_for_status() - + response = requests.get(api_url, timeout=10) + response.raise_for_status() # To raise an HTTPError for any bad responses releases = response.json() + if releases: - latest_release = releases[0] - return latest_release["tag_name"] + return get_latest_release_version(releases) except requests.RequestException as e: print(f"Error fetching latest SDK release: {e}") return None -def version_check_decorator(func: typing.Any) -> typing.Any: - @functools.wraps(func) - def wrapper(*args: typing.Any, **kwargs: typing.Any) -> typing.Any: - # Define a global flag to track whether the API version has been printed - global api_version_printed - if not api_version_printed: - latest_sdk_release = get_latest_sdk_release() - installed_sdk_release = version - - if ( - installed_sdk_release is not None - and latest_sdk_release is not None - and latest_sdk_release != installed_sdk_release - ): - warnings.warn( - f"Installed SDK Version: {installed_sdk_release}. It is recommended to install release version ({latest_sdk_release}).", - DeprecationWarning, - ) - # Set the flag to True to indicate that the version has been printed - api_version_printed = True - - return func(*args, **kwargs) - - return wrapper +class VersionCheckDecorator: + api_version_printed = False + + @classmethod + def version_check_decorator(cls, func: typing.Any) -> typing.Any: + @functools.wraps(func) + def wrapper(*args: typing.Any, **kwargs: typing.Any) -> typing.Any: + if not cls.api_version_printed: + latest_sdk_release = get_latest_sdk_release() + installed_sdk_release = version + + if ( + installed_sdk_release is not None + and latest_sdk_release is not None + and latest_sdk_release != installed_sdk_release + ): + warnings.warn( + f"Installed SDK Version: {installed_sdk_release}. " + f"It is recommended to install release version ({latest_sdk_release}).", + DeprecationWarning, + ) + cls.api_version_printed = True + + return func(*args, **kwargs) + + return wrapper # Initialize the flag to False diff --git a/smsdk/client.py b/smsdk/client.py index 4ffb9cc..37a8593 100644 --- a/smsdk/client.py +++ b/smsdk/client.py @@ -2,7 +2,7 @@ # coding: utf-8 """ Sight Machine SDK Client """ from __future__ import unicode_literals, absolute_import -from smsdk._version import version_check_decorator +from smsdk._version import VersionCheckDecorator import pandas as pd import numpy as np @@ -21,6 +21,7 @@ import logging log = logging.getLogger(__name__) +version_check_decorator = VersionCheckDecorator.version_check_decorator def time_string_to_epoch(time_string):