Adding Endpoints to Update and Retrieve Model-Metrics 23/14523/1
authorashishj1729 <jain.ashish@samsung.com>
Tue, 3 Jun 2025 11:24:19 +0000 (16:54 +0530)
committerashishj1729 <jain.ashish@samsung.com>
Tue, 3 Jun 2025 11:27:39 +0000 (16:57 +0530)
Issue-Id: AIMLFW-209

Change-Id: I351e62ffdfd89594e16d9fdf55238fb30bf2d5a6
Signed-off-by: ashishj1729 <jain.ashish@samsung.com>
trainingmgr/controller/trainingjob_controller.py
trainingmgr/db/trainingjob_db.py
trainingmgr/models/trainingjob.py
trainingmgr/schemas/trainingjob_schema.py
trainingmgr/service/training_job_service.py
trainingmgr/trainingmgr_main.py

index 070bcb8..8793ba7 100644 (file)
@@ -27,7 +27,7 @@ from trainingmgr.schemas.trainingjob_schema import TrainingJobSchema
 from trainingmgr.schemas.featuregroup_schema import FeatureGroupSchema
 from trainingmgr.schemas.problemdetail_schema import ProblemDetails
 from trainingmgr.service.training_job_service import delete_training_job, create_training_job, get_training_job, get_trainining_jobs, \
-get_steps_state, fetch_trainingjob_infos_from_model_id
+get_steps_state, fetch_trainingjob_infos_from_model_id, update_model_metrics_service, get_model_metrics_service
 from trainingmgr.common.trainingmgr_util import check_key_in_dictionary
 from trainingmgr.common.trainingConfig_parser import validateTrainingConfig
 from trainingmgr.service.mme_service import get_modelinfo_by_modelId_service
@@ -127,4 +127,34 @@ def get_trainingjob_infos_from_model_id(model_name, model_version):
         return jsonify(trainingjobs_schema.dump(trainingjob_infos)), 200
     except Exception as err:
         LOGGER.error(f"Error fetching training-job-infos corresponding to model_name = {model_name} and model_version = {model_version} : {str(err)}")
+        return ProblemDetails(500, "Internal Server Error", str(err)).to_json()
+    
+@training_job_controller.route('/training-jobs/update-model-metrics/<trainingjob_id>', methods=['POST'])
+def update_model_metrics(trainingjob_id):
+    '''
+     This API-endpoint takes trainingjob_id into account and updates the model_metrics associated with the trainingjob_id
+    '''
+    
+    try:
+        request_json = request.get_json()
+        LOGGER.debug(f'Updating model_metrics of  trainingJob-ID {trainingjob_id} with new metrics  {request_json}')
+        update_model_metrics_service(trainingjob_id, request_json)
+        return jsonify({}) ,200
+    except Exception as err:
+        LOGGER.error(f"Error Updating model_metrics of  trainingJob-ID {trainingjob_id} Error: {str(err)}")
+        return ProblemDetails(500, "Internal Server Error", str(err)).to_json()
+    
+@training_job_controller.route('/training-jobs/get-model-metrics/<trainingjob_id>', methods=['GET'])
+def get_model_metrics(trainingjob_id):
+    '''
+     This API-endpoint takes trainingjob_id into account and returns the model_metrics associated with the trainingjob_id
+    '''
+    
+    try:
+
+        LOGGER.debug(f'Retrieving model_metrics of  trainingJob-ID {trainingjob_id}')
+        model_metrics = get_model_metrics_service(trainingjob_id)
+        return jsonify(model_metrics), 200
+    except Exception as err:
+        LOGGER.error(f"Error Getting model_metrics of  trainingJob-ID {trainingjob_id}: {str(err)}")
         return ProblemDetails(500, "Internal Server Error", str(err)).to_json()
\ No newline at end of file
index 4378d70..59debd6 100644 (file)
@@ -37,17 +37,30 @@ PATTERN = re.compile(r"\w+")
 
 
 
-def change_field_value(traininigjob_id, field, value):
+def change_field_value(trainingjob_id, field, value):
     """
     This function updates field's value to field_value of trainingjob.
     """
     try:
-        trainingjob = TrainingJob.query.filter(TrainingJob.id==traininigjob_id).one()
+        trainingjob = TrainingJob.query.filter(TrainingJob.id==trainingjob_id).one()
         setattr(trainingjob, field, value)
         db.session.commit()
+    except NoResultFound as err:
+        raise DBException(f"Failed to execute change_field_value for id: {trainingjob_id}, because id doesn't exist in db")
     except Exception as err:
         raise DBException("Failed to execute query in change_field_value," + str(err))
 
+def get_field_value(trainingjob_id, field):
+    """
+    This function get field's value to field_value of trainingjob.
+    """
+    try:
+        trainingjob = TrainingJob.query.filter(TrainingJob.id==trainingjob_id).one()
+        return getattr(trainingjob, field)
+    except NoResultFound as err:
+        raise DBException(f"Failed to execute get_field_value for id: {trainingjob_id}, because id doesn't exist in db")
+    except Exception as err:
+        raise DBException("Failed to execute query in get_field_value," + str(err))
 
 def create_trainingjob(trainingjob):
         
index b439475..ec2fad7 100644 (file)
@@ -15,6 +15,7 @@
 #   limitations under the License.
 #
 # ==============================================================================
+import json
 from trainingmgr.models import db
 from sqlalchemy.sql import func
 from sqlalchemy import Integer, ForeignKey, String, DateTime, Column, Boolean
@@ -57,6 +58,7 @@ class TrainingJob(db.Model):
     
     model_url = Column(String(1000), nullable=True)
     model_id = Column(Integer, nullable=False)
+    model_metrics = db.Column(db.String(5000), nullable=True, default=json.dumps({}))
 
     #defineing relationships
     steps_state = relationship("TrainingJobStatus", back_populates="trainingjobs")
index a4322c5..c0b27a8 100644 (file)
@@ -41,7 +41,7 @@ class TrainingJobSchema(ma.SQLAlchemyAutoSchema):
     class Meta:
         model = TrainingJob
         load_instance = True
-        exclude = ("creation_time", "deletion_in_progress", "updation_time","run_id")
+        exclude = ("creation_time", "deletion_in_progress", "updation_time","run_id", "model_metrics")
     
     modelId = ma.Nested(ModelSchema)
 
index 144d141..c0d3df8 100644 (file)
@@ -22,7 +22,7 @@ from flask import jsonify
 from trainingmgr.common.trainingmgr_operations import data_extraction_start, notification_rapp
 from trainingmgr.db.model_db import get_model_by_modelId
 from trainingmgr.db.trainingjob_db import change_state_to_failed, delete_trainingjob_by_id, create_trainingjob, get_trainingjob,\
-change_steps_state, change_field_value, change_field_value, change_steps_state_df, changeartifact, get_trainingjobs_by_model_id_db
+change_steps_state, change_field_value, get_field_value, change_steps_state_df, changeartifact, get_trainingjobs_by_model_id_db
 from trainingmgr.common.exceptions_utls import DBException, TMException
 from trainingmgr.common.trainingConfig_parser import getField, setField
 from trainingmgr.handler.async_handler import DATAEXTRACTION_JOBS_CACHE
@@ -282,4 +282,19 @@ def fetch_trainingjob_infos_from_model_id(model_name, model_version):
         trainingjob_infos = get_trainingjobs_by_model_id_db(model_name, model_version)
         return trainingjob_infos
     except Exception as err:
-        raise TMException(f"Can't fetch trainingjob_infos from model_name {model_name} and model_version {model_version}| Error: " + str(err))
\ No newline at end of file
+        raise TMException(f"Can't fetch trainingjob_infos from model_name {model_name} and model_version {model_version}| Error: " + str(err))
+    
+    
+def update_model_metrics_service(trainingjob_id, model_metrics):
+    try:
+        model_metrics_str = json.dumps(model_metrics)
+        change_field_value(trainingjob_id, "model_metrics", model_metrics_str)
+    except Exception as err:
+        raise TMException(f"Can't Update model_metrics for trainingjob_id {trainingjob_id}| Error: " + str(err))
+    
+def get_model_metrics_service(trainingjob_id):
+    try:
+        model_metrics_str = get_field_value(trainingjob_id, "model_metrics")
+        return json.loads(model_metrics_str)
+    except Exception as err:
+        raise TMException(f"Can't Update model_metrics for trainingjob_id {trainingjob_id}| Error: " + str(err))
\ No newline at end of file
index 0b858dc..2554675 100644 (file)
@@ -539,7 +539,7 @@ if __name__ == "__main__":
         PS_DB_OBJ = PSDB(TRAININGMGR_CONFIG_OBJ)
         APP.config['SQLALCHEMY_DATABASE_URI']=f'postgresql+psycopg2://{TRAININGMGR_CONFIG_OBJ.ps_user}:{TRAININGMGR_CONFIG_OBJ.ps_password}@{TRAININGMGR_CONFIG_OBJ.ps_ip}:{TRAININGMGR_CONFIG_OBJ.ps_port}/training_manager_database'
         db.init_app(APP)
-        # Todo add flask db upgrade in the docker file  
+        # Todo add flask db upgrade in the docker file
         migrate = Migrate(APP, db) 
         with APP.app_context():
             db.create_all()