Register
Login
Resources
Docs Blog Datasets Glossary Case Studies Tutorials & Webinars
Product
Data Engine LLMs Platform Enterprise
Pricing Explore
Connect to our Discord channel

#609 Ci fix

Merged
Ghost merged 1 commits into Deci-AI:master from deci-ai:bugfix/infra-000_ci
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
  1. import logging
  2. import os
  3. import sys
  4. from pip._internal.operations.freeze import freeze
  5. from typing import List, Dict, Union
  6. from pathlib import Path
  7. from packaging.version import Version
  8. from super_gradients.common.abstractions.abstract_logger import get_logger
  9. from super_gradients.common.environment.ddp_utils import is_main_process
  10. LIB_CHECK_IMPOSSIBLE_MSG = 'Library check is not supported when super_gradients installed through "git+https://github.com/..." command'
  11. logger = get_logger(__name__, log_level=logging.DEBUG)
  12. def get_requirements_path(requirements_file_name: str) -> Union[None, Path]:
  13. """Get the path of requirement.txt from the root if exist.
  14. There is a difference when installed from artifact or locally.
  15. - In the first case, requirements.txt is copied to the package during the CI.
  16. - In the second case, requirements.txt in the root of the project.
  17. Note: This is because when installed from artifact only the source code is accessible, so requirements.txt has to be
  18. copied to the package root (./src/super_gradients). This is automatically done with the CI to make sure that
  19. in the github we only have 1 source of truth for requirements.txt. The consequence being that when the code
  20. is copied/cloned from github, the requirements.txt was not copied to the super_gradients package root, so we
  21. need to go to the project root (.) to find it.
  22. """
  23. file_path = Path(__file__) # super-gradients/src/super_gradients/sanity_check/env_sanity_check.py
  24. package_root = file_path.parent.parent # moving to super-gradients/src/super_gradients
  25. project_root = package_root.parent.parent # moving to super-gradients
  26. # If installed from artifact, requirements.txt is in package_root, if installed locally it is in project_root
  27. if (package_root / requirements_file_name).exists():
  28. return package_root / requirements_file_name
  29. elif (project_root / requirements_file_name).exists():
  30. return project_root / requirements_file_name
  31. else:
  32. return None # Could happen when installed through github directly ("pip install git+https://github.com/...")
  33. def get_installed_libs_with_version() -> Dict[str, str]:
  34. """Get all the installed libraries, and outputs it as a dict: lib -> version"""
  35. installed_libs_with_version = {}
  36. for lib_with_version in freeze():
  37. if "==" in lib_with_version:
  38. lib, version = lib_with_version.split("==")
  39. installed_libs_with_version[lib.lower()] = version
  40. return installed_libs_with_version
  41. def verify_installed_libraries() -> List[str]:
  42. """Check that all installed libs respect the requirement.txt"""
  43. requirements_path = get_requirements_path("requirements.txt")
  44. pro_requirements_path = get_requirements_path("requirements.pro.txt")
  45. if requirements_path is None:
  46. return [LIB_CHECK_IMPOSSIBLE_MSG]
  47. with open(requirements_path, "r") as f:
  48. requirements = f.readlines()
  49. installed_libs_with_version = get_installed_libs_with_version()
  50. # if pro_requirements_path is not None:
  51. with open(pro_requirements_path, "r") as f:
  52. pro_requirements = f.readlines()
  53. if "deci-lab-client" in installed_libs_with_version:
  54. requirements += pro_requirements
  55. errors = []
  56. for requirement in requirements:
  57. if ">=" in requirement:
  58. constraint = ">="
  59. elif "~=" in requirement:
  60. constraint = "~="
  61. elif "==" in requirement:
  62. constraint = "=="
  63. else:
  64. continue
  65. lib, required_version_str = requirement.split(constraint)
  66. if ",<=" in required_version_str:
  67. upper_limit_version = Version(required_version_str.split(",<=")[1])
  68. required_version_str = required_version_str.split(",<=")[0]
  69. constraint += ",<="
  70. if lib.lower() not in installed_libs_with_version.keys():
  71. errors.append(f"{lib} required but not found")
  72. continue
  73. installed_version_str = installed_libs_with_version[lib.lower()]
  74. installed_version, required_version = Version(installed_version_str), Version(required_version_str)
  75. is_constraint_respected = {
  76. ">=,<=": required_version <= installed_version <= upper_limit_version,
  77. ">=": installed_version >= required_version,
  78. "~=": (
  79. installed_version.major == required_version.major
  80. and installed_version.minor == required_version.minor
  81. and installed_version.micro >= required_version.micro
  82. ),
  83. "==": installed_version == required_version,
  84. }
  85. if not is_constraint_respected[constraint]:
  86. errors.append(f"{lib} is installed with version {installed_version} which does not satisfy {requirement} (based on {requirements_path})")
  87. return errors
  88. def verify_os() -> List[str]:
  89. """Verifying operating system name and platform"""
  90. if "linux" not in sys.platform.lower():
  91. return ["Deci officially supports only Linux kernels. Some features may not work as expected."]
  92. return []
  93. def run_env_sanity_check():
  94. """Run the sanity check tests and log everything that does not meet requirements"""
  95. display_sanity_check = os.getenv("DISPLAY_SANITY_CHECK", "False") == "True"
  96. stdout_log_level = logging.INFO if display_sanity_check else logging.DEBUG
  97. logger.setLevel(logging.DEBUG) # We want to log everything regardless of DISPLAY_SANITY_CHECK
  98. requirement_checkers = {
  99. "operating_system": verify_os,
  100. "libraries": verify_installed_libraries,
  101. }
  102. logger.log(stdout_log_level, "SuperGradients Sanity Check Started")
  103. logger.log(stdout_log_level, f"Checking the following components: {list(requirement_checkers.keys())}")
  104. logger.log(stdout_log_level, "_" * 20)
  105. lib_check_is_impossible = False
  106. sanity_check_errors = {}
  107. for test_name, test_function in requirement_checkers.items():
  108. logger.log(stdout_log_level, f"Verifying {test_name}...")
  109. errors = test_function()
  110. if errors == [LIB_CHECK_IMPOSSIBLE_MSG]:
  111. lib_check_is_impossible = True
  112. logger.log(stdout_log_level, LIB_CHECK_IMPOSSIBLE_MSG)
  113. elif len(errors) > 0:
  114. sanity_check_errors[test_name] = errors
  115. for error in errors:
  116. logger.log(logging.ERROR, f"\33[31mFailed to verify {test_name}: {error}\33[0m")
  117. else:
  118. logger.log(stdout_log_level, f"{test_name} OK")
  119. logger.log(stdout_log_level, "_" * 20)
  120. if sanity_check_errors:
  121. logger.log(stdout_log_level, f'The current environment does not meet Deci\'s needs, errors found in: {", ".join(list(sanity_check_errors.keys()))}')
  122. elif lib_check_is_impossible:
  123. logger.log(stdout_log_level, LIB_CHECK_IMPOSSIBLE_MSG)
  124. else:
  125. logger.log(stdout_log_level, "Great, Looks like the current environment meet's Deci's requirements!")
  126. # The last message needs to be displayed independently of DISPLAY_SANITY_CHECK
  127. if display_sanity_check:
  128. logger.info("** This check can be hidden by setting the env variable DISPLAY_SANITY_CHECK=False prior to import. **")
  129. else:
  130. logger.info(
  131. "** A sanity check is done when importing super_gradients for the first time. ** "
  132. "-> You can see the details by setting the env variable DISPLAY_SANITY_CHECK=True prior to import."
  133. )
  134. def env_sanity_check():
  135. """Run the sanity check tests and log everything that does not meet requirements"""
  136. if is_main_process():
  137. run_env_sanity_check()
  138. if __name__ == "__main__":
  139. env_sanity_check()
Discard
Tip!

Press p or to see the previous file or, n or to see the next file