[release-12.1.1] Tom/foundation sdk docs (#108909)
Actionlint / Lint GitHub Actions files (push) Waiting to run Details
Backend Unit Tests / Detect whether code changed (push) Waiting to run Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (1/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (2/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (3/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (4/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (5/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (6/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (7/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (8/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (1/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (2/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (3/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (4/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (5/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (6/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (7/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (8/8) (push) Blocked by required conditions Details
Backend Unit Tests / All backend unit tests complete (push) Blocked by required conditions Details
Lint Frontend / Detect whether code changed (push) Waiting to run Details
Lint Frontend / Lint (push) Blocked by required conditions Details
Lint Frontend / Typecheck (push) Blocked by required conditions Details
Lint Frontend / Betterer (push) Blocked by required conditions Details
Verify i18n / verify-i18n (push) Waiting to run Details
End-to-end tests / Detect whether code changed (push) Waiting to run Details
End-to-end tests / Build & Package Grafana (push) Blocked by required conditions Details
End-to-end tests / Build E2E test runner (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (--flags="--env dashboardScene=false", e2e/old-arch/dashboards-suite, dashboards-suite (old arch)) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (--flags="--env dashboardScene=false", e2e/old-arch/panels-suite, panels-suite (old arch)) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (--flags="--env dashboardScene=false", e2e/old-arch/smoke-tests-suite, smoke-tests-suite (old arch)) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (--flags="--env dashboardScene=false", e2e/old-arch/various-suite, various-suite (old arch)) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (e2e/dashboards-suite, dashboards-suite) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (e2e/panels-suite, panels-suite) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (e2e/smoke-tests-suite, smoke-tests-suite) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (e2e/various-suite, various-suite) (push) Blocked by required conditions Details
End-to-end tests / A11y test (push) Blocked by required conditions Details
End-to-end tests / All E2E tests complete (push) Blocked by required conditions Details
Frontend tests / Detect whether code changed (push) Waiting to run Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (1) (push) Blocked by required conditions Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (2) (push) Blocked by required conditions Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (3) (push) Blocked by required conditions Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (4) (push) Blocked by required conditions Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (5) (push) Blocked by required conditions Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (6) (push) Blocked by required conditions Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (7) (push) Blocked by required conditions Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (8) (push) Blocked by required conditions Details
Frontend tests / All frontend unit tests complete (push) Blocked by required conditions Details
Integration Tests / Sqlite (${{ matrix.shard }}) (1/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (2/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (3/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (4/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (5/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (6/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (7/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (8/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (1/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (2/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (3/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (4/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (5/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (6/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (7/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (8/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (1/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (2/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (3/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (4/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (5/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (6/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (7/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (8/8) (push) Waiting to run Details
Integration Tests / All backend integration tests complete (push) Blocked by required conditions Details
publish-technical-documentation-release / sync (push) Waiting to run Details
Reject GitHub secrets / reject-gh-secrets (push) Waiting to run Details
Build Release Packages / setup (push) Waiting to run Details
Build Release Packages / Dispatch grafana-enterprise build (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:darwin/amd64, darwin-amd64) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:darwin/arm64, darwin-arm64) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:linux/amd64,deb:grafana:linux/amd64,rpm:grafana:linux/amd64,docker:grafana:linux/amd64,docker:grafana:linux/amd64:ubuntu,npm:grafana,storybook, linux-amd64) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:linux/arm/v6,deb:grafana:linux/arm/v6, linux-armv6) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:linux/arm/v7,deb:grafana:linux/arm/v7,docker:grafana:linux/arm/v7,docker:grafana:linux/arm/v7:ubuntu, linux-armv7) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:linux/arm64,deb:grafana:linux/arm64,rpm:grafana:linux/arm64,docker:grafana:linux/arm64,docker:grafana:linux/arm64:ubuntu, linux-arm64) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:linux/s390x,deb:grafana:linux/s390x,rpm:grafana:linux/s390x,docker:grafana:linux/s390x,docker:grafana:linux/s390x:ubuntu, linux-s390x) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:windows/amd64,zip:grafana:windows/amd64,msi:grafana:windows/amd64, windows-amd64) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:windows/arm64,zip:grafana:windows/arm64, windows-arm64) (push) Blocked by required conditions Details
Build Release Packages / Upload artifacts (push) Blocked by required conditions Details
Shellcheck / Shellcheck scripts (push) Waiting to run Details
Swagger generated code / Verify committed API specs match (push) Waiting to run Details
Dispatch sync to mirror / dispatch-job (push) Waiting to run Details

Co-authored-by: Tom Glenn <289945+tomglenn@users.noreply.github.com>
Co-authored-by: Kim Nylander <104772500+knylander-grafana@users.noreply.github.com>
This commit is contained in:
grafana-delivery-bot[bot] 2025-07-30 14:10:24 +02:00 committed by GitHub
parent 7ff801727c
commit 5d5fa03cf6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 251 additions and 55 deletions

View File

@ -20,87 +20,279 @@ The [Grafana Foundation SDK](https://github.com/grafana/grafana-foundation-sdk)
- **Enhance version control:** Track changes seamlessly using standard version control systems like Git.
- **Automate deployments:** Integrate dashboard provisioning into your CI/CD pipelines for consistent and repeatable setups.
The SDK supports multiple programming languages, including Go, Java, PHP, Python, and TypeScript, allowing you to choose the one that best fits your development environment.
The SDK supports multiple programming languages, including Go, TypeScript, Python, PHP, and Java, so you can choose the one that best fits your development environment.
{{< youtube id="_OKQoABmg0Q" >}}
## Before you begin
Ensure you have the following prerequisites:
- **Programming environment:** Set up for your chosen language (for example, Node.js for TypeScript, Python 3.x for Python).
- **Programming environment:** Set up for your chosen language. For example: Go, Node.js for TypeScript, or Python 3.x for Python.
- **Grafana instance:** A running Grafana instance compatible with the SDK version youre using (refer to the [compatibility matrix](https://github.com/grafana/grafana-foundation-sdk#navigating-the-sdk)).
- **Package manager:** Appropriate for your language (for example, `npm` or `yarn` for JavaScript or TypeScript, `pip` for Python).
- **Package manager:** Appropriate for your language, for example, `npm` or `yarn` for TypeScript or `pip` for Python.
To get started, clone the [intro-to-foundation-sdk repository](https://github.com/grafana/intro-to-foundation-sdk) to access examples and a `docker-compose` stack.
## Install the Grafana Foundation SDK
### TypeScript
For TypeScript, install the SDK package via `npm`:
```bash
npm install @grafana/grafana-foundation-sdk
```
Or use `yarn`:
```bash
yarn add @grafana/grafana-foundation-sdk
```
### Go
For Go, install the SDK package via `go get`:
Select the `go` or `typescript` tab to view instructions to install the SDK.
For other languages, refer to the Grafana Foundation SDK documentation for installation instructions.
{{< code >}}
```go
go get github.com/grafana/grafana-foundation-sdk/go
```
### Python
For Python, install the SDK using `pip`:
```bash
pip install grafana-foundation-sdk
```typescript
npm install @grafana/grafana-foundation-sdk
```
For other languages, refer to the Grafana Foundation SDK documentation for detailed installation instructions.
{{< /code >}}
## Grafana Foundation SDK Overview
Here's a quick overview of how the Grafana Foundation SDK works:
- **Builder pattern:** The SDK uses a chainable builder pattern to let you define dashboards fluently. You start with a `DashboardBuilder`, then add panels, queries, and other components step by step.
- **Strong typing:** Everything in the SDK is strongly typed. This gives you autocompletion in your IDE, catches mistakes early, and helps ensure you're always using valid configuration values.
- **Structured options:** When a configuration get complex (like data reduction or display settings), the SDK uses typed option builders to keep things readable and predictable.
You'll see these concepts in action in the next example. These concepts are explained in more detail afterwards.
## Create a dashboard
The following example demonstrates how you can create a simple dashboard using TypeScript:
The following example demonstrates how you can create a simple dashboard:
```typescript
import { DashboardBuilder, RowBuilder } from '@grafana/grafana-foundation-sdk/dashboard';
import { DataqueryBuilder } from '@grafana/grafana-foundation-sdk/prometheus';
import { PanelBuilder } from '@grafana/grafana-foundation-sdk/timeseries';
const builder = new DashboardBuilder('Sample Dashboard')
.uid('sample-dashboard')
.tags(['example', 'typescript'])
.refresh('1m')
.time({ from: 'now-30m', to: 'now' })
.timezone('browser')
.withRow(new RowBuilder('Overview'))
.withPanel(
new PanelBuilder()
.title('Network Received')
.unit('bps')
.min(0)
.withTarget(
new DataqueryBuilder()
.expr('rate(node_network_receive_bytes_total{job="example-job", device!="lo"}[$__rate_interval]) * 8')
.legendFormat('{{ device }}')
)
);
console.log(JSON.stringify(builder.build(), null, 2));
{{< code >}}
```go
package main
// Import the appropriate Grafana Foundation SDK packages
import (
"encoding/json"
"log"
"github.com/grafana/grafana-foundation-sdk/go/cog"
"github.com/grafana/grafana-foundation-sdk/go/common"
"github.com/grafana/grafana-foundation-sdk/go/dashboard"
"github.com/grafana/grafana-foundation-sdk/go/stat"
"github.com/grafana/grafana-foundation-sdk/go/testdata"
"github.com/grafana/grafana-foundation-sdk/go/timeseries"
)
func main() {
// Define a data source reference for our testdata data source
testdataRef := dashboard.DataSourceRef{
Type: cog.ToPtr("grafana-testdata-datasource"),
Uid: cog.ToPtr("testdata"),
}
// Define our dashboard as strongly typed code
builder := dashboard.NewDashboardBuilder("My Dashboard").
WithPanel(
stat.NewPanelBuilder().
Title("Version").
Datasource(testdataRef).
ReduceOptions(common.NewReduceDataOptionsBuilder().
Calcs([]string{"lastNotNull"}).
Fields("/.*/")).
WithTarget(
testdata.NewDataqueryBuilder().
ScenarioId("csv_content").
CsvContent("version\nv1.2.3"),
),
).
WithPanel(
timeseries.NewPanelBuilder().
Title("Random Time Series").
Datasource(testdataRef).
WithTarget(
testdata.NewDataqueryBuilder().
ScenarioId("random_walk"),
),
)
// Build the dashboard - errors in configuration will be thrown here
dashboard, err := builder.Build()
if err != nil {
log.Fatalf("failed to build dashboard: %v", err)
}
// Output the generated dashboard as JSON
dashboardJson, err := json.MarshalIndent(dashboard, "", " ")
if err != nil {
log.Fatalf("failed to marshal dashboard: %v", err)
}
log.Printf("Dashboard JSON:\n%s", dashboardJson)
}
```
This code defines a dashboard titled “Sample Dashboard” with a single panel displaying data received on the network.
```typescript
// Import the appropriate Grafana Foundation SDK packages
import * as common from '@grafana/grafana-foundation-sdk/common';
import * as dashboard from '@grafana/grafana-foundation-sdk/dashboard';
import * as stat from '@grafana/grafana-foundation-sdk/stat';
import * as testdata from '@grafana/grafana-foundation-sdk/testdata';
import * as timeseries from '@grafana/grafana-foundation-sdk/timeseries';
// Define a data source reference for our testdata data source
const testDataRef: dashboard.DataSourceRef = {
type: 'grafana-testdata-datasource',
uid: 'testdata',
};
// Define our dashboard as strongly typed code
const builder = new dashboard.DashboardBuilder('My Dashboard')
.withPanel(
new stat.PanelBuilder()
.title('Version')
.reduceOptions(new common.ReduceDataOptionsBuilder().calcs(['lastNotNull']).fields('/.*/'))
.datasource(testdataRef)
.withTarget(new testdata.DataqueryBuilder().scenarioId('csv_content').csvContent('version\nv1.2.3'))
)
.withPanel(
new timeseries.PanelBuilder()
.title('Random Time Series')
.datasource(testdataRef)
.withTarget(new testdata.DataqueryBuilder().scenarioId('random_walk'))
);
// Build the dashboard - errors in configuration will be thrown here
const dashboard = builder.build();
// Output the generated dashboard as JSON
console.log(JSON.stringify(dashboard, null, 2));
```
{{< /code >}}
This code defines a dashboard titled “My Dashboard” with a two panels:
- a simple stat panel displaying a version number, and
- a time series panel displaying randomized data from the `testdata` data source `random_walk` scenario.
## Export and use the JSON
The `build()` method generates a JSON representation of your dashboard, which you can:
After you've defined your dashboard as code, build the final dashboard representation using the dashboard builder (typically using the `build()` function depending on language choice) and output the result as a JSON.
With the JSON payload, you can:
- **Manually import:** Paste into Grafanas dashboard import feature.
- **Automate:** Use Grafanas API to programmatically upload the dashboard JSON.
- **Automate:** Use [Grafanas API](../../developers/http_api/) or the [Grafana CLI](../grafana-cli/) to programmatically upload the dashboard JSON.
## Concepts
Now that you've seen how to define a basic dashboard using code, let's take a moment to explain how it all works behind the scenes. The Grafana Foundation SDK is built around a few core concepts that make your dashboards structured, reusable, and strongly typed.
### Builders
The SDK follows a builder pattern, which lets you compose dashboards step-by-step using chained method calls.
Almost every piece of the dashboard, including dashboards, panels, rows, queries, and variables, has its own `Builder` class.
Here are a few you've already seen:
- `DashboardBuilder` - Starts the dashboard definition and sets global configuration settings like title, UID, refresh interval, time range, etc.
- `PanelBuilder` - Creates individual visualizations like time series panels, stat panels, or log panels.
- `DataqueryBuilder` - Defines how a panel fetches data, for example, from Prometheus or the `testdata` plugin.
Builders are chainable, so you can fluently compose dashboards in a readable, structured way:
{{< code >}}
```go
stat.NewPanelBuilder().
Title("Version").
Datasource(testdataRef).
ReduceOptions(common.NewReduceDataOptionsBuilder().
Calcs([]string{"lastNotNull"}).
Fields("/.*/")).
WithTarget(
testdata.NewDataqueryBuilder().
ScenarioId("csv_content").
CsvContent("version\nv1.2.3"),
)
```
```typescript
new stat.PanelBuilder()
.title('Version')
.reduceOptions(new common.ReduceDataOptionsBuilder().calcs(['lastNotNull']).fields('/.*/'))
.datasource(testdataRef)
.withTarget(new testdata.DataqueryBuilder().scenarioId('csv_content').csvContent('version\nv1.2.3'));
```
{{< /code >}}
### Types
The Grafana Foundation SDK uses strong types under the hood to help catch mistakes before you deploy a broken dashboard.
For example:
- When setting a unit, you'll get autocomplete suggestions for valid Grafana units like `"percent"` or `"bps"`.
- When defining a time range, you'll be guided to provide the correct structure, like `from` and `to` values.
- When referencing data sources, you'll use a structured `DataSourceRef` object with defined `type` and `uid` fields.
This helps you:
- Avoid typos or unsupported configuration values
- Get full autocomplete and inline documentation in your IDE
- Write dashboards that are less error-prone and easier to maintain
Strong typing also makes it easier to build reusable patterns and components with confidence, especially in large codebases or teams.
### Options
Most builder methods accept simple values like strings or numbers, but others expect more structured option objects. These are used for things like:
- `ReduceDataOptions` - How to reduce time series data into single values (e.g. last, avg).
- `VizLegendOptions` - Configure how the legend of a panel is displayed.
- `CanvasElementOptions` - Define how the the various components of a Canvas panel should be displayed.
Example using options:
{{< code >}}
```go
stat.NewPanelBuilder().
ReduceOptions(common.NewReduceDataOptionsBuilder().
Calcs([]string{"lastNotNull"}).
Fields("/.*/"))
)
```
```typescript
new stat.PanelBuilder().reduceOptions(new common.ReduceDataOptionsBuilder().calcs(['lastNotNull']).fields('/.*/'));
```
{{< /code >}}
By using option builders, you don't need to manually construct deeply nested configuration objects. Instead, the SDK gives you a typed and guided API that mirrors a dashboards internal structure, making it easier to configure complex options without guesswork or referring back to the JSON schema.
## Explore a real-world example
If you want to explore further and see a more real-world example of using the Grafana Foundation SDK, watch the following walkthrough:
{{< youtube id="ZjWdGVsrCiQ" >}}
In this video, we generate a dashboard from code and deploy it using the Grafana API, covering patterns and practices you'd use in production environments. It also includes a working example of a web service that emits metrics and logs, and shows how to deploy a dashboard alongside it using Docker Compose.
You can find the full source code for this example in the [intro-to-foundation-sdk repository](https://github.com/grafana/intro-to-foundation-sdk/tree/main/generate-and-deploy-example).
## Summary
The Grafana Foundation SDK is designed to make dashboard creation:
- **Composable** through the use of chainable builders
- **Safe** with strong typing and clear APIs
- **Configurable** using structured options for fine control
As you build more advanced dashboards, youll work with additional builders and types to support richer functionality.
The SDK supports not just panels and queries, but also variables, thresholds, field overrides, transformations, and more.
Refer to [the full API reference](https://grafana.github.io/grafana-foundation-sdk/) to explore what's possible.
## Next steps
@ -108,4 +300,4 @@ Now that you understand the basics of using the Grafana Foundation SDK, here are
- **Explore more features:** Check out the [full API reference](https://grafana.github.io/grafana-foundation-sdk/) to learn about advanced dashboard configurations.
- **Version control your dashboards:** Store your dashboard code in a Git repository to track changes over time.
- **Automate dashboard provisioning with CI/CD:** Integrate the SDK into your CI/CD pipeline to deploy dashboards automatically.
- **Automate dashboard provisioning with CI/CD:** [Integrate the SDK into your CI/CD pipeline](./dashboard-automation) to deploy dashboards automatically.

View File

@ -29,6 +29,10 @@ This guide walks through:
By the end, every change to your dashboard code will be automatically created or updated in your Grafana instance without manual intervention.
{{< youtube id="cFnO8kVOaAI" >}}
You can find the full example source code in the [intro-to-foundation-sdk repository](https://github.com/grafana/intro-to-foundation-sdk/tree/main/github-actions-example).
## 1. Generating the dashboard JSON
Before deploying a dashboard, we need to define it in code using the Grafana Foundation SDK. We ran through an example of this in the Getting Started guide, however, in order to comply with the Kubernetes resource compatible API that Grafana exposes, well make some changes to the code to output the dashboard JSON in the appropriate format.