grafanalib
grafanalib copied to clipboard
Dashboard.to_json_data method does not return a valid json data.
Hi there~
I am trying to use Grafanalib
to generate Grafana dashboards programmatically. It works great, except that I need to write a to_json
function myself, since the Dashboard.to_json_data method
does not return a valid json data.
- System OS: MacOS Monterey
- Python Version: 3.8.10
- Grafanalib Version: 0.6.3
Below is the Python codes I wrote. If I don't use to_json
function to further process the dashboard.to_json_data()
, the json contains some Python objects which cannot be handled by standard Python json library.
Your feedback is appreciated, and if needed I'd like to contribute to this project. Thanks very much~
import json
from typing import List, Optional, Union
from grafanalib.core import Dashboard, GridPos, Panel, Target, TimeSeries
def gen_panel(title: str, metric: str, labels: dict) -> Panel:
expr = metric + \
'{' + ', '.join([f'{k}="{v}"' for k, v in labels.items()]) + '}'
return TimeSeries(
title=title,
dataSource=dict(),
targets=[
Target(
datasource='prometheus',
expr=expr,
),
],
gridPos=GridPos(h=9, w=12, x=0, y=0),
)
def gen_dashboard(
title: str,
panels: List[Panel],
description: Optional[str] = None,
tags: Optional[List[str]] = None,
timezone: Optional[str] = None
) -> Dashboard:
if description is None:
description = ""
if tags is None:
tags = []
if timezone is None:
timezone = ""
return Dashboard(
title=title,
description=description,
tags=tags,
timezone=timezone,
panels=panels,
).auto_panel_ids()
def _to_json(data: Union[dict, list], result: Union[dict, list]) -> None:
if isinstance(data, dict):
assert isinstance(result, dict)
for k, v in data.items():
if hasattr(v, "to_json_data"):
v = v.to_json_data()
if isinstance(v, dict):
result[k] = dict()
_to_json(v, result[k])
elif isinstance(v, list):
result[k] = list()
_to_json(v, result[k])
else:
result[k] = v
elif isinstance(data, list):
assert isinstance(result, list)
for v in data:
if hasattr(v, "to_json_data"):
v = v.to_json_data()
if isinstance(v, dict):
result.append(dict())
_to_json(v, result[-1])
elif isinstance(v, list):
result.append(list())
_to_json(v, result[-1])
else:
result.append(v)
else:
raise TypeError("data should be dict or list!")
def to_json(dashboard: Dashboard) -> str:
data = dashboard.to_json_data()
result = dict() # type: ignore
_to_json(data, result)
return json.dumps(result)
if __name__ == "__main__":
labels = {
"env": "Env.prod",
"job": "baz",
"ver": "001",
"sub_job": "zoo",
}
panels = [
gen_panel(
title="eg_foo",
metric="foo",
labels=labels,
),
gen_panel(
title="eg_bar",
metric="bar",
labels=labels,
),
]
dashboard = gen_dashboard(
title="dashboard_example",
panels=panels,
)
print(to_json(dashboard))