You can directly query the cost monitoring API using the same Grafana token provisioned in Programmatically accessing Prometheus data through Grafana.
Prerequisites¶
A Grafana service account token (see Programmatically accessing Prometheus data through Grafana for instructions)
A
.envfile to securely store your Grafana token (see Secrets, passwords and access tokens)A virtual environment with the following Python packages installed:
python-dotenvrequestsyarl
Sample Code¶
import json
import os
import requests
from dotenv import load_dotenv
from yarl import URL
# Load Grafana service account token from .env file
load_dotenv()
grafana_token = os.environ["GRAFANA_TOKEN"]
grafana_url = URL("https://grafana.<cluster_name>.2i2c.cloud/")
api_url = grafana_url / "api/datasources"
datasource = requests.get(
api_url,
headers={
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": f"Bearer {grafana_token}",
}
)
# Get the cost-monitoring yesoreyeram-infinity-datasource UID
datasource_uid = datasource.json()[1]["uid"]
target_url = URL("http://jupyterhub-cost-monitoring.support.svc.cluster.local")
# See https://jupyterhub-cost-monitoring.readthedocs.io/en/latest/api/ for available endpoints
subpath = "total-costs"
headers = {
"Authorization": f"Bearer {grafana_token}",
"Content-Type": "application/json"
}
payload = {
"queries": [
{
"datasource": {
"type": "yesoreyeram-infinity-datasource",
"uid": datasource_uid,
},
"url": str(target_url / subpath),
"url_options": {
"method": 'GET',
"data": '',
},
"type": "json",
"source": "url",
"format": "table",
"parser": "backend",
"root_selector": "",
# Columns can change depending on data returned by endpoint – see https://github.com/2i2c-org/jupyterhub-cost-monitoring/blob/a6e49c719e8600fc2490e2fb2a77da09ce4bcd1a/dashboards/common.libsonnet#L128 for examples from existing cloud cost grafana dashboards
"columns": [
{"selector": "date", "text": "Date", "type": "timestamp"},
{"selector": "name", "text": "Name", "type": "string"},
{"selector": "cost", "text": "Cost", "type": "number"},
],
}
],
"from": "now-1d",
"to": "now"
}
# https://grafana.com/docs/grafana-cloud/developer-resources/api-reference/http-api/data_source/#query-a-data-source
query_url = grafana_url / "api/ds/query"
response = requests.post(
query_url,
headers=headers,
data=json.dumps(payload)
)
response.raise_for_status()
data = response.json()
print(json.dumps(data, indent=2))