4

I'm trying to import the Superset dashboard through API but currently not successful yet. I'm following Superset API docs to import with endpoint

/api/v1/dashboard/import

My import payload as bellow:

POST /api/v1/dashboard/import/ HTTP/1.1
Host: localhost:8088
Authorization: Bearer <access token>
Content-Length: 289
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="formData"; filename="20210615_065115.json"
Content-Type: application/json

(data)
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="overwrite"

True
----WebKitFormBoundary7MA4YWxkTrZu0gW

I got a response with status 200 but the dashboard not import, and in the preview response on postman a got output as the image below: enter image description here

Anybody can help with this issue?

Thanks.

KelvinNguyen
  • 236
  • 3
  • 12

1 Answers1

6

Superset documentation isn't very clear about this but I finally managed to solve this problem.

As you can see your response is redirecting you to a login page. What you need to do is to first make a GET request to /api/v1/security/csrf_token/

And add header in your request to /api/v1/dashboard/import

'X-CSRFToken': csrf_token

Another incorrect thing in the documentation is that Content-type is not multipart/form-data; but it is text/html; charset=utf-8

So basically in your call you don't need to pass Content-type in headers

Python example:

import requests

headers = {
    'accept': 'application/json', 
    'Authorization': f'Bearer {jwt_token}', 
    'X-CSRFToken': csrf_token
}
files = { 
    'formData': (
        dashboard_path, 
        open(dashboard_path, 'rb'), 
        'application/json'
    )
}

response = self.session.post(url, files=files, headers=headers)

EDIT 30.08.2021

I've noticed that for some reason when I was running Superset with AUTH_TYPE = AUTH_OAUTH on production the solution above stopped working.

It requires additionally header Referer to be included in headers, so more safe option would be


import requests

headers = {
    'accept': 'application/json', 
    'Authorization': f'Bearer {jwt_token}', 
    'X-CSRFToken': csrf_token,
    'Referer': url
}
files = { 
    'formData': (
        dashboard_path, 
        open(dashboard_path, 'rb'), 
        'application/json'
    )
}

response = self.session.post(url, files=files, headers=headers)
bagerard
  • 5,681
  • 3
  • 24
  • 48
puchal
  • 1,883
  • 13
  • 25