chore(semantics): checkpoint orphan-reduction hub normalization batch

This commit is contained in:
2026-03-15 22:14:05 +03:00
parent 0bf55885a8
commit 54e90b589b
6 changed files with 87 additions and 79 deletions

View File

@@ -1,5 +1,6 @@
# [DEF:backend.src.core.superset_client:Module]
#
# @TIER: STANDARD
# @SEMANTICS: superset, api, client, rest, http, dashboard, dataset, import, export
# @PURPOSE: Предоставляет высокоуровневый клиент для взаимодействия с Superset REST API, инкапсулируя логику запросов, обработку ошибок и пагинацию.
# @LAYER: Core
@@ -23,13 +24,13 @@ from .utils.fileio import get_filename_from_headers
from .config_models import Environment
# [/SECTION]
# [DEF:SupersetClient:Class]
# [DEF:backend.src.core.superset_client.SupersetClient:Class]
# @TIER: STANDARD
# @PURPOSE: Класс-обёртка над Superset REST API, предоставляющий методы для работы с дашбордами и датасетами.
# @RELATION: [DEPENDS_ON] ->[backend.src.core.utils.network.APIClient]
# @RELATION: [DEPENDS_ON] ->[backend.src.core.config_models.Environment]
class SupersetClient:
# [DEF:__init__:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.__init__:Function]
# @TIER: STANDARD
# @PURPOSE: Инициализирует клиент, проверяет конфигурацию и создает сетевой клиент.
# @PRE: `env` должен быть валидным объектом Environment.
@@ -58,7 +59,7 @@ class SupersetClient:
app_logger.info("[SupersetClient.__init__][Exit] SupersetClient initialized.")
# [/DEF:__init__:Function]
# [DEF:authenticate:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.authenticate:Function]
# @TIER: STANDARD
# @PURPOSE: Authenticates the client using the configured credentials.
# @PRE: self.network must be initialized with valid auth configuration.
@@ -71,7 +72,7 @@ class SupersetClient:
# [/DEF:authenticate:Function]
@property
# [DEF:headers:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.headers:Function]
# @TIER: TRIVIAL
# @PURPOSE: Возвращает базовые HTTP-заголовки, используемые сетевым клиентом.
# @PRE: APIClient is initialized and authenticated.
@@ -83,7 +84,7 @@ class SupersetClient:
# [SECTION: DASHBOARD OPERATIONS]
# [DEF:get_dashboards:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.get_dashboards:Function]
# @TIER: STANDARD
# @PURPOSE: Получает полный список дашбордов, автоматически обрабатывая пагинацию.
# @PRE: Client is authenticated.
@@ -117,7 +118,7 @@ class SupersetClient:
return total_count, paginated_data
# [/DEF:get_dashboards:Function]
# [DEF:get_dashboards_page:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.get_dashboards_page:Function]
# @TIER: STANDARD
# @PURPOSE: Fetches a single dashboards page from Superset without iterating all pages.
# @PRE: Client is authenticated.
@@ -154,7 +155,7 @@ class SupersetClient:
return total_count, result
# [/DEF:get_dashboards_page:Function]
# [DEF:get_dashboards_summary:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.get_dashboards_summary:Function]
# @TIER: STANDARD
# @PURPOSE: Fetches dashboard metadata optimized for the grid.
# @PRE: Client is authenticated.
@@ -239,7 +240,7 @@ class SupersetClient:
return result
# [/DEF:get_dashboards_summary:Function]
# [DEF:get_dashboards_summary_page:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.get_dashboards_summary_page:Function]
# @TIER: STANDARD
# @PURPOSE: Fetches one page of dashboard metadata optimized for the grid.
# @PRE: page >= 1 and page_size > 0.
@@ -312,7 +313,7 @@ class SupersetClient:
return total_count, result
# [/DEF:get_dashboards_summary_page:Function]
# [DEF:_extract_owner_labels:Function]
# [DEF:backend.src.core.superset_client.SupersetClient._extract_owner_labels:Function]
# @TIER: TRIVIAL
# @PURPOSE: Normalize dashboard owners payload to stable display labels.
# @PRE: owners payload can be scalar, object or list.
@@ -340,7 +341,7 @@ class SupersetClient:
return normalized
# [/DEF:_extract_owner_labels:Function]
# [DEF:_extract_user_display:Function]
# [DEF:backend.src.core.superset_client.SupersetClient._extract_user_display:Function]
# @TIER: TRIVIAL
# @PURPOSE: Normalize user payload to a stable display name.
# @PRE: user payload can be string, dict or None.
@@ -369,7 +370,7 @@ class SupersetClient:
return None
# [/DEF:_extract_user_display:Function]
# [DEF:_sanitize_user_text:Function]
# [DEF:backend.src.core.superset_client.SupersetClient._sanitize_user_text:Function]
# @TIER: TRIVIAL
# @PURPOSE: Convert scalar value to non-empty user-facing text.
# @PRE: value can be any scalar type.
@@ -383,7 +384,7 @@ class SupersetClient:
return normalized
# [/DEF:_sanitize_user_text:Function]
# [DEF:get_dashboard:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.get_dashboard:Function]
# @TIER: STANDARD
# @PURPOSE: Fetches a single dashboard by ID.
# @PRE: Client is authenticated and dashboard_id exists.
@@ -396,7 +397,7 @@ class SupersetClient:
return cast(Dict, response)
# [/DEF:get_dashboard:Function]
# [DEF:get_chart:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.get_chart:Function]
# @TIER: STANDARD
# @PURPOSE: Fetches a single chart by ID.
# @PRE: Client is authenticated and chart_id exists.
@@ -409,7 +410,7 @@ class SupersetClient:
return cast(Dict, response)
# [/DEF:get_chart:Function]
# [DEF:get_dashboard_detail:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.get_dashboard_detail:Function]
# @TIER: STANDARD
# @PURPOSE: Fetches detailed dashboard information including related charts and datasets.
# @PRE: Client is authenticated and dashboard_id exists.
@@ -604,7 +605,7 @@ class SupersetClient:
}
# [/DEF:get_dashboard_detail:Function]
# [DEF:get_charts:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.get_charts:Function]
# @TIER: STANDARD
# @PURPOSE: Fetches all charts with pagination support.
# @PRE: Client is authenticated.
@@ -624,7 +625,8 @@ class SupersetClient:
return len(paginated_data), paginated_data
# [/DEF:get_charts:Function]
# [DEF:_extract_chart_ids_from_layout:Function]
# [DEF:backend.src.core.superset_client.SupersetClient._extract_chart_ids_from_layout:Function]
# @TIER: TRIVIAL
# @PURPOSE: Traverses dashboard layout metadata and extracts chart IDs from common keys.
# @PRE: payload can be dict/list/scalar.
# @POST: Returns a set of chart IDs found in nested structures.
@@ -656,7 +658,7 @@ class SupersetClient:
return found
# [/DEF:_extract_chart_ids_from_layout:Function]
# [DEF:export_dashboard:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.export_dashboard:Function]
# @TIER: STANDARD
# @PURPOSE: Экспортирует дашборд в виде ZIP-архива.
# @PRE: dashboard_id must exist in Superset.
@@ -681,7 +683,7 @@ class SupersetClient:
return response.content, filename
# [/DEF:export_dashboard:Function]
# [DEF:import_dashboard:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.import_dashboard:Function]
# @TIER: STANDARD
# @PURPOSE: Импортирует дашборд из ZIP-файла.
# @PRE: file_name must be a valid ZIP dashboard export.
@@ -713,7 +715,7 @@ class SupersetClient:
return self._do_import(file_path)
# [/DEF:import_dashboard:Function]
# [DEF:delete_dashboard:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.delete_dashboard:Function]
# @TIER: STANDARD
# @PURPOSE: Удаляет дашборд по его ID или slug.
# @PRE: dashboard_id must exist.
@@ -735,7 +737,7 @@ class SupersetClient:
# [SECTION: DATASET OPERATIONS]
# [DEF:get_datasets:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.get_datasets:Function]
# @TIER: STANDARD
# @PURPOSE: Получает полный список датасетов, автоматически обрабатывая пагинацию.
# @PRE: Client is authenticated.
@@ -756,7 +758,8 @@ class SupersetClient:
return total_count, paginated_data
# [/DEF:get_datasets:Function]
# [DEF:get_datasets_summary:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.get_datasets_summary:Function]
# @TIER: STANDARD
# @PURPOSE: Fetches dataset metadata optimized for the Dataset Hub grid.
# @PRE: Client is authenticated.
# @POST: Returns a list of dataset metadata summaries.
@@ -780,7 +783,8 @@ class SupersetClient:
return result
# [/DEF:get_datasets_summary:Function]
# [DEF:get_dataset_detail:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.get_dataset_detail:Function]
# @TIER: STANDARD
# @PURPOSE: Fetches detailed dataset information including columns and linked dashboards
# @PRE: Client is authenticated and dataset_id exists.
# @POST: Returns detailed dataset info with columns and linked dashboards.
@@ -892,7 +896,7 @@ class SupersetClient:
return result
# [/DEF:get_dataset_detail:Function]
# [DEF:get_dataset:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.get_dataset:Function]
# @TIER: STANDARD
# @PURPOSE: Получает информацию о конкретном датасете по его ID.
# @PRE: dataset_id must exist.
@@ -908,7 +912,7 @@ class SupersetClient:
return response
# [/DEF:get_dataset:Function]
# [DEF:update_dataset:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.update_dataset:Function]
# @TIER: STANDARD
# @PURPOSE: Обновляет данные датасета по его ID.
# @PRE: dataset_id must exist.
@@ -934,7 +938,7 @@ class SupersetClient:
# [SECTION: DATABASE OPERATIONS]
# [DEF:get_databases:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.get_databases:Function]
# @TIER: STANDARD
# @PURPOSE: Получает полный список баз данных.
# @PRE: Client is authenticated.
@@ -957,7 +961,7 @@ class SupersetClient:
return total_count, paginated_data
# [/DEF:get_databases:Function]
# [DEF:get_database:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.get_database:Function]
# @TIER: STANDARD
# @PURPOSE: Получает информацию о конкретной базе данных по её ID.
# @PRE: database_id must exist.
@@ -973,7 +977,7 @@ class SupersetClient:
return response
# [/DEF:get_database:Function]
# [DEF:get_databases_summary:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.get_databases_summary:Function]
# @TIER: STANDARD
# @PURPOSE: Fetch a summary of databases including uuid, name, and engine.
# @PRE: Client is authenticated.
@@ -994,7 +998,7 @@ class SupersetClient:
return databases
# [/DEF:get_databases_summary:Function]
# [DEF:get_database_by_uuid:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.get_database_by_uuid:Function]
# @TIER: STANDARD
# @PURPOSE: Find a database by its UUID.
# @PRE: db_uuid must be a valid UUID string.
@@ -1014,7 +1018,7 @@ class SupersetClient:
# [SECTION: HELPERS]
# [DEF:_resolve_target_id_for_delete:Function]
# [DEF:backend.src.core.superset_client.SupersetClient._resolve_target_id_for_delete:Function]
# @TIER: TRIVIAL
# @PURPOSE: Resolves a dashboard ID from either an ID or a slug.
# @PRE: Either dash_id or dash_slug should be provided.
@@ -1037,7 +1041,7 @@ class SupersetClient:
return None
# [/DEF:_resolve_target_id_for_delete:Function]
# [DEF:_do_import:Function]
# [DEF:backend.src.core.superset_client.SupersetClient._do_import:Function]
# @TIER: TRIVIAL
# @PURPOSE: Performs the actual multipart upload for import.
# @PRE: file_name must be a path to an existing ZIP file.
@@ -1059,7 +1063,7 @@ class SupersetClient:
)
# [/DEF:_do_import:Function]
# [DEF:_validate_export_response:Function]
# [DEF:backend.src.core.superset_client.SupersetClient._validate_export_response:Function]
# @TIER: TRIVIAL
# @PURPOSE: Validates that the export response is a non-empty ZIP archive.
# @PRE: response must be a valid requests.Response object.
@@ -1073,7 +1077,7 @@ class SupersetClient:
raise SupersetAPIError("Получены пустые данные при экспорте")
# [/DEF:_validate_export_response:Function]
# [DEF:_resolve_export_filename:Function]
# [DEF:backend.src.core.superset_client.SupersetClient._resolve_export_filename:Function]
# @TIER: TRIVIAL
# @PURPOSE: Determines the filename for an exported dashboard.
# @PRE: response must contain Content-Disposition header or dashboard_id must be provided.
@@ -1089,7 +1093,7 @@ class SupersetClient:
return filename
# [/DEF:_resolve_export_filename:Function]
# [DEF:_validate_query_params:Function]
# [DEF:backend.src.core.superset_client.SupersetClient._validate_query_params:Function]
# @TIER: TRIVIAL
# @PURPOSE: Ensures query parameters have default page and page_size.
# @PRE: query can be None or a dictionary.
@@ -1102,7 +1106,7 @@ class SupersetClient:
return {**base_query, **(query or {})}
# [/DEF:_validate_query_params:Function]
# [DEF:_fetch_total_object_count:Function]
# [DEF:backend.src.core.superset_client.SupersetClient._fetch_total_object_count:Function]
# @TIER: TRIVIAL
# @PURPOSE: Fetches the total number of items for a given endpoint.
# @PRE: endpoint must be a valid Superset API path.
@@ -1117,7 +1121,8 @@ class SupersetClient:
)
# [/DEF:_fetch_total_object_count:Function]
# [DEF:_fetch_all_pages:Function]
# [DEF:backend.src.core.superset_client.SupersetClient._fetch_all_pages:Function]
# @TIER: TRIVIAL
# @PURPOSE: Iterates through all pages to collect all data items.
# @PRE: pagination_options must contain base_query, total_count, and results_field.
# @POST: Returns a combined list of all items.
@@ -1126,7 +1131,8 @@ class SupersetClient:
return self.network.fetch_paginated_data(endpoint=endpoint, pagination_options=pagination_options)
# [/DEF:_fetch_all_pages:Function]
# [DEF:_validate_import_file:Function]
# [DEF:backend.src.core.superset_client.SupersetClient._validate_import_file:Function]
# @TIER: TRIVIAL
# @PURPOSE: Validates that the file to be imported is a valid ZIP with metadata.yaml.
# @PRE: zip_path must be a path to a file.
# @POST: Raises error if file is missing, not a ZIP, or missing metadata.
@@ -1142,7 +1148,8 @@ class SupersetClient:
raise SupersetAPIError(f"Архив {zip_path} не содержит 'metadata.yaml'")
# [/DEF:_validate_import_file:Function]
# [DEF:get_all_resources:Function]
# [DEF:backend.src.core.superset_client.SupersetClient.get_all_resources:Function]
# @TIER: STANDARD
# @PURPOSE: Fetches all resources of a given type with id, uuid, and name columns.
# @PARAM: resource_type (str) - One of "chart", "dataset", "dashboard".
# @PRE: Client is authenticated. resource_type is valid.
@@ -1191,6 +1198,6 @@ class SupersetClient:
# [/SECTION]
# [/DEF:SupersetClient:Class]
# [/DEF:backend.src.core.superset_client.SupersetClient:Class]
# [/DEF:backend.src.core.superset_client:Module]