def get(self, metric_id): """ Implements the GET method for endpoint "/metrics/{metric_id}/configs". By default the results are order by 'config_name' ascending. Implemented Query Parameters: - sort: allows one to order the resulting collection by 'config_name' in descending order. This should be done by specifying the query parameter as "sort=-config_name". Case insensitive. Note: if unknown query parameters are given these will be ignored. :param metric_id: the metric_id associated with this endpoint :return: a collection of metric configs for the specified metric_id """ query = MetricConfig.query.filter_by(metric_id=metric_id) # check if the 'sort' has been requested for the only implemented field sort = request.args.get("sort") if sort is not None and sort.lstrip("-").lower() == 'config_name': query = query.order_by(MetricConfig.config_name.desc()) else: # by default sorts ascending query = query.order_by(MetricConfig.config_name) # execute query configs = query.all() result = self.schema_collection.dump(configs) return success(result=result)
def post(self, metric_id): """ Implements the POST method for endpoint "/metrics/{metric_id}/configs". It should be used to create a new metric config. :param metric_id: the metric_id associated with this endpoint :return: the metric config as a json created in the database (in case of success) """ json_data = request.get_json(force=True) if not json_data: abort(400, 'No input data provided') # validate and deserialize input metric_config = self.load(json_data, session=db.session) # get respective metric by the id, associate the newly create config with this # metric obtained from the database metric = get_metric_by_id(metric_id) metric_config.metric = metric # add object to db try: db.session.add(metric_config) db.session.commit() except SQLAlchemyError as e: abort(400, message=f'Database error. Reason: {e}') # send result back result = self.schema.dump(metric_config) return success(result, code=201)
def put(self, metric_id, config_name): """ Implements the PUT method for endpoint "/metrics/{metric_id}/configs/{config_name}". It should be used to update a metric config_name. :param metric_id: the metric_id associated with this endpoint :param config_name: the name of the configuration being updated :return: the metric config as a json after the update (in case of success) """ json_data = request.get_json(force=True) if not json_data: abort(400, message='No input data provided') # Validate and deserialize input config = self._get_metric_config_by_name(metric_id, config_name) self.load(json_data, instance=config, session=db.session, partial=True) # if it was found and deserialized successfully try to commit try: db.session.commit() except SQLAlchemyError as e: abort(400, message=f'Database error. Reason: {e}') return success(json_data)
def post(self): """ Implements the POST method for endpoint "/metrics". It should be used to create a new metric. :return: the metric as a json created in the database (in case of success) """ json_data = request.get_json(force=True) if not json_data: abort(400, message='No input data provided') # make sure the metric_id (temporary) and metric_type (model) are filled json_data["metric_id"] = "TBD" json_data["metric_type"] = "model" # validate and deserialize input new_metric = self.load(json_data, session=db.session) # get the next metric id and update metric object try: db.session.add(new_metric) db.session.commit() except SQLAlchemyError as e: abort(400, message=f'Database error. Reason: {e}') # dump to json and return result result = self.schema.dump(new_metric) return success(result, code=201)
def get(self, metric_id): """ Implements the GET method for endpoint "/metrics/{metric_id}/runs". By default the results are order by 'cob_date' ascending. Implemented Query Parameters: - start: to obtain results from this "start" date (including). Format: YYYY-MM-DD. - end: to obtain results up to this "end" date (including). Format: YYYY-MM-DD. - breach: to filter results that were either in "breach" or not. Case insensitive. - status: to filter results according to a given metric result status. Case insensitive. - sort: allows one to order the resulting collection by 'cob_date' in descending order. This should be done by specifying the query parameter as "sort=-cob_date". Case insensitive. Note: if unknown query parameters are given these will be ignored. :param metric_id: the metric_id associated with this endpoint :return: a collection of metric results for the specified metric_id """ # base query will always filter by metric_id query = MetricRun.query.filter_by(metric_id=metric_id) # get query parameters from request start = request.args.get('start') end = request.args.get('end') breach = request.args.get('breach') status = request.args.get('status') sort = request.args.get("sort") # process (convert if needed) each parameter and append to query filters if start is not None: start = _datestr_to_datetime(start, 'start') query = query.filter(MetricRun.cob_date >= start) if end is not None: end = _datestr_to_datetime(end, 'end') query = query.filter(MetricRun.cob_date <= end) if breach is not None: breach = breach.lower() == 'true' query = query.filter_by(breach=breach) if status is not None: try: metric_status = MetricStatus.from_name(status) except ValueError as e: msg = f"Invalid 'status': {status}. Use one of {MetricStatus.values()}" abort(400, message=msg) query = query.filter(MetricRun.status == metric_status) # check if the 'sort' has been requested for the only implemented field if sort is not None and sort.lstrip("-").lower() == 'cob_date': query = query.order_by(MetricRun.cob_date.desc()) else: # by default sorts ascending query = query.order_by(MetricRun.cob_date) # execute query results = query.all() # dump results into a json like object res = self.schema_collection.dump(results) return success(result=res)
def delete(self, metric_id): """ Implements the DELETE method for endpoint "/metrics/{metric_id}". It should be used to delete a metric result matching the provided metric_id and cob_date. :param metric_id: the metric_id associated with this endpoint :return: the metric as a json after the delete (in case of success) """ metric = get_metric_by_id(metric_id) # dump as json to send in the end if del is successful result = self.schema.dump(metric) # if result was found, delete it from database try: db.session.delete(metric) db.session.commit() except SQLAlchemyError as e: abort(400, message=f'Database error. Reason: {e}') return success(result)
def delete(self, metric_id, config_name): """ Implements the DELETE method for endpoint "/metrics/{metric_id}/configs/{config_name}". It should be used to delete a metric config matching the provided metric_id and config_name. :param metric_id: the metric_id associated with this endpoint :param config_name: the name of the configuration being deleted :return: the metric config as a json after the delete (in case of success) """ config = self._get_metric_config_by_name(metric_id, config_name) result = self.schema.dump(config) # if result was found, delete it from database try: db.session.delete(config) db.session.commit() except SQLAlchemyError as e: abort(400, message=f'Database error. Reason: {e}') return success(result)
def put(self, metric_id): """ Implements the PUT method for endpoint "/metrics/{metric_id}". It should be used to update a metric. :param metric_id: the metric_id associated with this endpoint :return: the metric as a json after the update (in case of success) """ json_data = request.get_json(force=True) if not json_data: abort(400, message='No input data provided') # Validate and deserialize input metric = get_metric_by_id(metric_id) self.load(json_data, metric, db.session, partial=True) # if it was found and deserialized successfully try to commit try: db.session.commit() except SQLAlchemyError as e: abort(400, message=f'Database error. Reason: {e}') return success(json_data)
def get(self): """ Implements the GET method for endpoint "/metrics". By default the results are order by 'metric_id' ascending. Implemented Query Parameters: - is_active: to filter results that are either active or inactive. Boolean and case insensitive. - frequency: filter results based on a metric frequency. Values of this enum must be respected. Case insensitive. - threshold_type: filter results based on a metric threshold type. Values of this enum must be respected. Case insensitive. - sort: allows one to order the resulting collecting by 'metric_id' in descending order. This should be done by specifying the query parameter as "sort=-metric_id". Case insensitive. Note: if unknown query parameters are given these will be ignored. :return: a collection of metrics """ query = self.build_query() metrics = query.all() result = self.schema_collection.dump(metrics) return success(result)