adding featuregroup controller and making the featuregroup name unique 66/13866/5
authorrajdeep11 <rajdeep.sin@samsung.com>
Fri, 13 Dec 2024 12:57:37 +0000 (18:27 +0530)
committerrajdeep11 <rajdeep.sin@samsung.com>
Thu, 19 Dec 2024 11:16:02 +0000 (16:46 +0530)
Change-Id: I3218f65ee3e27ba1432dc6aa8b711615ddf3cf85
Signed-off-by: rajdeep11 <rajdeep.sin@samsung.com>
trainingmgr/controller/__init__.py
trainingmgr/controller/featuregroup_controller.py [new file with mode: 0644]
trainingmgr/models/featuregroup.py
trainingmgr/trainingmgr_main.py

index 677395c..51acd28 100644 (file)
@@ -14,4 +14,9 @@
 #   See the License for the specific language governing permissions and
 #   limitations under the License.
 #
-# ==================================================================================
\ No newline at end of file
+# ==================================================================================
+
+from .trainingjob_controller import training_job_controller
+from .featuregroup_controller import featuregroup_controller
+
+__all__ = ['training_job_controller', 'featuregroup_controller']
\ No newline at end of file
diff --git a/trainingmgr/controller/featuregroup_controller.py b/trainingmgr/controller/featuregroup_controller.py
new file mode 100644 (file)
index 0000000..af4ace4
--- /dev/null
@@ -0,0 +1,127 @@
+# ==================================================================================
+#
+#       Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved.
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#          http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+# ==================================================================================
+import json
+from flask_api import status
+from flask import Blueprint, jsonify, request
+from marshmallow import ValidationError
+from trainingmgr.common.exceptions_utls import DBException
+from trainingmgr.common.trainingmgr_operations import create_dme_filtered_data_job
+from trainingmgr.common.trainingmgr_util import check_trainingjob_name_or_featuregroup_name
+from trainingmgr.db.featuregroup_db import add_featuregroup, delete_feature_group_by_name
+from trainingmgr.common.trainingmgr_config import TrainingMgrConfig
+from trainingmgr.schemas import FeatureGroupSchema
+
+
+
+featuregroup_controller = Blueprint('featuregroup_controller', __name__)
+TRAININGMGR_CONFIG_OBJ = TrainingMgrConfig()
+LOGGER = TRAININGMGR_CONFIG_OBJ.logger
+MIMETYPE_JSON = "application/json"
+
+@featuregroup_controller.route('/featureGroup', methods=['POST'])
+def create_feature_group():
+    """
+    Rest endpoint to create feature group
+
+    Args in function:
+                NONE
+
+    Args in json:
+            json with below fields are given:
+                featureGroupName: str
+                    description
+                feature_list: str
+                    feature names
+                datalake: str
+                    name of datalake
+                bucket: str
+                    bucket name
+                host: str
+                    db host
+                port: str
+                    db port
+                token: str
+                    token for the bucket
+                db org: str
+                    db org name
+                measurement: str
+                    measurement of the influxdb
+                enable_Dme: boolean
+                    whether to enable dme
+                source_name: str
+                    name of source
+                DmePort: str
+                    DME port
+                measured_obj_class: str
+                    obj class for dme.
+                datalake_source: str
+                    string indicating datalake source
+
+    Returns:
+        1. For post request
+            json:
+                result : str
+                    result message
+                status code:
+                    HTTP status code 201
+        2. For put request
+            json:
+                result : str
+                    result message
+                status code:
+                    HTTP status code 200
+
+    Exceptions:
+        All exception are provided with exception message and HTTP status code."""
+    
+    api_response = {}
+    response_code = status.HTTP_500_INTERNAL_SERVER_ERROR
+    LOGGER.debug('feature Group Create request, ' + json.dumps(request.json))
+
+    try:
+        featuregroup = FeatureGroupSchema().load(request.get_json())
+        feature_group_name = featuregroup.featuregroup_name
+        # check the data conformance
+        # LOGGER.debug("the db info is : ", get_feature_group_by_name_db(PS_DB_OBJ, feature_group_name))
+        if (not check_trainingjob_name_or_featuregroup_name(feature_group_name) or
+            len(feature_group_name) < 3 or len(feature_group_name) > 63):
+            api_response = {"Exception": "Failed to create the feature group since feature group not valid"}
+            response_code = status.HTTP_400_BAD_REQUEST
+        else:
+            # the features are stored in string format in the db, and has to be passed as list of feature to the dme. Hence the conversion.
+            add_featuregroup(featuregroup)
+            api_response = FeatureGroupSchema().dump(featuregroup)
+            response_code =status.HTTP_200_OK
+            if featuregroup.enable_dme == True :
+                response= create_dme_filtered_data_job(TRAININGMGR_CONFIG_OBJ, featuregroup)
+                if response.status_code != 201:
+                    api_response={"Exception": "Cannot create dme job"}
+                    delete_feature_group_by_name(featuregroup)
+                    response_code=status.HTTP_400_BAD_REQUEST
+    except ValidationError as err:
+        LOGGER.error(f"Failed to create the feature Group {str(err)}")
+        return {"Exception": str(err)}, 400
+    except DBException as err:
+        LOGGER.error(f"Failed to create the feature Group {str(err)}")
+        return {"Exception": str(err)}, 400
+    except Exception as e:
+        api_response = {"Exception":str(e)}
+        LOGGER.error(f"Failed to create the feature Group {str(err)}")
+        jsonify(json.dumps(api_response)), 500
+    
+    return jsonify(api_response), 201
\ No newline at end of file
index 2c59b6f..ec9d2ff 100644 (file)
@@ -16,6 +16,7 @@
 #
 # ==================================================================================
 from . import db
+from sqlalchemy import UniqueConstraint
 
 class FeatureGroup(db.Model):
     __tablename__ = "featuregroup_info_table"
@@ -34,5 +35,9 @@ class FeatureGroup(db.Model):
     dme_port = db.Column(db.String(128), nullable=True)
     source_name = db.Column(db.String(20000), nullable=True)
 
+    __table_args__ = (
+        UniqueConstraint("featuregroup_name", name="unique featuregroup"),
+    )
+
     def __repr__(self):
         return f'<featuregroup {self.featuregroup_name}>'
\ No newline at end of file
index c0f41ef..3483a34 100644 (file)
@@ -54,7 +54,7 @@ from trainingmgr.models import db, TrainingJob, FeatureGroup
 from trainingmgr.schemas import ma, TrainingJobSchema , FeatureGroupSchema
 from trainingmgr.db.featuregroup_db import add_featuregroup, edit_featuregroup, get_feature_groups_db, \
     get_feature_group_by_name_db, delete_feature_group_by_name
-from trainingmgr.controller.trainingjob_controller import training_job_controller
+from trainingmgr.controller import featuregroup_controller, training_job_controller
 from trainingmgr.controller.pipeline_controller import pipeline_controller
 from trainingmgr.common.trainingConfig_parser import validateTrainingConfig, getField
 from trainingmgr.handler.async_handler import start_async_handler
@@ -65,6 +65,7 @@ APP = Flask(__name__)
 TRAININGMGR_CONFIG_OBJ = TrainingMgrConfig()
 from middleware.loggingMiddleware import LoggingMiddleware
 APP.wsgi_app = LoggingMiddleware(APP.wsgi_app)
+APP.register_blueprint(featuregroup_controller)
 APP.register_blueprint(training_job_controller)
 APP.register_blueprint(pipeline_controller)
 
@@ -649,98 +650,6 @@ def feature_group_by_name(featuregroup_name):
                     status= response_code,
                     mimetype=MIMETYPE_JSON)
 
-@APP.route('/featureGroup', methods=['POST'])
-def create_feature_group():
-    """
-    Rest endpoint to create feature group
-
-    Args in function:
-                NONE
-
-    Args in json:
-            json with below fields are given:
-                featureGroupName: str
-                    description
-                feature_list: str
-                    feature names
-                datalake: str
-                    name of datalake
-                bucket: str
-                    bucket name
-                host: str
-                    db host
-                port: str
-                    db port
-                token: str
-                    token for the bucket
-                db org: str
-                    db org name
-                measurement: str
-                    measurement of the influxdb
-                enable_Dme: boolean
-                    whether to enable dme
-                source_name: str
-                    name of source
-                DmePort: str
-                    DME port
-                measured_obj_class: str
-                    obj class for dme.
-                datalake_source: str
-                    string indicating datalake source
-
-    Returns:
-        1. For post request
-            json:
-                result : str
-                    result message
-                status code:
-                    HTTP status code 201
-        2. For put request
-            json:
-                result : str
-                    result message
-                status code:
-                    HTTP status code 200
-
-    Exceptions:
-        All exception are provided with exception message and HTTP status code."""
-    
-    api_response = {}
-    response_code = status.HTTP_500_INTERNAL_SERVER_ERROR
-    LOGGER.debug('feature Group Create request, ' + json.dumps(request.json))
-
-    try:
-        featuregroup = FeatureGroupSchema().load(request.get_json())
-        feature_group_name = featuregroup.featuregroup_name
-        # check the data conformance
-        # LOGGER.debug("the db info is : ", get_feature_group_by_name_db(PS_DB_OBJ, feature_group_name))
-        if (not check_trainingjob_name_or_featuregroup_name(feature_group_name) or
-            len(feature_group_name) < 3 or len(feature_group_name) > 63):
-            api_response = {"Exception": "Failed to create the feature group since feature group not valid"}
-            response_code = status.HTTP_400_BAD_REQUEST
-        else:
-            # the features are stored in string format in the db, and has to be passed as list of feature to the dme. Hence the conversion.
-            add_featuregroup(featuregroup)
-            api_response = FeatureGroupSchema().dump(featuregroup)
-            response_code =status.HTTP_200_OK
-            if featuregroup.enable_dme == True :
-                response= create_dme_filtered_data_job(TRAININGMGR_CONFIG_OBJ, featuregroup)
-                if response.status_code != 201:
-                    api_response={"Exception": "Cannot create dme job"}
-                    delete_feature_group_by_name(featuregroup)
-                    response_code=status.HTTP_400_BAD_REQUEST
-    except ValidationError as err:
-        return {"Exception": str(err)}, 400
-    except DBException as err:
-        return {"Exception": str(err)}, 400
-    except Exception as e:
-        err_msg = "Failed to create the feature Group "
-        api_response = {"Exception":str(e)}
-        LOGGER.error(str(e))
-    
-    return APP.response_class(response=json.dumps(api_response),
-                                        status=response_code,
-                                        mimetype=MIMETYPE_JSON)
 
 @APP.route('/featureGroup', methods=['GET'])
 def get_feature_group():