From d6cb177ef120d6932e1f1dab3a3d6f9ebfc52dd9 Mon Sep 17 00:00:00 2001 From: Marco Miller Date: Thu, 26 Aug 2021 12:10:29 -0400 Subject: [PATCH 1/4] Add XY tree TSP endpoint support to client w/ test Do not rename the existing --get-tree cli script option, to preserve backward compatibility with potential usage of it. Only use an 'xy' infix in the name of the hereby added option, discriminating it from that existing one for timegraph. Assume EntryModel's default XY_TREE model_type while initializing the GenericResponse for this case. Update README's own copy of ./tsp-cli-client -h, accordingly. Signed-off-by: Marco Miller --- README.md | 7 +++++-- test_tsp.py | 17 +++++++++++++++++ tsp-cli-client | 29 ++++++++++++++++++++++++++++- tsp/response.py | 3 +-- tsp/tsp_client.py | 26 ++++++++++++++++++++++++++ 5 files changed, 77 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 61cb8dd..5bf61f6 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,8 @@ usage: tsp-cli-client [-h] [--ip IP] [--port PORT] [--open-trace TRACE_PATH] [--list-experiment UUID] [--list-experiments] [--delete-experiment UUID] [--list-outputs UUID] [--list-output OUTPUT_ID] [--get-tree OUTPUT_ID] - [--uuid UUID] [--uuids [UUIDS ...]] [--do-delete-traces] + [--get-xy-tree OUTPUT_ID] [--uuid UUID] + [--uuids [UUIDS ...]] [--do-delete-traces] [--paths [PATHS ...]] [--list-extensions] [--load-extension EXTENSION_PATH] [--delete-extension EXTENSION_NAME] @@ -83,7 +84,9 @@ optional arguments: --list-outputs UUID Get details on the given trace --list-output OUTPUT_ID Get details on the given output of a trace - --get-tree OUTPUT_ID Get the tree of an output + --get-tree OUTPUT_ID Get the timegraph tree of an output + --get-xy-tree OUTPUT_ID + Get the XY tree of an output --uuid UUID The UUID of a trace --uuids [UUIDS ...] The list of UUIDs --do-delete-traces Also delete traces when deleting experiment diff --git a/test_tsp.py b/test_tsp.py index bf8148d..8bda650 100644 --- a/test_tsp.py +++ b/test_tsp.py @@ -228,6 +228,23 @@ def test_fetch_timegraph_tree(self, kernel): self._delete_experiments() self._delete_traces() + def test_fetch_xy_tree(self, kernel): + traces = [] + response = self.tsp_client.open_trace(os.path.basename(kernel), kernel) + traces.append(response.model.UUID) + response = self.tsp_client.open_experiment( + os.path.basename(kernel), traces) + assert response.status_code == 200 + experiment_uuid = response.model.UUID + + response = self.tsp_client.fetch_experiment_outputs(experiment_uuid) + output_id = response.model.descriptors[0].id + response = self.tsp_client.fetch_xy_tree(experiment_uuid, output_id) + assert response.status_code == 200 + assert response.model.model_type == response.model.model_type.XY_TREE + self._delete_experiments() + self._delete_traces() + def test_fetch_extensions_none(self): response = self.tsp_client.fetch_extensions() assert response.status_code == 200 diff --git a/tsp-cli-client b/tsp-cli-client index 41ee796..3dc765f 100755 --- a/tsp-cli-client +++ b/tsp-cli-client @@ -134,7 +134,9 @@ if __name__ == "__main__": parser.add_argument("--list-output", dest="list_output", help="Get details on the given output of a trace", metavar="OUTPUT_ID") parser.add_argument("--get-tree", dest="get_tree", - help="Get the tree of an output", metavar="OUTPUT_ID") + help="Get the timegraph tree of an output", metavar="OUTPUT_ID") + parser.add_argument("--get-xy-tree", dest="get_xy_tree", + help="Get the XY tree of an output", metavar="OUTPUT_ID") parser.add_argument("--uuid", dest="uuid", help="The UUID of a trace") parser.add_argument("--uuids", dest="uuids", help="The list of UUIDs", nargs="*") @@ -311,6 +313,31 @@ if __name__ == "__main__": print("Trace UUID is missing") sys.exit(1) + if (options.get_xy_tree): + if options.uuid is not None: + + output_descriptor = get_descriptor( + options.uuid, options.get_xy_tree) + if (output_descriptor is None): + sys.exit(1) + + response = tsp_client.fetch_xy_tree( + options.uuid, options.get_xy_tree) + if response.status_code == 200: + tree = response.model.model + + if (output_descriptor.type == "TREE_TIME_XY"): + treeModel = TreeModel(tree.entries, tree.descriptors) + else: + treeModel = TreeModel(tree.entries) + treeModel.print() + sys.exit(0) + else: + sys.exit(1) + else: + print("Trace UUID is missing") + sys.exit(1) + if (options.extensions): response = tsp_client.fetch_extensions() if response.status_code == 200: diff --git a/tsp/response.py b/tsp/response.py index 1496c8d..d4abc0e 100644 --- a/tsp/response.py +++ b/tsp/response.py @@ -79,8 +79,7 @@ def __init__(self, params, model_type): if self.model_type == ModelType.TIME_GRAPH_TREE: self.model = EntryModel(params.get(MODEL_KEY), self.model_type) elif self.model_type == ModelType.XY_TREE: - # TODO - print("not implemented") + self.model = EntryModel(params.get(MODEL_KEY)) elif self.model_type == ModelType.STATES: # TODO print("not implemented") diff --git a/tsp/tsp_client.py b/tsp/tsp_client.py index b402894..569f086 100644 --- a/tsp/tsp_client.py +++ b/tsp/tsp_client.py @@ -252,6 +252,32 @@ def fetch_timegraph_tree(self, exp_uuid, output_id, parameters=None): print("failed to get tree: {0}".format(response.status_code)) return TspClientResponse(None, response.status_code, response.text) + def fetch_xy_tree(self, exp_uuid, output_id, parameters=None): + ''' + Fetch XY tree, Model extends Entry + :param exp_uuid: Experiment UUID + :param output_id: Output ID + :param parameters: Query object + :returns: :class: `TspClientResponse ` object XY entry response with entries and headers + :rtype: TspClientResponse + ''' + api_url = '{0}experiments/{1}/outputs/XY/{2}/tree'.format( + self.base_url, exp_uuid, output_id) + + params = parameters + if (parameters is None): + requested_times = [0, 1] + my_parameters = {REQUESTED_TIME_KEY: requested_times} + params = {PARAMETERS_KEY: my_parameters} + + response = requests.post(api_url, json=params, headers=headers) + + if response.status_code == 200: + return TspClientResponse(GenericResponse(json.loads(response.content.decode('utf-8')), ModelType.XY_TREE), response.status_code, response.text) + else: + print("failed to get tree: {0}".format(response.status_code)) + return TspClientResponse(None, response.status_code, response.text) + def fetch_extensions(self): ''' Fetch Extensions (loaded files) From 1ee3bf8071dd8e35cde3ac8e9b60b17c636cde5e Mon Sep 17 00:00:00 2001 From: Marco Miller Date: Thu, 26 Aug 2021 16:52:26 -0400 Subject: [PATCH 2/4] Add XY data TSP endpoint support to client w/ test Add a --get-xy cli script option along with its --items and --times siblings. Update README's copy of script's -h, accordingly. Make that script able to print the resulting XYModel contents as applicable. Add a test, along with REQUESTED_TIME_XY value constants matching its kernel test trace used; this is the trace that is already used across all of those tests. Make that new test wait for its analysis to be done running (so, complete or else), prior to try accessing its XY data. The latter is otherwise not accessible yet. Limit this test scope depth to what the sibling tests currently cover. (Deeper coverage backlogged.) Move related constants as TspClient members so they are reused. Unlike existing TspClient methods, the hereby added one requires parameters, as it cannot infer default values for those in that specific case. Existing default requested_times values in TspClient may require revisiting. Signed-off-by: Marco Miller --- README.md | 8 +- test_tsp.py | 47 ++++++++++ tsp-cli-client | 29 +++++++ tsp/response.py | 4 +- tsp/tsp_client.py | 35 ++++++-- tsp/xy_model.py | 214 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 326 insertions(+), 11 deletions(-) create mode 100644 tsp/xy_model.py diff --git a/README.md b/README.md index 5bf61f6..14363fc 100644 --- a/README.md +++ b/README.md @@ -56,8 +56,9 @@ usage: tsp-cli-client [-h] [--ip IP] [--port PORT] [--open-trace TRACE_PATH] [--list-experiment UUID] [--list-experiments] [--delete-experiment UUID] [--list-outputs UUID] [--list-output OUTPUT_ID] [--get-tree OUTPUT_ID] - [--get-xy-tree OUTPUT_ID] [--uuid UUID] - [--uuids [UUIDS ...]] [--do-delete-traces] + [--get-xy-tree OUTPUT_ID] [--get-xy OUTPUT_ID] + [--items [ITEMS ...]] [--times [TIMES ...]] + [--uuid UUID] [--uuids [UUIDS ...]] [--do-delete-traces] [--paths [PATHS ...]] [--list-extensions] [--load-extension EXTENSION_PATH] [--delete-extension EXTENSION_NAME] @@ -87,6 +88,9 @@ optional arguments: --get-tree OUTPUT_ID Get the timegraph tree of an output --get-xy-tree OUTPUT_ID Get the XY tree of an output + --get-xy OUTPUT_ID Get the XY data of an output + --items [ITEMS ...] The list of XY items requested + --times [TIMES ...] The list of XY times requested --uuid UUID The UUID of a trace --uuids [UUIDS ...] The list of UUIDs --do-delete-traces Also delete traces when deleting experiment diff --git a/test_tsp.py b/test_tsp.py index 8bda650..d9a709a 100644 --- a/test_tsp.py +++ b/test_tsp.py @@ -22,9 +22,17 @@ import os import pytest +import time +from tsp.response import ResponseStatus from tsp.tsp_client import TspClient +REQUESTED_TIME_XY_START = 1332170682440133097 +REQUESTED_TIME_XY_END = 1332170692664579801 +REQUESTED_TIME_XY_LENGTH = 10 +REQUESTED_TIME_XY_STEP = (REQUESTED_TIME_XY_END - + REQUESTED_TIME_XY_START) / REQUESTED_TIME_XY_LENGTH + class TestTspClient: """TspClient test methods. @@ -245,6 +253,45 @@ def test_fetch_xy_tree(self, kernel): self._delete_experiments() self._delete_traces() + def test_fetch_xy(self, kernel): + traces = [] + response = self.tsp_client.open_trace(os.path.basename(kernel), kernel) + traces.append(response.model.UUID) + response = self.tsp_client.open_experiment( + os.path.basename(kernel), traces) + assert response.status_code == 200 + experiment_uuid = response.model.UUID + + response = self.tsp_client.fetch_experiment_outputs(experiment_uuid) + output_id = response.model.descriptors[0].id + status = ResponseStatus.RUNNING.name + while status == ResponseStatus.RUNNING.name: + time.sleep(1) + response = self.tsp_client.fetch_xy_tree( + experiment_uuid, output_id) + assert response.model is not None + status = response.model.status.upper() + + parameters = {} + requested_items = [] + for entry in response.model.model.entries: + requested_items.append(entry.id) + parameters[TspClient.REQUESTED_ITEM_KEY] = requested_items + + requested_times = [] + requested_time = REQUESTED_TIME_XY_START + while len(requested_times) < REQUESTED_TIME_XY_LENGTH: + requested_time += REQUESTED_TIME_XY_STEP + requested_times.append(int(requested_time)) + parameters[TspClient.REQUESTED_TIME_KEY] = requested_times + + params = {TspClient.PARAMETERS_KEY: parameters} + response = self.tsp_client.fetch_xy(experiment_uuid, output_id, params) + assert response.status_code == 200 + assert response.model.model_type == response.model.model_type.XY + self._delete_experiments() + self._delete_traces() + def test_fetch_extensions_none(self): response = self.tsp_client.fetch_extensions() assert response.status_code == 200 diff --git a/tsp-cli-client b/tsp-cli-client index 3dc765f..55a5b4b 100755 --- a/tsp-cli-client +++ b/tsp-cli-client @@ -36,6 +36,7 @@ from os.path import os from tsp.tree_model import TreeModel from tsp.tsp_client import TspClient +from tsp.xy_model import XYModel #api_token = 'your_token_goes_here' NS_PER_SEC = 1000000000 @@ -137,6 +138,12 @@ if __name__ == "__main__": help="Get the timegraph tree of an output", metavar="OUTPUT_ID") parser.add_argument("--get-xy-tree", dest="get_xy_tree", help="Get the XY tree of an output", metavar="OUTPUT_ID") + parser.add_argument("--get-xy", dest="get_xy", + help="Get the XY data of an output", metavar="OUTPUT_ID") + parser.add_argument("--items", dest="items", + help="The list of XY items requested", nargs="*") + parser.add_argument("--times", dest="times", + help="The list of XY times requested", nargs="*") parser.add_argument("--uuid", dest="uuid", help="The UUID of a trace") parser.add_argument("--uuids", dest="uuids", help="The list of UUIDs", nargs="*") @@ -338,6 +345,28 @@ if __name__ == "__main__": print("Trace UUID is missing") sys.exit(1) + if (options.get_xy): + if not options.items or not options.times: + print("Provide requested --items and --times for the XY data") + sys.exit(1) + + if options.uuid is not None: + parameters = {TspClient.REQUESTED_TIME_KEY: list(map(int, options.times)), + TspClient.REQUESTED_ITEM_KEY: list(map(int, options.items))} + params = {TspClient.PARAMETERS_KEY: parameters} + + response = tsp_client.fetch_xy( + options.uuid, options.get_xy, params) + if response.status_code == 200: + xyModel = response.model.model + xyModel.print() + sys.exit(0) + else: + sys.exit(1) + else: + print("Trace UUID is missing") + sys.exit(1) + if (options.extensions): response = tsp_client.fetch_extensions() if response.status_code == 200: diff --git a/tsp/response.py b/tsp/response.py index d4abc0e..ea69623 100644 --- a/tsp/response.py +++ b/tsp/response.py @@ -26,6 +26,7 @@ from tsp.output_descriptor import OutputDescriptor from tsp.entry_model import EntryModel from tsp.time_graph_model import TimeGraphModel +from tsp.xy_model import XYModel MODEL_KEY = "model" OUTPUT_DESCRIPTOR_KEY = "output" @@ -84,8 +85,7 @@ def __init__(self, params, model_type): # TODO print("not implemented") elif self.model_type == ModelType.XY: - # TODO - print("not implemented") + self.model = XYModel(params.get(MODEL_KEY)) ''' Output descriptor diff --git a/tsp/tsp_client.py b/tsp/tsp_client.py index 569f086..3fecff0 100644 --- a/tsp/tsp_client.py +++ b/tsp/tsp_client.py @@ -37,15 +37,16 @@ headers_form = {'content-type': 'application/x-www-form-urlencoded', 'Accept': 'application/json'} -PARAMETERS_KEY = 'parameters' -REQUESTED_TIME_KEY = 'requested_times' - class TspClient(object): ''' Trace Server Protocol tsp_cli_client ''' + PARAMETERS_KEY = 'parameters' + REQUESTED_TIME_KEY = 'requested_times' + REQUESTED_ITEM_KEY = 'requested_items' + def __init__(self, base_url): ''' Constructor @@ -241,8 +242,8 @@ def fetch_timegraph_tree(self, exp_uuid, output_id, parameters=None): params = parameters if (parameters is None): requested_times = [0, 1] - my_parameters = {REQUESTED_TIME_KEY: requested_times} - params = {PARAMETERS_KEY: my_parameters} + my_parameters = {self.REQUESTED_TIME_KEY: requested_times} + params = {self.PARAMETERS_KEY: my_parameters} response = requests.post(api_url, json=params, headers=headers) @@ -267,8 +268,8 @@ def fetch_xy_tree(self, exp_uuid, output_id, parameters=None): params = parameters if (parameters is None): requested_times = [0, 1] - my_parameters = {REQUESTED_TIME_KEY: requested_times} - params = {PARAMETERS_KEY: my_parameters} + my_parameters = {self.REQUESTED_TIME_KEY: requested_times} + params = {self.PARAMETERS_KEY: my_parameters} response = requests.post(api_url, json=params, headers=headers) @@ -278,6 +279,26 @@ def fetch_xy_tree(self, exp_uuid, output_id, parameters=None): print("failed to get tree: {0}".format(response.status_code)) return TspClientResponse(None, response.status_code, response.text) + def fetch_xy(self, exp_uuid, output_id, parameters): + ''' + Fetch XY xy, XYModel + :param exp_uuid: Experiment UUID + :param output_id: Output ID + :param parameters: Query object (mandatory here; no defaults possible) + :returns: :class: `TspClientResponse ` object XY series response + :rtype: TspClientResponse + ''' + api_url = '{0}experiments/{1}/outputs/XY/{2}/xy'.format( + self.base_url, exp_uuid, output_id) + + response = requests.post(api_url, json=parameters, headers=headers) + + if response.status_code == 200: + return TspClientResponse(GenericResponse(json.loads(response.content.decode('utf-8')), ModelType.XY), response.status_code, response.text) + else: + print("failed to get xy: {0}".format(response.status_code)) + return TspClientResponse(None, response.status_code, response.text) + def fetch_extensions(self): ''' Fetch Extensions (loaded files) diff --git a/tsp/xy_model.py b/tsp/xy_model.py new file mode 100644 index 0000000..7664c14 --- /dev/null +++ b/tsp/xy_model.py @@ -0,0 +1,214 @@ +# The MIT License (MIT) +# +# Copyright (C) 2021 - Ericsson +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import copy + +TITLE_KEY = "title" +COMMON_X_AXIS_KEY = "commonXAxis" +SERIES_KEY = "series" +SERIES_NAME_KEY = "seriesName" +SERIES_ID_KEY = "seriesId" +X_AXIS_KEY = "xAxis" +Y_AXIS_KEY = "yAxis" +X_VALUES_KEY = "xValues" +Y_VALUES_KEY = "yValues" +TAGS_KEY = "tags" +LABEL_KEY = "label" +UNIT_KEY = "unit" +DATA_TYPE_KEY = "dataType" + + +class XYModel(object): + ''' + Model of a XY chart, contains at least one XY series + ''' + + def __init__(self, params): + ''' + Title of the model + ''' + if TITLE_KEY in params: + self.title = params.get(TITLE_KEY) + del params[TITLE_KEY] + + ''' + Indicate if all the Y values are using the same X axis + ''' + if COMMON_X_AXIS_KEY in params: + self.common_x_axis = params.get(COMMON_X_AXIS_KEY) + del params[COMMON_X_AXIS_KEY] + + ''' + Array of XY series + ''' + self.series = [] + if SERIES_KEY in params: + for series in params.get(SERIES_KEY): + self.series.append(XYSeries(series)) + del params[SERIES_KEY] + + ''' + Store other key/value pairs that are not defined in the TSP in a dictionary + ''' + self.others = {} + if params: + self.others = copy.deepcopy(params) + + def print(self): + print(f'XY title: {self.title}') + + common_x_axis = False + if hasattr(self, 'common_x_axis'): + common_x_axis = self.common_x_axis + print(f'XY has common X axis: {common_x_axis}') + + for series in self.series: + series.print() + for other_item in self.others.items(): + print(f'XY other item: {other_item}') + + +class XYSeries(object): + ''' + Represent a XY series and its values + ''' + + def __init__(self, params): + ''' + Name of the series + ''' + if SERIES_NAME_KEY in params: + self.series_name = params.get(SERIES_NAME_KEY) + del params[SERIES_NAME_KEY] + + ''' + Ìd of the series + ''' + if SERIES_ID_KEY in params: + self.series_id = params.get(SERIES_ID_KEY) + del params[SERIES_ID_KEY] + + ''' + Description of the X axis + ''' + if X_AXIS_KEY in params: + self.x_axis = XYAxis(params.get(X_AXIS_KEY)) + del params[X_AXIS_KEY] + + ''' + Description of the Y axis + ''' + if Y_AXIS_KEY in params: + self.y_axis = XYAxis(params.get(Y_AXIS_KEY)) + del params[Y_AXIS_KEY] + + ''' + Series' X values + ''' + self.x_values = [] + if X_VALUES_KEY in params: + for x_value in params.get(X_VALUES_KEY): + self.x_values.append(x_value) + del params[X_VALUES_KEY] + + ''' + Series' Y values + ''' + self.y_values = [] + if Y_VALUES_KEY in params: + for y_value in params.get(Y_VALUES_KEY): + self.y_values.append(y_value) + del params[Y_VALUES_KEY] + + ''' + Array of tags for each XY value, used when a value passes a filter + ''' + self.tags = [] + if TAGS_KEY in params: + for tag in params.get(TAGS_KEY): + self.tags.append(tag) + del params[TAGS_KEY] + + ''' + Store other key/value pairs that are not defined in the TSP in a dictionary + ''' + self.others = {} + if params: + self.others = copy.deepcopy(params) + + def print(self): + print(f' Series name: {self.series_name}') + print(f' Series id: {self.series_id}') + + if hasattr(self, 'x_axis'): + print(f' Series X-axis:\n{self.x_axis.print()}') + print(f' Series Y-axis:\n{self.y_axis.print()}') + for value in self.x_values: + print(f' Series X-value: {value}') + for value in self.y_values: + print(f' Series Y-value: {value}') + for tag in self.tags: + print(f' Series tag: {tag}') + for other_item in self.others.items(): + print(f' Series other item: {other_item}') + + +class XYAxis(object): + ''' + Description of an axis for XY chart + ''' + + def __init__(self, params): + ''' + Label of the axis + ''' + if LABEL_KEY in params: + self.label = params.get(LABEL_KEY) + del params[LABEL_KEY] + + ''' + The units used for the axis, to be appended to the numbers + ''' + if UNIT_KEY in params: + self.unit = params.get(UNIT_KEY) + del params[UNIT_KEY] + + ''' + Type of data for this axis, to give hint on number formatting + ''' + if DATA_TYPE_KEY in params: + self.data_type = params.get(DATA_TYPE_KEY) + del params[DATA_TYPE_KEY] + + ''' + Store other key/value pairs that are not defined in the TSP in a dictionary + ''' + self.others = {} + if params: + self.others = copy.deepcopy(params) + + def print(self): + print(f' Axis label: {self.label}') + print(f' Axis unit: {self.unit}') + print(f' Axis data type: {self.data_type}') + for other_item in self.others.items(): + print(f' Axis other item: {other_item}') From c6c97769990cb63b5e05fb6dac172dc4f63700f6 Mon Sep 17 00:00:00 2001 From: Marco Miller Date: Fri, 3 Sep 2021 13:30:19 -0400 Subject: [PATCH 3/4] tsp-cli-client: Exit if fetched trees had no model While outputting a corresponding message should this happen. Have that code exit right away in the latter case, instead of not handling this. Use the past tense in that message, as the model may become available after a short while, if retried. Signed-off-by: Marco Miller --- tsp-cli-client | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tsp-cli-client b/tsp-cli-client index 55a5b4b..5664b66 100755 --- a/tsp-cli-client +++ b/tsp-cli-client @@ -307,6 +307,9 @@ if __name__ == "__main__": options.uuid, options.get_tree) if response.status_code == 200: tree = response.model.model + if tree is None: + print("Tree had no model; retry?") + sys.exit(1) if (output_descriptor.type == "DATA_TREE"): treeModel = TreeModel(tree.entries, tree.descriptors) @@ -332,6 +335,9 @@ if __name__ == "__main__": options.uuid, options.get_xy_tree) if response.status_code == 200: tree = response.model.model + if tree is None: + print("Tree had no model; retry?") + sys.exit(1) if (output_descriptor.type == "TREE_TIME_XY"): treeModel = TreeModel(tree.entries, tree.descriptors) From 6b9db2ced2eb2a32edccbddddb7c36a7d494fe90 Mon Sep 17 00:00:00 2001 From: Marco Miller Date: Wed, 15 Sep 2021 12:32:15 -0400 Subject: [PATCH 4/4] TspClient: Remove default requested_times if none Replace these previously ineffective defaults with none, if none passed. Signed-off-by: Marco Miller --- tsp/tsp_client.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tsp/tsp_client.py b/tsp/tsp_client.py index 3fecff0..a4f8073 100644 --- a/tsp/tsp_client.py +++ b/tsp/tsp_client.py @@ -241,9 +241,7 @@ def fetch_timegraph_tree(self, exp_uuid, output_id, parameters=None): params = parameters if (parameters is None): - requested_times = [0, 1] - my_parameters = {self.REQUESTED_TIME_KEY: requested_times} - params = {self.PARAMETERS_KEY: my_parameters} + params = {} response = requests.post(api_url, json=params, headers=headers) @@ -267,9 +265,7 @@ def fetch_xy_tree(self, exp_uuid, output_id, parameters=None): params = parameters if (parameters is None): - requested_times = [0, 1] - my_parameters = {self.REQUESTED_TIME_KEY: requested_times} - params = {self.PARAMETERS_KEY: my_parameters} + params = {} response = requests.post(api_url, json=params, headers=headers)