version.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. from __future__ import annotations
  2. from os import environ
  3. import requests
  4. from functools import cached_property
  5. from importlib.metadata import version as get_package_version, PackageNotFoundError
  6. from subprocess import check_output, CalledProcessError, PIPE
  7. from .errors import VersionNotFoundError
  8. from . import debug
  9. PACKAGE_NAME = "g4f"
  10. GITHUB_REPOSITORY = "xtekky/gpt4free"
  11. def get_pypi_version(package_name: str) -> str:
  12. """
  13. Retrieves the latest version of a package from PyPI.
  14. Args:
  15. package_name (str): The name of the package for which to retrieve the version.
  16. Returns:
  17. str: The latest version of the specified package from PyPI.
  18. Raises:
  19. VersionNotFoundError: If there is an error in fetching the version from PyPI.
  20. """
  21. try:
  22. response = requests.get(f"https://pypi.org/pypi/{package_name}/json").json()
  23. return response["info"]["version"]
  24. except requests.RequestException as e:
  25. raise VersionNotFoundError(f"Failed to get PyPI version: {e}")
  26. def get_github_version(repo: str) -> str:
  27. """
  28. Retrieves the latest release version from a GitHub repository.
  29. Args:
  30. repo (str): The name of the GitHub repository.
  31. Returns:
  32. str: The latest release version from the specified GitHub repository.
  33. Raises:
  34. VersionNotFoundError: If there is an error in fetching the version from GitHub.
  35. """
  36. try:
  37. response = requests.get(f"https://api.github.com/repos/{repo}/releases/latest")
  38. response.raise_for_status()
  39. return response.json()["tag_name"]
  40. except requests.RequestException as e:
  41. raise VersionNotFoundError(f"Failed to get GitHub release version: {e}")
  42. class VersionUtils:
  43. """
  44. Utility class for managing and comparing package versions of 'g4f'.
  45. """
  46. @cached_property
  47. def current_version(self) -> str:
  48. """
  49. Retrieves the current version of the 'g4f' package.
  50. Returns:
  51. str: The current version of 'g4f'.
  52. Raises:
  53. VersionNotFoundError: If the version cannot be determined from the package manager,
  54. Docker environment, or git repository.
  55. """
  56. if debug.version:
  57. return debug.version
  58. # Read from package manager
  59. try:
  60. return get_package_version(PACKAGE_NAME)
  61. except PackageNotFoundError:
  62. pass
  63. # Read from docker environment
  64. version = environ.get("G4F_VERSION")
  65. if version:
  66. return version
  67. # Read from git repository
  68. try:
  69. command = ["git", "describe", "--tags", "--abbrev=0"]
  70. return check_output(command, text=True, stderr=PIPE).strip()
  71. except CalledProcessError:
  72. pass
  73. return None
  74. @property
  75. def latest_version(self) -> str:
  76. """
  77. Retrieves the latest version of the 'g4f' package.
  78. Returns:
  79. str: The latest version of 'g4f'.
  80. """
  81. # Is installed via package manager?
  82. try:
  83. get_package_version(PACKAGE_NAME)
  84. except PackageNotFoundError:
  85. return get_github_version(GITHUB_REPOSITORY)
  86. return get_pypi_version(PACKAGE_NAME)
  87. def check_version(self) -> None:
  88. """
  89. Checks if the current version of 'g4f' is up to date with the latest version.
  90. Note:
  91. If a newer version is available, it prints a message with the new version and update instructions.
  92. """
  93. try:
  94. if self.current_version != self.latest_version:
  95. print(f'New g4f version: {self.latest_version} (current: {self.current_version}) | pip install -U g4f')
  96. except Exception as e:
  97. print(f'Failed to check g4f version: {e}')
  98. utils = VersionUtils()