Grafana Foundation SDK – Python
A set of tools, types and builder libraries for building and manipulating Grafana objects in Python.
Installing
python3 -m pip install 'grafana_foundation_sdk==v0.0.21'
Example usage
Building a dashboard
from grafana_foundation_sdk.builders.dashboard import Dashboard, Row
from grafana_foundation_sdk.builders.prometheus import Dataquery as PrometheusQuery
from grafana_foundation_sdk.builders.timeseries import Panel as Timeseries
from grafana_foundation_sdk.cog.encoder import JSONEncoder
from grafana_foundation_sdk.models.common import TimeZoneBrowser
def build_dashboard() -> Dashboard:
builder = (
Dashboard("[TEST] Node Exporter / Raspberry")
.uid("test-dashboard-raspberry")
.tags(["generated", "raspberrypi-node-integration"])
.refresh("1m")
.time("now-30m", "now")
.timezone(TimeZoneBrowser)
.with_row(Row("Overview"))
.with_panel(
Timeseries()
.title("Network Received")
.unit("bps")
.min_val(0)
.with_target(
PrometheusQuery()
.expr('rate(node_network_receive_bytes_total{job="integrations/raspberrypi-node", device!="lo"}[$__rate_interval]) * 8')
.legend_format("{{ device }}")
)
)
)
return builder
if __name__ == '__main__':
dashboard = build_dashboard().build()
encoder = JSONEncoder(sort_keys=True, indent=2)
print(encoder.encode(dashboard))
Unmarshaling a dashboard
import json
from grafana_foundation_sdk.cog.plugins import register_default_plugins
from grafana_foundation_sdk.models.dashboard import Dashboard as DashboardModel
if __name__ == '__main__':
# Required to correctly unmarshal panels and dataqueries
register_default_plugins()
with open("dashboard.json", "r") as f:
decoded_dashboard = DashboardModel.from_json(json.load(f))
print(decoded_dashboard)
Defining a custom query type
While the SDK ships with support for all core datasources and their query types, it can be extended for private/third-party plugins.
To do so, define a type and a builder for the custom query:
# src/customquery.py
from typing import Any, Optional, Self
from grafana_foundation_sdk.cog import variants as cogvariants
from grafana_foundation_sdk.cog import runtime as cogruntime
from grafana_foundation_sdk.cog import builder
class CustomQuery(cogvariants.Dataquery):
# ref_id and hide are expected on all queries
ref_id: Optional[str]
hide: Optional[bool]
# query is specific to the CustomQuery type
query: str
def __init__(self, query: str, ref_id: Optional[str] = None, hide: Optional[bool] = None):
self.query = query
self.ref_id = ref_id
self.hide = hide
def to_json(self) -> dict[str, object]:
payload: dict[str, object] = {
"query": self.query,
}
if self.ref_id is not None:
payload["refId"] = self.ref_id
if self.hide is not None:
payload["hide"] = self.hide
return payload
@classmethod
def from_json(cls, data: dict[str, Any]) -> Self:
args: dict[str, Any] = {}
if "query" in data:
args["query"] = data["query"]
if "refId" in data:
args["ref_id"] = data["refId"]
if "hide" in data:
args["hide"] = data["hide"]
return cls(**args)
def custom_query_variant_config() -> cogruntime.DataqueryConfig:
return cogruntime.DataqueryConfig(
# datasource plugin ID
identifier="custom-query",
from_json_hook=CustomQuery.from_json,
)
class CustomQueryBuilder(builder.Builder[CustomQuery]):
_internal: CustomQuery
def __init__(self, query: str):
self._internal = CustomQuery(query=query)
def build(self) -> CustomQuery:
return self._internal
def ref_id(self, ref_id: str) -> Self:
self._internal.ref_id = ref_id
return self
def hide(self, hide: bool) -> Self:
self._internal.hide = hide
return self
Register the type with cog, and use it as usual to build a dashboard:
from grafana_foundation_sdk.builders.dashboard import Dashboard, Row
from grafana_foundation_sdk.builders.timeseries import Panel as Timeseries
from grafana_foundation_sdk.cog.encoder import JSONEncoder
from grafana_foundation_sdk.cog.plugins import register_default_plugins
from grafana_foundation_sdk.cog.runtime import register_dataquery_variant
from src.customquery import custom_query_variant_config, CustomQueryBuilder
if __name__ == '__main__':
# Required to correctly unmarshal panels and dataqueries
register_default_plugins()
# This lets cog know about the newly created query type and how to unmarshal it.
register_dataquery_variant(custom_query_variant_config())
dashboard = (
Dashboard("Custom query type")
.uid("test-custom-query")
.refresh("1m")
.time("now-30m", "now")
.with_row(Row("Overview"))
.with_panel(
Timeseries()
.title("Sample panel")
.with_target(
CustomQueryBuilder("query here")
)
)
).build()
print(JSONEncoder(sort_keys=True, indent=2).encode(dashboard))
Defining a custom panel type
While the SDK ships with support for all core panels, it can be extended for private/third-party plugins.
To do so, define a type and a builder for the custom panel's options:
# src/custompanel.py
from typing import Any, Self
from grafana_foundation_sdk.cog import builder
from grafana_foundation_sdk.cog import runtime as cogruntime
from grafana_foundation_sdk.builders.dashboard import Panel as PanelBuilder
from grafana_foundation_sdk.models import dashboard
class CustomPanelOptions:
make_beautiful: bool
def __init__(self, make_beautiful: bool = False):
self.make_beautiful = make_beautiful
def to_json(self) -> dict[str, object]:
return {
"makeBeautiful": self.make_beautiful,
}
@classmethod
def from_json(cls, data: dict[str, Any]) -> Self:
args: dict[str, Any] = {}
if "makeBeautiful" in data:
args["make_beautiful"] = data["makeBeautiful"]
return cls(**args)
def custom_panel_variant_config() -> cogruntime.PanelCfgConfig:
return cogruntime.PanelCfgConfig(
# plugin ID
identifier="custom-panel",
options_from_json_hook=CustomPanelOptions.from_json,
)
class CustomPanelBuilder(PanelBuilder, builder.Builder[dashboard.Panel]):
def __init__(self):
super().__init__()
# plugin ID
self._internal.type_val = "custom-panel"
def make_beautiful(self) -> Self:
if self._internal.options is None:
self._internal.options = CustomPanelOptions()
assert isinstance(self._internal.options, CustomPanelOptions)
self._internal.options.make_beautiful = True
return self
Register the type with cog, and use it as usual to build a dashboard:
from grafana_foundation_sdk.builders.dashboard import Dashboard, Row
from grafana_foundation_sdk.cog.encoder import JSONEncoder
from grafana_foundation_sdk.cog.plugins import register_default_plugins
from grafana_foundation_sdk.cog.runtime import register_panelcfg_variant
from src.custompanel import custom_panel_variant_config, CustomPanelBuilder
if __name__ == '__main__':
# Required to correctly unmarshal panels and dataqueries
register_default_plugins()
# This lets cog know about the newly created panel type and how to unmarshal it.
register_panelcfg_variant(custom_panel_variant_config())
dashboard = (
Dashboard("Custom panel type")
.uid("test-custom-panel")
.refresh("1m")
.time("now-30m", "now")
.with_row(Row("Overview"))
.with_panel(
CustomPanelBuilder()
.title("Sample panel")
.make_beautiful()
)
).build()
print(JSONEncoder(sort_keys=True, indent=2).encode(dashboard))
Maturity
The code in this repository should be considered as "public preview". While it is used by Grafana Labs in production, it still is under active development.
License
Metadata
Release files for grafana-foundation-sdk 0.0.21
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| grafana_foundation_sdk-0.0.21.tar.gz | 770.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| grafana_foundation_sdk-0.0.21-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.3 MB
Release files / grafana_foundation_sdk-0.0.21.tar.gz
| Download URL | grafana_foundation_sdk-0.0.21.tar.gz |
|---|---|
| Size | 770.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cfacca0d4cc1941a522d11e20b5e701c802503d5b6d5342fb332d9acd9a30141
|
|
BLAKE2b-256 checksum How to use checksums |
198b7bab80709a86cf199afc7fefc9c3247e5cfecd5186cb30957202c89e0805
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / grafana_foundation_sdk-0.0.21-py3-none-any.whl
| Download URL | grafana_foundation_sdk-0.0.21-py3-none-any.whl |
|---|---|
| Size | 526.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
838b8cf35574d6bb2c3173b068e9461df4dc891aecd0f6674fefe244c2eba738
|
|
BLAKE2b-256 checksum How to use checksums |
7068edd3203201d6f1602cc00ee633905b2e6fb6d5b13a921b2554e700abcaad
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|