version.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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").json()
  38. return response["tag_name"]
  39. except requests.RequestException as e:
  40. raise VersionNotFoundError(f"Failed to get GitHub release version: {e}")
  41. class VersionUtils:
  42. """
  43. Utility class for managing and comparing package versions of 'g4f'.
  44. """
  45. @cached_property
  46. def current_version(self) -> str:
  47. """
  48. Retrieves the current version of the 'g4f' package.
  49. Returns:
  50. str: The current version of 'g4f'.
  51. Raises:
  52. VersionNotFoundError: If the version cannot be determined from the package manager,
  53. Docker environment, or git repository.
  54. """
  55. if debug.version:
  56. return debug.version
  57. # Read from package manager
  58. try:
  59. return get_package_version(PACKAGE_NAME)
  60. except PackageNotFoundError:
  61. pass
  62. # Read from docker environment
  63. version = environ.get("G4F_VERSION")
  64. if version:
  65. return version
  66. # Read from git repository
  67. try:
  68. command = ["git", "describe", "--tags", "--abbrev=0"]
  69. return check_output(command, text=True, stderr=PIPE).strip()
  70. except CalledProcessError:
  71. pass
  72. raise VersionNotFoundError("Version not found")
  73. @cached_property
  74. def latest_version(self) -> str:
  75. """
  76. Retrieves the latest version of the 'g4f' package.
  77. Returns:
  78. str: The latest version of 'g4f'.
  79. """
  80. # Is installed via package manager?
  81. try:
  82. get_package_version(PACKAGE_NAME)
  83. except PackageNotFoundError:
  84. return get_github_version(GITHUB_REPOSITORY)
  85. return get_pypi_version(PACKAGE_NAME)
  86. def check_version(self) -> None:
  87. """
  88. Checks if the current version of 'g4f' is up to date with the latest version.
  89. Note:
  90. If a newer version is available, it prints a message with the new version and update instructions.
  91. """
  92. try:
  93. if self.current_version != self.latest_version:
  94. print(f'New g4f version: {self.latest_version} (current: {self.current_version}) | pip install -U g4f')
  95. except Exception as e:
  96. print(f'Failed to check g4f version: {e}')
  97. utils = VersionUtils()