Coverage for mindsdb / api / http / gui.py: 18%

56 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-21 00:36 +0000

1import os 

2import shutil 

3import tempfile 

4from pathlib import Path 

5from zipfile import ZipFile 

6 

7import requests 

8from packaging.version import Version 

9 

10from mindsdb.utilities.config import Config 

11from mindsdb.utilities import log 

12 

13logger = log.getLogger(__name__) 

14 

15 

16def download_gui(destignation, version): 

17 if isinstance(destignation, str): 

18 destignation = Path(destignation) 

19 dist_zip_path = str(destignation.joinpath("dist.zip")) 

20 bucket = "https://mindsdb-web-builds.s3.amazonaws.com/" 

21 

22 resources = [{"url": bucket + "dist-V" + version + ".zip", "path": dist_zip_path}] 

23 

24 def get_resources(resource): 

25 response = requests.get(resource["url"]) 

26 if response.status_code != requests.status_codes.codes.ok: 

27 raise Exception(f"Error {response.status_code} GET {resource['url']}") 

28 open(resource["path"], "wb").write(response.content) 

29 

30 try: 

31 for r in resources: 

32 get_resources(r) 

33 except Exception: 

34 logger.exception("Error during downloading files from s3:") 

35 return False 

36 

37 static_folder = destignation 

38 static_folder.mkdir(mode=0o777, exist_ok=True, parents=True) 

39 ZipFile(dist_zip_path).extractall(static_folder) 

40 

41 if static_folder.joinpath("dist").is_dir(): 

42 shutil.move(str(destignation.joinpath("dist").joinpath("index.html")), static_folder) 

43 shutil.move(str(destignation.joinpath("dist").joinpath("assets")), static_folder) 

44 shutil.rmtree(destignation.joinpath("dist")) 

45 

46 os.remove(dist_zip_path) 

47 

48 version_txt_path = destignation.joinpath("version.txt") 

49 with open(version_txt_path, "wt") as f: 

50 f.write(version) 

51 

52 return True 

53 

54 """ 

55 # to make downloading faster download each resource in a separate thread 

56 with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: 

57 future_to_url = {executor.submit(get_resources, r): r for r in resources} 

58 for future in concurrent.futures.as_completed(future_to_url): 

59 res = future.result() 

60 if res is not None: 

61 raise res 

62 """ 

63 

64 

65def update_static(gui_version: Version): 

66 """Update Scout files basing on compatible-config.json content. 

67 Files will be downloaded and updated if new version of GUI > current. 

68 Current GUI version stored in static/version.txt. 

69 """ 

70 config = Config() 

71 static_path = Path(config["paths"]["static"]) 

72 

73 logger.info(f"New version of GUI available ({gui_version.base_version}). Downloading...") 

74 

75 temp_dir = tempfile.mkdtemp(prefix="mindsdb_gui_files_") 

76 success = download_gui(temp_dir, gui_version.base_version) 

77 if success is False: 

78 shutil.rmtree(temp_dir) 

79 return False 

80 

81 temp_dir_for_rm = tempfile.mkdtemp(prefix="mindsdb_gui_files_") 

82 shutil.rmtree(temp_dir_for_rm) 

83 shutil.copytree(str(static_path), temp_dir_for_rm) 

84 shutil.rmtree(str(static_path)) 

85 shutil.copytree(temp_dir, str(static_path)) 

86 shutil.rmtree(temp_dir_for_rm) 

87 

88 logger.info(f"GUI version updated to {gui_version.base_version}") 

89 return True