Programmatically creating multiple dashboards from the JSON of one master dsahboard

Hello,

I am currently attempting to write a program using a combination of command line and Python3 that will contact the Grafana server, download a copy of the JSON of one dashboard that I have designated to be the master, create a new JSON which has only the elements necessary to create a new dashboard and the design features that I would like (so id = null, uid = null, title, tags, timezone, refresh, templating, time, and panels, as well as folderUid and overwrite) and replace the device name of the master with the device name of each individual device in turn, and then upload the new dashboard for each device into their own respective folders.

I seem to be stumbling right at the very last hurdle, as I cannot seem to create multiple dashboards from within my Python script. For some reason I get a 412 error saying ā€œthe dashboard has been changed by someone elseā€ and ā€œversion-mismatchā€. This error only occurs if I set overwrite to false, however if I set overwrite to true, the program only seems to create the final dashboard, while the rest of the folders remain empty.

Iā€™m not sure if this is how the API works, but it seems as though you can only handle one dashboard-create per connection to the server (perhaps based on the API key?) per program, which just doesnā€™t seem right, so I think their must be something I am doing wrong.

I am connecting to the API using GrafanaFace from grafana_api.grafana_face, and then I am running this:

response = requests.post(f"http://localhost:81/api/dashboards/db", headers=headers, data=dashboard_json)

to create the dashboards.

Does anyone have any ideas?

Thanks

Welcome @control148

What is grafana face? Also please share your python code.

Grafana face is just a module I found from this website, Iā€™m using it to connect to the server.

I use it in the code as follows:

grafana_api = GrafanaFace(
auth=ā€˜API_KEYā€™,
host=ā€˜localhost:81ā€™
)

I have then created a function that I use to create the dashboards. There are a number of devices which all have identical data points in the database but require separate dashboards, so I have been iterating through the devices, changing the master JSON to suit and then running my function. I know that my code to update the JSON is working because I have tested that out for creating just one dashboard and it worked perfectly, itā€™s only when I introduce multiple dashboards that I get the error.

My function is as follows:

def createDashboard(title, templating, time, panels, folderUid):
grafana_api.dashboard.update_dashboard(dashboard={
ā€˜dashboardā€™: {ā€˜idā€™: ā€˜nullā€™,
ā€˜uidā€™: ā€˜nullā€™,
ā€˜titleā€™: title,
ā€˜tagsā€™: ā€˜ā€™,
ā€˜timezoneā€™: ā€˜browserā€™,
ā€˜schemaVersionā€™: 16,
ā€˜refreshā€™: ā€˜25sā€™,
ā€˜templatingā€™: templating,
ā€˜timeā€™: time,
ā€˜panelsā€™: panels},
ā€˜folderUidā€™: folderUid,
ā€˜overwriteā€™: True})

Where I sub in templating and time directly from the master JSON, panels I copy from the master JSON and then replace the device name, and folder UID I get from running a query to get a list of folders, filtering to get the relevant folder and extracting itā€™s UID.

As I said in my original post, when overwrite is set to True, the code runs without errors but it is only the last iteration which has a dashboard when I refresh the server. When I set overwrite to False, if the first iteration dashboard does not already exist, the code will create the first dashboard and then produce the error I mentioned above for every other dashboard. If the first iteration dashboard does exist, it wil produce the error for them all.

Sorry, Iā€™ve just re-read my original post and realised an inconsistency in my question. The function which I posted in my reply there was one method I used but it didnā€™t work so I also tried using this function:

def createDashboard(dashboard_config):
headers = {
ā€œAuthorizationā€: ā€œBearer API_KEYā€,
ā€œContent-Typeā€: ā€œapplication/jsonā€
}

dashboard_json = json.dumps(dashboard_config)

response = requests.post(f"http://localhost:81/api/dashboards/db", headers=headers, data=dashboard_json)

if response.status_code == 200:
	print("Dashboard created successfully")
else:
	print(f"Failed to create dashboard. Status code: {response.status_code}, Response: {response.text}")

Both functions produced the same errors.

I have also tried putting all of the dashboard JSONs into a list and then doing a single dashboard create using that list of dashboards (which didnā€™t work) and then also tried iterating through that list within the function (which also didnā€™t work).

There must be something I am missing (probably something really obvious!) but I just canā€™t see what.

I have realised my mistake (and it was indeed something very silly!). I my ID and UID I have filled in as ā€œnullā€ when it should have just been ā€œā€ (empty string). In my configuration, the dashboard was trying to create a dashboard with a UID of ā€˜nullā€™ and then trying again with the next dashboard, although, obviously, this UID was now already taken, hence the error.

Such a basic error that I completely overlooked it every single time, but it is working now. I have learned a lesson!

1 Like