Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create or Update Roles in Apache Superset Programmatically

Is there any way by which we can create new roles programmatically in Superset? I have checked the docs but can't find any hooks to create the roles programmatically.

like image 399
Bad Coder Avatar asked Jul 25 '26 03:07

Bad Coder


2 Answers

An alternative to the previous answers would be to enable the FAB REST API in Superset. Apache Superset uses Flask App Builder (FAB), whose API is hidden by default.

Setting FAB's configuration variable FAB_ADD_SECURITY_API = True in superset_config.py adds a CRUD REST API for users, roles, permissions, view_menus reachable under /api/v1/security. More on how to configure Apache Superset.

  • Add a new role (without permissions):
curl --request POST \
  --url http://localhost:8088/api/v1/security/roles/ \
  --header 'Authorization: Bearer token' \
  --header 'Content-Type: application/json' \
  --header 'X-CSRFToken: token' \
  --data '{"name": "my_new_role"}'

This creates the role "my_new_role" with id=6.

  • Add permission to role:
curl --request POST \
  --url http://localhost:8088/api/v1/security/roles/6/permissions \
  --header 'Authorization: Bearer token' \
  --header 'Content-Type: application/json' \
  --header 'X-CSRFToken: token' \
  --data '{"permission_view_menu_ids": [1,2]}'

This adds the permissions with id=1 and id=2 to the role with id=6.

Here is an example to do the same with Python:

import requests

base_url = 'http://localhost:8088/api/v1'

def get_bearer_token():
    payload = {
        "password": "admin",
        "provider": "db",
        "username": "admin"
    }
    headers = {"Content-Type": "application/json"}
    response = requests.request("POST", f"{base_url}/security/login", json=payload, headers=headers)
    return response.json()["access_token"]

def get_csrf_token():
    headers = {"Authorization": f"Bearer {get_bearer_token()}"}
    response = requests.request("GET", f"{base_url}/security/csrf_token/", data="", headers=headers)
    return response.json()["result"]

def add_role(name):
    headers = {
        'X-CSRFToken': get_csrf_token(),
        'Authorization': f"Bearer {get_bearer_token()}"
    }
    response = requests.request("POST", f"{base_url}/security/roles", json={"name": name}, headers=headers)
    return response.json()

def add_permissions_to_role(role_id, permissions):
    headers = {
        'X-CSRFToken': get_csrf_token(),
        'Authorization': f"Bearer {get_bearer_token()}"
    }
    response = requests.request("POST", f"{base_url}/security/roles/{role_id}/permissions", json={"permission_view_menu_ids": permissions}, headers=headers)
    return response.json()

add_role("my_new_role")
add_permissions_to_role(6, [1,2])
like image 128
Sebastian Liebscher Avatar answered Jul 26 '26 18:07

Sebastian Liebscher


Superset is using Flask App Builder which has which also has CRUD REST api for security models.

What you need to do is to enable API during initialisation of app, to achieve that you need to modify superset_config.py

Let's assume that you use docker-compose file provided by Superset https://github.com/apache/superset/tree/master/docker

in pythonpath_dev directory create custom_initializer.py file

custom_initializer.py code:

from superset.app import SupersetAppInitializer
from superset.extensions import appbuilder
from superset.security import SupersetSecurityManager


class MySupsersetAppInitializer(SupersetAppInitializer):
    def init_views(self) -> None:
        # Adds api for roles
        appbuilder.add_api(SupersetSecurityManager.role_api)

        # Uncomment if you want as well to add api for permissions, users, ect.

        # appbuilder.add_api(SupersetSecurityManager.permission_api)
        # appbuilder.add_api(SupersetSecurityManager.user_api)
        # appbuilder.add_api(SupersetSecurityManager.view_menu_api)
        # appbuilder.add_api(SupersetSecurityManager.permission_view_menu_api)

        super().init_views()

Now modify superset_config.py. Add those lines:

from custom_initializer import MySupsersetAppInitializer

APP_INITIALIZER = MySupsersetAppInitializer

Now you should be able to have access to API implemented by Flask App Builder

enter image description here

like image 30
puchal Avatar answered Jul 26 '26 16:07

puchal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!