Coverage for mindsdb / api / http / namespaces / tree.py: 24%

58 statements  

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

1import inspect 

2from collections import defaultdict 

3 

4from flask import current_app as ca, request 

5from flask_restx import Resource 

6 

7from mindsdb.api.http.utils import http_error 

8from mindsdb.api.http.namespaces.configs.tree import ns_conf 

9from mindsdb.metrics.metrics import api_endpoint_metrics 

10 

11 

12@ns_conf.route("/") 

13class GetRoot(Resource): 

14 @ns_conf.doc("get_tree_root") 

15 @api_endpoint_metrics("GET", "/tree") 

16 def get(self): 

17 databases = ca.database_controller.get_list() 

18 result = [ 

19 { 

20 "name": x["name"], 

21 "class": "db", 

22 "type": x["type"], 

23 "engine": x["engine"], 

24 "deletable": x["deletable"], 

25 "visible": x["visible"], 

26 } 

27 for x in databases 

28 ] 

29 return result 

30 

31 

32@ns_conf.route("/<db_name>") 

33@ns_conf.param("db_name", "Name of the database") 

34class GetLeaf(Resource): 

35 @ns_conf.doc("get_tree_leaf") 

36 @api_endpoint_metrics("GET", "/tree/database") 

37 def get(self, db_name): 

38 with_schemas = request.args.get("all_schemas") 

39 if isinstance(with_schemas, str): 

40 with_schemas = with_schemas.lower() in ("1", "true") 

41 else: 

42 with_schemas = False 

43 db_name = db_name.lower() 

44 databases = ca.database_controller.get_dict() 

45 if db_name not in databases: 

46 return http_error(400, "Error", f"There is no element with name '{db_name}'") 

47 db = databases[db_name] 

48 if db["type"] == "project": 

49 project = ca.database_controller.get_project(db_name) 

50 tables = project.get_tables() 

51 tables = [ 

52 { 

53 "name": key, 

54 "schema": None, 

55 "class": "table", 

56 "type": val["type"], 

57 "engine": val.get("engine"), 

58 "deletable": val.get("deletable"), 

59 } 

60 for key, val in tables.items() 

61 ] 

62 

63 jobs = ca.jobs_controller.get_list(db_name) 

64 tables = tables + [ 

65 {"name": job["name"], "schema": None, "class": "job", "type": "job", "engine": "job", "deletable": True} 

66 for job in jobs 

67 ] 

68 elif db["type"] == "data": 

69 handler = ca.integration_controller.get_data_handler(db_name) 

70 if "all" in inspect.signature(handler.get_tables).parameters: 

71 response = handler.get_tables(all=with_schemas) 

72 else: 

73 response = handler.get_tables() 

74 if response.type != "table": 

75 return [] 

76 table_types = {"BASE TABLE": "table", "VIEW": "view"} 

77 tables = response.data_frame.to_dict(orient="records") 

78 

79 schemas = defaultdict(list) 

80 

81 for table_meta in tables: 

82 table_meta = {key.lower(): val for key, val in table_meta.items()} 

83 schama = table_meta.get("table_schema") 

84 schemas[schama].append( 

85 { 

86 "name": table_meta["table_name"], 

87 "class": "table", 

88 "type": table_types.get(table_meta.get("table_type")), 

89 "engine": None, 

90 "deletable": False, 

91 } 

92 ) 

93 if len(schemas) == 1 and list(schemas.keys())[0] is None: 

94 tables = schemas[None] 

95 else: 

96 tables = [ 

97 {"name": key, "class": "schema", "deletable": False, "children": val} 

98 for key, val in schemas.items() 

99 ] 

100 elif db["type"] == "system": 

101 system_db = ca.database_controller.get_system_db(db_name) 

102 tables = system_db.get_tree_tables() 

103 tables = [ 

104 { 

105 "name": table.name, 

106 "class": table.kind, 

107 "type": "system view", 

108 "engine": None, 

109 "deletable": table.deletable, 

110 } 

111 for table in tables.values() 

112 ] 

113 return tables