Coverage for mindsdb / integrations / libs / ml_handler_process / describe_process.py: 14%

62 statements  

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

1import importlib 

2from textwrap import dedent 

3from types import ModuleType 

4from typing import Optional, Union 

5 

6from pandas import DataFrame 

7 

8import mindsdb.interfaces.storage.db as db 

9from mindsdb.utilities.config import Config 

10from mindsdb.interfaces.storage.model_fs import ModelStorage, HandlerStorage 

11from mindsdb.interfaces.model.model_controller import ModelController 

12 

13 

14def get_module_import_error_str(module: ModuleType) -> str: 

15 '''Make a str with human-readable module import error message 

16 

17 Atrs: 

18 module (ModuleType): module with import error 

19 

20 Returns: 

21 str: error message 

22 ''' 

23 is_cloud = Config().get('cloud', False) 

24 

25 msg = dedent(f'''\ 

26 ML engine '{module.name}' cannot be used. Reason is: 

27 {module.import_error} 

28 ''') 

29 

30 if is_cloud is False: 

31 msg += '\n' 

32 msg += dedent(f'''\ 

33 If error is related to missing dependencies, then try to run command in shell and restart mindsdb: 

34 pip install mindsdb[{module.name}] 

35 ''') 

36 

37 return msg 

38 

39 

40def describe_process(integration_id: int, attribute: Optional[Union[str, list]], 

41 model_id: int, module_path: str) -> DataFrame: 

42 '''get a model description 

43 

44 Args: 

45 model_id (int): id of the model 

46 integration_id (int): id of the integration 

47 attribute (Optional[Union[str, list]]): attribute, or list model attributes to describe 

48 module_path: (str): path integration module 

49 

50 Returns: 

51 DataFrame: usually 1-row dataframe with model description 

52 ''' 

53 module = importlib.import_module(module_path) 

54 

55 handlerStorage = HandlerStorage(integration_id) 

56 modelStorage = ModelStorage(model_id) 

57 

58 model_record = db.Predictor.query.get(model_id) 

59 if model_record is None: 

60 return DataFrame(['The model does not exist'], columns=['error']) 

61 

62 if isinstance(attribute, str) and attribute.lower() == 'import_error': 

63 return DataFrame([get_module_import_error_str(module)], columns=['error']) 

64 

65 if attribute is not None: 

66 if module.import_error is not None: 

67 return DataFrame([get_module_import_error_str(module)], columns=['error']) 

68 

69 try: 

70 ml_handler = module.Handler( 

71 engine_storage=handlerStorage, 

72 model_storage=modelStorage 

73 ) 

74 return ml_handler.describe(attribute) 

75 except NotImplementedError: 

76 return DataFrame() 

77 except Exception as e: 

78 return DataFrame( 

79 [f'{e.__class__.__name__}: {e}'], 

80 columns=['error'] 

81 ) 

82 else: 

83 model_info = ModelController.get_model_info(model_record) 

84 

85 attrs_df = DataFrame() 

86 if module.import_error is not None: 

87 attrs_df = DataFrame(['import_error'], columns=['error']) 

88 model_error = model_info['ERROR'][0] or '-' 

89 model_info['ERROR'][0] = 'ML engine error:\n\n' 

90 model_info['ERROR'][0] += get_module_import_error_str(module) 

91 model_info['ERROR'][0] += '\nModel error:\n\n' 

92 model_info['ERROR'][0] += model_error 

93 else: 

94 try: 

95 ml_handler = module.Handler( 

96 engine_storage=handlerStorage, 

97 model_storage=modelStorage 

98 ) 

99 attrs_df = ml_handler.describe(attribute) 

100 except NotImplementedError: 

101 pass 

102 except Exception as e: 

103 model_error = model_info['ERROR'][0] or '-' 

104 model_info['ERROR'][0] = 'ML engine error:\n\n' 

105 model_info['ERROR'][0] += f'{e.__class__.__name__}: {e}\n' 

106 model_info['ERROR'][0] += '\nModel error:\n\n' 

107 model_info['ERROR'][0] += model_error 

108 

109 attributes = [] 

110 if len(attrs_df) > 0 and len(attrs_df.columns) > 0: 

111 attributes = list(attrs_df[attrs_df.columns[0]]) 

112 if len(attributes) == 1 and isinstance(attributes[0], list): 

113 # first cell already has a list 

114 attributes = attributes[0] 

115 

116 model_info.insert(0, 'TABLES', [attributes]) 

117 return model_info