Knowledge Base Article

Automating the extraction and formatting of Sisense dashboard and widget scripts [Linux]

Sisense includes the capability to export all dashboard metadata in JSON format, both via the UI and via API. These include all metadata components of the dashboard and widgets, including widget and dashboard scripts. A common use case is to extract dashboard and widget scripts from one or more dashboard files, properly format JavaScript by converting escaped JSON strings into readable JavaScript, and remove default comment headers that are often present. This article provides a comprehensive Python script that automates extracting these scripts into separate files, formats them clearly, removes common default comments, organizes scripts by dashboard in separate folders, and adds a comment in each file indicating relevant details like the last viewed timestamp, widget type, and the URL to access the dashboard or widget.

How to Export Dashboards

Dashboards can be exported from the Sisense UI through the main dashboard menu, which provides a downloadable JSON file containing the complete dashboard metadata. 

 

 

Alternatively, the Sisense REST API allows you to programmatically export the full metadata of a dashboard using the following endpoint:

GET {your-sisense-domain.com}/api/dashboards/{dashboardID}/export

Terminology

  • Regular Expression (regex): A sequence of characters defining a search pattern, typically used to find or manipulate strings.
  • js-beautifier: A Python library used to format JavaScript code to enhance readability.

Step-by-Step Guide

Step 1: Export Dashboards

Export all relevant dashboards either via the Sisense GUI or API. Place all these dashboards in a directory/folder where this single Python file will also be saved and run.

Step 2: Install Required Python Dependencies

The Python tool's only external dependency is the jsbeautifier library. Pip can be used to install this dependency. This can be installed at the system level or in a Python virtual environment.

pip install jsbeautifier

Step 3: Copy and save the Full Python code

Copy this full code as a file named `sisense_script_extractor.py`. The script processes .dash files exported from Sisense, in the same folder. It reads each JSON-formatted file, extracts dashboard and widget scripts, formats the JavaScript neatly, and writes each script to its file, organized into a structured results directory.

#!/usr/bin/env python3 """ sisense_script_extractor.py This script scans the current directory for all files ending with “.dash” (Sisense dashboard export file), extracts the script code stored in the dashboard-level `script` field and in each widget’s `script` field, beautifies (formats) the code, removes known default template comment blocks, and saves the cleaned and formatted scripts to a structured “results/{dashboard_title}_{dashboard_oid}” folder. At the end of each output file, it appends a JS comment indicating the dashboard’s lastOpened timestamp, widget type, and the relevant Sisense URL path. Usage: python sisense_script_extractor.py Dependencies: - jsbeautifier (install via `pip install jsbeautifier`) """ import json import os import re from pathlib import Path import jsbeautifier as beautifier # Configuration constants RESULTS_DIR = Path("results") DEFAULT_TEMPLATE_DASHBOARD_SCRIPT = """/* Welcome to your Dashboard's Script. To learn how you can access the Widget and Dashboard objects, see the online documentation at https://sisense.dev/guides/js/extensions */""" WIDGET_TEMPLATE_REGEX = r"/\*.*?see the online documentation at.*?\*/" # ----------------------------------------------------------------------------- def beautify_js_code(js_code: str) -> str: """Beautify JavaScript code using jsbeautifier with a 4-space indent.""" opts = beautifier.default_options() opts.indent_size = 4 return beautifier.beautify(js_code, opts) # ----------------------------------------------------------------------------- def write_script_file(js_code: str, output_path: str, footer_comment: str) -> None: """Format JavaScript script, append footer comment, and write to specified file.""" cleaned_code = beautify_js_code(js_code) full_content = cleaned_code + "\n\n" + footer_comment with open(output_path, "w", encoding="utf-8") as file: file.write(full_content) print(f"Wrote script to {output_path}") # ----------------------------------------------------------------------------- def process_dashboard_file(dash_file_path: Path) -> None: """ Load, extract, format, and save scripts from a Sisense dashboard file (.dash). """ print(f"Processing dashboard file: {dash_file_path.name}") dashboard = json.loads(dash_file_path.read_text(encoding="utf-8")) # Create output directory: results/{title}_{oid} title_safe = dashboard.get("title", "dashboard").strip().replace(" ", "_") oid = dashboard.get("oid", "unknown") dashboard_output_dir = RESULTS_DIR / f"{title_safe}_{oid}" dashboard_output_dir.mkdir(parents=True, exist_ok=True) last_opened = dashboard.get("lastOpened", "unknown") # --- Dashboard-level script extraction and cleanup --- dash_script = dashboard.get("script") if isinstance(dash_script, str) and dash_script.strip(): cleaned_dash = dash_script.replace(DEFAULT_TEMPLATE_DASHBOARD_SCRIPT, "") footer = ( f"// Dashboard last opened on {last_opened}\n" f"// To view dashboard URL Path is /app/main/dashboards/{oid}" ) out_path = dashboard_output_dir / "dashboard_script_1.js" write_script_file(cleaned_dash, str(out_path), footer) # --- Widget-level script extraction and cleanup --- widgets = dashboard.get("widgets", []) if isinstance(widgets, list): widgets_dir = dashboard_output_dir / "widgets" widgets_dir.mkdir(exist_ok=True) for widget in widgets: widget_script = widget.get("script") if isinstance(widget_script, str) and widget_script.strip(): widget_clean = re.sub(WIDGET_TEMPLATE_REGEX, "", widget_script, flags=re.DOTALL) widget_oid = widget.get("oid", "unknown") widget_type = widget.get("type", "unknown") footer = ( f"// Dashboard last opened on {last_opened}\n" f"// Script is for widget type of {widget_type}\n" f"// To view widget URL Path is /app/main/dashboards/{oid}/widgets/{widget_oid}" ) out_path = widgets_dir / f"{widget_oid}_WidgetScript.js" write_script_file(widget_clean, str(out_path), footer) # ----------------------------------------------------------------------------- def main(): """Entry point: process all .dash files in the current directory.""" dash_files = list(Path(".").glob("*.dash")) if not dash_files: print("No .dash files found in the current folder.") return for dash_path in dash_files: process_dashboard_file(dash_path) if __name__ == "__main__": main()

Step 4: Run the Tool

If the dash files are saved in the same folder as the tool, run the following command to execute the Python script and extract and format all dashboard and widget scripts.

python sisense_script_extractor.py

The output will list all scripts found and saved, and the results folder will contain all scripts, formatted and with the footer comment.

Conclusion

This Python-based tool simplifies the extraction, formatting, and organization of scripts from exported Sisense dashboards. The structured outputs enable easier inspection, version control, organization, and migration of dashboard and widget scripts. As the script parameter is simply one parameter in an exported dash file, this code can easily be adapted to other dashboard or widget parameters beyond the “script” parameter, including extending to other dashboard or widget metadata parameters.

References/Related Content:

Disclaimer: This post outlines a potential custom workaround for a specific use case or provides instructions regarding a specific task. The solution may not work in all scenarios or Sisense versions, so we strongly recommend testing it in your environment before deployment. If you need further assistance with this, please let us know.

Updated 06-04-2025

1 Comment

  • JeremyFriedel's avatar
    JeremyFriedel
    Sisense Employee

    The introduction appears to be hidden by JS and CSS in some browsers, below is the article introduction:

    Sisense includes the capability to export all dashboard metadata in JSON format, both via the UI and via API. These include all metadata components of the dashboard and widgets, including widget and dashboard scripts. A common use case is to extract dashboard and widget scripts from one or more dashboard files, properly format JavaScript by converting escaped JSON strings into readable JavaScript, and remove default comment headers that are often present. This article provides a comprehensive Python script that automates extracting these scripts into separate files, formats them clearly, removes common default comments, organizes scripts by dashboard in separate folders, and adds a comment in each file indicating relevant details like the last viewed timestamp, widget type, and the URL to access the dashboard or widget.

    The code also appears to have had the line breaks removed:

    #!/usr/bin/env python3
    """
    sisense_script_extractor.py
    
    This script scans the current directory for all files ending with “.dash” (Sisense dashboard export file),
    extracts the script code stored in the dashboard-level `script` field and in each widget’s `script` field,
    beautifies (formats) the code, removes known default template comment blocks, and saves the cleaned and formatted scripts to a structured
    “results/{dashboard_title}_{dashboard_oid}” folder. At the end of each output file, it appends a JS comment
    indicating the dashboard’s lastOpened timestamp, widget type, and the relevant Sisense URL path.
    
    Usage:
        python sisense_script_extractor.py
    
    Dependencies:
        - jsbeautifier (install via `pip install jsbeautifier`)
    """
    
    
    import json
    import os
    import re
    from pathlib import Path
    import jsbeautifier as beautifier
    
    # Configuration constants
    RESULTS_DIR = Path("results")
    DEFAULT_TEMPLATE_DASHBOARD_SCRIPT = """/*
    Welcome to your Dashboard's Script.
    
    To learn how you can access the Widget and Dashboard objects, see the online documentation at https://sisense.dev/guides/js/extensions
    */"""
    WIDGET_TEMPLATE_REGEX = r"/\*.*?see the online documentation at.*?\*/"
    
    # -----------------------------------------------------------------------------
    def beautify_js_code(js_code: str) -> str:
        """Beautify JavaScript code using jsbeautifier with a 4-space indent."""
        opts = beautifier.default_options()
        opts.indent_size = 4
        return beautifier.beautify(js_code, opts)
    
    # -----------------------------------------------------------------------------
    def write_script_file(js_code: str, output_path: str, footer_comment: str) -> None:
        """Format JavaScript script, append footer comment, and write to specified file."""
        cleaned_code = beautify_js_code(js_code)
        full_content = cleaned_code + "\n\n" + footer_comment
        with open(output_path, "w", encoding="utf-8") as file:
            file.write(full_content)
        print(f"Wrote script to {output_path}")
    
    # -----------------------------------------------------------------------------
    def process_dashboard_file(dash_file_path: Path) -> None:
        """
        Load, extract, format, and save scripts from a Sisense dashboard file (.dash).
        """
        print(f"Processing dashboard file: {dash_file_path.name}")
        dashboard = json.loads(dash_file_path.read_text(encoding="utf-8"))
    
        # Create output directory: results/{title}_{oid}
        title_safe = dashboard.get("title", "dashboard").strip().replace(" ", "_")
        oid = dashboard.get("oid", "unknown")
        dashboard_output_dir = RESULTS_DIR / f"{title_safe}_{oid}"
        dashboard_output_dir.mkdir(parents=True, exist_ok=True)
    
        last_opened = dashboard.get("lastOpened", "unknown")
    
        # --- Dashboard-level script extraction and cleanup ---
        dash_script = dashboard.get("script")
        if isinstance(dash_script, str) and dash_script.strip():
            cleaned_dash = dash_script.replace(DEFAULT_TEMPLATE_DASHBOARD_SCRIPT, "")
            footer = (
                f"// Dashboard last opened on {last_opened}\n"
                f"// To view dashboard URL Path is /app/main/dashboards/{oid}"
            )
            out_path = dashboard_output_dir / "dashboard_script_1.js"
            write_script_file(cleaned_dash, str(out_path), footer)
    
        # --- Widget-level script extraction and cleanup ---
        widgets = dashboard.get("widgets", [])
        if isinstance(widgets, list):
            widgets_dir = dashboard_output_dir / "widgets"
            widgets_dir.mkdir(exist_ok=True)
            for widget in widgets:
                widget_script = widget.get("script")
                if isinstance(widget_script, str) and widget_script.strip():
                    widget_clean = re.sub(WIDGET_TEMPLATE_REGEX, "", widget_script, flags=re.DOTALL)
                    widget_oid = widget.get("oid", "unknown")
                    widget_type = widget.get("type", "unknown")
                    footer = (
                        f"// Dashboard last opened on {last_opened}\n"
                        f"// Script is for widget type of {widget_type}\n"
                        f"// To view widget URL Path is /app/main/dashboards/{oid}/widgets/{widget_oid}"
                    )
                    out_path = widgets_dir / f"{widget_oid}_WidgetScript.js"
                    write_script_file(widget_clean, str(out_path), footer)
    
    # -----------------------------------------------------------------------------
    def main():
        """Entry point: process all .dash files in the current directory."""
        dash_files = list(Path(".").glob("*.dash"))
        if not dash_files:
            print("No .dash files found in the current folder.")
            return
    
        for dash_path in dash_files:
            process_dashboard_file(dash_path)
    
    if __name__ == "__main__":
        main()