bito-code-review[bot] commented on code in PR #37434:
URL: https://github.com/apache/superset/pull/37434#discussion_r2733742515


##########
docs/docs/api.mdx:
##########
@@ -1,40 +1,590 @@
 ---
-title: API
+title: API Reference
 hide_title: true
 sidebar_position: 10
 ---
 
-import SwaggerUI from 'swagger-ui-react';
-import openapi from '/resources/openapi.json';
-import 'swagger-ui-react/swagger-ui.css';
 import { Alert } from 'antd';
 
-## API
+## REST API Reference
 
-Superset's public **REST API** follows the
-[OpenAPI specification](https://swagger.io/specification/), and is
-documented here. The docs below are generated using
-[Swagger React UI](https://www.npmjs.com/package/swagger-ui-react).
-
-:::resources
-- [Blog: The Superset REST 
API](https://preset.io/blog/2020-10-01-superset-api/)
-- [Blog: Accessing APIs with 
Superset](https://preset.io/blog/accessing-apis-with-superset/)
-:::
+Superset exposes a comprehensive **REST API** that follows the [OpenAPI 
specification](https://swagger.io/specification/).
+You can use this API to programmatically interact with Superset for 
automation, integrations, and custom applications.
 
 <Alert
   type="info"
-  message={
-    <div>
-      <strong>NOTE! </strong>
-      You can find an interactive version of this documentation on your local 
Superset
-      instance at <strong>/swagger/v1</strong> (unless disabled)
-    </div>
+  showIcon
+  message="Code Samples & Schema Documentation"
+  description={
+    <span>
+      Each endpoint includes ready-to-use code samples in 
<strong>cURL</strong>, <strong>Python</strong>, and <strong>JavaScript</strong>.
+      Browse the <a href="./schemas">Schema definitions</a> for detailed data 
model documentation.
+    </span>
   }
+  style={{ marginBottom: '24px' }}
 />
 
-<br />
-<br />
-<hr />
-<div className="swagger-container">
-  <SwaggerUI spec={openapi} />
-</div>
+---
+
+### Authentication
+
+Most API endpoints require authentication via JWT tokens.
+
+#### Quick Start
+
+```bash
+# 1. Get a JWT token
+curl -X POST http://localhost:8088/api/v1/security/login \
+  -H "Content-Type: application/json" \
+  -d '{"username": "admin", "password": "admin", "provider": "db"}'
+
+# 2. Use the access_token from the response
+curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
+  http://localhost:8088/api/v1/dashboard/
+```
+
+#### Security Endpoints
+
+| Method | Endpoint | Description |
+|--------|----------|-------------|
+| `GET` | [Get the CSRF token](./get-the-csrf-token) | 
`/api/v1/security/csrf_token/` |

Review Comment:
   <div>
   
   
   <div id="suggestion">
   <div id="issue"><b>Broken Documentation Links</b></div>
   <div id="fix">
   
   The updated API documentation includes numerous links to detailed endpoint 
documentation files (e.g., './get-the-csrf-token') that do not exist in the 
repository. This will result in broken links for users accessing the docs, 
potentially causing confusion or incorrect expectations about available 
documentation.
   </div>
   
   
   </div>
   
   
   
   
   <small><i>Code Review Run #d777be</i></small>
   </div>
   
   ---
   Should Bito avoid suggestions like this for future reviews? (<a 
href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
   - [ ] Yes, avoid them



##########
docs/yarn.lock:
##########
@@ -14243,16 +15205,44 @@ xss@^1.0.14:
     commander "^2.20.3"
     cssfilter "0.0.10"
 
+y18n@^5.0.5:
+  version "5.0.8"
+  resolved 
"https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55";
+  integrity 
sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
+
 yallist@^3.0.2:
   version "3.1.1"
   resolved 
"https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd";
   integrity 
sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
 
-yaml@^1.10.0:
[email protected]:
+  version "0.0.43"
+  resolved 
"https://registry.yarnpkg.com/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz#e8a23e6fb4c38076ab92995c5dca33f3d3d7c9bb";
+  integrity 
sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==
+
[email protected], yaml@^1.10.0:

Review Comment:
   <div>
   
   
   <div id="suggestion">
   <div id="issue"><b>Security vulnerability in yaml dependency</b></div>
   <div id="fix">
   
   The yaml package has been updated to version 1.10.2, which is affected by 
CVE-2023-2251, a high-severity vulnerability that allows denial of service via 
uncaught exception in the YAML parser. This could impact availability if the 
package processes untrusted YAML input. Upgrade to yaml version 2.2.2 or later 
to mitigate this risk.
   </div>
   
   
   </div>
   
   
   
   
   <small><i>Code Review Run #d777be</i></small>
   </div>
   
   ---
   Should Bito avoid suggestions like this for future reviews? (<a 
href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
   - [ ] Yes, avoid them



##########
docs/yarn.lock:
##########
@@ -8782,6 +9219,13 @@ js-yaml-loader@^1.2.2:
     loader-utils "^1.2.3"
     un-eval "^1.2.0"
 
[email protected]:

Review Comment:
   <div>
   
   
   <div id="suggestion">
   <div id="issue"><b>Security vulnerability in added dep</b></div>
   <div id="fix">
   
   This change adds js-yaml version 4.1.0, which has a known prototype 
pollution vulnerability (CVE-2025-64718). Although the package.json specifies 
^4.1.1, the lock file now includes the vulnerable version, potentially exposing 
the docs build to attacks if YAML parsing handles untrusted input. Consider 
updating dependencies to resolve to the patched version.
   </div>
   
   
   </div>
   
   
   
   
   <small><i>Code Review Run #d777be</i></small>
   </div>
   
   ---
   Should Bito avoid suggestions like this for future reviews? (<a 
href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
   - [ ] Yes, avoid them



##########
docs/scripts/fix-openapi-spec.py:
##########
@@ -0,0 +1,828 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+"""
+Fix missing schema references in the OpenAPI spec.
+
+This script patches the openapi.json file to add any missing schemas
+that are referenced but not defined.
+"""
+
+import json  # noqa: TID251 - standalone docs script
+import sys
+from pathlib import Path
+from typing import Any
+
+
+def add_missing_schemas(spec: dict[str, Any]) -> tuple[dict[str, Any], 
list[str]]:
+    """Add missing schema definitions to the OpenAPI spec."""
+    schemas = spec.get("components", {}).get("schemas", {})
+    fixed = []
+
+    # DashboardScreenshotPostSchema - based on superset/dashboards/schemas.py
+    if "DashboardScreenshotPostSchema" not in schemas:
+        schemas["DashboardScreenshotPostSchema"] = {
+            "type": "object",
+            "properties": {
+                "dataMask": {
+                    "type": "object",
+                    "description": "An object representing the data mask.",
+                    "additionalProperties": True,
+                },
+                "activeTabs": {
+                    "type": "array",
+                    "items": {"type": "string"},
+                    "description": "A list representing active tabs.",
+                },
+                "anchor": {
+                    "type": "string",
+                    "description": "A string representing the anchor.",
+                },
+                "urlParams": {
+                    "type": "array",
+                    "items": {
+                        "type": "array",
+                        "items": {"type": "string"},
+                        "minItems": 2,
+                        "maxItems": 2,
+                    },
+                    "description": "A list of tuples, each containing two 
strings.",
+                },
+            },
+        }
+        fixed.append("DashboardScreenshotPostSchema")
+
+    # DashboardNativeFiltersConfigUpdateSchema - based on 
superset/dashboards/schemas.py
+    if "DashboardNativeFiltersConfigUpdateSchema" not in schemas:
+        schemas["DashboardNativeFiltersConfigUpdateSchema"] = {
+            "type": "object",
+            "properties": {
+                "deleted": {
+                    "type": "array",
+                    "items": {"type": "string"},
+                    "description": "List of deleted filter IDs.",
+                },
+                "modified": {
+                    "type": "array",
+                    "items": {"type": "object"},
+                    "description": "List of modified filter configurations.",
+                },
+                "reordered": {
+                    "type": "array",
+                    "items": {"type": "string"},
+                    "description": "List of filter IDs in new order.",
+                },
+            },
+        }
+        fixed.append("DashboardNativeFiltersConfigUpdateSchema")
+
+    # DashboardColorsConfigUpdateSchema - based on 
superset/dashboards/schemas.py
+    if "DashboardColorsConfigUpdateSchema" not in schemas:
+        schemas["DashboardColorsConfigUpdateSchema"] = {
+            "type": "object",
+            "properties": {
+                "color_namespace": {
+                    "type": "string",
+                    "nullable": True,
+                    "description": "The color namespace.",
+                },
+                "color_scheme": {
+                    "type": "string",
+                    "nullable": True,
+                    "description": "The color scheme name.",
+                },
+                "map_label_colors": {
+                    "type": "object",
+                    "additionalProperties": {"type": "string"},
+                    "description": "Mapping of labels to colors.",
+                },
+                "shared_label_colors": {
+                    "type": "object",
+                    "additionalProperties": {"type": "string"},
+                    "description": "Shared label colors across charts.",
+                },
+                "label_colors": {
+                    "type": "object",
+                    "additionalProperties": {"type": "string"},
+                    "description": "Label to color mapping.",
+                },
+                "color_scheme_domain": {
+                    "type": "array",
+                    "items": {"type": "string"},
+                    "description": "Color scheme domain values.",
+                },
+            },
+        }
+        fixed.append("DashboardColorsConfigUpdateSchema")
+
+    # FormatQueryPayloadSchema - based on superset/sqllab/schemas.py
+    if "FormatQueryPayloadSchema" not in schemas:
+        schemas["FormatQueryPayloadSchema"] = {
+            "type": "object",
+            "required": ["sql"],
+            "properties": {
+                "sql": {
+                    "type": "string",
+                    "description": "The SQL query to format.",
+                },
+                "engine": {
+                    "type": "string",
+                    "nullable": True,
+                    "description": "The database engine.",
+                },
+                "database_id": {
+                    "type": "integer",
+                    "nullable": True,
+                    "description": "The database id.",
+                },
+                "template_params": {
+                    "type": "string",
+                    "nullable": True,
+                    "description": "The SQL query template params as JSON 
string.",
+                },
+            },
+        }
+        fixed.append("FormatQueryPayloadSchema")
+
+    # get_slack_channels_schema - based on superset/reports/schemas.py
+    if "get_slack_channels_schema" not in schemas:
+        schemas["get_slack_channels_schema"] = {
+            "type": "object",
+            "properties": {
+                "search_string": {
+                    "type": "string",
+                    "description": "String to search for in channel names.",
+                },
+                "types": {
+                    "type": "array",
+                    "items": {
+                        "type": "string",
+                        "enum": ["public_channel", "private_channel"],
+                    },
+                    "description": "Types of channels to search.",
+                },
+                "exact_match": {
+                    "type": "boolean",
+                    "description": "Whether to match channel names exactly.",
+                },
+            },
+        }
+        fixed.append("get_slack_channels_schema")
+
+    if "components" not in spec:
+        spec["components"] = {}
+    spec["components"]["schemas"] = schemas
+
+    return spec, fixed
+
+
+def path_to_operation_id(path: str, method: str) -> str:
+    """Convert a path and method to an operationId."""
+    # Remove /api/v1/ prefix
+    clean_path = path.replace("/api/v1/", "").strip("/")
+
+    # Replace path parameters
+    clean_path = clean_path.replace("{", "by_").replace("}", "")
+
+    # Create operation name
+    method_prefix = {
+        "get": "get",
+        "post": "create",
+        "put": "update",
+        "delete": "delete",
+        "patch": "patch",
+    }.get(method.lower(), method.lower())
+
+    return f"{method_prefix}_{clean_path}".replace("/", "_").replace("-", "_")
+
+
+def path_to_summary(path: str, method: str) -> str:
+    """Generate a human-readable summary from path and method."""
+    # Remove /api/v1/ prefix
+    clean_path = path.replace("/api/v1/", "").strip("/")
+
+    # Handle path parameters
+    parts = []
+    for part in clean_path.split("/"):
+        if part.startswith("{") and part.endswith("}"):
+            param = part[1:-1]
+            parts.append(f"by {param}")
+        else:
+            parts.append(part.replace("_", " ").replace("-", " "))
+
+    resource = " ".join(parts)
+
+    method_verb = {
+        "get": "Get",
+        "post": "Create",
+        "put": "Update",
+        "delete": "Delete",
+        "patch": "Update",
+    }.get(method.lower(), method.capitalize())
+
+    return f"{method_verb} {resource}"
+
+
+def add_missing_operation_ids(spec: dict[str, Any]) -> int:
+    """Add operationId and summary to operations that are missing them."""
+    fixed_count = 0
+
+    for path, methods in spec.get("paths", {}).items():
+        for method, details in methods.items():
+            if method not in ["get", "post", "put", "delete", "patch"]:
+                continue
+
+            if not isinstance(details, dict):
+                continue
+
+            summary = details.get("summary")
+            operation_id = details.get("operationId")
+
+            if not summary and not operation_id:
+                details["operationId"] = path_to_operation_id(path, method)
+                details["summary"] = path_to_summary(path, method)
+                fixed_count += 1
+
+    return fixed_count
+
+
+TAG_DESCRIPTIONS = {
+    "Advanced Data Type": "Advanced data type operations and conversions.",
+    "Annotation Layers": "Manage annotation layers and annotations for 
charts.",
+    "AsyncEventsRestApi": "Real-time event streaming via Server-Sent Events 
(SSE).",
+    "Available Domains": "Get available domains for the Superset instance.",
+    "CSS Templates": "Manage CSS templates for custom dashboard styling.",
+    "CacheRestApi": "Cache management and invalidation operations.",
+    "Charts": "Create, read, update, and delete charts (slices).",
+    "Current User": "Get information about the authenticated user.",
+    "Dashboard Filter State": "Manage temporary filter state for dashboards.",
+    "Dashboard Permanent Link": "Permanent links to dashboard states.",
+    "Dashboards": "Create, read, update, and delete dashboards.",
+    "Database": "Manage database connections and metadata.",
+    "Datasets": "Manage datasets (tables) used for building charts.",
+    "Datasources": "Query datasource metadata and column values.",
+    "Embedded Dashboard": "Configure embedded dashboard settings.",
+    "Explore": "Chart exploration and data querying endpoints.",
+    "Explore Form Data": "Manage temporary form data for chart exploration.",
+    "Explore Permanent Link": "Permanent links to chart explore states.",
+    "Import/export": "Import and export Superset assets.",
+    "LogRestApi": "Access audit logs and activity history.",
+    "Menu": "Get the Superset menu structure.",
+    "OpenApi": "Access the OpenAPI specification.",
+    "Queries": "View and manage SQL Lab query history.",
+    "Report Schedules": "Configure scheduled reports and alerts.",
+    "Row Level Security": "Manage row-level security rules for data access.",
+    "SQL Lab": "Execute SQL queries and manage SQL Lab sessions.",
+    "SQL Lab Permanent Link": "Permanent links to SQL Lab states.",
+    "Security": "Authentication and token management.",
+    "Security Permissions": "View available permissions.",
+    "Security Permissions on Resources (View Menus)": "Permission-resource 
mappings.",
+    "Security Resources (View Menus)": "Manage security resources (view 
menus).",
+    "Security Roles": "Manage security roles and their permissions.",
+    "Security Users": "Manage user accounts.",
+    "Tags": "Organize assets with tags.",
+    "User": "User profile and preferences.",
+}
+
+
+def generate_code_sample(
+    method: str, path: str, has_body: bool = False
+) -> list[dict[str, str]]:
+    """Generate code samples for an endpoint in multiple languages."""
+    # Clean up path for display
+    example_path = path.replace("{pk}", "1").replace("{id_or_slug}", "1")
+
+    samples = []
+
+    # cURL sample
+    curl_cmd = f'curl -X {method.upper()} 
"http://localhost:8088{example_path}";'
+    curl_cmd += ' \\\n  -H "Authorization: Bearer $ACCESS_TOKEN"'
+    if has_body:
+        curl_cmd += ' \\\n  -H "Content-Type: application/json"'
+        curl_cmd += ' \\\n  -d \'{"key": "value"}\''
+
+    samples.append(
+        {
+            "lang": "cURL",
+            "label": "cURL",
+            "source": curl_cmd,
+        }
+    )
+
+    # Python sample
+    if method.lower() == "get":
+        python_code = f"""import requests
+
+response = requests.get(
+    "http://localhost:8088{example_path}";,
+    headers={{"Authorization": "Bearer " + access_token}}
+)
+print(response.json())"""
+    elif method.lower() == "post":
+        python_code = f"""import requests
+
+response = requests.post(
+    "http://localhost:8088{example_path}";,
+    headers={{"Authorization": "Bearer " + access_token}},
+    json={{"key": "value"}}
+)
+print(response.json())"""
+    elif method.lower() == "put":
+        python_code = f"""import requests
+
+response = requests.put(
+    "http://localhost:8088{example_path}";,
+    headers={{"Authorization": "Bearer " + access_token}},
+    json={{"key": "value"}}
+)
+print(response.json())"""
+    elif method.lower() == "delete":
+        python_code = f"""import requests
+
+response = requests.delete(
+    "http://localhost:8088{example_path}";,
+    headers={{"Authorization": "Bearer " + access_token}}
+)
+print(response.status_code)"""
+    else:
+        python_code = f"""import requests
+
+response = requests.{method.lower()}(
+    "http://localhost:8088{example_path}";,
+    headers={{"Authorization": "Bearer " + access_token}}
+)
+print(response.json())"""
+
+    samples.append(
+        {
+            "lang": "Python",
+            "label": "Python",
+            "source": python_code,
+        }
+    )
+
+    # JavaScript sample
+    if method.lower() == "get":
+        js_code = f"""const response = await fetch(
+  "http://localhost:8088{example_path}";,
+  {{
+    headers: {{
+      "Authorization": `Bearer ${{accessToken}}`
+    }}
+  }}
+);
+const data = await response.json();
+console.log(data);"""
+    elif method.lower() in ["post", "put", "patch"]:
+        js_code = f"""const response = await fetch(
+  "http://localhost:8088{example_path}";,
+  {{
+    method: "{method.upper()}",
+    headers: {{
+      "Authorization": `Bearer ${{accessToken}}`,
+      "Content-Type": "application/json"
+    }},
+    body: JSON.stringify({{ key: "value" }})
+  }}
+);
+const data = await response.json();
+console.log(data);"""
+    else:
+        js_code = f"""const response = await fetch(
+  "http://localhost:8088{example_path}";,
+  {{
+    method: "{method.upper()}",
+    headers: {{
+      "Authorization": `Bearer ${{accessToken}}`
+    }}
+  }}
+);
+console.log(response.status);"""
+
+    samples.append(
+        {
+            "lang": "JavaScript",
+            "label": "JavaScript",
+            "source": js_code,
+        }
+    )
+
+    return samples

Review Comment:
   <div>
   
   
   <div id="suggestion">
   <div id="issue"><b>Undefined variables in code samples</b></div>
   <div id="fix">
   
   The generated code samples reference undefined variables, causing runtime 
errors when users copy the examples.
   </div>
   
   
   </div>
   
   
   
   
   <small><i>Code Review Run #251f5b</i></small>
   </div><div>
   
   
   <div id="suggestion">
   <div id="issue"><b>Runtime Error in Code Samples</b></div>
   <div id="fix">
   
   The generate_code_sample function produces code samples with undefined 
variables (access_token in Python, accessToken in JavaScript), leading to 
runtime errors if users copy and run the samples. This affects all HTTP method 
branches in the function.
   </div>
   
   
   </div>
   
   
   
   
   <small><i>Code Review Run #d777be</i></small>
   </div>
   
   ---
   Should Bito avoid suggestions like this for future reviews? (<a 
href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
   - [ ] Yes, avoid them



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to