python_environment_check.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. # Copyright (c) Sebastian Raschka under Apache License 2.0 (see LICENSE.txt).
  2. # Source for "Build a Large Language Model From Scratch"
  3. # - https://www.manning.com/books/build-a-large-language-model-from-scratch
  4. # Code: https://github.com/rasbt/LLMs-from-scratch
  5. from importlib.metadata import PackageNotFoundError, import_module
  6. import importlib.metadata
  7. from os.path import dirname, exists, join, realpath
  8. from packaging.version import parse as version_parse
  9. import platform
  10. import sys
  11. if version_parse(platform.python_version()) < version_parse("3.9"):
  12. print("[FAIL] We recommend Python 3.9 or newer but"
  13. " found version %s" % (sys.version))
  14. else:
  15. print("[OK] Your Python version is %s" % (platform.python_version()))
  16. def get_packages(pkgs):
  17. versions = []
  18. for p in pkgs:
  19. try:
  20. imported = import_module(p)
  21. try:
  22. version = (getattr(imported, "__version__", None) or
  23. getattr(imported, "version", None) or
  24. getattr(imported, "version_info", None))
  25. if version is None:
  26. # If common attributes don"t exist, use importlib.metadata
  27. version = importlib.metadata.version(p)
  28. versions.append(version)
  29. except PackageNotFoundError:
  30. # Handle case where package is not installed
  31. versions.append("0.0")
  32. except ImportError:
  33. # Fallback if importlib.import_module fails for unexpected reasons
  34. versions.append("0.0")
  35. return versions
  36. def get_requirements_dict():
  37. PROJECT_ROOT = dirname(realpath(__file__))
  38. PROJECT_ROOT_UP_TWO = dirname(dirname(PROJECT_ROOT))
  39. REQUIREMENTS_FILE = join(PROJECT_ROOT_UP_TWO, "requirements.txt")
  40. if not exists(REQUIREMENTS_FILE):
  41. REQUIREMENTS_FILE = join(PROJECT_ROOT, "requirements.txt")
  42. d = {}
  43. with open(REQUIREMENTS_FILE) as f:
  44. for line in f:
  45. if not line.strip():
  46. continue
  47. if "," in line:
  48. left, right = line.split(",")
  49. lower = right.split("#")[0].strip()
  50. package, _, upper = left.split(" ")
  51. package = package.strip()
  52. _, lower = lower.split(" ")
  53. lower = lower.strip()
  54. upper = upper.strip()
  55. d[package] = (upper, lower)
  56. else:
  57. line = line.split("#")[0].strip()
  58. line = line.split(" ")
  59. line = [ln.strip() for ln in line]
  60. d[line[0]] = line[-1]
  61. return d
  62. def check_packages(d):
  63. versions = get_packages(d.keys())
  64. for (pkg_name, suggested_ver), actual_ver in zip(d.items(), versions):
  65. if isinstance(suggested_ver, tuple):
  66. lower, upper = suggested_ver[0], suggested_ver[1]
  67. else:
  68. lower = suggested_ver
  69. upper = None
  70. if actual_ver == "N/A":
  71. continue
  72. actual_ver = version_parse(actual_ver)
  73. lower = version_parse(lower)
  74. if upper is not None:
  75. upper = version_parse(upper)
  76. if actual_ver < lower and upper is None:
  77. print(f"[FAIL] {pkg_name} {actual_ver}, please upgrade to >= {lower}")
  78. elif actual_ver < lower:
  79. print(f"[FAIL] {pkg_name} {actual_ver}, please upgrade to >= {lower} and < {upper}")
  80. elif upper is not None and actual_ver >= upper:
  81. print(f"[FAIL] {pkg_name} {actual_ver}, please downgrade to >= {lower} and < {upper}")
  82. else:
  83. print(f"[OK] {pkg_name} {actual_ver}")
  84. def main():
  85. d = get_requirements_dict()
  86. check_packages(d)
  87. if __name__ == "__main__":
  88. main()