subagents

This commit is contained in:
2026-03-20 17:20:24 +03:00
parent b89b9a66f2
commit 1149e8df1d
36 changed files with 4313 additions and 327 deletions

View File

@@ -35,6 +35,7 @@ class SupersetClient:
# @PRE: `env` должен быть валидным объектом Environment.
# @POST: Атрибуты `env` и `network` созданы и готовы к работе.
# @DATA_CONTRACT: Input[Environment] -> self.network[APIClient]
# @RELATION: [DEPENDS_ON] ->[Environment]
# @RELATION: [DEPENDS_ON] ->[APIClient]
def __init__(self, env: Environment):
with belief_scope("__init__"):
@@ -311,7 +312,7 @@ class SupersetClient:
})
return total_count, result
# [/DEF:backend.src.core.superset_client.SupersetClient.get_dashboards_summary_page:Function]
# [/DEF:SupersetClient.get_dashboards_summary_page:Function]
# [DEF:SupersetClient._extract_owner_labels:Function]
# @COMPLEXITY: 1
@@ -368,9 +369,9 @@ class SupersetClient:
if email:
return email
return None
# [/DEF:backend.src.core.superset_client.SupersetClient._extract_user_display:Function]
# [/DEF:SupersetClient._extract_user_display:Function]
# [DEF:backend.src.core.superset_client.SupersetClient._sanitize_user_text:Function]
# [DEF:SupersetClient._sanitize_user_text:Function]
# @COMPLEXITY: 1
# @PURPOSE: Convert scalar value to non-empty user-facing text.
# @PRE: value can be any scalar type.
@@ -382,7 +383,7 @@ class SupersetClient:
if not normalized:
return None
return normalized
# [/DEF:backend.src.core.superset_client.SupersetClient._sanitize_user_text:Function]
# [/DEF:SupersetClient._sanitize_user_text:Function]
# [DEF:SupersetClient.get_dashboard:Function]
# @COMPLEXITY: 3
@@ -413,6 +414,206 @@ class SupersetClient:
return cast(Dict, response)
# [/DEF:SupersetClient.get_dashboard_permalink_state:Function]
# [DEF:SupersetClient.get_native_filter_state:Function]
# @COMPLEXITY: 2
# @PURPOSE: Fetches stored native filter state by filter state key.
# @PRE: Client is authenticated and filter_state_key exists.
# @POST: Returns native filter state payload from Superset API.
# @DATA_CONTRACT: Input[dashboard_id: Union[int, str], filter_state_key: str] -> Output[Dict]
# @RELATION: [CALLS] ->[APIClient.request]
def get_native_filter_state(self, dashboard_id: Union[int, str], filter_state_key: str) -> Dict:
with belief_scope("SupersetClient.get_native_filter_state", f"dashboard={dashboard_id}, key={filter_state_key}"):
response = self.network.request(
method="GET",
endpoint=f"/dashboard/{dashboard_id}/filter_state/{filter_state_key}"
)
return cast(Dict, response)
# [/DEF:SupersetClient.get_native_filter_state:Function]
# [DEF:SupersetClient.extract_native_filters_from_permalink:Function]
# @COMPLEXITY: 3
# @PURPOSE: Extract native filters dataMask from a permalink key.
# @PRE: Client is authenticated and permalink_key exists.
# @POST: Returns extracted dataMask with filter states.
# @DATA_CONTRACT: Input[permalink_key: str] -> Output[Dict]
# @RELATION: [CALLS] ->[SupersetClient.get_dashboard_permalink_state]
def extract_native_filters_from_permalink(self, permalink_key: str) -> Dict:
with belief_scope("SupersetClient.extract_native_filters_from_permalink", f"key={permalink_key}"):
permalink_response = self.get_dashboard_permalink_state(permalink_key)
# Permalink response structure: { "result": { "state": { "dataMask": {...}, ... } } }
# or directly: { "state": { "dataMask": {...}, ... } }
result = permalink_response.get("result", permalink_response)
state = result.get("state", result)
data_mask = state.get("dataMask", {})
extracted_filters = {}
for filter_id, filter_data in data_mask.items():
if not isinstance(filter_data, dict):
continue
extracted_filters[filter_id] = {
"extraFormData": filter_data.get("extraFormData", {}),
"filterState": filter_data.get("filterState", {}),
"ownState": filter_data.get("ownState", {}),
}
return {
"dataMask": extracted_filters,
"activeTabs": state.get("activeTabs", []),
"anchor": state.get("anchor"),
"chartStates": state.get("chartStates", {}),
"permalink_key": permalink_key,
}
# [/DEF:SupersetClient.extract_native_filters_from_permalink:Function]
# [DEF:SupersetClient.extract_native_filters_from_key:Function]
# @COMPLEXITY: 3
# @PURPOSE: Extract native filters from a native_filters_key URL parameter.
# @PRE: Client is authenticated, dashboard_id and filter_state_key exist.
# @POST: Returns extracted filter state with extraFormData.
# @DATA_CONTRACT: Input[dashboard_id: Union[int, str], filter_state_key: str] -> Output[Dict]
# @RELATION: [CALLS] ->[SupersetClient.get_native_filter_state]
def extract_native_filters_from_key(self, dashboard_id: Union[int, str], filter_state_key: str) -> Dict:
with belief_scope("SupersetClient.extract_native_filters_from_key", f"dashboard={dashboard_id}, key={filter_state_key}"):
filter_response = self.get_native_filter_state(dashboard_id, filter_state_key)
# Filter state response structure: { "result": { "value": "{...json...}" } }
# or: { "value": "{...json...}" }
result = filter_response.get("result", filter_response)
value = result.get("value")
if isinstance(value, str):
try:
parsed_value = json.loads(value)
except json.JSONDecodeError as e:
app_logger.warning("[extract_native_filters_from_key][Warning] Failed to parse filter state JSON: %s", e)
parsed_value = {}
elif isinstance(value, dict):
parsed_value = value
else:
parsed_value = {}
# The parsed value contains filter state with structure:
# { "filter_id": { "id": "...", "extraFormData": {...}, "filterState": {...} } }
# or a single filter: { "id": "...", "extraFormData": {...}, "filterState": {...} }
extracted_filters = {}
if "id" in parsed_value and "extraFormData" in parsed_value:
# Single filter format
filter_id = parsed_value.get("id", filter_state_key)
extracted_filters[filter_id] = {
"extraFormData": parsed_value.get("extraFormData", {}),
"filterState": parsed_value.get("filterState", {}),
"ownState": parsed_value.get("ownState", {}),
}
else:
# Multiple filters format
for filter_id, filter_data in parsed_value.items():
if not isinstance(filter_data, dict):
continue
extracted_filters[filter_id] = {
"extraFormData": filter_data.get("extraFormData", {}),
"filterState": filter_data.get("filterState", {}),
"ownState": filter_data.get("ownState", {}),
}
return {
"dataMask": extracted_filters,
"dashboard_id": dashboard_id,
"filter_state_key": filter_state_key,
}
# [/DEF:SupersetClient.extract_native_filters_from_key:Function]
# [DEF:SupersetClient.parse_dashboard_url_for_filters:Function]
# @COMPLEXITY: 3
# @PURPOSE: Parse a Superset dashboard URL and extract native filter state if present.
# @PRE: url must be a valid Superset dashboard URL with optional permalink or native_filters_key.
# @POST: Returns extracted filter state or empty dict if no filters found.
# @DATA_CONTRACT: Input[url: str] -> Output[Dict]
# @RELATION: [CALLS] ->[SupersetClient.extract_native_filters_from_permalink]
# @RELATION: [CALLS] ->[SupersetClient.extract_native_filters_from_key]
def parse_dashboard_url_for_filters(self, url: str) -> Dict:
with belief_scope("SupersetClient.parse_dashboard_url_for_filters", f"url={url}"):
import urllib.parse
parsed_url = urllib.parse.urlparse(url)
query_params = urllib.parse.parse_qs(parsed_url.query)
path_parts = parsed_url.path.rstrip("/").split("/")
result = {
"url": url,
"dashboard_id": None,
"filter_type": None,
"filters": {},
}
# Check for permalink URL: /dashboard/p/{key}/ or /superset/dashboard/p/{key}/
if "p" in path_parts:
try:
p_index = path_parts.index("p")
if p_index + 1 < len(path_parts):
permalink_key = path_parts[p_index + 1]
filter_data = self.extract_native_filters_from_permalink(permalink_key)
result["filter_type"] = "permalink"
result["filters"] = filter_data
return result
except ValueError:
pass
# Check for native_filters_key in query params
native_filters_key = query_params.get("native_filters_key", [None])[0]
if native_filters_key:
# Extract dashboard ID or slug from URL path
dashboard_ref = None
if "dashboard" in path_parts:
try:
dash_index = path_parts.index("dashboard")
if dash_index + 1 < len(path_parts):
potential_id = path_parts[dash_index + 1]
# Skip if it's a reserved word
if potential_id not in ("p", "list", "new"):
dashboard_ref = potential_id
except ValueError:
pass
if dashboard_ref:
# Resolve slug to numeric ID — the filter_state API requires a numeric ID
resolved_id = None
try:
resolved_id = int(dashboard_ref)
except (ValueError, TypeError):
try:
dash_resp = self.get_dashboard(dashboard_ref)
dash_data = dash_resp.get("result", dash_resp) if isinstance(dash_resp, dict) else {}
raw_id = dash_data.get("id")
if raw_id is not None:
resolved_id = int(raw_id)
except Exception as e:
app_logger.warning("[parse_dashboard_url_for_filters][Warning] Failed to resolve dashboard slug '%s' to ID: %s", dashboard_ref, e)
if resolved_id is not None:
filter_data = self.extract_native_filters_from_key(resolved_id, native_filters_key)
result["filter_type"] = "native_filters_key"
result["dashboard_id"] = resolved_id
result["filters"] = filter_data
return result
else:
app_logger.warning("[parse_dashboard_url_for_filters][Warning] Could not resolve dashboard_id from URL for native_filters_key")
# Check for native_filters in query params (direct filter values)
native_filters = query_params.get("native_filters", [None])[0]
if native_filters:
try:
parsed_filters = json.loads(native_filters)
result["filter_type"] = "native_filters"
result["filters"] = {"dataMask": parsed_filters}
return result
except json.JSONDecodeError as e:
app_logger.warning("[parse_dashboard_url_for_filters][Warning] Failed to parse native_filters JSON: %s", e)
return result
# [/DEF:SupersetClient.parse_dashboard_url_for_filters:Function]
# [DEF:SupersetClient.get_chart:Function]
# @COMPLEXITY: 3
# @PURPOSE: Fetches a single chart by ID.
@@ -911,13 +1112,13 @@ class SupersetClient:
return result
# [/DEF:backend.src.core.superset_client.SupersetClient.get_dataset_detail:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.get_dataset:Function]
# [DEF:SupersetClient.get_dataset:Function]
# @COMPLEXITY: 3
# @PURPOSE: Получает информацию о конкретном датасете по его ID.
# @PRE: dataset_id must exist.
# @POST: Returns dataset details.
# @DATA_CONTRACT: Input[dataset_id: int] -> Output[Dict]
# @RELATION: [CALLS] ->[backend.src.core.utils.network.APIClient.request]
# @RELATION: [CALLS] ->[APIClient.request]
def get_dataset(self, dataset_id: int) -> Dict:
with belief_scope("SupersetClient.get_dataset", f"id={dataset_id}"):
app_logger.info("[get_dataset][Enter] Fetching dataset %s.", dataset_id)
@@ -925,19 +1126,20 @@ class SupersetClient:
response = cast(Dict, response)
app_logger.info("[get_dataset][Exit] Got dataset %s.", dataset_id)
return response
# [/DEF:backend.src.core.superset_client.SupersetClient.get_dataset:Function]
# [/DEF:SupersetClient.get_dataset:Function]
# [DEF:SupersetClient.compile_dataset_preview:Function]
# @COMPLEXITY: 4
# @PURPOSE: Compile dataset preview SQL through the real Superset chart-data endpoint and return normalized SQL output.
# @PURPOSE: Compile dataset preview SQL through the strongest supported Superset preview endpoint family and return normalized SQL output.
# @PRE: dataset_id must be valid and template_params/effective_filters must represent the current preview session inputs.
# @POST: Returns normalized compiled SQL plus raw upstream response without guessing unsupported endpoints.
# @POST: Returns normalized compiled SQL plus raw upstream response, preferring legacy form_data transport with explicit fallback to chart-data.
# @DATA_CONTRACT: Input[dataset_id:int, template_params:Dict, effective_filters:List[Dict]] -> Output[Dict[str, Any]]
# @RELATION: [CALLS] ->[SupersetClient.get_dataset]
# @RELATION: [CALLS] ->[SupersetClient.build_dataset_preview_query_context]
# @RELATION: [CALLS] ->[SupersetClient.build_dataset_preview_legacy_form_data]
# @RELATION: [CALLS] ->[APIClient.request]
# @RELATION: [CALLS] ->[SupersetClient._extract_compiled_sql_from_chart_data_response]
# @SIDE_EFFECT: Performs upstream dataset lookup and chart-data network I/O against Superset.
# @RELATION: [CALLS] ->[SupersetClient._extract_compiled_sql_from_preview_response]
# @SIDE_EFFECT: Performs upstream dataset lookup and preview network I/O against Superset.
def compile_dataset_preview(
self,
dataset_id: int,
@@ -945,14 +1147,6 @@ class SupersetClient:
effective_filters: Optional[List[Dict[str, Any]]] = None,
) -> Dict[str, Any]:
with belief_scope("SupersetClient.compile_dataset_preview", f"id={dataset_id}"):
app_logger.reason(
"Compiling dataset preview via Superset chart-data endpoint",
extra={
"dataset_id": dataset_id,
"template_param_count": len(template_params or {}),
"filter_count": len(effective_filters or []),
},
)
dataset_response = self.get_dataset(dataset_id)
dataset_record = dataset_response.get("result", dataset_response) if isinstance(dataset_response, dict) else {}
query_context = self.build_dataset_preview_query_context(
@@ -961,31 +1155,197 @@ class SupersetClient:
template_params=template_params or {},
effective_filters=effective_filters or [],
)
response = self.network.request(
method="POST",
endpoint="/chart/data",
data=json.dumps(query_context),
headers={"Content-Type": "application/json"},
legacy_form_data = self.build_dataset_preview_legacy_form_data(
dataset_id=dataset_id,
dataset_record=dataset_record,
template_params=template_params or {},
effective_filters=effective_filters or [],
)
normalized = self._extract_compiled_sql_from_chart_data_response(response)
normalized["query_context"] = query_context
legacy_form_data_payload = json.dumps(legacy_form_data, sort_keys=True, default=str)
request_payload = json.dumps(query_context)
strategy_attempts: List[Dict[str, Any]] = []
strategy_candidates: List[Dict[str, Any]] = [
{
"endpoint_kind": "legacy_explore_form_data",
"endpoint": "/explore_json/form_data",
"request_transport": "query_param_form_data",
"params": {"form_data": legacy_form_data_payload},
},
{
"endpoint_kind": "legacy_data_form_data",
"endpoint": "/data",
"request_transport": "query_param_form_data",
"params": {"form_data": legacy_form_data_payload},
},
{
"endpoint_kind": "v1_chart_data",
"endpoint": "/chart/data",
"request_transport": "json_body",
"data": request_payload,
"headers": {"Content-Type": "application/json"},
},
]
for candidate in strategy_candidates:
endpoint_kind = candidate["endpoint_kind"]
endpoint_path = candidate["endpoint"]
request_transport = candidate["request_transport"]
request_params = deepcopy(candidate.get("params") or {})
request_body = candidate.get("data")
request_headers = deepcopy(candidate.get("headers") or {})
request_param_keys = sorted(request_params.keys())
request_payload_keys: List[str] = []
if isinstance(request_body, str):
try:
decoded_request_body = json.loads(request_body)
if isinstance(decoded_request_body, dict):
request_payload_keys = sorted(decoded_request_body.keys())
except json.JSONDecodeError:
request_payload_keys = []
elif isinstance(request_body, dict):
request_payload_keys = sorted(request_body.keys())
strategy_diagnostics = {
"endpoint": endpoint_path,
"endpoint_kind": endpoint_kind,
"request_transport": request_transport,
"contains_root_datasource": endpoint_kind == "v1_chart_data" and "datasource" in query_context,
"contains_form_datasource": endpoint_kind.startswith("legacy_") and "datasource" in legacy_form_data,
"contains_query_object_datasource": bool(query_context.get("queries")) and isinstance(query_context["queries"][0], dict) and "datasource" in query_context["queries"][0],
"request_param_keys": request_param_keys,
"request_payload_keys": request_payload_keys,
}
app_logger.reason(
"Attempting Superset dataset preview compilation strategy",
extra={
"dataset_id": dataset_id,
**strategy_diagnostics,
"request_params": request_params,
"request_payload": request_body,
"legacy_form_data": legacy_form_data if endpoint_kind.startswith("legacy_") else None,
"query_context": query_context if endpoint_kind == "v1_chart_data" else None,
"template_param_count": len(template_params or {}),
"filter_count": len(effective_filters or []),
},
)
try:
response = self.network.request(
method="POST",
endpoint=endpoint_path,
params=request_params or None,
data=request_body,
headers=request_headers or None,
)
normalized = self._extract_compiled_sql_from_preview_response(response)
normalized["query_context"] = query_context
normalized["legacy_form_data"] = legacy_form_data
normalized["endpoint"] = endpoint_path
normalized["endpoint_kind"] = endpoint_kind
normalized["dataset_id"] = dataset_id
normalized["strategy_attempts"] = strategy_attempts + [
{
**strategy_diagnostics,
"success": True,
}
]
app_logger.reflect(
"Dataset preview compilation returned normalized SQL payload",
extra={
"dataset_id": dataset_id,
**strategy_diagnostics,
"success": True,
"compiled_sql_length": len(str(normalized.get("compiled_sql") or "")),
"response_diagnostics": normalized.get("response_diagnostics"),
},
)
return normalized
except Exception as exc:
failure_diagnostics = {
**strategy_diagnostics,
"success": False,
"error": str(exc),
}
strategy_attempts.append(failure_diagnostics)
app_logger.explore(
"Superset dataset preview compilation strategy failed",
extra={
"dataset_id": dataset_id,
**failure_diagnostics,
"request_params": request_params,
"request_payload": request_body,
},
)
raise SupersetAPIError(
"Superset preview compilation failed for all known strategies "
f"(attempts={strategy_attempts!r})"
)
# [/DEF:SupersetClient.compile_dataset_preview:Function]
# [DEF:SupersetClient.build_dataset_preview_legacy_form_data:Function]
# @COMPLEXITY: 4
# @PURPOSE: Build browser-style legacy form_data payload for Superset preview endpoints inferred from observed deployment traffic.
# @PRE: dataset_record should come from Superset dataset detail when possible.
# @POST: Returns one serialized-ready form_data structure preserving native filter clauses in legacy transport fields.
# @DATA_CONTRACT: Input[dataset_id:int,dataset_record:Dict,template_params:Dict,effective_filters:List[Dict]] -> Output[Dict[str, Any]]
# @RELATION: [CALLS] ->[SupersetClient.build_dataset_preview_query_context]
# @SIDE_EFFECT: Emits reasoning diagnostics describing the inferred legacy payload shape.
def build_dataset_preview_legacy_form_data(
self,
dataset_id: int,
dataset_record: Dict[str, Any],
template_params: Dict[str, Any],
effective_filters: List[Dict[str, Any]],
) -> Dict[str, Any]:
with belief_scope("SupersetClient.build_dataset_preview_legacy_form_data", f"id={dataset_id}"):
query_context = self.build_dataset_preview_query_context(
dataset_id=dataset_id,
dataset_record=dataset_record,
template_params=template_params,
effective_filters=effective_filters,
)
query_object = deepcopy(query_context.get("queries", [{}])[0] if query_context.get("queries") else {})
legacy_form_data = deepcopy(query_context.get("form_data", {}))
legacy_form_data.pop("datasource", None)
legacy_form_data["metrics"] = deepcopy(query_object.get("metrics", ["count"]))
legacy_form_data["columns"] = deepcopy(query_object.get("columns", []))
legacy_form_data["orderby"] = deepcopy(query_object.get("orderby", []))
legacy_form_data["annotation_layers"] = deepcopy(query_object.get("annotation_layers", []))
legacy_form_data["row_limit"] = query_object.get("row_limit", 1000)
legacy_form_data["series_limit"] = query_object.get("series_limit", 0)
legacy_form_data["url_params"] = deepcopy(query_object.get("url_params", template_params))
legacy_form_data["applied_time_extras"] = deepcopy(query_object.get("applied_time_extras", {}))
legacy_form_data["result_format"] = query_context.get("result_format", "json")
legacy_form_data["result_type"] = query_context.get("result_type", "query")
legacy_form_data["force"] = bool(query_context.get("force", True))
extras = query_object.get("extras")
if isinstance(extras, dict):
legacy_form_data["extras"] = deepcopy(extras)
time_range = query_object.get("time_range")
if time_range:
legacy_form_data["time_range"] = time_range
app_logger.reflect(
"Dataset preview compilation returned normalized SQL payload",
"Built Superset legacy preview form_data payload from browser-observed request shape",
extra={
"dataset_id": dataset_id,
"compiled_sql_length": len(str(normalized.get("compiled_sql") or "")),
"legacy_endpoint_inference": "POST /explore_json/form_data?form_data=... primary, POST /data?form_data=... fallback, based on observed browser traffic",
"contains_form_datasource": "datasource" in legacy_form_data,
"legacy_form_data_keys": sorted(legacy_form_data.keys()),
"legacy_extra_filters": legacy_form_data.get("extra_filters", []),
"legacy_extra_form_data": legacy_form_data.get("extra_form_data", {}),
},
)
return normalized
# [/DEF:backend.src.core.superset_client.SupersetClient.compile_dataset_preview:Function]
return legacy_form_data
# [/DEF:SupersetClient.build_dataset_preview_legacy_form_data:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.build_dataset_preview_query_context:Function]
# [DEF:SupersetClient.build_dataset_preview_query_context:Function]
# @COMPLEXITY: 4
# @PURPOSE: Build a reduced-scope chart-data query context for deterministic dataset preview compilation.
# @PRE: dataset_record should come from Superset dataset detail when possible.
# @POST: Returns an explicit chart-data payload based on current session inputs and dataset metadata.
# @DATA_CONTRACT: Input[dataset_id:int,dataset_record:Dict,template_params:Dict,effective_filters:List[Dict]] -> Output[Dict[str, Any]]
# @RELATION: [CALLS] ->[backend.src.core.superset_client.SupersetClient._normalize_effective_filters_for_query_context]
# @RELATION: [CALLS] ->[SupersetClient._normalize_effective_filters_for_query_context]
# @SIDE_EFFECT: Emits reasoning and reflection logs for deterministic preview payload construction.
def build_dataset_preview_query_context(
self,
@@ -996,7 +1356,9 @@ class SupersetClient:
) -> Dict[str, Any]:
with belief_scope("SupersetClient.build_dataset_preview_query_context", f"id={dataset_id}"):
normalized_template_params = deepcopy(template_params or {})
normalized_filters = self._normalize_effective_filters_for_query_context(effective_filters or [])
normalized_filter_payload = self._normalize_effective_filters_for_query_context(effective_filters or [])
normalized_filters = normalized_filter_payload["filters"]
normalized_extra_form_data = normalized_filter_payload["extra_form_data"]
datasource_payload: Dict[str, Any] = {
"id": dataset_id,
@@ -1011,6 +1373,23 @@ class SupersetClient:
if datasource_type:
datasource_payload["type"] = datasource_type
serialized_dataset_template_params = dataset_record.get("template_params")
if isinstance(serialized_dataset_template_params, str) and serialized_dataset_template_params.strip():
try:
parsed_dataset_template_params = json.loads(serialized_dataset_template_params)
if isinstance(parsed_dataset_template_params, dict):
for key, value in parsed_dataset_template_params.items():
normalized_template_params.setdefault(str(key), value)
except json.JSONDecodeError:
app_logger.explore(
"Dataset template_params could not be parsed while building preview query context",
extra={"dataset_id": dataset_id},
)
extra_form_data: Dict[str, Any] = deepcopy(normalized_extra_form_data)
if normalized_filters:
extra_form_data["filters"] = deepcopy(normalized_filters)
query_object: Dict[str, Any] = {
"filters": normalized_filters,
"extras": {"where": ""},
@@ -1021,33 +1400,56 @@ class SupersetClient:
"row_limit": 1000,
"series_limit": 0,
"url_params": normalized_template_params,
"custom_params": normalized_template_params,
"applied_time_extras": {},
"result_type": "query",
}
schema = dataset_record.get("schema")
if schema:
query_object["schema"] = schema
time_range = dataset_record.get("default_time_range")
time_range = extra_form_data.get("time_range") or dataset_record.get("default_time_range")
if time_range:
query_object["time_range"] = time_range
extra_form_data["time_range"] = time_range
result_format = dataset_record.get("result_format") or "json"
result_type = dataset_record.get("result_type") or "full"
result_type = "query"
return {
form_data: Dict[str, Any] = {
"datasource": f"{datasource_payload['id']}__{datasource_payload['type']}",
"datasource_id": datasource_payload["id"],
"datasource_type": datasource_payload["type"],
"viz_type": "table",
"slice_id": None,
"query_mode": "raw",
"url_params": normalized_template_params,
"extra_filters": deepcopy(normalized_filters),
"adhoc_filters": [],
}
if extra_form_data:
form_data["extra_form_data"] = extra_form_data
payload = {
"datasource": datasource_payload,
"queries": [query_object],
"form_data": {
"datasource": f"{datasource_payload['id']}__{datasource_payload['type']}",
"viz_type": "table",
"slice_id": None,
"query_mode": "raw",
"url_params": normalized_template_params,
},
"form_data": form_data,
"result_format": result_format,
"result_type": result_type,
"force": True,
}
app_logger.reflect(
"Built Superset dataset preview query context",
extra={
"dataset_id": dataset_id,
"datasource": datasource_payload,
"normalized_effective_filters": normalized_filters,
"normalized_filter_diagnostics": normalized_filter_payload["diagnostics"],
"result_type": result_type,
"result_format": result_format,
},
)
return payload
# [/DEF:backend.src.core.superset_client.SupersetClient.build_dataset_preview_query_context:Function]
# [DEF:backend.src.core.superset_client.SupersetClient._normalize_effective_filters_for_query_context:Function]
@@ -1058,56 +1460,170 @@ class SupersetClient:
def _normalize_effective_filters_for_query_context(
self,
effective_filters: List[Dict[str, Any]],
) -> List[Dict[str, Any]]:
) -> Dict[str, Any]:
with belief_scope("SupersetClient._normalize_effective_filters_for_query_context"):
normalized_filters: List[Dict[str, Any]] = []
merged_extra_form_data: Dict[str, Any] = {}
diagnostics: List[Dict[str, Any]] = []
for item in effective_filters:
if not isinstance(item, dict):
continue
column = str(item.get("variable_name") or item.get("filter_name") or "").strip()
if not column:
continue
value = item.get("effective_value")
if value is None:
continue
operator = "IN" if isinstance(value, list) else "=="
normalized_filters.append(
display_name = str(
item.get("display_name")
or item.get("filter_name")
or item.get("variable_name")
or "unresolved_filter"
).strip()
value = item.get("effective_value")
normalized_payload = item.get("normalized_filter_payload")
preserved_clauses: List[Dict[str, Any]] = []
preserved_extra_form_data: Dict[str, Any] = {}
used_preserved_clauses = False
if isinstance(normalized_payload, dict):
raw_clauses = normalized_payload.get("filter_clauses")
if isinstance(raw_clauses, list):
preserved_clauses = [
deepcopy(clause)
for clause in raw_clauses
if isinstance(clause, dict)
]
raw_extra_form_data = normalized_payload.get("extra_form_data")
if isinstance(raw_extra_form_data, dict):
preserved_extra_form_data = deepcopy(raw_extra_form_data)
if isinstance(preserved_extra_form_data, dict):
for key, extra_value in preserved_extra_form_data.items():
if key == "filters":
continue
merged_extra_form_data[key] = deepcopy(extra_value)
outgoing_clauses: List[Dict[str, Any]] = []
if preserved_clauses:
for clause in preserved_clauses:
clause_copy = deepcopy(clause)
if "val" not in clause_copy and value is not None:
clause_copy["val"] = deepcopy(value)
outgoing_clauses.append(clause_copy)
used_preserved_clauses = True
elif preserved_extra_form_data:
outgoing_clauses = []
else:
column = str(item.get("variable_name") or item.get("filter_name") or "").strip()
if column and value is not None:
operator = "IN" if isinstance(value, list) else "=="
outgoing_clauses.append(
{
"col": column,
"op": operator,
"val": value,
}
)
normalized_filters.extend(outgoing_clauses)
diagnostics.append(
{
"col": column,
"op": operator,
"val": value,
"filter_name": display_name,
"value_origin": (
normalized_payload.get("value_origin")
if isinstance(normalized_payload, dict)
else None
),
"used_preserved_clauses": used_preserved_clauses,
"outgoing_clauses": deepcopy(outgoing_clauses),
}
)
return normalized_filters
app_logger.reason(
"Normalized effective preview filter for Superset query context",
extra={
"filter_name": display_name,
"used_preserved_clauses": used_preserved_clauses,
"outgoing_clauses": outgoing_clauses,
"value_origin": (
normalized_payload.get("value_origin")
if isinstance(normalized_payload, dict)
else "heuristic_reconstruction"
),
},
)
return {
"filters": normalized_filters,
"extra_form_data": merged_extra_form_data,
"diagnostics": diagnostics,
}
# [/DEF:backend.src.core.superset_client.SupersetClient._normalize_effective_filters_for_query_context:Function]
# [DEF:backend.src.core.superset_client.SupersetClient._extract_compiled_sql_from_chart_data_response:Function]
# [DEF:backend.src.core.superset_client.SupersetClient._extract_compiled_sql_from_preview_response:Function]
# @COMPLEXITY: 3
# @PURPOSE: Normalize compiled SQL from a chart-data response by reading result[].query fields first.
# @PRE: response must be the decoded response body from /api/v1/chart/data.
# @PURPOSE: Normalize compiled SQL from either chart-data or legacy form_data preview responses.
# @PRE: response must be the decoded preview response body from a supported Superset endpoint.
# @POST: Returns compiled SQL and raw response or raises SupersetAPIError when the endpoint does not expose query text.
def _extract_compiled_sql_from_chart_data_response(self, response: Any) -> Dict[str, Any]:
with belief_scope("SupersetClient._extract_compiled_sql_from_chart_data_response"):
def _extract_compiled_sql_from_preview_response(self, response: Any) -> Dict[str, Any]:
with belief_scope("SupersetClient._extract_compiled_sql_from_preview_response"):
if not isinstance(response, dict):
raise SupersetAPIError("Superset chart/data response was not a JSON object")
raise SupersetAPIError("Superset preview response was not a JSON object")
response_diagnostics: List[Dict[str, Any]] = []
result_payload = response.get("result")
if not isinstance(result_payload, list):
raise SupersetAPIError("Superset chart/data response did not include a result list")
if isinstance(result_payload, list):
for index, item in enumerate(result_payload):
if not isinstance(item, dict):
continue
compiled_sql = str(item.get("query") or item.get("sql") or item.get("compiled_sql") or "").strip()
response_diagnostics.append(
{
"index": index,
"status": item.get("status"),
"applied_filters": item.get("applied_filters"),
"rejected_filters": item.get("rejected_filters"),
"has_query": bool(compiled_sql),
"source": "result_list",
}
)
if compiled_sql:
return {
"compiled_sql": compiled_sql,
"raw_response": response,
"response_diagnostics": response_diagnostics,
}
for item in result_payload:
if not isinstance(item, dict):
continue
compiled_sql = str(item.get("query") or "").strip()
top_level_candidates: List[Tuple[str, Any]] = [
("query", response.get("query")),
("sql", response.get("sql")),
("compiled_sql", response.get("compiled_sql")),
]
if isinstance(result_payload, dict):
top_level_candidates.extend(
[
("result.query", result_payload.get("query")),
("result.sql", result_payload.get("sql")),
("result.compiled_sql", result_payload.get("compiled_sql")),
]
)
for source, candidate in top_level_candidates:
compiled_sql = str(candidate or "").strip()
response_diagnostics.append(
{
"source": source,
"has_query": bool(compiled_sql),
}
)
if compiled_sql:
return {
"compiled_sql": compiled_sql,
"raw_response": response,
"response_diagnostics": response_diagnostics,
}
raise SupersetAPIError("Superset chart/data response did not expose compiled SQL in result[].query")
# [/DEF:backend.src.core.superset_client.SupersetClient._extract_compiled_sql_from_chart_data_response:Function]
raise SupersetAPIError(
"Superset preview response did not expose compiled SQL "
f"(diagnostics={response_diagnostics!r})"
)
# [/DEF:backend.src.core.superset_client.SupersetClient._extract_compiled_sql_from_preview_response:Function]
# [DEF:SupersetClient.update_dataset:Function]
# @COMPLEXITY: 3