fix: add missing impact and requires_restart fields to config metadata

- Added infer_impact() function to determine configuration impact levels
- Added infer_requires_restart() function to determine restart requirements
- Updated export_config_metadata.py to include these fields in JSON output
- Fixes ConfigurationTable.tsx error: "Cannot read properties of undefined (reading 'toUpperCase')"
- All 218 configuration settings now include impact and requires_restart fields
- Fixed type annotations and linting issues in extract_config_schema.py

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Maxime Beauchemin
2025-07-18 02:59:18 -07:00
parent 30e731a15b
commit a21a1824e3
5 changed files with 9044 additions and 186 deletions

View File

@@ -2,13 +2,14 @@
"""
Export configuration metadata to JSON for documentation generation.
This script extracts configuration metadata from SupersetConfig and generates
JSON files that can be imported into the documentation site.
This script loads the comprehensive configuration schema from config_schema.json
and formats it for documentation generation.
This script is called by docs/scripts/generate_docs.sh as part of the
unified documentation generation process.
"""
import json as json_module
import sys
from pathlib import Path
from typing import Any, Dict, List
@@ -17,55 +18,113 @@ from typing import Any, Dict, List
superset_root = Path(__file__).parent.parent.parent
sys.path.insert(0, str(superset_root))
from superset.config_extensions import SupersetConfig # noqa: E402
from superset.utils import json # noqa: E402
def infer_impact(key: str) -> str:
"""Infer the impact level based on the configuration key name."""
name_lower = key.lower()
# High impact - security, database, core functionality
if any(
term in name_lower
for term in [
"secret",
"key",
"password",
"database",
"uri",
"url",
"security",
"auth",
]
):
return "high"
# Medium impact - performance, features, UI
elif any(
term in name_lower
for term in ["limit", "timeout", "cache", "feature", "flag", "theme"]
):
return "medium"
# Low impact - logging, debugging, minor settings
else:
return "low"
def infer_requires_restart(key: str) -> bool:
"""Infer if the configuration requires a restart based on the key name."""
name_lower = key.lower()
# These typically require restart
if any(
term in name_lower
for term in [
"secret",
"key",
"database",
"uri",
"url",
"security",
"auth",
"ssl",
"tls",
]
):
return True
# These typically don't require restart
elif any(
term in name_lower for term in ["limit", "timeout", "cache", "log", "debug"]
):
return False
# Default to requiring restart for safety
return True
def export_config_metadata() -> List[Dict[str, Any]]:
"""Export configuration metadata as JSON."""
config = SupersetConfig()
# Load the comprehensive configuration schema
schema_file = superset_root / "superset" / "config_schema.json"
# Get all settings metadata
settings_metadata = config.DATABASE_SETTINGS_SCHEMA
if not schema_file.exists():
print(
"Warning: config_schema.json not found. "
"Please run scripts/extract_config_schema.py first."
)
return []
with open(schema_file, "r") as f:
schema_data = json_module.load(f)
configs = schema_data.get("configs", {})
# Transform metadata for documentation
docs_metadata = []
for key, schema in settings_metadata.items():
# Skip readonly settings for user documentation
if schema.get("readonly", False):
continue
for key, config in configs.items():
# Build environment variable name
env_var = f"SUPERSET__{key}"
# Extract nested example if available
nested_example = None
if schema.get("type") == "object" and "example" in schema:
if config.get("type") == "object":
nested_example = f"SUPERSET__{key}__example__nested_key=value"
# Format type information
type_info = str(schema.get("type", "unknown"))
if type_info == "integer":
min_val = schema.get("minimum")
max_val = schema.get("maximum")
if min_val is not None or max_val is not None:
min_str = str(min_val) if min_val is not None else "N/A"
max_str = str(max_val) if max_val is not None else "N/A"
type_info += f" ({min_str} - {max_str})"
# Format type information (keep it simple, no boundaries)
type_info = str(config.get("type", "unknown"))
doc_entry = {
"key": key,
"title": schema.get("title", key),
"description": schema.get("description", ""),
"title": key.replace("_", " ").title(), # Convert SNAKE_CASE to Title Case
"description": config.get("description", ""),
"type": type_info,
"category": schema.get("category", "general"),
"impact": schema.get("impact", "medium"),
"requires_restart": schema.get("requires_restart", True),
"default": schema.get("default"),
"category": config.get("category", "general"),
"default": config.get("default"),
"env_var": env_var,
"nested_example": nested_example,
"documentation_url": schema.get("documentation_url"),
"impact": infer_impact(key),
"requires_restart": infer_requires_restart(key),
}
docs_metadata.append(doc_entry)
@@ -88,15 +147,14 @@ def export_config_metadata() -> List[Dict[str, Any]]:
# Export all settings
with open(output_dir / "config_metadata.json", "w") as f:
f.write(
json.dumps(
{
"all_settings": docs_metadata,
"by_category": categories,
"categories": list(categories.keys()),
},
indent=2,
)
json_module.dump(
{
"all_settings": docs_metadata,
"by_category": categories,
"categories": list(categories.keys()),
},
f,
indent=2,
)
output_file = output_dir / "config_metadata.json"

View File

@@ -30,9 +30,9 @@ cd "$(dirname "$0")/.."
# Track any failures
FAILED_TASKS=()
# 1. Export configuration metadata
echo "📊 Exporting configuration metadata..."
if python scripts/export_config_metadata.py; then
# 1. Extract configuration schema and export metadata
echo "📊 Extracting configuration schema and exporting metadata..."
if python ../scripts/extract_config_schema.py && python scripts/export_config_metadata.py; then
echo "✅ Configuration metadata exported successfully"
else
echo "⚠️ Warning: Failed to export configuration metadata"
@@ -47,7 +47,6 @@ import sys
sys.path.insert(0, '..')
from superset.app import create_app
from superset.cli.update import update_api_docs
from flask.cli import with_appcontext
import os
# Set required environment variables