Skip to content

Commit 427f039

Browse files
author
Pascal Zimmermann
authored
Merge 5eb4e9e into 94ea786
2 parents 94ea786 + 5eb4e9e commit 427f039

File tree

11 files changed

+1795
-23
lines changed

11 files changed

+1795
-23
lines changed

README.md

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,32 @@ In general my focus inside this project is to implement and deliver old and new
124124
### Short URL
125125
- Create a short url
126126

127+
### User
128+
- Search Users
129+
- Get user by id
130+
- Get user by username or email
131+
- Update the user
132+
- Get user organizations
133+
- Get user teams
134+
- Switch the specific user context
135+
- Get the current user
136+
- Update the current user
137+
- Update the current password
138+
- Switch current user context
139+
- Get current user organizations
140+
- Get current user teams
141+
- Star a dashboard
142+
- Unstar a dashboard
143+
- Get auth tokens
144+
- Revoke auth tokens
145+
146+
### Snapshot
147+
- Create a new snapshot
148+
- Get all snapshots
149+
- Get a specific snapshot by key
150+
- Delete snapshot by key
151+
- Delete snapshot by delete key
152+
127153
## Feature timeline
128154

129155
The following table describes the plan to implement the rest of the Grafana API functionality. Please, open an issue and vote them up, if you prefer a faster implementation of an API functionality.
@@ -136,14 +162,12 @@ The following table describes the plan to implement the rest of the Grafana API
136162
| [External Group Sync HTTP API](https://grafana.com/docs/grafana/latest/http_api/external_group_sync/) | | | | |
137163
| [Fine-grained access control HTTP API](https://grafana.com/docs/grafana/latest/http_api/access_control/) | | | | |
138164
| [HTTP Preferences API](https://grafana.com/docs/grafana/latest/http_api/preferences/) | | | | |
139-
| [HTTP Snapshot API](https://grafana.com/docs/grafana/latest/http_api/snapshot/) | 16 | [ZPascal](https://github.com/ZPascal) | | |
140165
| [Library Element HTTP API](https://grafana.com/docs/grafana/latest/http_api/library_element/) | | | | |
141166
| [Licensing HTTP API](https://grafana.com/docs/grafana/latest/http_api/licensing/) | | | | |
142167
| [Other HTTP API](https://grafana.com/docs/grafana/latest/http_api/other/) | | | | |
143-
| [Playlist HTTP API](https://grafana.com/docs/grafana/latest/http_api/playlist/) | | | | |
168+
| [Playlist HTTP API](https://grafana.com/docs/grafana/latest/http_api/playlist/) | 20 | [ZPascal](https://github.com/ZPascal) | | |
144169
| [Reporting API](https://grafana.com/docs/grafana/latest/http_api/reporting/) | | | | |
145-
| [Team HTTP API](https://grafana.com/docs/grafana/latest/http_api/team/) | | | | |
146-
| [User HTTP API](https://grafana.com/docs/grafana/latest/http_api/user/) | 16 | [ZPascal](https://github.com/ZPascal) | | |
170+
| [Team HTTP API](https://grafana.com/docs/grafana/latest/http_api/team/) | 20 | [ZPascal](https://github.com/ZPascal) | | |
147171

148172
## Installation
149173

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
requests
2-
pydoc-markdown==4.6.2
2+
pydoc-markdown==4.6.3
33
mkdocs
44
mkdocs-material

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
setuptools.setup(
1010
name="grafana-api-sdk",
11-
version="0.0.3",
11+
version="0.0.4",
1212
author="Pascal Zimmermann",
1313
author_email="[email protected]",
1414
description="A Grafana API SDK",

src/grafana_api/alerting_notifications.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,6 @@ def test_notification_channel(self, notification_channel: dict):
333333
.json()
334334
)
335335

336-
print(api_call)
337-
338336
if api_call.get("message") != "Test notification sent":
339337
logging.error(f"Check the error: {api_call}.")
340338
raise Exception

src/grafana_api/model.py

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,27 @@
88
class APIEndpoints(Enum):
99
"""The class includes all necessary API endpoint strings to connect the Grafana API"""
1010

11-
SEARCH = "/api/search"
12-
DASHBOARDS = "/api/dashboards"
13-
FOLDERS = "/api/folders"
14-
LEGACY_ALERTS = "/api/alerts"
15-
ALERT_NOTIFICATIONS = "/api/alert-notifications"
16-
ALERTS_ALERTMANAGER = "/api/alertmanager"
17-
ALERTS_PROMETHEUS = "/api/prometheus"
18-
ALERTS_RULER = "/api/ruler"
19-
ALERTS_TESTING = "/api/v1"
20-
ALERTS_NGALERT = "/api/v1/ngalert"
21-
DATASOURCES = "/api/datasources"
22-
DATASOURCE_QUERY = "/api/tsdb/query"
23-
SHORT_URLS = "/api/short-urls"
24-
ORGANISATION = "/api/org"
25-
ORGANISATIONS = "/api/orgs"
11+
api_prefix = "/api"
12+
13+
SEARCH = f"{api_prefix}/search"
14+
DASHBOARDS = f"{api_prefix}/dashboards"
15+
FOLDERS = f"{api_prefix}/folders"
16+
LEGACY_ALERTS = f"{api_prefix}/alerts"
17+
ALERT_NOTIFICATIONS = f"{api_prefix}/alert-notifications"
18+
ALERTS_ALERTMANAGER = f"{api_prefix}/alertmanager"
19+
ALERTS_PROMETHEUS = f"{api_prefix}/prometheus"
20+
ALERTS_RULER = f"{api_prefix}/ruler"
21+
ALERTS_TESTING = f"{api_prefix}/v1"
22+
ALERTS_NGALERT = f"{api_prefix}/v1/ngalert"
23+
DATASOURCES = f"{api_prefix}/datasources"
24+
DATASOURCE_QUERY = f"{api_prefix}/tsdb/query"
25+
SHORT_URLS = f"{api_prefix}/short-urls"
26+
ORGANISATION = f"{api_prefix}/org"
27+
ORGANISATIONS = f"{api_prefix}/orgs"
28+
USER = f"{api_prefix}/user"
29+
USERS = f"{api_prefix}/users"
30+
SNAPSHOTS = f"{api_prefix}/snapshots"
31+
DASHBOARD_SNAPSHOTS = f"{api_prefix}/dashboard/snapshots"
2632

2733

2834
class RequestsMethods(Enum):
@@ -196,3 +202,19 @@ class RulerRule(NamedTuple):
196202
labels: dict
197203
record: str
198204
for_id: int = 0
205+
206+
207+
class UserObject(NamedTuple):
208+
"""The class includes all necessary variables to generate a User object that is necessary to update a Grafana User
209+
210+
Args:
211+
email (str): Specify the name of the rule
212+
name (str): Specify the annotations of the rule
213+
login (str): Specify the expression of the rule
214+
theme (str): Specify the Grafana alert of the rule
215+
"""
216+
217+
email: str
218+
name: str
219+
login: str
220+
theme: str

src/grafana_api/snapshot.py

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
import json
2+
import logging
3+
4+
from .model import (
5+
APIModel,
6+
APIEndpoints,
7+
RequestsMethods,
8+
)
9+
from .api import Api
10+
11+
12+
class Snapshot:
13+
"""The class includes all necessary methods to access the Grafana snapshot API endpoints
14+
15+
Args:
16+
grafana_api_model (APIModel): Inject a Grafana API model object that includes all necessary values and information
17+
18+
Attributes:
19+
grafana_api_model (APIModel): This is where we store the grafana_api_model
20+
"""
21+
22+
def __init__(self, grafana_api_model: APIModel):
23+
self.grafana_api_model = grafana_api_model
24+
25+
def create_new_snapshot(
26+
self,
27+
dashboard_json: dict,
28+
name: str = None,
29+
expires: int = None,
30+
external: bool = False,
31+
key: str = None,
32+
delete_key: str = None,
33+
) -> dict:
34+
"""The method includes a functionality to create the specified dashboard snapshot
35+
36+
Args:
37+
dashboard_json (dict): Specify the dashboard_json of the dashboard
38+
name (str): Specify the optional name of the dashboard snapshot
39+
expires (int): Specify the optional expiry time as seconds of the dashboard snapshot. 3600 is 1 hour, 86400 is 1 day (default never expired)
40+
external (bool): Specify the optional external server rather than locally (default False)
41+
key (str): Specify the optional unique key. Required if external is true.
42+
delete_key (str): Specify the optional unique key used to delete the snapshot. It is different from the key so that only the creator can delete the snapshot. Required if external is true.
43+
44+
Raises:
45+
ValueError: Missed specifying a necessary value
46+
Exception: Unspecified error by executing the API call
47+
48+
Returns:
49+
api_call (dict): Returns the snapshot information of the dashboard
50+
"""
51+
52+
if dashboard_json != dict():
53+
if external:
54+
if (key is None or len(key) == 0) and (
55+
delete_key is None or len(delete_key) == 0
56+
):
57+
logging.error(
58+
"It's necessary that you define the key and the delete_key, if you use the external snapshot "
59+
"opportunity. "
60+
)
61+
raise ValueError
62+
63+
snapshot_json: dict = {
64+
"dashboard": dashboard_json,
65+
"name": name,
66+
"expires": expires,
67+
"external": external,
68+
"key": key,
69+
"deleteKey": delete_key,
70+
}
71+
72+
api_call: dict = (
73+
Api(self.grafana_api_model)
74+
.call_the_api(
75+
APIEndpoints.SNAPSHOTS.value,
76+
RequestsMethods.POST,
77+
json.dumps(snapshot_json),
78+
)
79+
.json()
80+
)
81+
82+
if api_call == dict() or api_call.get("id") is None:
83+
logging.error(f"Check the error: {api_call}.")
84+
raise Exception
85+
else:
86+
return api_call
87+
else:
88+
logging.error("There is no dashboard_json defined.")
89+
raise ValueError
90+
91+
def get_snapshots(self) -> list:
92+
"""The method includes a functionality to list all dashboard snapshots
93+
94+
Raises:
95+
Exception: Unspecified error by executing the API call
96+
97+
Returns:
98+
api_call (list): Returns all dashboard snapshots
99+
"""
100+
101+
api_call: list = (
102+
Api(self.grafana_api_model)
103+
.call_the_api(
104+
APIEndpoints.DASHBOARD_SNAPSHOTS.value,
105+
)
106+
.json()
107+
)
108+
109+
if api_call == list() or api_call[0].get("id") is None:
110+
logging.error(f"Check the error: {api_call}.")
111+
raise Exception
112+
else:
113+
return api_call
114+
115+
def get_snapshot_by_key(self, key: str) -> dict:
116+
"""The method includes a functionality to get a specific dashboard snapshot by the key
117+
118+
Args:
119+
key (str): Specify the key of the dashboard snapshot
120+
121+
Raises:
122+
ValueError: Missed specifying a necessary value
123+
Exception: Unspecified error by executing the API call
124+
125+
Returns:
126+
api_call (dict): Returns a specific dashboard snapshot
127+
"""
128+
129+
if len(key) != 0:
130+
api_call: dict = (
131+
Api(self.grafana_api_model)
132+
.call_the_api(
133+
f"{APIEndpoints.SNAPSHOTS.value}/{key}",
134+
)
135+
.json()
136+
)
137+
138+
if api_call == dict() or api_call.get("dashboard").get("id") is None:
139+
logging.error(f"Check the error: {api_call}.")
140+
raise Exception
141+
else:
142+
return api_call
143+
else:
144+
logging.error("There is no key defined.")
145+
raise ValueError
146+
147+
def delete_snapshot_by_key(self, key: str):
148+
"""The method includes a functionality to delete a specific dashboard snapshot by the key
149+
150+
Args:
151+
key (str): Specify the key of the dashboard snapshot
152+
153+
Raises:
154+
ValueError: Missed specifying a necessary value
155+
Exception: Unspecified error by executing the API call
156+
157+
Returns:
158+
None
159+
"""
160+
161+
if len(key) != 0:
162+
api_call: dict = (
163+
Api(self.grafana_api_model)
164+
.call_the_api(
165+
f"{APIEndpoints.SNAPSHOTS.value}/{key}", RequestsMethods.DELETE
166+
)
167+
.json()
168+
)
169+
170+
if (
171+
api_call.get("message")
172+
!= "Snapshot deleted. It might take an hour before it's cleared from any CDN caches."
173+
):
174+
logging.error(f"Check the error: {api_call}.")
175+
raise Exception
176+
else:
177+
logging.info("You successfully destroyed the dashboard snapshot.")
178+
else:
179+
logging.error("There is no key defined.")
180+
raise ValueError
181+
182+
def delete_snapshot_by_delete_key(self, delete_key: str):
183+
"""The method includes a functionality to delete a specific dashboard snapshot by the delete_key
184+
185+
Args:
186+
delete_key (str): Specify the delete_key of the dashboard snapshot
187+
188+
Raises:
189+
ValueError: Missed specifying a necessary value
190+
Exception: Unspecified error by executing the API call
191+
192+
Returns:
193+
None
194+
"""
195+
196+
if len(delete_key) != 0:
197+
api_call: dict = (
198+
Api(self.grafana_api_model)
199+
.call_the_api(
200+
f"{APIEndpoints.SNAPSHOTS.value}-delete/{delete_key}",
201+
)
202+
.json()
203+
)
204+
205+
if (
206+
api_call.get("message")
207+
!= "Snapshot deleted. It might take an hour before it's cleared from any CDN caches."
208+
):
209+
logging.error(f"Check the error: {api_call}.")
210+
raise Exception
211+
else:
212+
logging.info("You successfully destroyed the dashboard snapshot.")
213+
else:
214+
logging.error("There is no delete_key defined.")
215+
raise ValueError

0 commit comments

Comments
 (0)