Skip to content

Commit

Permalink
add representation methods and encoders
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
arfio authored and bhufmann committed Nov 5, 2024
1 parent d22176b commit 32e46a2
Show file tree
Hide file tree
Showing 14 changed files with 331 additions and 73 deletions.
25 changes: 25 additions & 0 deletions tsp/entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
# SOFTWARE.

"""Entry classes file."""
import json

from enum import Enum

Expand Down Expand Up @@ -115,3 +116,27 @@ def __init__(self, params):
if params.get(STYLE_KEY) is not None:
self.style = OutputElementStyle(params.get(STYLE_KEY))
del params[STYLE_KEY]

class EntryHeaderEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, EntryHeader):
return {'name': obj.name}
return super().default(obj)

class EntryEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Entry):
return {
'id': obj.id,
'parent_id': obj.parent_id,
'labels': obj.labels,
'style': EntryElementStyleEncoder().default(obj.style) if obj.style else None
}
return super().default(obj)

class EntryElementStyleEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, OutputElementStyle):
# Assuming OutputElementStyle has a to_dict method
return obj.to_dict()
return super().default(obj)
17 changes: 15 additions & 2 deletions tsp/entry_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@
# SOFTWARE.

"""EntryModel class file."""
import json

from tsp.model_type import ModelType
from tsp.time_graph_model import TimeGraphEntry
from tsp.entry import EntryHeader, Entry
from tsp.time_graph_model import TimeGraphEntry, TimeGraphEntryEncoder
from tsp.entry import EntryHeader, Entry, EntryHeaderEncoder, EntryEncoder

HEADER_KEY = "headers"
ENTRIES_KEY = "entries"
Expand Down Expand Up @@ -56,3 +57,15 @@ def __init__(self, params, model_type=ModelType.XY_TREE):
else:
self.entries.append(Entry(entry))
del params[ENTRIES_KEY]

def __repr__(self) -> str:
return 'EntryModel({})'.format(', '.join(str(entry) for entry in self.entries))

class EntryModelEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, EntryModel):
return {
'headers': [EntryHeaderEncoder().default(header) for header in obj.headers],
'entries': [TimeGraphEntryEncoder().default(entry) if isinstance(entry, TimeGraphEntry) else EntryEncoder().default(entry) for entry in obj.entries]
}
return super().default(obj)
22 changes: 21 additions & 1 deletion tsp/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@

"""Experiment class file."""

from tsp.trace_set import TraceSet
import json
from tsp.trace_set import TraceSet, TraceSetEncoder
from tsp.indexing_status import IndexingStatus

NA = "N/A"
Expand Down Expand Up @@ -95,3 +96,22 @@ def __init__(self, params):
# Array of all the traces contained in the experiment
if TRACES_TIME_KEY in params:
self.traces = TraceSet(params.get(TRACES_TIME_KEY))

def __repr__(self):
return 'Experiment({}: UUID={}, start={}, end={}, nevent={}, traces={}, indexing={})'.format(
self.name, self.UUID, self.start, self.end, self.number_of_events, self.traces, self.indexing_status
)

class ExperimentEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Experiment):
return {
'name': obj.name,
'UUID': obj.UUID,
'start': obj.start,
'end': obj.end,
'nbEvents': obj.number_of_events,
'indexing': obj.indexing_status.name,
'traces': TraceSetEncoder().default(obj.traces)
}
return super().default(obj)
12 changes: 10 additions & 2 deletions tsp/experiment_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@

"""ExperimentSet class file."""

from tsp.experiment import Experiment

import json
from tsp.experiment import Experiment, ExperimentEncoder

# pylint: disable=too-few-public-methods
class ExperimentSet:
Expand All @@ -38,3 +38,11 @@ def __init__(self, params):
self.experiments = []
for obj in params:
self.experiments.append(Experiment(obj))

class ExperimentSetEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, ExperimentSet):
return [
ExperimentEncoder().default(experiment) for experiment in obj.experiments
]
return super().default(obj)
21 changes: 21 additions & 0 deletions tsp/output_descriptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

"""OutputDescriptor class file."""

import json

NA = "N/A"
UNKOWN = "UNKNOWN"
ID_KEY = "id"
Expand Down Expand Up @@ -113,3 +115,22 @@ def __init__(self, params):
del params[COMPATIBLE_PROVIDERS_KEY]
else:
self.compatible_providers = []

def __repr__(self):
return 'OutputDescriptor(id={}, name={}, description={})'.format(self.id, self.name, self.description)

class OutputDescriptorEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, OutputDescriptor):
return {
'id': obj.id,
'name': obj.name,
'description': obj.description,
'type': obj.type,
'query_parameters': obj.query_parameters,
'start': obj.start,
'end': obj.end,
'final': obj.final,
'compatible_providers': obj.compatible_providers
}
return super().default(obj)
3 changes: 3 additions & 0 deletions tsp/output_descriptor_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,6 @@ def __init__(self, params):
self.descriptors = []
for obj in params:
self.descriptors.append(OutputDescriptor(obj))

def __repr__(self):
return ', '.join([str(descriptor) for descriptor in self.descriptors])
35 changes: 32 additions & 3 deletions tsp/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,18 @@

"""Response classes file."""

import json

from enum import Enum

from tsp.model_type import ModelType
from tsp.output_descriptor import OutputDescriptor
from tsp.entry_model import EntryModel
from tsp.virtual_table_header_model import VirtualTableHeaderModel
from tsp.xy_model import XYModel
from tsp.virtual_table_model import VirtualTableModel
from tsp.time_graph_model import TimeGraphModel, TimeGraphArrow
from tsp.time_graph_model import TimeGraphModel, TimeGraphArrow, TimeGraphModelEncoder, TimeGraphArrowEncoder
from tsp.xy_model import XYModel
from tsp.entry_model import EntryModel, EntryModelEncoder
from tsp.xy_model import XYModel, XYModelEncoder

MODEL_KEY = "model"
OUTPUT_DESCRIPTOR_KEY = "output"
Expand Down Expand Up @@ -117,3 +120,29 @@ def __init__(self, params, model_type):
self.status_text = params.get(STATUS_MESSAGE_KEY)
else: # pragma: no cover
self.status_text = ""

def __repr__(self) -> str:
return 'GenericResponse(model_type={}, model={}, output_descriptor={}, status={}, status_text={})'.format(
self.model_type, self.model, self.output, self.status, self.status_text
)


class GenericResponseEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, GenericResponse):
model = obj.model
if model is None:
return None
if obj.model_type == ModelType.TIME_GRAPH_TREE \
or obj.model_type == ModelType.XY_TREE \
or obj.model_type == ModelType.DATA_TREE:
model = EntryModelEncoder().default(obj.model)
elif obj.model_type == ModelType.TIME_GRAPH_STATE:
model = TimeGraphModelEncoder().default(obj.model)
elif obj.model_type == ModelType.TIME_GRAPH_ARROW:
model = [TimeGraphArrowEncoder().default(arrow) for arrow in obj.model]
elif obj.model_type == ModelType.XY:
model = XYModelEncoder().default(obj.model)
return model

return super().default(obj)
70 changes: 68 additions & 2 deletions tsp/time_graph_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
# SOFTWARE.

"""TimeGraph classes file."""

from tsp.entry import Entry
import json
from tsp.entry import Entry, EntryElementStyleEncoder

TYPE_KEY = "type"
START_TIME_KEY = "start"
Expand Down Expand Up @@ -70,6 +70,8 @@ def __init__(self, params):
self.has_row_model = params.get(HAS_ROW_MODEL_KEY)
del params[HAS_ROW_MODEL_KEY]

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

class TimeGraphModel:
'''
Expand All @@ -83,6 +85,8 @@ def __init__(self, params):
self.rows.append(TimeGraphRow(row))
del params[ROWS_KEY]

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

class TimeGraphRow:
'''
Expand All @@ -104,6 +108,9 @@ def __init__(self, params):
self.states.append(TimeGraphState(state))
del params[STATES_KEY]

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


class TimeGraphState:
'''
Expand Down Expand Up @@ -143,6 +150,9 @@ def __init__(self, params):
self.style = params.get(STYLE_KEY)
del params[STYLE_KEY]

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


class TimeGraphArrow:
'''
Expand Down Expand Up @@ -186,3 +196,59 @@ def __init__(self, params):
if STYLE_KEY in params:
self.style = params.get(STYLE_KEY)
del params[STYLE_KEY]

class TimeGraphEntryEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, TimeGraphEntry):
return {
'id': obj.id,
'parent_id': obj.parent_id,
'labels': obj.labels,
'style': EntryElementStyleEncoder().default(obj.style) if obj.style else None,
'start': obj.start_time if obj.start_time else None,
'end': obj.end_time if obj.end_time else None,
'hasData': obj.has_row_model
}
return super().default(obj)

class TimeGraphModelEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, TimeGraphModel):
return {
'rows': [TimeGraphRowEncoder().default(row) for row in obj.rows]
}
return super().default(obj)

class TimeGraphRowEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, TimeGraphRow):
return {
'entry_id': obj.entry_id,
'states': [TimeGraphStateEncoder().default(state) for state in obj.states]
}
return super().default(obj)

class TimeGraphStateEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, TimeGraphState):
return {
'start': obj.start_time,
'end': obj.end_time,
# 'duration': obj.duration,
# 'values': obj.value,
# 'tags': obj.tags,
'style': obj.style
}
return super().default(obj)

class TimeGraphArrowEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, TimeGraphArrow):
return {
'sourceId': obj.source_id,
'targetId': obj.target_id,
'start': obj.start,
'end': obj.end,
'style': obj.style
}
return super().default(obj)
21 changes: 20 additions & 1 deletion tsp/trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@

"""Trace class file."""

import json
from tsp.indexing_status import IndexingStatus


NA = "N/A"
UUID_KEY = "UUID"
NAME_KEY = "name"
Expand Down Expand Up @@ -106,3 +106,22 @@ def __init__(self, params):
del params[INDEXING_STATUS_KEY]
else: # pragma: no cover
self.indexing_status = 0

def __repr__(self):
return 'Trace({}: UUID={}, start={}, end={}, nevent={}, path={}, indexing={})'.format(
self.name, self.UUID, self.start, self.end, self.number_of_events, self.path, self.indexing_status
)

class TraceEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Trace):
return {
'name': obj.name,
'UUID': obj.UUID,
'start': obj.start,
'end': obj.end,
'nbEvents': obj.number_of_events,
'path': obj.path,
'indexing': obj.indexing_status.name
}
return super().default(obj)
15 changes: 13 additions & 2 deletions tsp/trace_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@

"""TraceSet class file."""

from tsp.trace import Trace

import json
from tsp.trace import Trace, TraceEncoder

# pylint: disable=too-few-public-methods
class TraceSet:
Expand All @@ -38,3 +38,14 @@ def __init__(self, params):
self.traces = []
for obj in params:
self.traces.append(Trace(obj))

def __repr__(self) -> str:
return 'TraceSet({})'.format(', '.join(str(trace) for trace in self.traces))

class TraceSetEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, TraceSet):
return [
TraceEncoder().default(trace) for trace in obj.traces
]
return super().default(obj)
Loading

0 comments on commit 32e46a2

Please sign in to comment.