Grafana Panels

Extract the list of panel titles from a Grafana dashboard JSON. Each panel title is located at spec.elements.panel-N.spec.title, where panel-N uses a numeric suffix (for example, panel-1 or panel-3).

import json
import re
from typing import Dict, List, Optional
import sys

Command-line argument: path to Grafana dashboard JSON file

if len(sys.argv) != 2:
    print("Usage: python grafana_panels.py <dashboard_json_file>")
    sys.exit(1)

grafana_json_path = sys.argv[1]

The OutputFile class opens a file whose name is provided to its constructor. Its print method behaves like the built-in print but also writes the output to that file. The class includes a close method that closes the file.

class OutputFile:
    def __init__(self, filename: str):
        self.file = open(filename, "w", encoding="utf-8")

    def print(self, *args, **kwargs):
        # Print to stdout
        print(*args, **kwargs)
        # Print to file
        print(*args, **kwargs, file=self.file)

    def close(self):
        self.file.close()

out = OutputFile(grafana_json_path + ".md")

Extracts panel titles located at spec -> elements -> "panel-N" -> spec -> title.

def process_spec(spec: Dict):
    title: Optional[str] = spec.get("title")
    if not isinstance(title, str):
        return

    if len(title) == 0:
        title = "."
    out.print(f"### {title}\n")
    data = spec.get("data", {})
    data_spec = data.get("spec", {})
    queries = data_spec.get("queries", [])
    for q in queries:
        query = q.get("spec", {}).get("query", {})
        expr = query.get("spec", {}).get("expr")
        if expr != None:
            out.print(f"```\n{expr}\n```\n")

def process_json(dashboard: Dict):
    elements = dashboard.get("spec", {}).get("elements", {})
    if not isinstance(elements, dict):
        return

    for key, panel_obj in elements.items():
        if re.match(r"^panel-\d+$", key) and isinstance(panel_obj, dict):
            process_spec(panel_obj.get("spec", {}))

Load a dashboard JSON file and print the titles

with open(grafana_json_path, "r", encoding="utf-8") as f:
    dashboard_json = json.load(f)

titles = process_json(dashboard_json)

out.close()
print("----------------------------")