Skip to content

Commit 32e46a2

Browse files
arfiobhufmann
authored andcommitted
add representation methods and encoders
The encoders are useful to store objects on disk between multiple calls to a program. This is useful in some cases where you need to recover the previous state of your run. The representations implementation is very useful to print the results of the requests to know what you got. It is very useful for debugging and testing out things when developping. Signed-off-by: Arnaud Fiorini <[email protected]>
1 parent d22176b commit 32e46a2

14 files changed

+331
-73
lines changed

tsp/entry.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
# SOFTWARE.
2222

2323
"""Entry classes file."""
24+
import json
2425

2526
from enum import Enum
2627

@@ -115,3 +116,27 @@ def __init__(self, params):
115116
if params.get(STYLE_KEY) is not None:
116117
self.style = OutputElementStyle(params.get(STYLE_KEY))
117118
del params[STYLE_KEY]
119+
120+
class EntryHeaderEncoder(json.JSONEncoder):
121+
def default(self, obj):
122+
if isinstance(obj, EntryHeader):
123+
return {'name': obj.name}
124+
return super().default(obj)
125+
126+
class EntryEncoder(json.JSONEncoder):
127+
def default(self, obj):
128+
if isinstance(obj, Entry):
129+
return {
130+
'id': obj.id,
131+
'parent_id': obj.parent_id,
132+
'labels': obj.labels,
133+
'style': EntryElementStyleEncoder().default(obj.style) if obj.style else None
134+
}
135+
return super().default(obj)
136+
137+
class EntryElementStyleEncoder(json.JSONEncoder):
138+
def default(self, obj):
139+
if isinstance(obj, OutputElementStyle):
140+
# Assuming OutputElementStyle has a to_dict method
141+
return obj.to_dict()
142+
return super().default(obj)

tsp/entry_model.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@
2121
# SOFTWARE.
2222

2323
"""EntryModel class file."""
24+
import json
2425

2526
from tsp.model_type import ModelType
26-
from tsp.time_graph_model import TimeGraphEntry
27-
from tsp.entry import EntryHeader, Entry
27+
from tsp.time_graph_model import TimeGraphEntry, TimeGraphEntryEncoder
28+
from tsp.entry import EntryHeader, Entry, EntryHeaderEncoder, EntryEncoder
2829

2930
HEADER_KEY = "headers"
3031
ENTRIES_KEY = "entries"
@@ -56,3 +57,15 @@ def __init__(self, params, model_type=ModelType.XY_TREE):
5657
else:
5758
self.entries.append(Entry(entry))
5859
del params[ENTRIES_KEY]
60+
61+
def __repr__(self) -> str:
62+
return 'EntryModel({})'.format(', '.join(str(entry) for entry in self.entries))
63+
64+
class EntryModelEncoder(json.JSONEncoder):
65+
def default(self, obj):
66+
if isinstance(obj, EntryModel):
67+
return {
68+
'headers': [EntryHeaderEncoder().default(header) for header in obj.headers],
69+
'entries': [TimeGraphEntryEncoder().default(entry) if isinstance(entry, TimeGraphEntry) else EntryEncoder().default(entry) for entry in obj.entries]
70+
}
71+
return super().default(obj)

tsp/experiment.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222

2323
"""Experiment class file."""
2424

25-
from tsp.trace_set import TraceSet
25+
import json
26+
from tsp.trace_set import TraceSet, TraceSetEncoder
2627
from tsp.indexing_status import IndexingStatus
2728

2829
NA = "N/A"
@@ -95,3 +96,22 @@ def __init__(self, params):
9596
# Array of all the traces contained in the experiment
9697
if TRACES_TIME_KEY in params:
9798
self.traces = TraceSet(params.get(TRACES_TIME_KEY))
99+
100+
def __repr__(self):
101+
return 'Experiment({}: UUID={}, start={}, end={}, nevent={}, traces={}, indexing={})'.format(
102+
self.name, self.UUID, self.start, self.end, self.number_of_events, self.traces, self.indexing_status
103+
)
104+
105+
class ExperimentEncoder(json.JSONEncoder):
106+
def default(self, obj):
107+
if isinstance(obj, Experiment):
108+
return {
109+
'name': obj.name,
110+
'UUID': obj.UUID,
111+
'start': obj.start,
112+
'end': obj.end,
113+
'nbEvents': obj.number_of_events,
114+
'indexing': obj.indexing_status.name,
115+
'traces': TraceSetEncoder().default(obj.traces)
116+
}
117+
return super().default(obj)

tsp/experiment_set.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222

2323
"""ExperimentSet class file."""
2424

25-
from tsp.experiment import Experiment
26-
25+
import json
26+
from tsp.experiment import Experiment, ExperimentEncoder
2727

2828
# pylint: disable=too-few-public-methods
2929
class ExperimentSet:
@@ -38,3 +38,11 @@ def __init__(self, params):
3838
self.experiments = []
3939
for obj in params:
4040
self.experiments.append(Experiment(obj))
41+
42+
class ExperimentSetEncoder(json.JSONEncoder):
43+
def default(self, obj):
44+
if isinstance(obj, ExperimentSet):
45+
return [
46+
ExperimentEncoder().default(experiment) for experiment in obj.experiments
47+
]
48+
return super().default(obj)

tsp/output_descriptor.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
"""OutputDescriptor class file."""
2424

25+
import json
26+
2527
NA = "N/A"
2628
UNKOWN = "UNKNOWN"
2729
ID_KEY = "id"
@@ -113,3 +115,22 @@ def __init__(self, params):
113115
del params[COMPATIBLE_PROVIDERS_KEY]
114116
else:
115117
self.compatible_providers = []
118+
119+
def __repr__(self):
120+
return 'OutputDescriptor(id={}, name={}, description={})'.format(self.id, self.name, self.description)
121+
122+
class OutputDescriptorEncoder(json.JSONEncoder):
123+
def default(self, obj):
124+
if isinstance(obj, OutputDescriptor):
125+
return {
126+
'id': obj.id,
127+
'name': obj.name,
128+
'description': obj.description,
129+
'type': obj.type,
130+
'query_parameters': obj.query_parameters,
131+
'start': obj.start,
132+
'end': obj.end,
133+
'final': obj.final,
134+
'compatible_providers': obj.compatible_providers
135+
}
136+
return super().default(obj)

tsp/output_descriptor_set.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,6 @@ def __init__(self, params):
3838
self.descriptors = []
3939
for obj in params:
4040
self.descriptors.append(OutputDescriptor(obj))
41+
42+
def __repr__(self):
43+
return ', '.join([str(descriptor) for descriptor in self.descriptors])

tsp/response.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,18 @@
2222

2323
"""Response classes file."""
2424

25+
import json
26+
2527
from enum import Enum
2628

2729
from tsp.model_type import ModelType
2830
from tsp.output_descriptor import OutputDescriptor
29-
from tsp.entry_model import EntryModel
3031
from tsp.virtual_table_header_model import VirtualTableHeaderModel
31-
from tsp.xy_model import XYModel
3232
from tsp.virtual_table_model import VirtualTableModel
33-
from tsp.time_graph_model import TimeGraphModel, TimeGraphArrow
33+
from tsp.time_graph_model import TimeGraphModel, TimeGraphArrow, TimeGraphModelEncoder, TimeGraphArrowEncoder
34+
from tsp.xy_model import XYModel
35+
from tsp.entry_model import EntryModel, EntryModelEncoder
36+
from tsp.xy_model import XYModel, XYModelEncoder
3437

3538
MODEL_KEY = "model"
3639
OUTPUT_DESCRIPTOR_KEY = "output"
@@ -117,3 +120,29 @@ def __init__(self, params, model_type):
117120
self.status_text = params.get(STATUS_MESSAGE_KEY)
118121
else: # pragma: no cover
119122
self.status_text = ""
123+
124+
def __repr__(self) -> str:
125+
return 'GenericResponse(model_type={}, model={}, output_descriptor={}, status={}, status_text={})'.format(
126+
self.model_type, self.model, self.output, self.status, self.status_text
127+
)
128+
129+
130+
class GenericResponseEncoder(json.JSONEncoder):
131+
def default(self, obj):
132+
if isinstance(obj, GenericResponse):
133+
model = obj.model
134+
if model is None:
135+
return None
136+
if obj.model_type == ModelType.TIME_GRAPH_TREE \
137+
or obj.model_type == ModelType.XY_TREE \
138+
or obj.model_type == ModelType.DATA_TREE:
139+
model = EntryModelEncoder().default(obj.model)
140+
elif obj.model_type == ModelType.TIME_GRAPH_STATE:
141+
model = TimeGraphModelEncoder().default(obj.model)
142+
elif obj.model_type == ModelType.TIME_GRAPH_ARROW:
143+
model = [TimeGraphArrowEncoder().default(arrow) for arrow in obj.model]
144+
elif obj.model_type == ModelType.XY:
145+
model = XYModelEncoder().default(obj.model)
146+
return model
147+
148+
return super().default(obj)

tsp/time_graph_model.py

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
# SOFTWARE.
2222

2323
"""TimeGraph classes file."""
24-
25-
from tsp.entry import Entry
24+
import json
25+
from tsp.entry import Entry, EntryElementStyleEncoder
2626

2727
TYPE_KEY = "type"
2828
START_TIME_KEY = "start"
@@ -70,6 +70,8 @@ def __init__(self, params):
7070
self.has_row_model = params.get(HAS_ROW_MODEL_KEY)
7171
del params[HAS_ROW_MODEL_KEY]
7272

73+
def __repr__(self) -> str:
74+
return 'TimeGraphEntry(start={}, end={})'.format(self.start_time, self.end_time)
7375

7476
class TimeGraphModel:
7577
'''
@@ -83,6 +85,8 @@ def __init__(self, params):
8385
self.rows.append(TimeGraphRow(row))
8486
del params[ROWS_KEY]
8587

88+
def __repr__(self) -> str:
89+
return 'TimeGraphModel({})'.format(', '.join(str(row) for row in self.rows))
8690

8791
class TimeGraphRow:
8892
'''
@@ -104,6 +108,9 @@ def __init__(self, params):
104108
self.states.append(TimeGraphState(state))
105109
del params[STATES_KEY]
106110

111+
def __repr__(self) -> str:
112+
return 'TimeGraphRow({})'.format(', '.join([str(state) for state in self.states]))
113+
107114

108115
class TimeGraphState:
109116
'''
@@ -143,6 +150,9 @@ def __init__(self, params):
143150
self.style = params.get(STYLE_KEY)
144151
del params[STYLE_KEY]
145152

153+
def __repr__(self) -> str:
154+
return 'TimeGraphState({}start={}, end={})'.format(f'label={self.label}, ',self.start_time, self.end_time)
155+
146156

147157
class TimeGraphArrow:
148158
'''
@@ -186,3 +196,59 @@ def __init__(self, params):
186196
if STYLE_KEY in params:
187197
self.style = params.get(STYLE_KEY)
188198
del params[STYLE_KEY]
199+
200+
class TimeGraphEntryEncoder(json.JSONEncoder):
201+
def default(self, obj):
202+
if isinstance(obj, TimeGraphEntry):
203+
return {
204+
'id': obj.id,
205+
'parent_id': obj.parent_id,
206+
'labels': obj.labels,
207+
'style': EntryElementStyleEncoder().default(obj.style) if obj.style else None,
208+
'start': obj.start_time if obj.start_time else None,
209+
'end': obj.end_time if obj.end_time else None,
210+
'hasData': obj.has_row_model
211+
}
212+
return super().default(obj)
213+
214+
class TimeGraphModelEncoder(json.JSONEncoder):
215+
def default(self, obj):
216+
if isinstance(obj, TimeGraphModel):
217+
return {
218+
'rows': [TimeGraphRowEncoder().default(row) for row in obj.rows]
219+
}
220+
return super().default(obj)
221+
222+
class TimeGraphRowEncoder(json.JSONEncoder):
223+
def default(self, obj):
224+
if isinstance(obj, TimeGraphRow):
225+
return {
226+
'entry_id': obj.entry_id,
227+
'states': [TimeGraphStateEncoder().default(state) for state in obj.states]
228+
}
229+
return super().default(obj)
230+
231+
class TimeGraphStateEncoder(json.JSONEncoder):
232+
def default(self, obj):
233+
if isinstance(obj, TimeGraphState):
234+
return {
235+
'start': obj.start_time,
236+
'end': obj.end_time,
237+
# 'duration': obj.duration,
238+
# 'values': obj.value,
239+
# 'tags': obj.tags,
240+
'style': obj.style
241+
}
242+
return super().default(obj)
243+
244+
class TimeGraphArrowEncoder(json.JSONEncoder):
245+
def default(self, obj):
246+
if isinstance(obj, TimeGraphArrow):
247+
return {
248+
'sourceId': obj.source_id,
249+
'targetId': obj.target_id,
250+
'start': obj.start,
251+
'end': obj.end,
252+
'style': obj.style
253+
}
254+
return super().default(obj)

tsp/trace.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222

2323
"""Trace class file."""
2424

25+
import json
2526
from tsp.indexing_status import IndexingStatus
2627

27-
2828
NA = "N/A"
2929
UUID_KEY = "UUID"
3030
NAME_KEY = "name"
@@ -106,3 +106,22 @@ def __init__(self, params):
106106
del params[INDEXING_STATUS_KEY]
107107
else: # pragma: no cover
108108
self.indexing_status = 0
109+
110+
def __repr__(self):
111+
return 'Trace({}: UUID={}, start={}, end={}, nevent={}, path={}, indexing={})'.format(
112+
self.name, self.UUID, self.start, self.end, self.number_of_events, self.path, self.indexing_status
113+
)
114+
115+
class TraceEncoder(json.JSONEncoder):
116+
def default(self, obj):
117+
if isinstance(obj, Trace):
118+
return {
119+
'name': obj.name,
120+
'UUID': obj.UUID,
121+
'start': obj.start,
122+
'end': obj.end,
123+
'nbEvents': obj.number_of_events,
124+
'path': obj.path,
125+
'indexing': obj.indexing_status.name
126+
}
127+
return super().default(obj)

tsp/trace_set.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222

2323
"""TraceSet class file."""
2424

25-
from tsp.trace import Trace
26-
25+
import json
26+
from tsp.trace import Trace, TraceEncoder
2727

2828
# pylint: disable=too-few-public-methods
2929
class TraceSet:
@@ -38,3 +38,14 @@ def __init__(self, params):
3838
self.traces = []
3939
for obj in params:
4040
self.traces.append(Trace(obj))
41+
42+
def __repr__(self) -> str:
43+
return 'TraceSet({})'.format(', '.join(str(trace) for trace in self.traces))
44+
45+
class TraceSetEncoder(json.JSONEncoder):
46+
def default(self, obj):
47+
if isinstance(obj, TraceSet):
48+
return [
49+
TraceEncoder().default(trace) for trace in obj.traces
50+
]
51+
return super().default(obj)

0 commit comments

Comments
 (0)