032: fix remaining sync→async propagation (17 call sites)
Core fixes:
- service_datasource.py: fetch_datasource_metadata() → async
- service.py: create_job(), update_job() → async (callers await)
- _job_routes.py: await create_job/update_job
Maintenance scanners:
- _dashboard_scanner.py: 4 functions → async (find_affected, _get_linked,
_apply_filters, _resolve_title)
- _chart_manager.py: 3 functions → async
- _banner_renderer.py: rebuild_banner → async
- _orchestrators.py: 3 orchestrators → async
- maintenance_banner.py: await async calls
Migration:
- dry_run_orchestrator.py: run(), _build_target_signatures() → async
- risk_assessor.py: build_risks() → async
- migration.py: await service.run()
- mapping_service.py: sync_environment() → async
Dead code:
- _helpers.py: _find_dashboard_id_by_slug marked DEPRECATED
This commit is contained in:
@@ -171,7 +171,7 @@ def _build_banner_text_for_dashboard(
|
||||
# @SIDE_EFFECT Modifies Superset chart. Writes DB.
|
||||
# @RELATION DEPENDS_ON -> [build_banner_text]
|
||||
# @RELATION DEPENDS_ON -> [SupersetDashboardsWriteMixin]
|
||||
def rebuild_banner(
|
||||
async def rebuild_banner(
|
||||
banner_id: str,
|
||||
db_session: Session,
|
||||
superset_client: SupersetClient,
|
||||
@@ -225,7 +225,7 @@ def rebuild_banner(
|
||||
# Update banner on dashboard (native MARKDOWN in layout)
|
||||
if banner.chart_id:
|
||||
try:
|
||||
superset_client.update_banner_on_dashboard(
|
||||
await superset_client.update_banner_on_dashboard(
|
||||
banner.dashboard_id, banner.chart_id, banner_text
|
||||
)
|
||||
except Exception as e:
|
||||
|
||||
@@ -29,7 +29,7 @@ from ._dashboard_scanner import _resolve_dashboard_title
|
||||
# @POST Returns MaintenanceDashboardBanner with chart_id set. Chart is placed at top of dashboard.
|
||||
# @SIDE_EFFECT Creates chart in Superset, modifies dashboard layout, writes DB row.
|
||||
# @RELATION DEPENDS_ON -> [SupersetDashboardsWriteMixin]
|
||||
def ensure_banner_chart(
|
||||
async def ensure_banner_chart(
|
||||
dashboard_id: int,
|
||||
environment_id: str,
|
||||
superset_client: SupersetClient,
|
||||
@@ -61,7 +61,7 @@ def ensure_banner_chart(
|
||||
)
|
||||
# Verify the chart still exists in Superset
|
||||
try:
|
||||
superset_client.get_chart(existing.chart_id)
|
||||
await superset_client.get_chart(existing.chart_id)
|
||||
app_logger.reflect(
|
||||
"Existing banner chart is alive, reusing",
|
||||
extra={"banner_id": existing.id, "chart_id": existing.chart_id},
|
||||
@@ -81,7 +81,7 @@ def ensure_banner_chart(
|
||||
|
||||
# Create markdown chart in Superset
|
||||
try:
|
||||
chart_id = superset_client.create_markdown_chart(
|
||||
chart_id = await superset_client.create_markdown_chart(
|
||||
dashboard_id, "*Maintenance banner placeholder*"
|
||||
)
|
||||
except Exception as e:
|
||||
@@ -94,7 +94,7 @@ def ensure_banner_chart(
|
||||
|
||||
# Insert chart at top of dashboard layout
|
||||
try:
|
||||
superset_client.update_dashboard_layout(dashboard_id, chart_id)
|
||||
await superset_client.update_dashboard_layout(dashboard_id, chart_id)
|
||||
except Exception as e:
|
||||
app_logger.explore(
|
||||
"Failed to update dashboard layout, deleting chart",
|
||||
@@ -103,7 +103,7 @@ def ensure_banner_chart(
|
||||
)
|
||||
# Clean up the chart we just created
|
||||
try:
|
||||
superset_client.delete_chart(chart_id)
|
||||
await superset_client.delete_chart(chart_id)
|
||||
except Exception:
|
||||
pass
|
||||
raise
|
||||
@@ -138,7 +138,7 @@ def ensure_banner_chart(
|
||||
# @RELATION CALLS -> [ensure_banner_chart]
|
||||
# @RELATION CALLS -> [_build_banner_text_for_dashboard]
|
||||
# @RELATION CALLS -> [_resolve_dashboard_title]
|
||||
def _process_dashboards_for_start(
|
||||
async def _process_dashboards_for_start(
|
||||
dashboard_ids: list[int],
|
||||
event_id: str,
|
||||
environment_id: str,
|
||||
@@ -158,7 +158,7 @@ def _process_dashboards_for_start(
|
||||
)
|
||||
try:
|
||||
# Ensure banner chart exists
|
||||
banner = ensure_banner_chart(
|
||||
banner = await ensure_banner_chart(
|
||||
dash_id,
|
||||
environment_id,
|
||||
superset_client,
|
||||
@@ -184,7 +184,7 @@ def _process_dashboards_for_start(
|
||||
# Update banner content on dashboard (native MARKDOWN in layout)
|
||||
if banner.chart_id:
|
||||
try:
|
||||
superset_client.update_banner_on_dashboard(
|
||||
await superset_client.update_banner_on_dashboard(
|
||||
dash_id, banner.chart_id, banner_text
|
||||
)
|
||||
except Exception as e:
|
||||
@@ -207,7 +207,7 @@ def _process_dashboards_for_start(
|
||||
db_session.flush()
|
||||
|
||||
# Resolve dashboard title
|
||||
title = _resolve_dashboard_title(dash_id, superset_client)
|
||||
title = await _resolve_dashboard_title(dash_id, superset_client)
|
||||
successful_dashboards.append(
|
||||
{
|
||||
"id": dash_id,
|
||||
@@ -239,7 +239,7 @@ def _process_dashboards_for_start(
|
||||
# still use same banner → rebuild; if no other events → remove banner (chart + layout).
|
||||
# @SIDE_EFFECT Modifies Superset dashboards (removes charts, updates layouts). Writes DB.
|
||||
# @RELATION CALLS -> [rebuild_banner]
|
||||
def _process_states_for_end(
|
||||
async def _process_states_for_end(
|
||||
states: list[MaintenanceDashboardState],
|
||||
event_id: str,
|
||||
superset_client: SupersetClient,
|
||||
@@ -278,7 +278,7 @@ def _process_states_for_end(
|
||||
# Other events still active — rebuild banner text
|
||||
state.status = MaintenanceDashboardStateStatus.REMOVED
|
||||
db_session.flush()
|
||||
rebuild_banner(banner_id, db_session, superset_client)
|
||||
await rebuild_banner(banner_id, db_session, superset_client)
|
||||
app_logger.reflect(
|
||||
"Banner rebuilt after removing event",
|
||||
extra={"banner_id": banner_id, "dashboard_id": dash_id},
|
||||
@@ -291,7 +291,7 @@ def _process_states_for_end(
|
||||
# Remove chart from layout
|
||||
if banner.chart_id:
|
||||
try:
|
||||
superset_client.remove_chart_from_layout(
|
||||
await superset_client.remove_chart_from_layout(
|
||||
dash_id, banner.chart_id
|
||||
)
|
||||
except Exception as e:
|
||||
@@ -311,7 +311,7 @@ def _process_states_for_end(
|
||||
|
||||
# Delete chart
|
||||
try:
|
||||
superset_client.delete_chart(banner.chart_id)
|
||||
await superset_client.delete_chart(banner.chart_id)
|
||||
except Exception as e:
|
||||
app_logger.explore(
|
||||
"Failed to delete chart",
|
||||
|
||||
@@ -23,7 +23,7 @@ from ..sql_table_extractor import extract_tables_from_sql
|
||||
# @SIDE_EFFECT Fetches all datasets from Superset (paginated). May be slow with many datasets.
|
||||
# @RELATION DEPENDS_ON -> [SupersetClient]
|
||||
# @RELATION DEPENDS_ON -> [SqlTableExtractorModule]
|
||||
def find_affected_dashboards(
|
||||
async def find_affected_dashboards(
|
||||
tables: list[str],
|
||||
superset_client: SupersetClient,
|
||||
settings: MaintenanceSettings | None = None,
|
||||
@@ -48,7 +48,7 @@ def find_affected_dashboards(
|
||||
|
||||
# Fetch all datasets from Superset
|
||||
try:
|
||||
_, datasets = superset_client.get_datasets()
|
||||
_, datasets = await superset_client.get_datasets()
|
||||
except Exception as e:
|
||||
app_logger.explore(
|
||||
"Failed to fetch datasets from Superset",
|
||||
@@ -78,7 +78,7 @@ def find_affected_dashboards(
|
||||
if not is_virtual and ds_schema and ds_table:
|
||||
qualified = f"{ds_schema}.{ds_table}"
|
||||
if qualified in target_tables:
|
||||
linked = _get_linked_dashboards(superset_client, ds_id)
|
||||
linked = await _get_linked_dashboards(superset_client, ds_id)
|
||||
matched_dashboard_ids.update(linked)
|
||||
continue
|
||||
|
||||
@@ -86,7 +86,7 @@ def find_affected_dashboards(
|
||||
if is_virtual and ds_sql:
|
||||
extracted = extract_tables_from_sql(ds_sql)
|
||||
if extracted & target_tables:
|
||||
linked = _get_linked_dashboards(superset_client, ds_id)
|
||||
linked = await _get_linked_dashboards(superset_client, ds_id)
|
||||
matched_dashboard_ids.update(linked)
|
||||
|
||||
app_logger.reflect(
|
||||
@@ -95,7 +95,7 @@ def find_affected_dashboards(
|
||||
)
|
||||
|
||||
# Apply filtering from settings
|
||||
result = _apply_dashboard_filters(
|
||||
result = await _apply_dashboard_filters(
|
||||
list(matched_dashboard_ids), superset_client, settings
|
||||
)
|
||||
|
||||
@@ -110,14 +110,14 @@ def find_affected_dashboards(
|
||||
# #region _get_linked_dashboards [C:2] [TYPE Function]
|
||||
# @BRIEF Fetch linked dashboards for a dataset from Superset.
|
||||
# @SIDE_EFFECT Calls Superset API.
|
||||
def _get_linked_dashboards(
|
||||
async def _get_linked_dashboards(
|
||||
superset_client: SupersetClient,
|
||||
dataset_id: int | None,
|
||||
) -> set[int]:
|
||||
if not dataset_id:
|
||||
return set()
|
||||
try:
|
||||
detail = superset_client.get_dataset_detail(dataset_id)
|
||||
detail = await superset_client.get_dataset_detail(dataset_id)
|
||||
linked = detail.get("linked_dashboards", [])
|
||||
return {int(d["id"]) for d in linked if d.get("id")}
|
||||
except Exception as e:
|
||||
@@ -132,7 +132,7 @@ def _get_linked_dashboards(
|
||||
|
||||
# #region _apply_dashboard_filters [C:2] [TYPE Function]
|
||||
# @BRIEF Apply scope (published/draft/all), excluded, and forced filters from settings.
|
||||
def _apply_dashboard_filters(
|
||||
async def _apply_dashboard_filters(
|
||||
dashboard_ids: list[int],
|
||||
superset_client: SupersetClient,
|
||||
settings: MaintenanceSettings | None,
|
||||
@@ -147,7 +147,7 @@ def _apply_dashboard_filters(
|
||||
# Apply scope filtering
|
||||
if settings.dashboard_scope != DashboardScope.ALL:
|
||||
try:
|
||||
_, all_dashboards = superset_client.get_dashboards()
|
||||
_, all_dashboards = await superset_client.get_dashboards()
|
||||
scope = settings.dashboard_scope
|
||||
filtered: list[int] = []
|
||||
for did in dashboard_ids:
|
||||
@@ -186,12 +186,12 @@ def _apply_dashboard_filters(
|
||||
|
||||
# #region _resolve_dashboard_title [C:2] [TYPE Function]
|
||||
# @BRIEF Resolve dashboard title from Superset by ID.
|
||||
def _resolve_dashboard_title(
|
||||
async def _resolve_dashboard_title(
|
||||
dashboard_id: int,
|
||||
superset_client: SupersetClient,
|
||||
) -> str:
|
||||
try:
|
||||
_, dashboards = superset_client.get_dashboards()
|
||||
_, dashboards = await superset_client.get_dashboards()
|
||||
for d in dashboards:
|
||||
if d.get("id") == dashboard_id:
|
||||
return d.get("dashboard_title") or d.get("title") or str(dashboard_id)
|
||||
|
||||
@@ -56,16 +56,12 @@ def build_idempotency_key(
|
||||
# @BELIEF Uses belief_scope with REASON/REFLECT/EXPLORE markers.
|
||||
# @RELATION CALLS -> [find_affected_dashboards]
|
||||
# @RELATION CALLS -> [_process_dashboards_for_start]
|
||||
def start_maintenance(
|
||||
async def start_maintenance(
|
||||
event_id: str,
|
||||
db_session: Session,
|
||||
superset_client: SupersetClient,
|
||||
) -> dict[str, Any]:
|
||||
with belief_scope("start_maintenance", f"event_id={event_id}"):
|
||||
app_logger.reason(
|
||||
"Starting maintenance event",
|
||||
extra={"event_id": event_id},
|
||||
)
|
||||
|
||||
# Load event
|
||||
event = db_session.query(MaintenanceEvent).filter(
|
||||
@@ -100,7 +96,7 @@ def start_maintenance(
|
||||
|
||||
# Find affected dashboards
|
||||
try:
|
||||
dashboard_ids = find_affected_dashboards(
|
||||
dashboard_ids = await find_affected_dashboards(
|
||||
event.tables,
|
||||
superset_client,
|
||||
settings,
|
||||
@@ -142,7 +138,7 @@ def start_maintenance(
|
||||
}
|
||||
|
||||
# Process each dashboard
|
||||
successful_dashboards, failed_dashboards, _ = _process_dashboards_for_start(
|
||||
successful_dashboards, failed_dashboards, _ = await _process_dashboards_for_start(
|
||||
dashboard_ids,
|
||||
event_id,
|
||||
environment_id,
|
||||
@@ -193,7 +189,7 @@ def start_maintenance(
|
||||
# @SIDE_EFFECT Modifies Superset dashboards (removes charts, updates layouts). Writes DB.
|
||||
# @BELIEF Uses belief_scope with REASON/REFLECT/EXPLORE markers.
|
||||
# @RELATION CALLS -> [_process_states_for_end]
|
||||
def end_maintenance(
|
||||
async def end_maintenance(
|
||||
event_id: str,
|
||||
db_session: Session,
|
||||
superset_client: SupersetClient,
|
||||
@@ -234,7 +230,7 @@ def end_maintenance(
|
||||
).all()
|
||||
|
||||
# Delegate per-state processing
|
||||
removed_count, failed_removals = _process_states_for_end(
|
||||
removed_count, failed_removals = await _process_states_for_end(
|
||||
states, event_id, superset_client, db_session,
|
||||
)
|
||||
|
||||
@@ -268,7 +264,7 @@ def end_maintenance(
|
||||
# @SIDE_EFFECT Modifies multiple Superset dashboards. Writes multiple DB rows.
|
||||
# @BELIEF Uses belief_scope with REASON/REFLECT/EXPLORE markers.
|
||||
# @RELATION CALLS -> [end_maintenance]
|
||||
def end_all_maintenance(
|
||||
async def end_all_maintenance(
|
||||
db_session: Session,
|
||||
superset_client: SupersetClient,
|
||||
) -> dict[str, Any]:
|
||||
@@ -302,7 +298,7 @@ def end_all_maintenance(
|
||||
extra={"event_id": event.id},
|
||||
)
|
||||
try:
|
||||
result = end_maintenance(
|
||||
result = await end_maintenance(
|
||||
event.id, db_session, superset_client
|
||||
)
|
||||
total_removed += result.get("removed_from", 0)
|
||||
|
||||
Reference in New Issue
Block a user