sysinfo.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. import json
  2. import os
  3. import sys
  4. import subprocess
  5. import platform
  6. import hashlib
  7. import re
  8. from pathlib import Path
  9. from modules import paths_internal, timer, shared_cmd_options, errors, launch_utils
  10. checksum_token = "DontStealMyGamePlz__WINNERS_DONT_USE_DRUGS__DONT_COPY_THAT_FLOPPY"
  11. environment_whitelist = {
  12. "GIT",
  13. "INDEX_URL",
  14. "WEBUI_LAUNCH_LIVE_OUTPUT",
  15. "GRADIO_ANALYTICS_ENABLED",
  16. "PYTHONPATH",
  17. "TORCH_INDEX_URL",
  18. "TORCH_COMMAND",
  19. "REQS_FILE",
  20. "XFORMERS_PACKAGE",
  21. "CLIP_PACKAGE",
  22. "OPENCLIP_PACKAGE",
  23. "ASSETS_REPO",
  24. "STABLE_DIFFUSION_REPO",
  25. "K_DIFFUSION_REPO",
  26. "BLIP_REPO",
  27. "ASSETS_COMMIT_HASH",
  28. "STABLE_DIFFUSION_COMMIT_HASH",
  29. "K_DIFFUSION_COMMIT_HASH",
  30. "BLIP_COMMIT_HASH",
  31. "COMMANDLINE_ARGS",
  32. "IGNORE_CMD_ARGS_ERRORS",
  33. }
  34. def pretty_bytes(num, suffix="B"):
  35. for unit in ["", "K", "M", "G", "T", "P", "E", "Z", "Y"]:
  36. if abs(num) < 1024 or unit == 'Y':
  37. return f"{num:.0f}{unit}{suffix}"
  38. num /= 1024
  39. def get():
  40. res = get_dict()
  41. text = json.dumps(res, ensure_ascii=False, indent=4)
  42. h = hashlib.sha256(text.encode("utf8"))
  43. text = text.replace(checksum_token, h.hexdigest())
  44. return text
  45. re_checksum = re.compile(r'"Checksum": "([0-9a-fA-F]{64})"')
  46. def check(x):
  47. m = re.search(re_checksum, x)
  48. if not m:
  49. return False
  50. replaced = re.sub(re_checksum, f'"Checksum": "{checksum_token}"', x)
  51. h = hashlib.sha256(replaced.encode("utf8"))
  52. return h.hexdigest() == m.group(1)
  53. def get_cpu_info():
  54. cpu_info = {"model": platform.processor()}
  55. try:
  56. import psutil
  57. cpu_info["count logical"] = psutil.cpu_count(logical=True)
  58. cpu_info["count physical"] = psutil.cpu_count(logical=False)
  59. except Exception as e:
  60. cpu_info["error"] = str(e)
  61. return cpu_info
  62. def get_ram_info():
  63. try:
  64. import psutil
  65. ram = psutil.virtual_memory()
  66. return {x: pretty_bytes(getattr(ram, x, 0)) for x in ["total", "used", "free", "active", "inactive", "buffers", "cached", "shared"] if getattr(ram, x, 0) != 0}
  67. except Exception as e:
  68. return str(e)
  69. def get_packages():
  70. try:
  71. return subprocess.check_output([sys.executable, '-m', 'pip', 'freeze', '--all']).decode("utf8").splitlines()
  72. except Exception as pip_error:
  73. try:
  74. import importlib.metadata
  75. packages = importlib.metadata.distributions()
  76. return sorted([f"{package.metadata['Name']}=={package.version}" for package in packages])
  77. except Exception as e2:
  78. return {'error pip': pip_error, 'error importlib': str(e2)}
  79. def get_dict():
  80. config = get_config()
  81. res = {
  82. "Platform": platform.platform(),
  83. "Python": platform.python_version(),
  84. "Version": launch_utils.git_tag(),
  85. "Commit": launch_utils.commit_hash(),
  86. "Git status": git_status(paths_internal.script_path),
  87. "Script path": paths_internal.script_path,
  88. "Data path": paths_internal.data_path,
  89. "Extensions dir": paths_internal.extensions_dir,
  90. "Checksum": checksum_token,
  91. "Commandline": get_argv(),
  92. "Torch env info": get_torch_sysinfo(),
  93. "Exceptions": errors.get_exceptions(),
  94. "CPU": get_cpu_info(),
  95. "RAM": get_ram_info(),
  96. "Extensions": get_extensions(enabled=True, fallback_disabled_extensions=config.get('disabled_extensions', [])),
  97. "Inactive extensions": get_extensions(enabled=False, fallback_disabled_extensions=config.get('disabled_extensions', [])),
  98. "Environment": get_environment(),
  99. "Config": config,
  100. "Startup": timer.startup_record,
  101. "Packages": get_packages(),
  102. }
  103. return res
  104. def get_environment():
  105. return {k: os.environ[k] for k in sorted(os.environ) if k in environment_whitelist}
  106. def get_argv():
  107. res = []
  108. for v in sys.argv:
  109. if shared_cmd_options.cmd_opts.gradio_auth and shared_cmd_options.cmd_opts.gradio_auth == v:
  110. res.append("<hidden>")
  111. continue
  112. if shared_cmd_options.cmd_opts.api_auth and shared_cmd_options.cmd_opts.api_auth == v:
  113. res.append("<hidden>")
  114. continue
  115. res.append(v)
  116. return res
  117. re_newline = re.compile(r"\r*\n")
  118. def get_torch_sysinfo():
  119. try:
  120. import torch.utils.collect_env
  121. info = torch.utils.collect_env.get_env_info()._asdict()
  122. return {k: re.split(re_newline, str(v)) if "\n" in str(v) else v for k, v in info.items()}
  123. except Exception as e:
  124. return str(e)
  125. def run_git(path, *args):
  126. try:
  127. return subprocess.check_output([launch_utils.git, '-C', path, *args], shell=False, encoding='utf8').strip()
  128. except Exception as e:
  129. return str(e)
  130. def git_status(path):
  131. if (Path(path) / '.git').is_dir():
  132. return run_git(paths_internal.script_path, 'status')
  133. def get_info_from_repo_path(path: Path):
  134. is_repo = (path / '.git').is_dir()
  135. return {
  136. 'name': path.name,
  137. 'path': str(path),
  138. 'commit': run_git(path, 'rev-parse', 'HEAD') if is_repo else None,
  139. 'branch': run_git(path, 'branch', '--show-current') if is_repo else None,
  140. 'remote': run_git(path, 'remote', 'get-url', 'origin') if is_repo else None,
  141. }
  142. def get_extensions(*, enabled, fallback_disabled_extensions=None):
  143. try:
  144. from modules import extensions
  145. if extensions.extensions:
  146. def to_json(x: extensions.Extension):
  147. return {
  148. "name": x.name,
  149. "path": x.path,
  150. "commit": x.commit_hash,
  151. "branch": x.branch,
  152. "remote": x.remote,
  153. }
  154. return [to_json(x) for x in extensions.extensions if not x.is_builtin and x.enabled == enabled]
  155. else:
  156. return [get_info_from_repo_path(d) for d in Path(paths_internal.extensions_dir).iterdir() if d.is_dir() and enabled != (str(d.name) in fallback_disabled_extensions)]
  157. except Exception as e:
  158. return str(e)
  159. def get_config():
  160. try:
  161. from modules import shared
  162. return shared.opts.data
  163. except Exception as _:
  164. try:
  165. with open(shared_cmd_options.cmd_opts.ui_settings_file, 'r') as f:
  166. return json.load(f)
  167. except Exception as e:
  168. return str(e)