Repository: mindsdb/mindsdb

Issue:
List of available trained models
It would be great if we can have some options like mindsdb.getExistingModels some kind of feature to see all the existing models that I trained. So that I can pick easily one and proceed with my stuff.


Discussion:
yes, we can do this, lets add it to the feature requests. I can guide you on how to do it too.
https://github.com/mindsdb/main/issues/new?template=feature-mindsb-request.md
Hello, this is not a bug, I have added it as feature only, let me know when can you guide me?
@torrmal I could probably help out with this

@AbhishekRaoC for sure, please feel free to do so, if you add the method to the mindsdb controller it will be fantastic, make sure to use the collections that we have: libs/data_entities/*

best regards,

Jorge


Resolving patch:
diff --git a/mindsdb/api/mysql/mysql_proxy/mysql_proxy.py b/mindsdb/api/mysql/mysql_proxy/mysql_proxy.py
--- a/mindsdb/api/mysql/mysql_proxy/mysql_proxy.py
+++ b/mindsdb/api/mysql/mysql_proxy/mysql_proxy.py
@@ -470,51 +470,133 @@ def _check_predict_columns(self, predict_column_names, ds_column_names):
 
         return cleaned_predict_column_names
 
-    def answer_describe_predictor(self, predictor_name):
+    def _get_model_info(self, data):
+        models_data = data.get("submodel_data", [])
+        if models_data == []:
+            raise ErBadTableError("predictor doesn't contain enough data to generate 'model' attribute")
+        data = []
+        for model in models_data:
+            m_data = []
+            m_data.append(model["name"])
+            m_data.append(model["accuracy"])
+            m_data.append(1 if model["is_best"] else 0)
+            data.append(m_data)
+        return data
+
+    def _get_features_info(self, data):
+        ai_info = data.get('json_ai', {})
+        if ai_info == {}:
+            raise ErBadTableError("predictor doesn't contain enough data to generate 'feature' attribute.")
+        data = []
+        dtype_dict = ai_info["dtype_dict"]
+        for column in dtype_dict:
+            c_data = []
+            c_data.append(column)
+            c_data.append(dtype_dict[column])
+            c_data.append(ai_info["encoders"][column]["module"])
+            if ai_info["encoders"][column]["args"].get("is_target", "False") == "True":
+                c_data.append("target")
+            else:
+                c_data.append("feature")
+            data.append(c_data)
+        return data
+
+    def answer_describe_predictor(self, predictor_value):
+        predictor_attr = None
+        if isinstance(predictor_value, (list, tuple)):
+            predictor_name = predictor_value[0]
+            predictor_attr = predictor_value[1]
+        else:
+            predictor_name = predictor_value
         model_interface = self.session.model_interface
         models = model_interface.get_models()
         if predictor_name not in [x['name'] for x in models]:
             raise ErBadTableError(f"Can't describe predictor. There is no predictor with name '{predictor_name}'")
         description = model_interface.get_model_description(predictor_name)
-        description = [
-            description['accuracies'],
-            description['column_importances'],
-            description['outputs'],
-            description['inputs'],
-            description['datasource'],
-            description['model']
-        ]
-        packages = self.get_tabel_packets(
-            columns=[{
-                'table_name': '',
-                'name': 'accuracies',
-                'type': TYPES.MYSQL_TYPE_VAR_STRING
-            }, {
-                'table_name': '',
-                'name': 'column_importances',
-                'type': TYPES.MYSQL_TYPE_VAR_STRING
-            }, {
-                'table_name': '',
-                'name': "outputs",
-                'type': TYPES.MYSQL_TYPE_VAR_STRING
-            }, {
-                'table_name': '',
-                'name': 'inputs',
-                'type': TYPES.MYSQL_TYPE_VAR_STRING
-            }, {
-                'table_name': '',
-                'name': 'datasource',
-                'type': TYPES.MYSQL_TYPE_VAR_STRING
-            }, {
-                'table_name': '',
-                'name': 'model',
-                'type': TYPES.MYSQL_TYPE_VAR_STRING
-            }],
-            data=[description]
-        )
+
+        if predictor_attr is None:
+            description = [
+                description['accuracies'],
+                description['column_importances'],
+                description['outputs'],
+                description['inputs'],
+                description['datasource'],
+                description['model']
+            ]
+            packages = self.get_tabel_packets(
+                columns=[{
+                    'table_name': '',
+                    'name': 'accuracies',
+                    'type': TYPES.MYSQL_TYPE_VAR_STRING
+                }, {
+                    'table_name': '',
+                    'name': 'column_importances',
+                    'type': TYPES.MYSQL_TYPE_VAR_STRING
+                }, {
+                    'table_name': '',
+                    'name': "outputs",
+                    'type': TYPES.MYSQL_TYPE_VAR_STRING
+                }, {
+                    'table_name': '',
+                    'name': 'inputs',
+                    'type': TYPES.MYSQL_TYPE_VAR_STRING
+                }, {
+                    'table_name': '',
+                    'name': 'datasource',
+                    'type': TYPES.MYSQL_TYPE_VAR_STRING
+                }, {
+                    'table_name': '',
+                    'name': 'model',
+                    'type': TYPES.MYSQL_TYPE_VAR_STRING
+                }],
+                data=[description]
+            )
+        else:
+            data = model_interface.get_model_data(predictor_name)
+            if predictor_attr == "features":
+                data = self._get_features_info(data)
+                packages = self.get_tabel_packets(
+                    columns=[{
+                        'table_name': '',
+                        'name': 'column',
+                        'type': TYPES.MYSQL_TYPE_VAR_STRING
+                    }, {
+                        'table_name': '',
+                        'name': 'type',
+                        'type': TYPES.MYSQL_TYPE_VAR_STRING
+                    }, {
+                        'table_name': '',
+                        'name': "encoder",
+                        'type': TYPES.MYSQL_TYPE_VAR_STRING
+                    }, {
+                        'table_name': '',
+                        'name': 'role',
+                        'type': TYPES.MYSQL_TYPE_VAR_STRING
+                    }],
+                    data=data
+                )
+            elif predictor_attr == "model":
+                data = self._get_model_info(data)
+                packages = self.get_tabel_packets(
+                    columns=[{
+                        'table_name': '',
+                        'name': 'name',
+                        'type': TYPES.MYSQL_TYPE_VAR_STRING
+                    }, {
+                        'table_name': '',
+                        'name': 'performance',
+                        'type': TYPES.MYSQL_TYPE_VAR_STRING
+                    }, {
+                        'table_name': '',
+                        'name': "selected",
+                        'type': TYPES.MYSQL_TYPE_VAR_STRING
+                    }],
+                    data=data
+                )
+            else:
+                raise ErNotSupportedYet("DESCRIBE '%s' predictor attribute is not supported yet" % predictor_attr)
         packages.append(self.last_packet())
         self.send_package_group(packages)
-        return
 
     def answer_retrain_predictor(self, predictor_name):
         model_interface = self.session.model_interface
@@ -1163,7 +1245,10 @@ def query_answer(self, sql):
             self.answer_drop_datasource(ds_name)
             return
         elif type(statement) == Describe:
-            self.answer_describe_predictor(statement.value.parts[-1])
+            if statement.value.parts[-1] in ("model", "features"):
+                self.answer_describe_predictor(statement.value.parts[-2:])
+            else:
+                self.answer_describe_predictor(statement.value.parts[-1])
             return
         elif type(statement) == RetrainPredictor:
             self.answer_retrain_predictor(statement.name.parts[-1])


Test patch: