From ab16ca56ab7b87781c6cd7c4cbdc973a62d3cfc7 Mon Sep 17 00:00:00 2001
From: Leah Tacke genannt Unterberg <leah.tgu@pads.rwth-aachen.de>
Date: Thu, 27 Feb 2025 17:37:12 +0100
Subject: [PATCH] progress on dashboard definition modeling

---
 .../superset/definitions/dashboard.py         | 128 ++++++
 mitm_tooling/utilities/python_utils.py        |  10 +-
 .../Event_Annotations_199.yaml                |  61 +++
 .../Event_Type_Counts_202.yaml                |  81 ++++
 .../Event_Type_Counts_205.yaml                | 103 +++++
 .../Events_per_Object_203.yaml                | 101 +++++
 .../asset_export_samples/MAED_Testing_12.yaml | 392 ++++++++++++++++++
 .../Measurement_Type_Counts_204.yaml          | 104 +++++
 test/asset_export_samples/Objects_201.yaml    |  65 +++
 .../Segment_Annotations_200.yaml              |  47 +++
 test/asset_export_samples/TS_Plot_198.yaml    | 177 ++++++++
 test/asset_export_samples/metadata.yaml       |   3 +
 .../query_context_count_ts.yaml               | 203 +++++++++
 .../query_context_pie.yaml                    | 131 ++++++
 .../query_context_ts.yaml                     | 197 +++++++++
 .../query_context_ts_bar.yaml                 | 197 +++++++++
 16 files changed, 1995 insertions(+), 5 deletions(-)
 create mode 100644 mitm_tooling/transformation/superset/definitions/dashboard.py
 create mode 100644 test/asset_export_samples/Event_Annotations_199.yaml
 create mode 100644 test/asset_export_samples/Event_Type_Counts_202.yaml
 create mode 100644 test/asset_export_samples/Event_Type_Counts_205.yaml
 create mode 100644 test/asset_export_samples/Events_per_Object_203.yaml
 create mode 100644 test/asset_export_samples/MAED_Testing_12.yaml
 create mode 100644 test/asset_export_samples/Measurement_Type_Counts_204.yaml
 create mode 100644 test/asset_export_samples/Objects_201.yaml
 create mode 100644 test/asset_export_samples/Segment_Annotations_200.yaml
 create mode 100644 test/asset_export_samples/TS_Plot_198.yaml
 create mode 100644 test/asset_export_samples/metadata.yaml
 create mode 100644 test/asset_export_samples/query_context_count_ts.yaml
 create mode 100644 test/asset_export_samples/query_context_pie.yaml
 create mode 100644 test/asset_export_samples/query_context_ts.yaml
 create mode 100644 test/asset_export_samples/query_context_ts_bar.yaml

diff --git a/mitm_tooling/transformation/superset/definitions/dashboard.py b/mitm_tooling/transformation/superset/definitions/dashboard.py
new file mode 100644
index 0000000..4c30dff
--- /dev/null
+++ b/mitm_tooling/transformation/superset/definitions/dashboard.py
@@ -0,0 +1,128 @@
+from enum import StrEnum
+from typing import Literal
+from uuid import UUID
+
+import pydantic
+
+from mitm_tooling.representation import ColumnName
+from .constants import StrUUID
+from ..factories.utils import mk_uuid
+
+DashboardInternalID = str
+
+
+class DashboardComponentType(StrEnum):
+    CHART = 'CHART'
+    HEADER = 'HEADER'
+    GRID = 'GRID'
+    ROW = 'ROW'
+    ROOT = 'ROOT'
+
+
+class ComponentMeta(pydantic.BaseModel):
+    pass
+
+
+class DashboardComponent(pydantic.BaseModel):
+    id: DashboardInternalID
+    type: DashboardComponentType
+    meta: ComponentMeta | None = pydantic.Field(strict=False, default=None)
+    children: list[DashboardInternalID] = pydantic.Field(default_factory=list)
+
+
+class HeaderMeta(ComponentMeta):
+    text: str
+
+
+class DashboardHeader(DashboardComponent):
+    type: Literal[DashboardComponentType.HEADER] = DashboardComponentType.HEADER
+    meta: HeaderMeta
+
+
+class RowMeta(ComponentMeta):
+    background: str = 'BACKGROUND_TRANSPARENT'
+
+
+class DashboardRow(DashboardComponent):
+    type: Literal[DashboardComponentType.ROW] = DashboardComponentType.ROW
+    meta: RowMeta
+
+
+class ChartMeta(ComponentMeta):
+    uuid: StrUUID
+    width: int
+    height: int
+    chartId: int | None = None
+    sliceName: str | None = None
+
+
+class DashboardChart(DashboardComponent):
+    type: Literal[DashboardComponentType.CHART] = DashboardComponentType.CHART
+    meta: ChartMeta
+
+
+DASHBOARD_VERSION_KEY_LITERAL = Literal['DASHBOARD_VERSION_KEY']
+
+DashboardPositionData = dict[DASHBOARD_VERSION_KEY_LITERAL | DashboardInternalID, str | DashboardComponent]
+
+
+def mk_dashboard_position_data(chart_grid: list[list[DashboardChart]]) -> DashboardPositionData:
+    res = {
+        'DASHBOARD_VERSION_KEY': 'v2',
+        'HEADER_ID': ...
+    }
+
+    return res
+
+
+class ControlValues(pydantic.BaseModel):
+    enableEmptyFilter: bool = False
+    defaultToFirstItem: bool | None = False
+    multiSelect: bool | None = True
+    searchAllOptions: bool | None = False
+    inverseSelection: bool | None = False
+
+
+class ColName(pydantic.BaseModel):
+    name: str
+
+
+class DatasetReference(pydantic.BaseModel):
+    datasetUuid: StrUUID
+
+
+class ColumnOfDataset(DatasetReference):
+    column: ColName
+
+
+class FilterType(StrEnum):
+    FILTER_SELECT = 'filter_select'
+    FILTER_TIME_GRAIN = 'filter_timegrain'
+
+
+class NativeFilterConfig(pydantic.BaseModel):
+    id: str
+    name: str
+    targets: list[DatasetReference | ColumnOfDataset] = pydantic.Field(default_factory=list)
+    controlValues: ControlValues = pydantic.Field(default_factory=ControlValues)
+    filterType: FilterType = FilterType.FILTER_SELECT
+    type: str = 'NATIVE_FILTER'
+
+
+def mk_filter_config(name: str, target_cols: list[tuple[ColumnName, UUID]], ft: FilterType = FilterType.FILTER_SELECT,
+                     control_values: ControlValues = ControlValues()) -> NativeFilterConfig:
+    return NativeFilterConfig(
+        id=f'NATIVE_FILTER-{mk_uuid().hex[:12]}',
+        name=name,
+        filterType=ft,
+        controlValues=control_values,
+        targets=[
+            ColumnOfDataset(column=ColName(name=c), datasetUuid=ds_uuid) for c, ds_uuid in (target_cols or [])
+        ]
+    )
+
+
+class DashboardMetadata(pydantic.BaseModel):
+    color_scheme: str = 'blueToGreen'
+    cross_filters_enabled: bool = True
+    native_filter_configuration: list[NativeFilterConfig] = pydantic.Field(default_factory=list)
diff --git a/mitm_tooling/utilities/python_utils.py b/mitm_tooling/utilities/python_utils.py
index b2c18d7..d840fdd 100644
--- a/mitm_tooling/utilities/python_utils.py
+++ b/mitm_tooling/utilities/python_utils.py
@@ -1,6 +1,6 @@
 import itertools
 from collections.abc import Sequence, Mapping
-from typing import TypeVar, Hashable, Iterable, Callable, Any, Union, TypeVarTuple, Unpack, overload
+from typing import TypeVar, Hashable, Iterable, Callable, Any, Union, TypeVarTuple, Unpack, overload, Literal
 
 
 def i_th(i: int, result_constr: type | None = tuple):
@@ -91,17 +91,17 @@ def inner_list_concat(d1: dict[K, list[Any]], d2: dict[K, list[Any]]) -> dict[K,
 
 
 @overload
-def pick_from_mapping(d: Mapping[K, T], keys: Sequence[K], *, flatten: bool = True) -> list[T]: ...
+def pick_from_mapping(d: Mapping[K, T], keys: Sequence[K]) -> list[tuple[K, T]]: ...
 
 
 @overload
-def pick_from_mapping(d: Mapping[K, T], keys: Sequence[K], *, flatten: bool = False) -> list[tuple[K, T]]: ...
+def pick_from_mapping(d: Mapping[K, T], keys: Sequence[K], *, flatten: Literal[True]) -> list[T]: ...
 
 
 @overload
-def pick_from_mapping(d: Mapping[K, T], keys: Sequence[K], *, flatten: bool) -> list[T] | list[tuple[K, T]]: ...
+def pick_from_mapping(d: Mapping[K, T], keys: Sequence[K], *, flatten: Literal[False]) -> list[tuple[K, T]]: ...
+
 
-# TODO maybe fix type annotations?
 def pick_from_mapping(d: Mapping[K, T], keys: Sequence[K], *, flatten: bool = False) -> list[T] | list[tuple[K, T]]:
     if flatten:
         return [d[k] for k in keys]
diff --git a/test/asset_export_samples/Event_Annotations_199.yaml b/test/asset_export_samples/Event_Annotations_199.yaml
new file mode 100644
index 0000000..d2d5692
--- /dev/null
+++ b/test/asset_export_samples/Event_Annotations_199.yaml
@@ -0,0 +1,61 @@
+slice_name: Event Annotations
+description: null
+certified_by: null
+certification_details: null
+viz_type: table
+params:
+  datasource: 26__table
+  viz_type: table
+  query_mode: raw
+  groupby: []
+  time_grain_sqla: P1D
+  temporal_columns_lookup:
+    time: true
+  all_columns:
+  - object
+  - type
+  - time
+  percent_metrics: []
+  adhoc_filters:
+  - expressionType: SIMPLE
+    subject: time
+    operator: TEMPORAL_RANGE
+    comparator: No filter
+    clause: WHERE
+    sqlExpression: null
+    isExtra: false
+    isNew: false
+    datasourceWarning: false
+    filterOptionName: filter_zdzt2v171mi_3t4spqhnfkf
+  - expressionType: SIMPLE
+    subject: kind
+    operator: ==
+    operatorId: EQUALS
+    comparator: E
+    clause: WHERE
+    sqlExpression: null
+    isExtra: false
+    isNew: false
+    datasourceWarning: false
+    filterOptionName: filter_02gaxl0iklci_wu8eum560fs
+  order_by_cols:
+  - '["time", true]'
+  row_limit: 1000
+  server_page_length: 10
+  order_desc: true
+  table_timestamp_format: smart_date
+  allow_render_html: true
+  show_cell_bars: true
+  color_pn: true
+  comparison_color_scheme: Green
+  comparison_type: values
+  extra_form_data: {}
+  dashboards: []
+query_context: '{"datasource":{"id":26,"type":"table"},"force":false,"queries":[{"filters":[{"col":"time","op":"TEMPORAL_RANGE","val":"No
+  filter"},{"col":"kind","op":"==","val":"E"}],"extras":{"having":"","where":""},"applied_time_extras":{},"columns":["object","type","time"],"orderby":[["time",true]],"annotation_layers":[],"row_limit":1000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"post_processing":[],"time_offsets":[]}],"form_data":{"datasource":"26__table","viz_type":"table","query_mode":"raw","groupby":[],"time_grain_sqla":"P1D","temporal_columns_lookup":{"time":true},"all_columns":["object","type","time"],"percent_metrics":[],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"time","operator":"TEMPORAL_RANGE","comparator":"No
+  filter","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_zdzt2v171mi_3t4spqhnfkf"},{"expressionType":"SIMPLE","subject":"kind","operator":"==","operatorId":"EQUALS","comparator":"E","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_02gaxl0iklci_wu8eum560fs"}],"order_by_cols":["[\"time\",
+  true]"],"row_limit":1000,"server_page_length":10,"order_desc":true,"table_timestamp_format":"smart_date","allow_render_html":true,"show_cell_bars":true,"color_pn":true,"comparison_color_scheme":"Green","comparison_type":"values","extra_form_data":{},"dashboards":[],"force":false,"result_format":"json","result_type":"full","include_time":false},"result_format":"json","result_type":"full"}'
+cache_timeout: null
+uuid: 323fc686-1f2f-49ce-9fad-5382e8376d8d
+version: 1.0.0
+dataset_uuid: 9912824b-b393-4acf-9f6b-b0d042ddac29
diff --git a/test/asset_export_samples/Event_Type_Counts_202.yaml b/test/asset_export_samples/Event_Type_Counts_202.yaml
new file mode 100644
index 0000000..ca3bd51
--- /dev/null
+++ b/test/asset_export_samples/Event_Type_Counts_202.yaml
@@ -0,0 +1,81 @@
+slice_name: Event Type Counts
+description: null
+certified_by: null
+certification_details: null
+viz_type: pie
+params:
+  datasource: 26__table
+  viz_type: pie
+  groupby:
+  - type
+  metric:
+    expressionType: SIMPLE
+    column:
+      advanced_data_type: null
+      certification_details: null
+      certified_by: null
+      column_name: type
+      description: null
+      expression: null
+      filterable: true
+      groupby: true
+      id: 772
+      is_certified: false
+      is_dttm: false
+      python_date_format: null
+      type: VARCHAR
+      type_generic: 1
+      verbose_name: null
+      warning_markdown: null
+    aggregate: COUNT
+    sqlExpression: null
+    datasourceWarning: false
+    hasCustomLabel: false
+    label: COUNT(type)
+    optionName: metric_0hcszvnysjqu_1znn0m0ezlw
+  adhoc_filters:
+  - expressionType: SIMPLE
+    subject: time
+    operator: TEMPORAL_RANGE
+    comparator: No filter
+    clause: WHERE
+    sqlExpression: null
+    isExtra: false
+    isNew: false
+    datasourceWarning: false
+    filterOptionName: filter_g4xezxjmej6_ctfpq7bs3ad
+  - expressionType: SIMPLE
+    subject: kind
+    operator: ==
+    operatorId: EQUALS
+    comparator: E
+    clause: WHERE
+    sqlExpression: null
+    isExtra: false
+    isNew: false
+    datasourceWarning: false
+    filterOptionName: filter_cx1vb3yeeya_ey59yynuao7
+  row_limit: 100
+  sort_by_metric: true
+  color_scheme: supersetColors
+  show_labels_threshold: 5
+  show_legend: true
+  legendType: scroll
+  legendOrientation: top
+  label_type: key
+  number_format: SMART_NUMBER
+  date_format: smart_date
+  show_labels: true
+  labels_outside: true
+  outerRadius: 70
+  innerRadius: 30
+  extra_form_data: {}
+  dashboards:
+  - 12
+query_context: '{"datasource":{"id":26,"type":"table"},"force":false,"queries":[{"filters":[{"col":"time","op":"TEMPORAL_RANGE","val":"No
+  filter"},{"col":"kind","op":"==","val":"E"}],"extras":{"having":"","where":""},"applied_time_extras":{},"columns":["type"],"metrics":[{"expressionType":"SIMPLE","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"type","description":null,"expression":null,"filterable":true,"groupby":true,"id":772,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"VARCHAR","type_generic":1,"verbose_name":null,"warning_markdown":null},"aggregate":"COUNT","sqlExpression":null,"datasourceWarning":false,"hasCustomLabel":false,"label":"COUNT(type)","optionName":"metric_0hcszvnysjqu_1znn0m0ezlw"}],"orderby":[[{"expressionType":"SIMPLE","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"type","description":null,"expression":null,"filterable":true,"groupby":true,"id":772,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"VARCHAR","type_generic":1,"verbose_name":null,"warning_markdown":null},"aggregate":"COUNT","sqlExpression":null,"datasourceWarning":false,"hasCustomLabel":false,"label":"COUNT(type)","optionName":"metric_0hcszvnysjqu_1znn0m0ezlw"},false]],"annotation_layers":[],"row_limit":100,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{}}],"form_data":{"datasource":"26__table","viz_type":"pie","groupby":["type"],"metric":{"expressionType":"SIMPLE","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"type","description":null,"expression":null,"filterable":true,"groupby":true,"id":772,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"VARCHAR","type_generic":1,"verbose_name":null,"warning_markdown":null},"aggregate":"COUNT","sqlExpression":null,"datasourceWarning":false,"hasCustomLabel":false,"label":"COUNT(type)","optionName":"metric_0hcszvnysjqu_1znn0m0ezlw"},"adhoc_filters":[{"expressionType":"SIMPLE","subject":"time","operator":"TEMPORAL_RANGE","comparator":"No
+  filter","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_g4xezxjmej6_ctfpq7bs3ad"},{"expressionType":"SIMPLE","subject":"kind","operator":"==","operatorId":"EQUALS","comparator":"E","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_cx1vb3yeeya_ey59yynuao7"}],"row_limit":100,"sort_by_metric":true,"color_scheme":"supersetColors","show_labels_threshold":5,"show_legend":true,"legendType":"scroll","legendOrientation":"top","label_type":"key","number_format":"SMART_NUMBER","date_format":"smart_date","show_labels":true,"labels_outside":true,"outerRadius":70,"innerRadius":30,"extra_form_data":{},"dashboards":[12],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}'
+cache_timeout: null
+uuid: a23b6fd1-5835-4fd3-9c7b-1c09d189d986
+version: 1.0.0
+dataset_uuid: 9912824b-b393-4acf-9f6b-b0d042ddac29
diff --git a/test/asset_export_samples/Event_Type_Counts_205.yaml b/test/asset_export_samples/Event_Type_Counts_205.yaml
new file mode 100644
index 0000000..1bb5786
--- /dev/null
+++ b/test/asset_export_samples/Event_Type_Counts_205.yaml
@@ -0,0 +1,103 @@
+slice_name: Event Type Counts
+description: null
+certified_by: null
+certification_details: null
+viz_type: echarts_timeseries_line
+params:
+  datasource: 26__table
+  viz_type: echarts_timeseries_line
+  x_axis: time
+  x_axis_sort_asc: true
+  x_axis_sort_series: name
+  x_axis_sort_series_ascending: true
+  metrics:
+  - expressionType: SIMPLE
+    column:
+      advanced_data_type: null
+      certification_details: null
+      certified_by: null
+      column_name: time
+      description: null
+      expression: null
+      filterable: true
+      groupby: true
+      id: 769
+      is_certified: false
+      is_dttm: true
+      python_date_format: null
+      type: DATETIME
+      type_generic: 2
+      verbose_name: null
+      warning_markdown: null
+    aggregate: COUNT
+    sqlExpression: null
+    datasourceWarning: false
+    hasCustomLabel: false
+    label: COUNT(time)
+    optionName: metric_mdfvifcu2zf_eayy1rictqi
+  groupby:
+  - object
+  - type
+  adhoc_filters:
+  - expressionType: SIMPLE
+    subject: time
+    operator: TEMPORAL_RANGE
+    comparator: No filter
+    clause: WHERE
+    sqlExpression: null
+    isExtra: false
+    isNew: false
+    datasourceWarning: false
+    filterOptionName: filter_m1tuiynrv8_5m5j3jrqjp9
+  - expressionType: SIMPLE
+    subject: kind
+    operator: ==
+    operatorId: EQUALS
+    comparator: E
+    clause: WHERE
+    sqlExpression: null
+    isExtra: false
+    isNew: false
+    datasourceWarning: false
+    filterOptionName: filter_os3hoez7s8g_ooftrrs7cx8
+  order_desc: true
+  row_limit: 10000
+  truncate_metric: true
+  show_empty_columns: true
+  comparison_type: values
+  annotation_layers: []
+  forecastPeriods: 10
+  forecastInterval: 0.8
+  x_axis_title_margin: 15
+  y_axis_title_margin: 15
+  y_axis_title_position: Left
+  sort_series_type: sum
+  color_scheme: supersetColors
+  time_shift_color: true
+  seriesType: line
+  only_total: true
+  opacity: 0.2
+  markerSize: 6
+  show_legend: true
+  legendType: scroll
+  legendOrientation: top
+  x_axis_time_format: smart_date
+  rich_tooltip: true
+  showTooltipTotal: true
+  showTooltipPercentage: true
+  tooltipTimeFormat: smart_date
+  y_axis_format: SMART_NUMBER
+  truncateXAxis: true
+  y_axis_bounds:
+  - null
+  - null
+  extra_form_data: {}
+  dashboards:
+  - 12
+query_context: '{"datasource":{"id":26,"type":"table"},"force":false,"queries":[{"filters":[{"col":"time","op":"TEMPORAL_RANGE","val":"No
+  filter"},{"col":"kind","op":"==","val":"E"}],"extras":{"having":"","where":""},"applied_time_extras":{},"columns":[{"columnType":"BASE_AXIS","sqlExpression":"time","label":"time","expressionType":"SQL"},"object","type"],"metrics":[{"expressionType":"SIMPLE","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"time","description":null,"expression":null,"filterable":true,"groupby":true,"id":769,"is_certified":false,"is_dttm":true,"python_date_format":null,"type":"DATETIME","type_generic":2,"verbose_name":null,"warning_markdown":null},"aggregate":"COUNT","sqlExpression":null,"datasourceWarning":false,"hasCustomLabel":false,"label":"COUNT(time)","optionName":"metric_mdfvifcu2zf_eayy1rictqi"}],"orderby":[[{"expressionType":"SIMPLE","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"time","description":null,"expression":null,"filterable":true,"groupby":true,"id":769,"is_certified":false,"is_dttm":true,"python_date_format":null,"type":"DATETIME","type_generic":2,"verbose_name":null,"warning_markdown":null},"aggregate":"COUNT","sqlExpression":null,"datasourceWarning":false,"hasCustomLabel":false,"label":"COUNT(time)","optionName":"metric_mdfvifcu2zf_eayy1rictqi"},false]],"annotation_layers":[],"row_limit":10000,"series_columns":["object","type"],"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"time_offsets":[],"post_processing":[{"operation":"pivot","options":{"index":["time"],"columns":["object","type"],"aggregates":{"COUNT(time)":{"operator":"mean"}},"drop_missing_columns":false}},{"operation":"rename","options":{"columns":{"COUNT(time)":null},"level":0,"inplace":true}},{"operation":"flatten"}]}],"form_data":{"datasource":"26__table","viz_type":"echarts_timeseries_line","x_axis":"time","x_axis_sort_asc":true,"x_axis_sort_series":"name","x_axis_sort_series_ascending":true,"metrics":[{"expressionType":"SIMPLE","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"time","description":null,"expression":null,"filterable":true,"groupby":true,"id":769,"is_certified":false,"is_dttm":true,"python_date_format":null,"type":"DATETIME","type_generic":2,"verbose_name":null,"warning_markdown":null},"aggregate":"COUNT","sqlExpression":null,"datasourceWarning":false,"hasCustomLabel":false,"label":"COUNT(time)","optionName":"metric_mdfvifcu2zf_eayy1rictqi"}],"groupby":["object","type"],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"time","operator":"TEMPORAL_RANGE","comparator":"No
+  filter","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_m1tuiynrv8_5m5j3jrqjp9"},{"expressionType":"SIMPLE","subject":"kind","operator":"==","operatorId":"EQUALS","comparator":"E","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_os3hoez7s8g_ooftrrs7cx8"}],"order_desc":true,"row_limit":10000,"truncate_metric":true,"show_empty_columns":true,"comparison_type":"values","annotation_layers":[],"forecastPeriods":10,"forecastInterval":0.8,"x_axis_title_margin":15,"y_axis_title_margin":15,"y_axis_title_position":"Left","sort_series_type":"sum","color_scheme":"supersetColors","time_shift_color":true,"seriesType":"line","only_total":true,"opacity":0.2,"markerSize":6,"show_legend":true,"legendType":"scroll","legendOrientation":"top","x_axis_time_format":"smart_date","rich_tooltip":true,"showTooltipTotal":true,"showTooltipPercentage":true,"tooltipTimeFormat":"smart_date","y_axis_format":"SMART_NUMBER","truncateXAxis":true,"y_axis_bounds":[null,null],"extra_form_data":{},"dashboards":[12],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}'
+cache_timeout: null
+uuid: 55f30587-c90f-4c35-8ada-1892b2305a12
+version: 1.0.0
+dataset_uuid: 9912824b-b393-4acf-9f6b-b0d042ddac29
diff --git a/test/asset_export_samples/Events_per_Object_203.yaml b/test/asset_export_samples/Events_per_Object_203.yaml
new file mode 100644
index 0000000..2367ab7
--- /dev/null
+++ b/test/asset_export_samples/Events_per_Object_203.yaml
@@ -0,0 +1,101 @@
+slice_name: Events per Object
+description: null
+certified_by: null
+certification_details: null
+viz_type: echarts_timeseries_bar
+params:
+  datasource: 26__table
+  viz_type: echarts_timeseries_bar
+  x_axis: object
+  time_grain_sqla: P1D
+  x_axis_sort_asc: true
+  x_axis_sort_series: name
+  x_axis_sort_series_ascending: true
+  metrics:
+  - expressionType: SIMPLE
+    column:
+      advanced_data_type: null
+      certification_details: null
+      certified_by: null
+      column_name: type
+      description: null
+      expression: null
+      filterable: true
+      groupby: true
+      id: 772
+      is_certified: false
+      is_dttm: false
+      python_date_format: null
+      type: VARCHAR
+      type_generic: 1
+      verbose_name: null
+      warning_markdown: null
+    aggregate: COUNT
+    sqlExpression: null
+    datasourceWarning: false
+    hasCustomLabel: false
+    label: COUNT(type)
+    optionName: metric_ixu59vrx32j_imygsjnt0rj
+  groupby:
+  - type
+  adhoc_filters:
+  - expressionType: SIMPLE
+    subject: time
+    operator: TEMPORAL_RANGE
+    comparator: No filter
+    clause: WHERE
+    sqlExpression: null
+    isExtra: false
+    isNew: false
+    datasourceWarning: false
+    filterOptionName: filter_tqzpewcfw7_uvcvr7iuqpa
+  - expressionType: SIMPLE
+    subject: kind
+    operator: ==
+    operatorId: EQUALS
+    comparator: E
+    clause: WHERE
+    sqlExpression: null
+    isExtra: false
+    isNew: false
+    datasourceWarning: false
+    filterOptionName: filter_5av1palfie2_44zwtwhl163
+  order_desc: true
+  row_limit: 10000
+  truncate_metric: true
+  show_empty_columns: true
+  comparison_type: values
+  annotation_layers: []
+  forecastPeriods: 10
+  forecastInterval: 0.8
+  orientation: vertical
+  x_axis_title_margin: 15
+  y_axis_title_margin: 15
+  y_axis_title_position: Left
+  sort_series_type: sum
+  color_scheme: supersetColors
+  time_shift_color: true
+  only_total: true
+  show_legend: true
+  legendType: scroll
+  legendOrientation: top
+  x_axis_time_format: smart_date
+  y_axis_format: SMART_NUMBER
+  y_axis_bounds:
+  - null
+  - null
+  truncateXAxis: true
+  rich_tooltip: true
+  showTooltipTotal: true
+  showTooltipPercentage: true
+  tooltipTimeFormat: smart_date
+  extra_form_data: {}
+  dashboards:
+  - 12
+query_context: '{"datasource":{"id":26,"type":"table"},"force":false,"queries":[{"filters":[{"col":"time","op":"TEMPORAL_RANGE","val":"No
+  filter"},{"col":"kind","op":"==","val":"E"}],"extras":{"time_grain_sqla":"P1D","having":"","where":""},"applied_time_extras":{},"columns":[{"timeGrain":"P1D","columnType":"BASE_AXIS","sqlExpression":"object","label":"object","expressionType":"SQL"},"type"],"metrics":[{"expressionType":"SIMPLE","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"type","description":null,"expression":null,"filterable":true,"groupby":true,"id":772,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"VARCHAR","type_generic":1,"verbose_name":null,"warning_markdown":null},"aggregate":"COUNT","sqlExpression":null,"datasourceWarning":false,"hasCustomLabel":false,"label":"COUNT(type)","optionName":"metric_ixu59vrx32j_imygsjnt0rj"}],"orderby":[[{"expressionType":"SIMPLE","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"type","description":null,"expression":null,"filterable":true,"groupby":true,"id":772,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"VARCHAR","type_generic":1,"verbose_name":null,"warning_markdown":null},"aggregate":"COUNT","sqlExpression":null,"datasourceWarning":false,"hasCustomLabel":false,"label":"COUNT(type)","optionName":"metric_ixu59vrx32j_imygsjnt0rj"},false]],"annotation_layers":[],"row_limit":10000,"series_columns":["type"],"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"time_offsets":[],"post_processing":[{"operation":"pivot","options":{"index":["object"],"columns":["type"],"aggregates":{"COUNT(type)":{"operator":"mean"}},"drop_missing_columns":false}},{"operation":"rename","options":{"columns":{"COUNT(type)":null},"level":0,"inplace":true}},{"operation":"flatten"}]}],"form_data":{"datasource":"26__table","viz_type":"echarts_timeseries_bar","x_axis":"object","time_grain_sqla":"P1D","x_axis_sort_asc":true,"x_axis_sort_series":"name","x_axis_sort_series_ascending":true,"metrics":[{"expressionType":"SIMPLE","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"type","description":null,"expression":null,"filterable":true,"groupby":true,"id":772,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"VARCHAR","type_generic":1,"verbose_name":null,"warning_markdown":null},"aggregate":"COUNT","sqlExpression":null,"datasourceWarning":false,"hasCustomLabel":false,"label":"COUNT(type)","optionName":"metric_ixu59vrx32j_imygsjnt0rj"}],"groupby":["type"],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"time","operator":"TEMPORAL_RANGE","comparator":"No
+  filter","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_tqzpewcfw7_uvcvr7iuqpa"},{"expressionType":"SIMPLE","subject":"kind","operator":"==","operatorId":"EQUALS","comparator":"E","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_5av1palfie2_44zwtwhl163"}],"order_desc":true,"row_limit":10000,"truncate_metric":true,"show_empty_columns":true,"comparison_type":"values","annotation_layers":[],"forecastPeriods":10,"forecastInterval":0.8,"orientation":"vertical","x_axis_title_margin":15,"y_axis_title_margin":15,"y_axis_title_position":"Left","sort_series_type":"sum","color_scheme":"supersetColors","time_shift_color":true,"only_total":true,"show_legend":true,"legendType":"scroll","legendOrientation":"top","x_axis_time_format":"smart_date","y_axis_format":"SMART_NUMBER","y_axis_bounds":[null,null],"truncateXAxis":true,"rich_tooltip":true,"showTooltipTotal":true,"showTooltipPercentage":true,"tooltipTimeFormat":"smart_date","extra_form_data":{},"dashboards":[12],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}'
+cache_timeout: null
+uuid: f7691976-41e2-4071-80e5-aace13802190
+version: 1.0.0
+dataset_uuid: 9912824b-b393-4acf-9f6b-b0d042ddac29
diff --git a/test/asset_export_samples/MAED_Testing_12.yaml b/test/asset_export_samples/MAED_Testing_12.yaml
new file mode 100644
index 0000000..ec58dbd
--- /dev/null
+++ b/test/asset_export_samples/MAED_Testing_12.yaml
@@ -0,0 +1,392 @@
+dashboard_title: MAED Testing
+description: null
+css: ''
+slug: null
+certified_by: ''
+certification_details: ''
+published: false
+uuid: 0c7a4f90-874a-4a7f-9c16-5b1702cd57b3
+position:
+  CHART-eG2NNbDAqWVTjuAvtrVx-:
+    children: []
+    id: CHART-eG2NNbDAqWVTjuAvtrVx-
+    meta:
+      chartId: 199
+      height: 50
+      sliceName: Event Annotations
+      uuid: 323fc686-1f2f-49ce-9fad-5382e8376d8d
+      width: 4
+    parents:
+    - ROOT_ID
+    - GRID_ID
+    - ROW-DH7fZO5qABf48CYGz9LK3
+    type: CHART
+  CHART-explore-198-1:
+    children: []
+    id: CHART-explore-198-1
+    meta:
+      chartId: 198
+      height: 50
+      sliceName: TS Plot
+      uuid: 77b89150-c063-4c7e-b8c9-75b7a002dd6e
+      width: 12
+    parents:
+    - ROOT_ID
+    - GRID_ID
+    - ROW-OFpU7_PD3uh6LU2vcXAwU
+    type: CHART
+  CHART-explore-200-1:
+    children: []
+    id: CHART-explore-200-1
+    meta:
+      chartId: 200
+      height: 50
+      sliceName: Segment Annotations
+      uuid: e38df49e-9726-4e6f-8164-8fa2c8dc83b0
+      width: 4
+    parents:
+    - ROOT_ID
+    - GRID_ID
+    - ROW-DH7fZO5qABf48CYGz9LK3
+    type: CHART
+  CHART-explore-201-1:
+    children: []
+    id: CHART-explore-201-1
+    meta:
+      chartId: 201
+      height: 50
+      sliceName: Objects
+      uuid: ea2e9e77-ed7a-41c0-af86-71e465a00248
+      width: 4
+    parents:
+    - ROOT_ID
+    - GRID_ID
+    - ROW--Om-dRTvFsC1G4qiUoEqw
+    type: CHART
+  CHART-explore-202-1:
+    children: []
+    id: CHART-explore-202-1
+    meta:
+      chartId: 202
+      height: 50
+      sliceName: Event Type Counts
+      uuid: a23b6fd1-5835-4fd3-9c7b-1c09d189d986
+      width: 4
+    parents:
+    - ROOT_ID
+    - GRID_ID
+    - ROW--Om-dRTvFsC1G4qiUoEqw
+    type: CHART
+  CHART-explore-203-1:
+    children: []
+    id: CHART-explore-203-1
+    meta:
+      chartId: 203
+      height: 50
+      sliceName: Events per Object
+      uuid: f7691976-41e2-4071-80e5-aace13802190
+      width: 4
+    parents:
+    - ROOT_ID
+    - GRID_ID
+    - ROW--Om-dRTvFsC1G4qiUoEqw
+    type: CHART
+  CHART-explore-204-1:
+    children: []
+    id: CHART-explore-204-1
+    meta:
+      chartId: 204
+      height: 50
+      sliceName: Measurement Type Counts
+      uuid: 863251c1-af2f-4c51-a758-3417a47acc6c
+      width: 4
+    parents:
+    - ROOT_ID
+    - GRID_ID
+    - ROW-sC7Kd-wc9BWPSGXjm7Qtp
+    type: CHART
+  DASHBOARD_VERSION_KEY: v2
+  GRID_ID:
+    children:
+    - ROW-f87YZWpASScCiBtzTX8uj
+    - ROW-OFpU7_PD3uh6LU2vcXAwU
+    - ROW-DH7fZO5qABf48CYGz9LK3
+    - ROW-N-98ZABA0X
+    id: GRID_ID
+    parents:
+    - ROOT_ID
+    type: GRID
+  HEADER_ID:
+    id: HEADER_ID
+    meta:
+      text: MAED Testing
+    type: HEADER
+  ROOT_ID:
+    children:
+    - GRID_ID
+    id: ROOT_ID
+    type: ROOT
+  ROW-DH7fZO5qABf48CYGz9LK3:
+    children:
+    - CHART-explore-204-1
+    - CHART-explore-200-1
+    - CHART-eG2NNbDAqWVTjuAvtrVx-
+    id: ROW-DH7fZO5qABf48CYGz9LK3
+    meta:
+      background: BACKGROUND_TRANSPARENT
+    parents:
+    - ROOT_ID
+    - GRID_ID
+    type: ROW
+  ROW-OFpU7_PD3uh6LU2vcXAwU:
+    children:
+    - CHART-explore-198-1
+    id: ROW-OFpU7_PD3uh6LU2vcXAwU
+    meta:
+      '0': ROOT_ID
+      background: BACKGROUND_TRANSPARENT
+    parents:
+    - ROOT_ID
+    - GRID_ID
+    type: ROW
+  ROW-f87YZWpASScCiBtzTX8uj:
+    children:
+    - CHART-explore-201-1
+    - CHART-explore-202-1
+    - CHART-explore-203-1
+    id: ROW-f87YZWpASScCiBtzTX8uj
+    meta:
+      background: BACKGROUND_TRANSPARENT
+    parents:
+    - ROOT_ID
+    - GRID_ID
+    type: ROW
+  ROW-N-98ZABA0X:
+    children:
+    - CHART-U7N7YVJ8
+    id: ROW-N-98ZABA0X
+    meta:
+      '0': ROOT_ID
+      background: BACKGROUND_TRANSPARENT
+    type: ROW
+    parents:
+    - ROOT_ID
+    - GRID_ID
+  CHART-U7N7YVJ8:
+    children: []
+    id: CHART-U7N7YVJ8
+    meta:
+      chartId: 205
+      height: 50
+      sliceName: Event Type Counts
+      uuid: 55f30587-c90f-4c35-8ada-1892b2305a12
+      width: 4
+    type: CHART
+    parents:
+    - ROOT_ID
+    - GRID_ID
+    - ROW-N-98ZABA0X
+metadata:
+  label_colors: {}
+  color_scheme: blueToGreen
+  timed_refresh_immune_slices: []
+  expanded_slices: {}
+  refresh_frequency: 0
+  shared_label_colors:
+  - completed
+  - error
+  - overheated
+  - started
+  map_label_colors:
+    started: '#3200A7'
+    completed: '#004CDA'
+    error: '#0074F1'
+    overheated: '#0096EF'
+    Printer A: '#3200A7'
+    Printer B: '#004CDA'
+    Printer C: '#0074F1'
+    Printer A, position: '#3200A7'
+    Printer B, position: '#004CDA'
+    Printer C, position: '#0074F1'
+    AVG(x), Printer A: '#3200A7'
+    AVG(x), Printer C: '#004CDA'
+    AVG(x), Printer B: '#0074F1'
+    segments: '#0096EF'
+  color_scheme_domain:
+  - '#3200A7'
+  - '#004CDA'
+  - '#0074F1'
+  - '#0096EF'
+  - '#53BFFF'
+  - '#41C8E6'
+  - '#30DEDE'
+  - '#04D9C7'
+  - '#00EAA2'
+  - '#A6FF93'
+  cross_filters_enabled: true
+  native_filter_configuration:
+  - id: NATIVE_FILTER-XAKXJuJ4ySPG0XmBub1ip
+    controlValues:
+      enableEmptyFilter: false
+      defaultToFirstItem: false
+      multiSelect: true
+      searchAllOptions: false
+      inverseSelection: false
+    name: Object
+    filterType: filter_select
+    targets:
+    - column:
+        name: object
+      datasetUuid: ed66a423-9bcc-4127-aa6a-ecc78af22a3e
+    defaultDataMask:
+      extraFormData: {}
+      filterState: {}
+      ownState: {}
+    cascadeParentIds: []
+    scope:
+      rootPath:
+      - ROOT_ID
+      excluded: []
+    type: NATIVE_FILTER
+    description: ''
+    chartsInScope:
+    - 198
+    - 200
+    tabsInScope: []
+  - id: NATIVE_FILTER-COGmceRQVxnT7mZHRtxEf
+    controlValues:
+      enableEmptyFilter: false
+    name: Time Grain
+    filterType: filter_timegrain
+    targets:
+    - datasetUuid: ed66a423-9bcc-4127-aa6a-ecc78af22a3e
+    defaultDataMask:
+      extraFormData: {}
+      filterState: {}
+      ownState: {}
+    cascadeParentIds: []
+    scope:
+      rootPath:
+      - ROOT_ID
+      excluded: []
+    type: NATIVE_FILTER
+    description: ''
+    chartsInScope:
+    - 198
+    - 200
+    tabsInScope: []
+  - id: NATIVE_FILTER-uw0eH_fUncKHCjyNKTnKS
+    controlValues:
+      enableEmptyFilter: false
+    name: Time Range
+    filterType: filter_time
+    targets:
+    - {}
+    defaultDataMask:
+      extraFormData: {}
+      filterState: {}
+      ownState: {}
+    cascadeParentIds: []
+    scope:
+      rootPath:
+      - ROOT_ID
+      excluded: []
+    type: NATIVE_FILTER
+    description: ''
+    chartsInScope:
+    - 198
+    - 200
+    tabsInScope: []
+  chart_configuration:
+    '198':
+      id: 198
+      crossFilters:
+        scope: global
+        chartsInScope:
+        - 199
+        - 200
+        - 201
+        - 202
+        - 203
+        - 204
+    '199':
+      id: 199
+      crossFilters:
+        scope: global
+        chartsInScope:
+        - 198
+        - 200
+        - 201
+        - 202
+        - 203
+        - 204
+    '200':
+      id: 200
+      crossFilters:
+        scope: global
+        chartsInScope:
+        - 198
+        - 199
+        - 201
+        - 202
+        - 203
+        - 204
+    '201':
+      id: 201
+      crossFilters:
+        scope: global
+        chartsInScope:
+        - 198
+        - 199
+        - 200
+        - 202
+        - 203
+        - 204
+    '202':
+      id: 202
+      crossFilters:
+        scope: global
+        chartsInScope:
+        - 198
+        - 199
+        - 200
+        - 201
+        - 203
+        - 204
+    '203':
+      id: 203
+      crossFilters:
+        scope: global
+        chartsInScope:
+        - 198
+        - 199
+        - 200
+        - 201
+        - 202
+        - 204
+    '204':
+      id: 204
+      crossFilters:
+        scope: global
+        chartsInScope:
+        - 198
+        - 199
+        - 200
+        - 201
+        - 202
+        - 203
+  global_chart_configuration:
+    scope:
+      rootPath:
+      - ROOT_ID
+      excluded: []
+    chartsInScope:
+    - 198
+    - 199
+    - 200
+    - 201
+    - 202
+    - 203
+    - 204
+  default_filters: '{}'
+version: 1.0.0
diff --git a/test/asset_export_samples/Measurement_Type_Counts_204.yaml b/test/asset_export_samples/Measurement_Type_Counts_204.yaml
new file mode 100644
index 0000000..a984313
--- /dev/null
+++ b/test/asset_export_samples/Measurement_Type_Counts_204.yaml
@@ -0,0 +1,104 @@
+slice_name: Measurement Type Counts
+description: null
+certified_by: null
+certification_details: null
+viz_type: echarts_timeseries_line
+params:
+  datasource: 26__table
+  viz_type: echarts_timeseries_line
+  x_axis: time
+  time_grain_sqla: PT1M
+  x_axis_sort_asc: true
+  x_axis_sort_series: name
+  x_axis_sort_series_ascending: true
+  metrics:
+  - expressionType: SIMPLE
+    column:
+      advanced_data_type: null
+      certification_details: null
+      certified_by: null
+      column_name: time
+      description: null
+      expression: null
+      filterable: true
+      groupby: true
+      id: 788
+      is_certified: false
+      is_dttm: true
+      python_date_format: null
+      type: DATETIME
+      type_generic: 2
+      verbose_name: null
+      warning_markdown: null
+    aggregate: COUNT
+    sqlExpression: null
+    datasourceWarning: false
+    hasCustomLabel: false
+    label: COUNT(time)
+    optionName: metric_okswlkr3i48_qso3022kmz
+  groupby:
+  - object
+  - type
+  adhoc_filters:
+  - expressionType: SIMPLE
+    subject: time
+    operator: TEMPORAL_RANGE
+    comparator: No filter
+    clause: WHERE
+    sqlExpression: null
+    isExtra: false
+    isNew: false
+    datasourceWarning: false
+    filterOptionName: filter_h96362s5uia_e7n5judrk97
+  - expressionType: SIMPLE
+    subject: kind
+    operator: ==
+    operatorId: EQUALS
+    comparator: M
+    clause: WHERE
+    sqlExpression: null
+    isExtra: false
+    isNew: false
+    datasourceWarning: false
+    filterOptionName: filter_dyuk62snqcb_jjbnuc6e7f
+  order_desc: true
+  row_limit: 10000
+  truncate_metric: true
+  show_empty_columns: true
+  comparison_type: values
+  annotation_layers: []
+  forecastPeriods: 10
+  forecastInterval: 0.8
+  x_axis_title_margin: 15
+  y_axis_title_margin: 15
+  y_axis_title_position: Left
+  sort_series_type: sum
+  color_scheme: supersetColors
+  time_shift_color: true
+  seriesType: line
+  only_total: true
+  opacity: 0.2
+  markerSize: 6
+  show_legend: true
+  legendType: scroll
+  legendOrientation: top
+  x_axis_time_format: smart_date
+  rich_tooltip: true
+  showTooltipTotal: true
+  showTooltipPercentage: true
+  tooltipTimeFormat: smart_date
+  y_axis_format: SMART_NUMBER
+  truncateXAxis: true
+  y_axis_bounds:
+  - null
+  - null
+  extra_form_data: {}
+  dashboards:
+  - 12
+query_context: '{"datasource":{"id":26,"type":"table"},"force":false,"queries":[{"filters":[{"col":"time","op":"TEMPORAL_RANGE","val":"No
+  filter"},{"col":"kind","op":"==","val":"M"}],"extras":{"time_grain_sqla":"PT1M","having":"","where":""},"applied_time_extras":{},"columns":[{"timeGrain":"PT1M","columnType":"BASE_AXIS","sqlExpression":"time","label":"time","expressionType":"SQL"},"object","type"],"metrics":[{"expressionType":"SIMPLE","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"time","description":null,"expression":null,"filterable":true,"groupby":true,"id":788,"is_certified":false,"is_dttm":true,"python_date_format":null,"type":"DATETIME","type_generic":2,"verbose_name":null,"warning_markdown":null},"aggregate":"COUNT","sqlExpression":null,"datasourceWarning":false,"hasCustomLabel":false,"label":"COUNT(time)","optionName":"metric_okswlkr3i48_qso3022kmz"}],"orderby":[[{"expressionType":"SIMPLE","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"time","description":null,"expression":null,"filterable":true,"groupby":true,"id":788,"is_certified":false,"is_dttm":true,"python_date_format":null,"type":"DATETIME","type_generic":2,"verbose_name":null,"warning_markdown":null},"aggregate":"COUNT","sqlExpression":null,"datasourceWarning":false,"hasCustomLabel":false,"label":"COUNT(time)","optionName":"metric_okswlkr3i48_qso3022kmz"},false]],"annotation_layers":[],"row_limit":10000,"series_columns":["object","type"],"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"time_offsets":[],"post_processing":[{"operation":"pivot","options":{"index":["time"],"columns":["object","type"],"aggregates":{"COUNT(time)":{"operator":"mean"}},"drop_missing_columns":false}},{"operation":"rename","options":{"columns":{"COUNT(time)":null},"level":0,"inplace":true}},{"operation":"flatten"}]}],"form_data":{"datasource":"26__table","viz_type":"echarts_timeseries_line","x_axis":"time","time_grain_sqla":"PT1M","x_axis_sort_asc":true,"x_axis_sort_series":"name","x_axis_sort_series_ascending":true,"metrics":[{"expressionType":"SIMPLE","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"time","description":null,"expression":null,"filterable":true,"groupby":true,"id":788,"is_certified":false,"is_dttm":true,"python_date_format":null,"type":"DATETIME","type_generic":2,"verbose_name":null,"warning_markdown":null},"aggregate":"COUNT","sqlExpression":null,"datasourceWarning":false,"hasCustomLabel":false,"label":"COUNT(time)","optionName":"metric_okswlkr3i48_qso3022kmz"}],"groupby":["object","type"],"adhoc_filters":[{"expressionType":"SIMPLE","subject":"time","operator":"TEMPORAL_RANGE","comparator":"No
+  filter","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_h96362s5uia_e7n5judrk97"},{"expressionType":"SIMPLE","subject":"kind","operator":"==","operatorId":"EQUALS","comparator":"M","clause":"WHERE","sqlExpression":null,"isExtra":false,"isNew":false,"datasourceWarning":false,"filterOptionName":"filter_dyuk62snqcb_jjbnuc6e7f"}],"order_desc":true,"row_limit":10000,"truncate_metric":true,"show_empty_columns":true,"comparison_type":"values","annotation_layers":[],"forecastPeriods":10,"forecastInterval":0.8,"x_axis_title_margin":15,"y_axis_title_margin":15,"y_axis_title_position":"Left","sort_series_type":"sum","color_scheme":"supersetColors","time_shift_color":true,"seriesType":"line","only_total":true,"opacity":0.2,"markerSize":6,"show_legend":true,"legendType":"scroll","legendOrientation":"top","x_axis_time_format":"smart_date","rich_tooltip":true,"showTooltipTotal":true,"showTooltipPercentage":true,"tooltipTimeFormat":"smart_date","y_axis_format":"SMART_NUMBER","truncateXAxis":true,"y_axis_bounds":[null,null],"extra_form_data":{},"dashboards":[12],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}'
+cache_timeout: null
+uuid: 863251c1-af2f-4c51-a758-3417a47acc6c
+version: 1.0.0
+dataset_uuid: 9912824b-b393-4acf-9f6b-b0d042ddac29
diff --git a/test/asset_export_samples/Objects_201.yaml b/test/asset_export_samples/Objects_201.yaml
new file mode 100644
index 0000000..37eb9f3
--- /dev/null
+++ b/test/asset_export_samples/Objects_201.yaml
@@ -0,0 +1,65 @@
+slice_name: Objects
+description: null
+certified_by: null
+certification_details: null
+viz_type: pie
+params:
+  datasource: 26__table
+  viz_type: pie
+  groupby:
+  - object
+  metric:
+    expressionType: SIMPLE
+    column:
+      advanced_data_type: null
+      certification_details: null
+      certified_by: null
+      column_name: object
+      description: null
+      expression: null
+      filterable: true
+      groupby: true
+      id: 770
+      is_certified: false
+      is_dttm: false
+      python_date_format: null
+      type: VARCHAR
+      type_generic: 1
+      verbose_name: null
+      warning_markdown: null
+    aggregate: COUNT
+    sqlExpression: null
+    datasourceWarning: false
+    hasCustomLabel: false
+    label: COUNT(object)
+    optionName: metric_drbk8s9c927_9mrsq033mll
+  adhoc_filters:
+  - clause: WHERE
+    subject: time
+    operator: TEMPORAL_RANGE
+    comparator: No filter
+    expressionType: SIMPLE
+  row_limit: 100
+  sort_by_metric: true
+  color_scheme: supersetColors
+  show_labels_threshold: 5
+  show_legend: true
+  legendType: scroll
+  legendOrientation: top
+  label_type: key
+  number_format: SMART_NUMBER
+  date_format: smart_date
+  show_labels: true
+  labels_outside: true
+  outerRadius: 70
+  innerRadius: 30
+  extra_form_data: {}
+  dashboards:
+  - 12
+query_context: '{"datasource":{"id":26,"type":"table"},"force":false,"queries":[{"filters":[{"col":"time","op":"TEMPORAL_RANGE","val":"No
+  filter"}],"extras":{"having":"","where":""},"applied_time_extras":{},"columns":["object"],"metrics":[{"expressionType":"SIMPLE","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"object","description":null,"expression":null,"filterable":true,"groupby":true,"id":770,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"VARCHAR","type_generic":1,"verbose_name":null,"warning_markdown":null},"aggregate":"COUNT","sqlExpression":null,"datasourceWarning":false,"hasCustomLabel":false,"label":"COUNT(object)","optionName":"metric_drbk8s9c927_9mrsq033mll"}],"orderby":[[{"expressionType":"SIMPLE","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"object","description":null,"expression":null,"filterable":true,"groupby":true,"id":770,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"VARCHAR","type_generic":1,"verbose_name":null,"warning_markdown":null},"aggregate":"COUNT","sqlExpression":null,"datasourceWarning":false,"hasCustomLabel":false,"label":"COUNT(object)","optionName":"metric_drbk8s9c927_9mrsq033mll"},false]],"annotation_layers":[],"row_limit":100,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{}}],"form_data":{"datasource":"26__table","viz_type":"pie","groupby":["object"],"metric":{"expressionType":"SIMPLE","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"object","description":null,"expression":null,"filterable":true,"groupby":true,"id":770,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"VARCHAR","type_generic":1,"verbose_name":null,"warning_markdown":null},"aggregate":"COUNT","sqlExpression":null,"datasourceWarning":false,"hasCustomLabel":false,"label":"COUNT(object)","optionName":"metric_drbk8s9c927_9mrsq033mll"},"adhoc_filters":[{"clause":"WHERE","subject":"time","operator":"TEMPORAL_RANGE","comparator":"No
+  filter","expressionType":"SIMPLE"}],"row_limit":100,"sort_by_metric":true,"color_scheme":"supersetColors","show_labels_threshold":5,"show_legend":true,"legendType":"scroll","legendOrientation":"top","label_type":"key","number_format":"SMART_NUMBER","date_format":"smart_date","show_labels":true,"labels_outside":true,"outerRadius":70,"innerRadius":30,"extra_form_data":{},"dashboards":[12],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}'
+cache_timeout: null
+uuid: ea2e9e77-ed7a-41c0-af86-71e465a00248
+version: 1.0.0
+dataset_uuid: 9912824b-b393-4acf-9f6b-b0d042ddac29
diff --git a/test/asset_export_samples/Segment_Annotations_200.yaml b/test/asset_export_samples/Segment_Annotations_200.yaml
new file mode 100644
index 0000000..b7518a7
--- /dev/null
+++ b/test/asset_export_samples/Segment_Annotations_200.yaml
@@ -0,0 +1,47 @@
+slice_name: Segment Annotations
+description: null
+certified_by: null
+certification_details: null
+viz_type: table
+params:
+  datasource: 33__table
+  viz_type: table
+  query_mode: raw
+  groupby: []
+  time_grain_sqla: P1D
+  temporal_columns_lookup:
+    start: true
+    end: true
+  all_columns:
+  - object
+  - concept
+  - start
+  - end
+  percent_metrics: []
+  adhoc_filters:
+  - clause: WHERE
+    subject: start
+    operator: TEMPORAL_RANGE
+    comparator: No filter
+    expressionType: SIMPLE
+  order_by_cols:
+  - '["segment_index", true]'
+  row_limit: 1000
+  server_page_length: 10
+  order_desc: true
+  table_timestamp_format: smart_date
+  allow_render_html: true
+  show_cell_bars: true
+  color_pn: true
+  comparison_color_scheme: Green
+  comparison_type: values
+  extra_form_data: {}
+  dashboards:
+  - 12
+query_context: '{"datasource":{"id":33,"type":"table"},"force":false,"queries":[{"filters":[{"col":"start","op":"TEMPORAL_RANGE","val":"No
+  filter"}],"extras":{"having":"","where":""},"applied_time_extras":{},"columns":["object","concept","start","end"],"orderby":[["segment_index",true]],"annotation_layers":[],"row_limit":1000,"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"post_processing":[],"time_offsets":[]}],"form_data":{"datasource":"33__table","viz_type":"table","query_mode":"raw","groupby":[],"time_grain_sqla":"P1D","temporal_columns_lookup":{"start":true,"end":true},"all_columns":["object","concept","start","end"],"percent_metrics":[],"adhoc_filters":[{"clause":"WHERE","subject":"start","operator":"TEMPORAL_RANGE","comparator":"No
+  filter","expressionType":"SIMPLE"}],"order_by_cols":["[\"segment_index\", true]"],"row_limit":1000,"server_page_length":10,"order_desc":true,"table_timestamp_format":"smart_date","allow_render_html":true,"show_cell_bars":true,"color_pn":true,"comparison_color_scheme":"Green","comparison_type":"values","extra_form_data":{},"dashboards":[12],"force":false,"result_format":"json","result_type":"full","include_time":false},"result_format":"json","result_type":"full"}'
+cache_timeout: null
+uuid: e38df49e-9726-4e6f-8164-8fa2c8dc83b0
+version: 1.0.0
+dataset_uuid: 696b6908-9f00-4054-ba07-d2f38c4bb4e2
diff --git a/test/asset_export_samples/TS_Plot_198.yaml b/test/asset_export_samples/TS_Plot_198.yaml
new file mode 100644
index 0000000..8d97717
--- /dev/null
+++ b/test/asset_export_samples/TS_Plot_198.yaml
@@ -0,0 +1,177 @@
+slice_name: TS Plot
+description: null
+certified_by: null
+certification_details: null
+viz_type: echarts_timeseries_line
+params:
+  datasource: 30__table
+  viz_type: echarts_timeseries_line
+  slice_id: 198
+  x_axis: time
+  metrics:
+  - aggregate: AVG
+    column:
+      advanced_data_type: null
+      certification_details: null
+      certified_by: null
+      column_name: x
+      description: null
+      expression: null
+      filterable: true
+      groupby: false
+      id: 792
+      is_certified: false
+      is_dttm: false
+      python_date_format: null
+      type: FLOAT
+      type_generic: 0
+      verbose_name: null
+      warning_markdown: null
+    datasourceWarning: false
+    expressionType: SIMPLE
+    hasCustomLabel: false
+    label: AVG(x)
+    optionName: metric_bst76yz6pyi_9c0iv4es1df
+    sqlExpression: null
+  - aggregate: AVG
+    column:
+      advanced_data_type: null
+      certification_details: null
+      certified_by: null
+      column_name: y
+      description: null
+      expression: null
+      filterable: true
+      groupby: false
+      id: 793
+      is_certified: false
+      is_dttm: false
+      python_date_format: null
+      type: FLOAT
+      type_generic: 0
+      verbose_name: null
+      warning_markdown: null
+    datasourceWarning: false
+    expressionType: SIMPLE
+    hasCustomLabel: false
+    label: AVG(y)
+    optionName: metric_n14797p4yx_1yaq6favkyf
+    sqlExpression: null
+  - aggregate: AVG
+    column:
+      advanced_data_type: null
+      certification_details: null
+      certified_by: null
+      column_name: z
+      description: null
+      expression: null
+      filterable: true
+      groupby: false
+      id: 794
+      is_certified: false
+      is_dttm: false
+      python_date_format: null
+      type: FLOAT
+      type_generic: 0
+      verbose_name: null
+      warning_markdown: null
+    datasourceWarning: false
+    expressionType: SIMPLE
+    hasCustomLabel: false
+    label: AVG(z)
+    optionName: metric_lw1vtm2ab9_chfv4ocx5g8
+    sqlExpression: null
+  groupby:
+  - object
+  adhoc_filters:
+  - clause: WHERE
+    comparator: No filter
+    datasourceWarning: false
+    expressionType: SIMPLE
+    filterOptionName: filter_7a7ky5oe75g_6imahu3y5qm
+    isExtra: false
+    isNew: false
+    operator: TEMPORAL_RANGE
+    sqlExpression: null
+    subject: time
+  row_limit: 5000
+  truncate_metric: true
+  show_empty_columns: true
+  comparison_type: values
+  annotation_layers:
+  - annotationType: EVENT
+    color: null
+    descriptionColumns:
+    - object
+    - type
+    hideLine: false
+    intervalEndColumn: ''
+    name: events
+    opacity: ''
+    overrides:
+      time_range: null
+    show: false
+    showLabel: false
+    showMarkers: false
+    sourceType: table
+    style: solid
+    timeColumn: time
+    titleColumn: type
+    value: 199
+    width: 1
+  - name: segments
+    annotationType: INTERVAL
+    sourceType: table
+    color: null
+    opacity: ''
+    style: solid
+    width: 1
+    showMarkers: false
+    hideLine: false
+    overrides:
+      time_range: null
+    show: true
+    showLabel: false
+    titleColumn: concept
+    descriptionColumns:
+    - object
+    - concept
+    timeColumn: start
+    intervalEndColumn: end
+    value: 200
+  forecastEnabled: false
+  forecastPeriods: 10
+  forecastInterval: 0.8
+  x_axis_title_margin: 15
+  y_axis_title_margin: 15
+  y_axis_title_position: Left
+  sort_series_type: sum
+  color_scheme: blueToGreen
+  time_shift_color: true
+  seriesType: line
+  only_total: true
+  opacity: 0.2
+  markerSize: 6
+  show_legend: true
+  legendType: scroll
+  legendOrientation: top
+  x_axis_time_format: smart_date
+  rich_tooltip: true
+  showTooltipTotal: true
+  showTooltipPercentage: true
+  tooltipTimeFormat: smart_date
+  y_axis_format: SMART_NUMBER
+  truncateXAxis: true
+  y_axis_bounds:
+  - null
+  - null
+  extra_form_data: {}
+  dashboards:
+  - 12
+query_context: '{"datasource":{"id":30,"type":"table"},"force":false,"queries":[{"filters":[{"col":"time","op":"TEMPORAL_RANGE","val":"No
+  filter"}],"extras":{"having":"","where":""},"applied_time_extras":{},"columns":[{"columnType":"BASE_AXIS","sqlExpression":"time","label":"time","expressionType":"SQL"},"object"],"metrics":[{"aggregate":"AVG","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"x","description":null,"expression":null,"filterable":true,"groupby":false,"id":792,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"FLOAT","type_generic":0,"verbose_name":null,"warning_markdown":null},"datasourceWarning":false,"expressionType":"SIMPLE","hasCustomLabel":false,"label":"AVG(x)","optionName":"metric_bst76yz6pyi_9c0iv4es1df","sqlExpression":null},{"aggregate":"AVG","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"y","description":null,"expression":null,"filterable":true,"groupby":false,"id":793,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"FLOAT","type_generic":0,"verbose_name":null,"warning_markdown":null},"datasourceWarning":false,"expressionType":"SIMPLE","hasCustomLabel":false,"label":"AVG(y)","optionName":"metric_n14797p4yx_1yaq6favkyf","sqlExpression":null},{"aggregate":"AVG","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"z","description":null,"expression":null,"filterable":true,"groupby":false,"id":794,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"FLOAT","type_generic":0,"verbose_name":null,"warning_markdown":null},"datasourceWarning":false,"expressionType":"SIMPLE","hasCustomLabel":false,"label":"AVG(z)","optionName":"metric_lw1vtm2ab9_chfv4ocx5g8","sqlExpression":null}],"orderby":[[{"aggregate":"AVG","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"x","description":null,"expression":null,"filterable":true,"groupby":false,"id":792,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"FLOAT","type_generic":0,"verbose_name":null,"warning_markdown":null},"datasourceWarning":false,"expressionType":"SIMPLE","hasCustomLabel":false,"label":"AVG(x)","optionName":"metric_bst76yz6pyi_9c0iv4es1df","sqlExpression":null},false]],"annotation_layers":[{"annotationType":"EVENT","color":null,"descriptionColumns":["object","type"],"hideLine":false,"intervalEndColumn":"","name":"events","opacity":"","overrides":{"time_range":null},"show":false,"showLabel":false,"showMarkers":false,"sourceType":"table","style":"solid","timeColumn":"time","titleColumn":"type","value":199,"width":1},{"name":"segments","annotationType":"INTERVAL","sourceType":"table","color":null,"opacity":"","style":"solid","width":1,"showMarkers":false,"hideLine":false,"overrides":{"time_range":null},"show":true,"showLabel":false,"titleColumn":"concept","descriptionColumns":["object","concept"],"timeColumn":"start","intervalEndColumn":"end","value":200}],"row_limit":5000,"series_columns":["object"],"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"time_offsets":[],"post_processing":[{"operation":"pivot","options":{"index":["time"],"columns":["object"],"aggregates":{"AVG(x)":{"operator":"mean"},"AVG(y)":{"operator":"mean"},"AVG(z)":{"operator":"mean"}},"drop_missing_columns":false}},{"operation":"flatten"}]}],"form_data":{"datasource":"30__table","viz_type":"echarts_timeseries_line","slice_id":198,"x_axis":"time","metrics":[{"aggregate":"AVG","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"x","description":null,"expression":null,"filterable":true,"groupby":false,"id":792,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"FLOAT","type_generic":0,"verbose_name":null,"warning_markdown":null},"datasourceWarning":false,"expressionType":"SIMPLE","hasCustomLabel":false,"label":"AVG(x)","optionName":"metric_bst76yz6pyi_9c0iv4es1df","sqlExpression":null},{"aggregate":"AVG","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"y","description":null,"expression":null,"filterable":true,"groupby":false,"id":793,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"FLOAT","type_generic":0,"verbose_name":null,"warning_markdown":null},"datasourceWarning":false,"expressionType":"SIMPLE","hasCustomLabel":false,"label":"AVG(y)","optionName":"metric_n14797p4yx_1yaq6favkyf","sqlExpression":null},{"aggregate":"AVG","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"z","description":null,"expression":null,"filterable":true,"groupby":false,"id":794,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"FLOAT","type_generic":0,"verbose_name":null,"warning_markdown":null},"datasourceWarning":false,"expressionType":"SIMPLE","hasCustomLabel":false,"label":"AVG(z)","optionName":"metric_lw1vtm2ab9_chfv4ocx5g8","sqlExpression":null}],"groupby":["object"],"adhoc_filters":[{"clause":"WHERE","comparator":"No
+  filter","datasourceWarning":false,"expressionType":"SIMPLE","filterOptionName":"filter_7a7ky5oe75g_6imahu3y5qm","isExtra":false,"isNew":false,"operator":"TEMPORAL_RANGE","sqlExpression":null,"subject":"time"}],"row_limit":5000,"truncate_metric":true,"show_empty_columns":true,"comparison_type":"values","annotation_layers":[{"annotationType":"EVENT","color":null,"descriptionColumns":["object","type"],"hideLine":false,"intervalEndColumn":"","name":"events","opacity":"","overrides":{"time_range":null},"show":false,"showLabel":false,"showMarkers":false,"sourceType":"table","style":"solid","timeColumn":"time","titleColumn":"type","value":199,"width":1},{"name":"segments","annotationType":"INTERVAL","sourceType":"table","color":null,"opacity":"","style":"solid","width":1,"showMarkers":false,"hideLine":false,"overrides":{"time_range":null},"show":true,"showLabel":false,"titleColumn":"concept","descriptionColumns":["object","concept"],"timeColumn":"start","intervalEndColumn":"end","value":200}],"forecastEnabled":false,"forecastPeriods":10,"forecastInterval":0.8,"x_axis_title_margin":15,"y_axis_title_margin":15,"y_axis_title_position":"Left","sort_series_type":"sum","color_scheme":"blueToGreen","time_shift_color":true,"seriesType":"line","only_total":true,"opacity":0.2,"markerSize":6,"show_legend":true,"legendType":"scroll","legendOrientation":"top","x_axis_time_format":"smart_date","rich_tooltip":true,"showTooltipTotal":true,"showTooltipPercentage":true,"tooltipTimeFormat":"smart_date","y_axis_format":"SMART_NUMBER","truncateXAxis":true,"y_axis_bounds":[null,null],"extra_form_data":{},"dashboards":[12],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"}'
+cache_timeout: null
+uuid: 77b89150-c063-4c7e-b8c9-75b7a002dd6e
+version: 1.0.0
+dataset_uuid: ed66a423-9bcc-4127-aa6a-ecc78af22a3e
diff --git a/test/asset_export_samples/metadata.yaml b/test/asset_export_samples/metadata.yaml
new file mode 100644
index 0000000..8c7312d
--- /dev/null
+++ b/test/asset_export_samples/metadata.yaml
@@ -0,0 +1,3 @@
+version: 1.0.0
+type: Dashboard
+timestamp: '2025-02-04T15:45:31.029163+00:00'
diff --git a/test/asset_export_samples/query_context_count_ts.yaml b/test/asset_export_samples/query_context_count_ts.yaml
new file mode 100644
index 0000000..f4514fe
--- /dev/null
+++ b/test/asset_export_samples/query_context_count_ts.yaml
@@ -0,0 +1,203 @@
+datasource:
+  id: 26
+  type: table
+force: false
+form_data:
+  adhoc_filters:
+  - clause: WHERE
+    comparator: No  filter
+    datasourceWarning: false
+    expressionType: SIMPLE
+    filterOptionName: filter_h96362s5uia_e7n5judrk97
+    isExtra: false
+    isNew: false
+    operator: TEMPORAL_RANGE
+    sqlExpression: null
+    subject: time
+  - clause: WHERE
+    comparator: M
+    datasourceWarning: false
+    expressionType: SIMPLE
+    filterOptionName: filter_dyuk62snqcb_jjbnuc6e7f
+    isExtra: false
+    isNew: false
+    operator: ==
+    operatorId: EQUALS
+    sqlExpression: null
+    subject: kind
+  annotation_layers: []
+  color_scheme: supersetColors
+  comparison_type: values
+  dashboards:
+  - 12
+  datasource: 26__table
+  extra_form_data: {}
+  force: false
+  forecastInterval: 0.8
+  forecastPeriods: 10
+  groupby:
+  - object
+  - type
+  legendOrientation: top
+  legendType: scroll
+  markerSize: 6
+  metrics:
+  - aggregate: COUNT
+    column:
+      advanced_data_type: null
+      certification_details: null
+      certified_by: null
+      column_name: time
+      description: null
+      expression: null
+      filterable: true
+      groupby: true
+      id: 788
+      is_certified: false
+      is_dttm: true
+      python_date_format: null
+      type: DATETIME
+      type_generic: 2
+      verbose_name: null
+      warning_markdown: null
+    datasourceWarning: false
+    expressionType: SIMPLE
+    hasCustomLabel: false
+    label: COUNT(time)
+    optionName: metric_okswlkr3i48_qso3022kmz
+    sqlExpression: null
+  only_total: true
+  opacity: 0.2
+  order_desc: true
+  result_format: json
+  result_type: full
+  rich_tooltip: true
+  row_limit: 10000
+  seriesType: line
+  showTooltipPercentage: true
+  showTooltipTotal: true
+  show_empty_columns: true
+  show_legend: true
+  sort_series_type: sum
+  time_grain_sqla: PT1M
+  time_shift_color: true
+  tooltipTimeFormat: smart_date
+  truncateXAxis: true
+  truncate_metric: true
+  viz_type: echarts_timeseries_line
+  x_axis: time
+  x_axis_sort_asc: true
+  x_axis_sort_series: name
+  x_axis_sort_series_ascending: true
+  x_axis_time_format: smart_date
+  x_axis_title_margin: 15
+  y_axis_bounds:
+  - null
+  - null
+  y_axis_format: SMART_NUMBER
+  y_axis_title_margin: 15
+  y_axis_title_position: Left
+queries:
+- annotation_layers: []
+  applied_time_extras: {}
+  columns:
+  - columnType: BASE_AXIS
+    expressionType: SQL
+    label: time
+    sqlExpression: time
+    timeGrain: PT1M
+  - object
+  - type
+  custom_form_data: {}
+  custom_params: {}
+  extras:
+    having: ''
+    time_grain_sqla: PT1M
+    where: ''
+  filters:
+  - col: time
+    op: TEMPORAL_RANGE
+    val: No filter
+  - col: kind
+    op: ==
+    val: M
+  metrics:
+  - aggregate: COUNT
+    column:
+      advanced_data_type: null
+      certification_details: null
+      certified_by: null
+      column_name: time
+      description: null
+      expression: null
+      filterable: true
+      groupby: true
+      id: 788
+      is_certified: false
+      is_dttm: true
+      python_date_format: null
+      type: DATETIME
+      type_generic: 2
+      verbose_name: null
+      warning_markdown: null
+    datasourceWarning: false
+    expressionType: SIMPLE
+    hasCustomLabel: false
+    label: COUNT(time)
+    optionName: metric_okswlkr3i48_qso3022kmz
+    sqlExpression: null
+  order_desc: true
+  orderby:
+  - - aggregate: COUNT
+      column:
+        advanced_data_type: null
+        certification_details: null
+        certified_by: null
+        column_name: time
+        description: null
+        expression: null
+        filterable: true
+        groupby: true
+        id: 788
+        is_certified: false
+        is_dttm: true
+        python_date_format: null
+        type: DATETIME
+        type_generic: 2
+        verbose_name: null
+        warning_markdown: null
+      datasourceWarning: false
+      expressionType: SIMPLE
+      hasCustomLabel: false
+      label: COUNT(time)
+      optionName: metric_okswlkr3i48_qso3022kmz
+      sqlExpression: null
+    - false
+  post_processing:
+  - operation: pivot
+    options:
+      aggregates:
+        COUNT(time):
+          operator: mean
+      columns:
+      - object
+      - type
+      drop_missing_columns: false
+      index:
+      - time
+  - operation: rename
+    options:
+      columns:
+        COUNT(time): null
+      inplace: true
+      level: 0
+  - operation: flatten
+  row_limit: 10000
+  series_columns:
+  - object
+  - type
+  series_limit: 0
+  time_offsets: []
+  url_params: {}
+result_format: json
+result_type: full
\ No newline at end of file
diff --git a/test/asset_export_samples/query_context_pie.yaml b/test/asset_export_samples/query_context_pie.yaml
new file mode 100644
index 0000000..63d3d28
--- /dev/null
+++ b/test/asset_export_samples/query_context_pie.yaml
@@ -0,0 +1,131 @@
+datasource:
+  id: 26
+  type: table
+force: false
+form_data:
+  adhoc_filters:
+  - clause: WHERE
+    comparator: No  filter
+    expressionType: SIMPLE
+    operator: TEMPORAL_RANGE
+    subject: time
+  color_scheme: supersetColors
+  dashboards:
+  - 12
+  datasource: 26__table
+  date_format: smart_date
+  extra_form_data: {}
+  force: false
+  groupby:
+  - object
+  innerRadius: 30
+  label_type: key
+  labels_outside: true
+  legendOrientation: top
+  legendType: scroll
+  metric:
+    aggregate: COUNT
+    column:
+      advanced_data_type: null
+      certification_details: null
+      certified_by: null
+      column_name: object
+      description: null
+      expression: null
+      filterable: true
+      groupby: true
+      id: 770
+      is_certified: false
+      is_dttm: false
+      python_date_format: null
+      type: VARCHAR
+      type_generic: 1
+      verbose_name: null
+      warning_markdown: null
+    datasourceWarning: false
+    expressionType: SIMPLE
+    hasCustomLabel: false
+    label: COUNT(object)
+    optionName: metric_drbk8s9c927_9mrsq033mll
+    sqlExpression: null
+  number_format: SMART_NUMBER
+  outerRadius: 70
+  result_format: json
+  result_type: full
+  row_limit: 100
+  show_labels: true
+  show_labels_threshold: 5
+  show_legend: true
+  sort_by_metric: true
+  viz_type: pie
+queries:
+- annotation_layers: []
+  applied_time_extras: {}
+  columns:
+  - object
+  custom_form_data: {}
+  custom_params: {}
+  extras:
+    having: ''
+    where: ''
+  filters:
+  - col: time
+    op: TEMPORAL_RANGE
+    val: No filter
+  metrics:
+  - aggregate: COUNT
+    column:
+      advanced_data_type: null
+      certification_details: null
+      certified_by: null
+      column_name: object
+      description: null
+      expression: null
+      filterable: true
+      groupby: true
+      id: 770
+      is_certified: false
+      is_dttm: false
+      python_date_format: null
+      type: VARCHAR
+      type_generic: 1
+      verbose_name: null
+      warning_markdown: null
+    datasourceWarning: false
+    expressionType: SIMPLE
+    hasCustomLabel: false
+    label: COUNT(object)
+    optionName: metric_drbk8s9c927_9mrsq033mll
+    sqlExpression: null
+  order_desc: true
+  orderby:
+  - - aggregate: COUNT
+      column:
+        advanced_data_type: null
+        certification_details: null
+        certified_by: null
+        column_name: object
+        description: null
+        expression: null
+        filterable: true
+        groupby: true
+        id: 770
+        is_certified: false
+        is_dttm: false
+        python_date_format: null
+        type: VARCHAR
+        type_generic: 1
+        verbose_name: null
+        warning_markdown: null
+      datasourceWarning: false
+      expressionType: SIMPLE
+      hasCustomLabel: false
+      label: COUNT(object)
+      optionName: metric_drbk8s9c927_9mrsq033mll
+      sqlExpression: null
+    - false
+  row_limit: 100
+  series_limit: 0
+  url_params: {}
+result_format: json
+result_type: full
diff --git a/test/asset_export_samples/query_context_ts.yaml b/test/asset_export_samples/query_context_ts.yaml
new file mode 100644
index 0000000..526dbe4
--- /dev/null
+++ b/test/asset_export_samples/query_context_ts.yaml
@@ -0,0 +1,197 @@
+datasource:
+  id: 26
+  type: table
+force: false
+form_data:
+  adhoc_filters:
+  - clause: WHERE
+    comparator: No filter
+    datasourceWarning: false
+    expressionType: SIMPLE
+    filterOptionName: filter_tqzpewcfw7_uvcvr7iuqpa
+    isExtra: false
+    isNew: false
+    operator: TEMPORAL_RANGE
+    sqlExpression: null
+    subject: time
+  - clause: WHERE
+    comparator: E
+    datasourceWarning: false
+    expressionType: SIMPLE
+    filterOptionName: filter_5av1palfie2_44zwtwhl163
+    isExtra: false
+    isNew: false
+    operator: ==
+    operatorId: EQUALS
+    sqlExpression: null
+    subject: kind
+  annotation_layers: []
+  color_scheme: supersetColors
+  comparison_type: values
+  dashboards:
+  - 12
+  datasource: 26__table
+  extra_form_data: {}
+  force: false
+  forecastInterval: 0.8
+  forecastPeriods: 10
+  groupby:
+  - type
+  legendOrientation: top
+  legendType: scroll
+  metrics:
+  - aggregate: COUNT
+    column:
+      advanced_data_type: null
+      certification_details: null
+      certified_by: null
+      column_name: type
+      description: null
+      expression: null
+      filterable: true
+      groupby: true
+      id: 772
+      is_certified: false
+      is_dttm: false
+      python_date_format: null
+      type: VARCHAR
+      type_generic: 1
+      verbose_name: null
+      warning_markdown: null
+    datasourceWarning: false
+    expressionType: SIMPLE
+    hasCustomLabel: false
+    label: COUNT(type)
+    optionName: metric_ixu59vrx32j_imygsjnt0rj
+    sqlExpression: null
+  only_total: true
+  order_desc: true
+  orientation: vertical
+  result_format: json
+  result_type: full
+  rich_tooltip: true
+  row_limit: 10000
+  showTooltipPercentage: true
+  showTooltipTotal: true
+  show_empty_columns: true
+  show_legend: true
+  sort_series_type: sum
+  time_grain_sqla: P1D
+  time_shift_color: true
+  tooltipTimeFormat: smart_date
+  truncateXAxis: true
+  truncate_metric: true
+  viz_type: echarts_timeseries_bar
+  x_axis: object
+  x_axis_sort_asc: true
+  x_axis_sort_series: name
+  x_axis_sort_series_ascending: true
+  x_axis_time_format: smart_date
+  x_axis_title_margin: 15
+  y_axis_bounds:
+  - null
+  - null
+  y_axis_format: SMART_NUMBER
+  y_axis_title_margin: 15
+  y_axis_title_position: Left
+queries:
+- annotation_layers: []
+  applied_time_extras: {}
+  columns:
+  - columnType: BASE_AXIS
+    expressionType: SQL
+    label: object
+    sqlExpression: object
+    timeGrain: P1D
+  - type
+  custom_form_data: {}
+  custom_params: {}
+  extras:
+    having: ''
+    time_grain_sqla: P1D
+    where: ''
+  filters:
+  - col: time
+    op: TEMPORAL_RANGE
+    val: No filter
+  - col: kind
+    op: ==
+    val: E
+  metrics:
+  - aggregate: COUNT
+    column:
+      advanced_data_type: null
+      certification_details: null
+      certified_by: null
+      column_name: type
+      description: null
+      expression: null
+      filterable: true
+      groupby: true
+      id: 772
+      is_certified: false
+      is_dttm: false
+      python_date_format: null
+      type: VARCHAR
+      type_generic: 1
+      verbose_name: null
+      warning_markdown: null
+    datasourceWarning: false
+    expressionType: SIMPLE
+    hasCustomLabel: false
+    label: COUNT(type)
+    optionName: metric_ixu59vrx32j_imygsjnt0rj
+    sqlExpression: null
+  order_desc: true
+  orderby:
+  - - aggregate: COUNT
+      column:
+        advanced_data_type: null
+        certification_details: null
+        certified_by: null
+        column_name: type
+        description: null
+        expression: null
+        filterable: true
+        groupby: true
+        id: 772
+        is_certified: false
+        is_dttm: false
+        python_date_format: null
+        type: VARCHAR
+        type_generic: 1
+        verbose_name: null
+        warning_markdown: null
+      datasourceWarning: false
+      expressionType: SIMPLE
+      hasCustomLabel: false
+      label: COUNT(type)
+      optionName: metric_ixu59vrx32j_imygsjnt0rj
+      sqlExpression: null
+    - false
+  post_processing:
+  - operation: pivot
+    options:
+      aggregates:
+        COUNT(type):
+          operator: mean
+      columns:
+      - type
+      drop_missing_columns: false
+      index:
+      - object
+  - operation: rename
+    options:
+      columns:
+        COUNT(type): null
+      inplace: true
+      level: 0
+  - operation: flatten
+  row_limit: 10000
+  series_columns:
+  - type
+  series_limit: 0
+  time_offsets: []
+  url_params: {}
+result_format: json
+result_type: full
\ No newline at end of file
diff --git a/test/asset_export_samples/query_context_ts_bar.yaml b/test/asset_export_samples/query_context_ts_bar.yaml
new file mode 100644
index 0000000..d00121d
--- /dev/null
+++ b/test/asset_export_samples/query_context_ts_bar.yaml
@@ -0,0 +1,197 @@
+datasource:
+  id: 26
+  type: table
+force: false
+form_data:
+  adhoc_filters:
+  - clause: WHERE
+    comparator: No filter
+    datasourceWarning: false
+    expressionType: SIMPLE
+    filterOptionName: filter_tqzpewcfw7_uvcvr7iuqpa
+    isExtra: false
+    isNew: false
+    operator: TEMPORAL_RANGE
+    sqlExpression: null
+    subject: time
+  - clause: WHERE
+    comparator: E
+    datasourceWarning: false
+    expressionType: SIMPLE
+    filterOptionName: filter_5av1palfie2_44zwtwhl163
+    isExtra: false
+    isNew: false
+    operator: ==
+    operatorId: EQUALS
+    sqlExpression: null
+    subject: kind
+  annotation_layers: []
+  color_scheme: supersetColors
+  comparison_type: values
+  dashboards:
+  - 12
+  datasource: 26__table
+  extra_form_data: {}
+  force: false
+  forecastInterval: 0.8
+  forecastPeriods: 10
+  groupby:
+  - type
+  legendOrientation: top
+  legendType: scroll
+  metrics:
+  - aggregate: COUNT
+    column:
+      advanced_data_type: null
+      certification_details: null
+      certified_by: null
+      column_name: type
+      description: null
+      expression: null
+      filterable: true
+      groupby: true
+      id: 772
+      is_certified: false
+      is_dttm: false
+      python_date_format: null
+      type: VARCHAR
+      type_generic: 1
+      verbose_name: null
+      warning_markdown: null
+    datasourceWarning: false
+    expressionType: SIMPLE
+    hasCustomLabel: false
+    label: COUNT(type)
+    optionName: metric_ixu59vrx32j_imygsjnt0rj
+    sqlExpression: null
+  only_total: true
+  order_desc: true
+  orientation: vertical
+  result_format: json
+  result_type: full
+  rich_tooltip: true
+  row_limit: 10000
+  showTooltipPercentage: true
+  showTooltipTotal: true
+  show_empty_columns: true
+  show_legend: true
+  sort_series_type: sum
+  time_grain_sqla: P1D
+  time_shift_color: true
+  tooltipTimeFormat: smart_date
+  truncateXAxis: true
+  truncate_metric: true
+  viz_type: echarts_timeseries_bar
+  x_axis: object
+  x_axis_sort_asc: true
+  x_axis_sort_series: name
+  x_axis_sort_series_ascending: true
+  x_axis_time_format: smart_date
+  x_axis_title_margin: 15
+  y_axis_bounds:
+  - null
+  - null
+  y_axis_format: SMART_NUMBER
+  y_axis_title_margin: 15
+  y_axis_title_position: Left
+queries:
+- annotation_layers: []
+  applied_time_extras: {}
+  columns:
+  - columnType: BASE_AXIS
+    expressionType: SQL
+    label: object
+    sqlExpression: object
+    timeGrain: P1D
+  - type
+  custom_form_data: {}
+  custom_params: {}
+  extras:
+    having: ''
+    time_grain_sqla: P1D
+    where: ''
+  filters:
+  - col: time
+    op: TEMPORAL_RANGE
+    val: No  filter
+  - col: kind
+    op: ==
+    val: E
+  metrics:
+  - aggregate: COUNT
+    column:
+      advanced_data_type: null
+      certification_details: null
+      certified_by: null
+      column_name: type
+      description: null
+      expression: null
+      filterable: true
+      groupby: true
+      id: 772
+      is_certified: false
+      is_dttm: false
+      python_date_format: null
+      type: VARCHAR
+      type_generic: 1
+      verbose_name: null
+      warning_markdown: null
+    datasourceWarning: false
+    expressionType: SIMPLE
+    hasCustomLabel: false
+    label: COUNT(type)
+    optionName: metric_ixu59vrx32j_imygsjnt0rj
+    sqlExpression: null
+  order_desc: true
+  orderby:
+  - - aggregate: COUNT
+      column:
+        advanced_data_type: null
+        certification_details: null
+        certified_by: null
+        column_name: type
+        description: null
+        expression: null
+        filterable: true
+        groupby: true
+        id: 772
+        is_certified: false
+        is_dttm: false
+        python_date_format: null
+        type: VARCHAR
+        type_generic: 1
+        verbose_name: null
+        warning_markdown: null
+      datasourceWarning: false
+      expressionType: SIMPLE
+      hasCustomLabel: false
+      label: COUNT(type)
+      optionName: metric_ixu59vrx32j_imygsjnt0rj
+      sqlExpression: null
+    - false
+  post_processing:
+  - operation: pivot
+    options:
+      aggregates:
+        COUNT(type):
+          operator: mean
+      columns:
+      - type
+      drop_missing_columns: false
+      index:
+      - object
+  - operation: rename
+    options:
+      columns:
+        COUNT(type): null
+      inplace: true
+      level: 0
+  - operation: flatten
+  row_limit: 10000
+  series_columns:
+  - type
+  series_limit: 0
+  time_offsets: []
+  url_params: {}
+result_format: json
+result_type: full
\ No newline at end of file
-- 
GitLab