A Python library for programmatically creating and managing Grafana dashboards with type-safe, schema-driven models.
- 🎯 Type-Safe: Pydantic models generated from Grafana's JSON schemas ensure type safety
- 🔄 Schema-Driven: Automatically adapts to schema changes - no hardcoded field lists
- 🚀 Easy to Use: Simple Python API for creating dashboards and panels
- 🔐 Secure: Environment variable support for credentials
- 📦 Comprehensive: Supports dashboards, panels, datasources, and more
pip install grafanaramaOr using Poetry:
poetry add grafanaramadocker compose up -dThis starts Grafana on http://localhost:3000 (default credentials: admin/admin).
Create a .env file or export environment variables:
# Option 1: Use API Key
export GRAFANA_API_KEY="your_api_key_here"
# Option 2: Use Basic Auth (simpler for testing)
export GRAFANA_USER="admin"
export GRAFANA_PASSWORD="admin"from grafanarama import DashboardObject, Spec
from grafanarama.core.dashboard import Panel, GridPos
from grafanarama.apiclient import GrafanaClient
import os
# Create a text panel
text_panel = Panel(
type="text",
id=1,
title="Hello World!",
gridPos=GridPos(x=0, y=0, w=24, h=8),
options={
"mode": "markdown",
"content": "# My First Dashboard\n\nCreated with Grafanarama!"
}
)
# Create the dashboard
dashboard = DashboardObject(
title="My Dashboard",
schemaVersion=39,
panels=[text_panel]
)
# Send to Grafana
client = GrafanaClient(
host=os.getenv("GRAFANA_HOST", "localhost"),
port=int(os.getenv("GRAFANA_PORT", "3000")),
auth_user=os.getenv("GRAFANA_USER", "admin"),
auth_pass=os.getenv("GRAFANA_PASSWORD", "admin"),
)
client.send_dashboard(dashboard)See the examples/ directory for more examples:
simple_dashboard.py- Basic dashboard with a text paneldashboard_with_text_panel.py- More detailed text panel exampletest_auth.py- Test your Grafana authentication
Run an example:
export GRAFANA_USER="admin"
export GRAFANA_PASSWORD="admin"
python examples/simple_dashboard.pyGrafanarama uses Pydantic models generated from Grafana's JSON schemas. This means:
- ✅ Maintainable: When Grafana schemas change, regenerate models - no manual updates needed
- ✅ Type-Safe: Full type checking and validation
- ✅ Auto-Detection: Array fields and nested structures are automatically detected from schemas
- ✅ Future-Proof: Works with any Grafana resource type (dashboards, datasources, etc.)
- Model Generation: Pydantic models are generated from Grafana JSON schemas using
datamodel-codegen - Schema Introspection: The library uses
model_json_schema()to introspect field types - Smart Defaults: Array fields automatically convert
nullto[]based on schema information - Serialization: Dashboards are serialized to Grafana-compatible JSON with all required fields
The main class for creating dashboards:
from grafanarama import DashboardObject, Spec
dashboard = DashboardObject(
title="My Dashboard",
schemaVersion=39,
panels=[...],
# All Spec fields are supported
)Create panels for your dashboard:
from grafanarama.core.dashboard import Panel, GridPos
panel = Panel(
type="text", # Panel type (text, timeseries, stat, etc.)
id=1,
title="My Panel",
gridPos=GridPos(x=0, y=0, w=24, h=8), # Position and size
options={...} # Panel-specific options
)API client for interacting with Grafana:
from grafanarama.apiclient import GrafanaClient
client = GrafanaClient(
host="localhost",
port=3000,
apiKey="your_key", # or use auth_user/auth_pass
use_https=False
)
# Send dashboard
client.send_dashboard(dashboard, overwrite=True)
# Get dashboard
dashboard_data = client.get_dashboard("dashboard-slug")
# Send datasource
client.send_datasource(datasource)Currently supported Grafana resources:
- ✅ Dashboards - Full support
- ✅ Panels - All panel types
- ✅ Datasources - Basic support
- 🔄 Access Policies - Models available
- 🔄 Teams - Models available
- 🔄 Roles - Models available
- 🔄 Library Panels - Models available
More resources can be added by generating models from Grafana schemas.
# Clone the repository
git clone https://github.com/esalituro/grafanarama.git
cd grafanarama
# Install dependencies
poetry install
# Activate virtual environment
poetry shellpytestModels are generated from Grafana JSON schemas. See Taskfile.yml for generation tasks.
grafanarama/
├── core/ # Core Grafana resource models (dashboards, teams, etc.)
├── composable/ # Composable elements (panels, data queries)
├── apiclient.py # HTTP client for Grafana API
├── schema_utils.py # Schema introspection utilities
└── __init__.py # DashboardObject and main exports
examples/
├── simple_dashboard.py
├── dashboard_with_text_panel.py
└── test_auth.py
| Variable | Description | Default |
|---|---|---|
GRAFANA_API_KEY |
Grafana API key | None |
GRAFANA_USER |
Basic auth username | None |
GRAFANA_PASSWORD |
Basic auth password | None |
GRAFANA_HOST |
Grafana host | localhost |
GRAFANA_PORT |
Grafana port | 3000 |
GRAFANA_USE_HTTPS |
Use HTTPS | false |
If you get a 401 error, test your authentication:
python examples/test_auth.pyThis will help diagnose authentication problems.
If you see "tags expected array" or similar errors:
- Make sure you're using the latest version
- The library automatically handles array field defaults
- Check that all required fields are present
Service account tokens (starting with glsa_) may not work with all Grafana versions. Use regular API keys or basic auth instead.
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
MIT License - see LICENSE file for details.