or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

admin-and-rbac.mdalerting.mdauthentication.mdclient-management.mddashboards.mddata-models.mddatasources.mdindex.mdlibrary-elements.mdplugin-management.mdsnapshot-management.mdusers-and-orgs.md

dashboards.mddocs/

0

# Dashboard Operations

1

2

Complete dashboard lifecycle management including creation, updates, deletion, permissions, versioning, search capabilities, and dashboard folder management. This covers both individual dashboard operations and bulk management functionality.

3

4

## Capabilities

5

6

### Dashboard CRUD Operations

7

8

Core dashboard management operations for creating, reading, updating, and deleting dashboards by UID or name.

9

10

```python { .api }

11

def get_dashboard(self, dashboard_uid: str):

12

"""

13

Get dashboard by UID.

14

15

Args:

16

dashboard_uid (str): Dashboard UID

17

18

Returns:

19

dict: Dashboard object with metadata and JSON model

20

"""

21

...

22

23

def get_dashboard_by_name(self, dashboard_name: str):

24

"""

25

Get dashboard by name (deprecated in Grafana 8+).

26

27

Args:

28

dashboard_name (str): Dashboard name

29

30

Returns:

31

dict: Dashboard object

32

"""

33

...

34

35

def update_dashboard(self, dashboard: dict):

36

"""

37

Create or update dashboard.

38

39

Args:

40

dashboard (dict): Dashboard payload with dashboard object and metadata

41

42

Returns:

43

dict: Operation result with UID, ID, URL, and version

44

"""

45

...

46

47

def delete_dashboard(self, dashboard_uid: str):

48

"""

49

Delete dashboard by UID.

50

51

Args:

52

dashboard_uid (str): Dashboard UID

53

54

Returns:

55

dict: Deletion result

56

"""

57

...

58

59

def get_home_dashboard(self):

60

"""

61

Get the home dashboard for current user/organization.

62

63

Returns:

64

dict: Home dashboard object

65

"""

66

...

67

```

68

69

**Usage Example:**

70

71

```python

72

from grafana_client import GrafanaApi, TokenAuth

73

74

api = GrafanaApi(auth=TokenAuth("your-token"), host="grafana.example.com")

75

76

# Get existing dashboard

77

dashboard = api.dashboard.get_dashboard("dashboard-uid-here")

78

print(f"Dashboard: {dashboard['dashboard']['title']}")

79

80

# Create new dashboard

81

new_dashboard = {

82

"dashboard": {

83

"title": "My New Dashboard",

84

"tags": ["example", "api"],

85

"timezone": "browser",

86

"panels": [

87

{

88

"id": 1,

89

"title": "Sample Panel",

90

"type": "text",

91

"gridPos": {"h": 3, "w": 24, "x": 0, "y": 0},

92

"options": {"content": "Hello from API!"}

93

}

94

],

95

"time": {"from": "now-1h", "to": "now"},

96

"refresh": "5s"

97

},

98

"message": "Created via API",

99

"overwrite": False

100

}

101

102

result = api.dashboard.update_dashboard(new_dashboard)

103

print(f"Created dashboard UID: {result['uid']}")

104

105

# Update existing dashboard

106

dashboard['dashboard']['title'] = "Updated Title"

107

update_result = api.dashboard.update_dashboard({

108

"dashboard": dashboard['dashboard'],

109

"message": "Updated title",

110

"overwrite": True

111

})

112

```

113

114

### Dashboard Tags Management

115

116

Operations for managing dashboard tags and retrieving tag-based information.

117

118

```python { .api }

119

def get_dashboards_tags(self):

120

"""

121

Get all dashboard tags in the organization.

122

123

Returns:

124

list: List of tag objects with tag names and counts

125

"""

126

...

127

```

128

129

**Usage Example:**

130

131

```python

132

# Get all dashboard tags

133

tags = api.dashboard.get_dashboards_tags()

134

for tag in tags:

135

print(f"Tag: {tag['term']} (used by {tag['count']} dashboards)")

136

```

137

138

### Dashboard Permissions Management

139

140

Managing dashboard-level permissions for users, teams, and roles using both UID and ID-based methods.

141

142

```python { .api }

143

def get_permissions_by_uid(self, dashboard_uid: str):

144

"""

145

Get dashboard permissions by UID.

146

147

Args:

148

dashboard_uid (str): Dashboard UID

149

150

Returns:

151

list: List of permission objects with user/team/role and permission level

152

"""

153

...

154

155

def update_permissions_by_uid(self, dashboard_uid: str, items: list):

156

"""

157

Update dashboard permissions by UID.

158

159

Args:

160

dashboard_uid (str): Dashboard UID

161

items (list): List of permission objects

162

"""

163

...

164

165

def get_permissions_by_id(self, dashboard_id: int):

166

"""

167

Get dashboard permissions by ID (deprecated, use UID method).

168

169

Args:

170

dashboard_id (int): Dashboard ID

171

172

Returns:

173

list: List of permission objects

174

"""

175

...

176

177

def update_permissions_by_id(self, dashboard_id: int, items: list):

178

"""

179

Update dashboard permissions by ID (deprecated, use UID method).

180

181

Args:

182

dashboard_id (int): Dashboard ID

183

items (list): List of permission objects

184

"""

185

...

186

187

def get_dashboard_permissions(self, dashboard_id: int):

188

"""

189

Get dashboard permissions by ID (deprecated, use get_permissions_by_id).

190

191

Args:

192

dashboard_id (int): Dashboard ID

193

194

Returns:

195

list: List of permission objects

196

"""

197

...

198

199

def update_dashboard_permissions(self, dashboard_id: int, items: list):

200

"""

201

Update dashboard permissions by ID (deprecated, use update_permissions_by_id).

202

203

Args:

204

dashboard_id (int): Dashboard ID

205

items (list): List of permission objects

206

"""

207

...

208

209

def get_permissions_generic(self, identifier: str, idtype: str = "uid"):

210

"""

211

Generic method to get permissions by identifier.

212

213

Args:

214

identifier (str): Dashboard identifier (UID or ID)

215

idtype (str): Identifier type ("uid" or "id")

216

217

Returns:

218

list: List of permission objects

219

"""

220

...

221

222

def update_permissions_generic(self, identifier: str, items: list, idtype: str = "uid"):

223

"""

224

Generic method to update permissions by identifier.

225

226

Args:

227

identifier (str): Dashboard identifier (UID or ID)

228

items (list): List of permission objects

229

idtype (str): Identifier type ("uid" or "id")

230

"""

231

...

232

```

233

234

**Permission Object Structure:**

235

236

```python

237

# Permission item structure

238

permission_item = {

239

"userId": 0, # User ID (optional, mutually exclusive with teamId/role)

240

"teamId": 0, # Team ID (optional, mutually exclusive with userId/role)

241

"role": "Viewer", # Built-in role (optional, mutually exclusive with userId/teamId)

242

"permission": 1 # Permission level: 1=View, 2=Edit, 4=Admin

243

}

244

```

245

246

**Usage Example:**

247

248

```python

249

# Get current permissions

250

permissions = api.dashboard.get_permissions_by_uid("dashboard-uid")

251

for perm in permissions:

252

if 'userId' in perm:

253

print(f"User {perm['userId']}: {perm['permissionName']}")

254

elif 'teamId' in perm:

255

print(f"Team {perm['teamId']}: {perm['permissionName']}")

256

elif 'role' in perm:

257

print(f"Role {perm['role']}: {perm['permissionName']}")

258

259

# Update permissions

260

new_permissions = [

261

{

262

"teamId": 2,

263

"permission": 2 # Edit permission

264

},

265

{

266

"role": "Editor",

267

"permission": 1 # View permission

268

},

269

{

270

"userId": 5,

271

"permission": 4 # Admin permission

272

}

273

]

274

275

api.dashboard.update_permissions_by_uid("dashboard-uid", new_permissions)

276

print("Permissions updated successfully")

277

```

278

279

### Dashboard Search Integration

280

281

Dashboard search is handled through the Search API element but often used in dashboard workflows.

282

283

```python

284

# Search for dashboards by various criteria

285

search_results = api.search.search_dashboards(

286

query="production", # Text query

287

tags=["monitoring"], # Filter by tags

288

folderIds=[1, 2], # Filter by folder IDs

289

type="dash-db", # Type filter

290

starred=True, # Only starred dashboards

291

limit=50 # Result limit

292

)

293

294

for dashboard in search_results:

295

print(f"Found: {dashboard['title']} (UID: {dashboard['uid']})")

296

```

297

298

### Dashboard Folders Integration

299

300

Dashboard folder operations are managed through the Folder API but commonly used with dashboard management.

301

302

```python

303

# Create folder for dashboards

304

folder_result = api.folder.create_folder(

305

title="Production Dashboards",

306

uid="prod-dashboards"

307

)

308

309

# Create dashboard in specific folder

310

dashboard_with_folder = {

311

"dashboard": {

312

"title": "Production Metrics",

313

"tags": ["production"],

314

"panels": []

315

},

316

"folderId": folder_result['id'], # Assign to folder

317

"message": "Created in production folder"

318

}

319

320

result = api.dashboard.update_dashboard(dashboard_with_folder)

321

```

322

323

### Advanced Dashboard Operations

324

325

**Dashboard Starring:**

326

327

```python

328

# Star/unstar dashboards (through User API)

329

api.user.star_actual_user_dashboard(dashboard_id=123)

330

api.user.unstar_actual_user_dashboard(dashboard_id=123)

331

```

332

333

**Dashboard Snapshots:**

334

335

```python

336

# Create dashboard snapshot (through Snapshots API)

337

snapshot_data = {

338

"dashboard": dashboard['dashboard'],

339

"name": "Production Snapshot",

340

"expires": 3600, # Expires in 1 hour

341

"external": False

342

}

343

344

snapshot_result = api.snapshots.create_new_snapshot(**snapshot_data)

345

print(f"Snapshot URL: {snapshot_result['url']}")

346

```

347

348

### Error Handling

349

350

Common dashboard operation errors and how to handle them:

351

352

```python

353

from grafana_client import GrafanaClientError, GrafanaBadInputError

354

355

try:

356

# Attempt to get dashboard

357

dashboard = api.dashboard.get_dashboard("non-existent-uid")

358

except GrafanaClientError as e:

359

if e.status_code == 404:

360

print("Dashboard not found")

361

elif e.status_code == 403:

362

print("Access denied - insufficient permissions")

363

else:

364

print(f"Client error: {e.message}")

365

366

try:

367

# Attempt to create dashboard with invalid data

368

invalid_dashboard = {

369

"dashboard": {

370

# Missing required fields

371

}

372

}

373

api.dashboard.update_dashboard(invalid_dashboard)

374

except GrafanaBadInputError as e:

375

print(f"Invalid dashboard data: {e.message}")

376

```

377

378

### Async Dashboard Operations

379

380

All dashboard operations support async versions:

381

382

```python

383

import asyncio

384

from grafana_client import AsyncGrafanaApi, TokenAuth

385

386

async def manage_dashboards():

387

api = AsyncGrafanaApi(auth=TokenAuth("your-token"), host="grafana.example.com")

388

389

# Async dashboard operations

390

dashboard = await api.dashboard.get_dashboard("dashboard-uid")

391

tags = await api.dashboard.get_dashboards_tags()

392

permissions = await api.dashboard.get_permissions_by_uid("dashboard-uid")

393

394

# Concurrent operations

395

dashboard_tasks = [

396

api.dashboard.get_dashboard(uid)

397

for uid in ["uid1", "uid2", "uid3"]

398

]

399

dashboards = await asyncio.gather(*dashboard_tasks)

400

401

print(f"Retrieved {len(dashboards)} dashboards")

402

403

asyncio.run(manage_dashboards())

404

```

405

406

### Dashboard JSON Structure

407

408

Understanding the dashboard JSON structure for creation and updates:

409

410

```python

411

# Complete dashboard structure example

412

dashboard_json = {

413

"dashboard": {

414

"id": None, # Auto-generated, set to null for new dashboards

415

"uid": "custom-uid", # Optional custom UID

416

"title": "My Dashboard",

417

"description": "Dashboard created via API",

418

"tags": ["api", "example"],

419

"timezone": "browser", # "browser", "utc", or timezone string

420

"editable": True,

421

"hideControls": False,

422

"schemaVersion": 30, # Grafana schema version

423

"version": 0, # Auto-incremented

424

"refresh": "5s", # Auto-refresh interval

425

"time": { # Time range

426

"from": "now-6h",

427

"to": "now"

428

},

429

"timepicker": { # Time picker configuration

430

"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]

431

},

432

"templating": { # Variables/templating

433

"list": []

434

},

435

"annotations": { # Annotations configuration

436

"list": []

437

},

438

"panels": [ # Dashboard panels

439

{

440

"id": 1,

441

"title": "Sample Panel",

442

"type": "stat",

443

"gridPos": {"h": 8, "w": 12, "x": 0, "y": 0},

444

"fieldConfig": {

445

"defaults": {},

446

"overrides": []

447

},

448

"options": {},

449

"targets": [ # Data queries

450

{

451

"expr": "up",

452

"refId": "A"

453

}

454

]

455

}

456

]

457

},

458

"message": "Created via API", # Commit message

459

"overwrite": False, # Overwrite existing dashboard

460

"folderId": 0 # Folder ID (0 = General folder)

461

}

462

```

463

464

### Best Practices

465

466

1. **Use UIDs over IDs**: Prefer UID-based methods as they're more stable across Grafana instances

467

2. **Validate JSON**: Ensure dashboard JSON is valid before creating/updating

468

3. **Handle Permissions**: Check and manage dashboard permissions appropriately

469

4. **Version Control**: Use commit messages to track dashboard changes

470

5. **Error Handling**: Implement proper error handling for all dashboard operations

471

6. **Async for Bulk**: Use async API for bulk dashboard operations

472

7. **Tag Management**: Use consistent tagging strategies for dashboard organization