def delete(self, path, subscription): url = self.endpoint + path headers = { 'Content-Type': 'application/json', 'apim-subscription-id': subscription } if self.username and self.password: auth = (self.username, self.password) else: auth = None retryrequests = RetryRequests(self.retrycount, self.retryinterval) try: r = retryrequests.delete(url=url, headers=headers, auth=auth, timeout=REQUEST_TIMEOUT_SECONDS, verify=False) return r.json() except Exception as e: raise Exception('MAGA service api "{}" failed, {}'.format( path, str(e)))
def post(self, path, data, subscription): url = self.endpoint + path headers = { 'Content-Type': 'application/json', 'Ocp-Apim-Subscription-Key': subscription } if self.username and self.password: auth = (self.username, self.password) else: auth = None retryrequests = RetryRequests(self.retrycount, self.retryinterval) try: r = retryrequests.post(url=url, headers=headers, auth=auth, data=json.dumps(data), timeout=REQUEST_TIMEOUT_SECONDS, verify=False) if r.status_code != 204: return r.json() except Exception as e: raise Exception( 'MAGA service api "{}" failed, request:{}, {}'.format( path, data, str(e)))
def __init__(self, endpoint, series_limit, username=None, password=None, retrycount=3, retryinterval=1000): self.endpoint = endpoint self.series_limit = series_limit self.username = username self.password = password self.retryrequests = RetryRequests(retrycount, retryinterval)
class TSANAClient(object): def __init__(self, endpoint, series_limit, username=None, password=None, retrycount=3, retryinterval=1000): self.endpoint = endpoint self.series_limit = series_limit self.username = username self.password = password self.retryrequests = RetryRequests(retrycount, retryinterval) def post(self, api_key, path, data): url = self.endpoint + path headers = { "x-api-key": api_key, "Content-Type": "application/json" } if self.username and self.password: auth = (self.username, self.password) else: auth = None try: r = self.retryrequests.post(url=url, headers=headers, auth=auth, data=json.dumps(data), timeout=REQUEST_TIMEOUT_SECONDS, verify=False) if r.status_code != 204: return r.json() except Exception as e: raise Exception('TSANA service api "{}" failed, request:{}, {}'.format(path, data, str(e))) def put(self, api_key, path, data): url = self.endpoint + path headers = { "x-api-key": api_key, "Content-Type": "application/json" } if self.username and self.password: auth = (self.username, self.password) else: auth = None try: r = self.retryrequests.put(url=url, headers=headers, auth=auth, data=json.dumps(data), timeout=REQUEST_TIMEOUT_SECONDS, verify=False) if r.status_code != 204: return r.json() except Exception as e: raise Exception('TSANA service api "{}" failed, request:{}, {}'.format(path, data, str(e))) def get(self, api_key, path): url = self.endpoint + path headers = { "x-api-key": api_key, "Content-Type": "application/json" } if self.username and self.password: auth = (self.username, self.password) else: auth = None try: r = self.retryrequests.get(url=url, headers=headers, auth=auth, timeout=REQUEST_TIMEOUT_SECONDS, verify=False) return r.json() except Exception as e: raise Exception('TSANA service api "{}" failed, {}'.format(path, str(e))) # To get the meta of a specific metric from TSANA # Parameters: # apiKey: api key for specific user # metric_id: a UUID string # Return: # meta: the meta of the specified metric, or None if there is something wrong. def get_metric_meta(self, api_key, metric_id): return self.get(api_key, '/metrics/' + metric_id + '/meta') def get_dimesion_values(self, api_key, metric_id, dimension_name): dims = self.get(api_key, '/metrics/' + metric_id + '/dimensions') if 'dimensions' in dims and dimension_name in dims['dimensions']: return dims['dimensions'][dimension_name] else: return None # Query time series from TSANA # Parameters: # apiKey: api key for specific user # series_sets: Array of series set # start_time: inclusive, the first timestamp to be query # end_time: exclusive # offset: a number will be added to each timestamp of each time-series. The unit is defined by granularity # granularityName: if Offset > 0, the granularityName is Monthly / Weekly / Daily / Hourly / Minutely / Secondly / Custom # granularityAmount: if granularityName is Custom, granularityAmount is the seconds of the exact granularity # Return: # A array of Series object def get_timeseries(self, api_key, series_sets, start_time, end_time, offset=0, granularityName=None, granularityAmount=0, top=1): if offset != 0 and granularityName is None: offset = 0 end_str = dt_to_str(end_time) start_str = dt_to_str(start_time) dedup = {} series = [] # Query each series's tag for data in series_sets: dim = {} if 'dimensionFilter' not in data: data['dimensionFilter'] = data['filters'] for dimkey in data['dimensionFilter']: dim[dimkey] = [data['dimensionFilter'][dimkey]] para = dict(metricId=data['metricId'], dimensions=dim, count=top, startTime=start_str) ret = self.post(api_key, '/metrics/' + data['metricId'] + '/rank-series', data=para) for s in ret['value']: if s['seriesId'] not in dedup: s['seriesSetId'] = data['seriesSetId'] s['startTime'] = start_str s['endTime'] = end_str s['dimension'] = s['dimensions'] del s['dimensions'] series.append(s) dedup[s['seriesId']] = True # Query the data multi_series_data = None if len(series) > 0: ret = self.post(api_key, '/metrics/series/data', data=dict(value=series)) if granularityName is not None: multi_series_data = [ Series(factor['id']['metricId'], series[idx]['seriesSetId'], factor['id']['dimension'], [dict(timestamp=get_time_offset(str_to_dt(y[0]), (granularityName, granularityAmount), offset) , value=y[1]) for y in factor['values']]) for idx, factor in enumerate(ret['value']) ] else: multi_series_data = [ Series(factor['id']['metricId'], series[idx]['seriesSetId'], factor['id']['dimension'], value=[dict(timestamp=y[0] , value=y[1]) for y in factor['values']]) for idx, factor in enumerate(ret['value']) ] else: log.info("Series is empty") return multi_series_data # Save a training result back to TSANA # Parameters: # parameters: a dict object which should includes # apiKey: api key for specific user # groupId: groupId in TSANA, which is copied from inference request, or from the entity # instance: instance object, which is copied from the inference request, or from the entity # model_id: model id # model_state: model state(TRAINING,READY,FAILED,DELETED) # message: detail message # Return: # result: STATE_SUCCESS / STATE_FAIL # message: description for the result def save_training_result(self, parameters, model_id, model_state:str, message:str): try: body = { 'modelId': model_id, 'state': model_state, 'message': message } self.put(parameters['apiKey'], '/timeSeriesGroups/' + parameters['groupId'] + '/appInstances/' + parameters['instance']['instanceId'] + '/modelKey', body) return STATUS_SUCCESS, '' except Exception as e: traceback.print_exc(file=sys.stdout) return STATUS_FAIL, str(e) # Save a inference result back to TSANA # Parameters: # parameters: a dict object which should includes # apiKey: api key for specific user # groupId: groupId in TSANA, which is copied from inference request, or from the entity # instance: instance object, which is copied from the inference request, or from the entity # result: an array of inference result. # Return: # result: STATE_SUCCESS / STATE_FAIL # messagee: description for the result def save_inference_result(self, parameters, result): try: if len(result) <= 0: return STATUS_SUCCESS, '' body = { 'groupId': parameters['groupId'], 'instanceId': parameters['instance']['instanceId'], 'results': [] } for item in result: item['timestamp'] = dt_to_str(str_to_dt(item['timestamp'])) body['results'].append({ 'params': parameters['instance']['params'], 'timestamp': item['timestamp'], 'result': item, 'status': InferenceState.Ready.name }) self.post(parameters['apiKey'], '/timeSeriesGroups/' + parameters['groupId'] + '/appInstances/' + parameters['instance']['instanceId'] + '/saveResult', body) return STATUS_SUCCESS, '' except Exception as e: traceback.print_exc(file=sys.stdout) return STATUS_FAIL, str(e) # Save a inference result back to TSANA # Parameters: # parameters: a dict object which should includes # apiKey: api key for specific user # groupId: groupId in TSANA, which is copied from inference request, or from the entity # instance: instance object, which is copied from the inference request, or from the entity # metric_id: a UUID string # dimensions: a dict includes dimension name and value # timestamps: an array of timestamps # values: an array of inference result values # Return: # result: STATE_SUCCESS / STATE_FAIL # messagee: description for the result def save_data_points(self, parameters, metricId, dimensions, timestamps, values): try: if len(values) <= 0: return STATUS_SUCCESS, '' body = { "metricId": metricId, "dimensions": dimensions, "timestamps": timestamps, "values": values } print(json.dumps(body)) self.post(parameters['apiKey'], '/pushData', body) return STATUS_SUCCESS, '' except Exception as e: traceback.print_exc(file=sys.stdout) return STATUS_FAIL, str(e) def get_inference_result(self, parameters, start_time, end_time): try: ret = self.get(parameters['apiKey'], '/timeSeriesGroups/' + parameters['groupId'] + '/appInstances/' + parameters['instance']['instanceId'] + '/history?startTime=' + dt_to_str(start_time) + '&endTime=' + dt_to_str(end_time)) return STATUS_SUCCESS, '', ret except Exception as e: traceback.print_exc(file=sys.stdout) return STATUS_FAIL, str(e), None