From: ashishj1729 Date: Tue, 3 Jun 2025 11:24:19 +0000 (+0530) Subject: Adding Endpoints to Update and Retrieve Model-Metrics X-Git-Tag: 4.0.0~3 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F23%2F14523%2F1;p=aiml-fw%2Fawmf%2Ftm.git Adding Endpoints to Update and Retrieve Model-Metrics Issue-Id: AIMLFW-209 Change-Id: I351e62ffdfd89594e16d9fdf55238fb30bf2d5a6 Signed-off-by: ashishj1729 --- diff --git a/trainingmgr/controller/trainingjob_controller.py b/trainingmgr/controller/trainingjob_controller.py index 070bcb8..8793ba7 100644 --- a/trainingmgr/controller/trainingjob_controller.py +++ b/trainingmgr/controller/trainingjob_controller.py @@ -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/', 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/', 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 diff --git a/trainingmgr/db/trainingjob_db.py b/trainingmgr/db/trainingjob_db.py index 4378d70..59debd6 100644 --- a/trainingmgr/db/trainingjob_db.py +++ b/trainingmgr/db/trainingjob_db.py @@ -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): diff --git a/trainingmgr/models/trainingjob.py b/trainingmgr/models/trainingjob.py index b439475..ec2fad7 100644 --- a/trainingmgr/models/trainingjob.py +++ b/trainingmgr/models/trainingjob.py @@ -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") diff --git a/trainingmgr/schemas/trainingjob_schema.py b/trainingmgr/schemas/trainingjob_schema.py index a4322c5..c0b27a8 100644 --- a/trainingmgr/schemas/trainingjob_schema.py +++ b/trainingmgr/schemas/trainingjob_schema.py @@ -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) diff --git a/trainingmgr/service/training_job_service.py b/trainingmgr/service/training_job_service.py index 144d141..c0d3df8 100644 --- a/trainingmgr/service/training_job_service.py +++ b/trainingmgr/service/training_job_service.py @@ -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 diff --git a/trainingmgr/trainingmgr_main.py b/trainingmgr/trainingmgr_main.py index 0b858dc..2554675 100644 --- a/trainingmgr/trainingmgr_main.py +++ b/trainingmgr/trainingmgr_main.py @@ -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()