"""Logic for retrieving top metrics for accounts.""" from typing import Any, Mapping from ddtrace import tracer from analytics.constants import cache from analytics.constants.ordering import ORDER_DIRECTIONS from analytics.queries.format import format_row from analytics.queries.top_accounts_metrics import TopAccountsMetrics from analytics.schemas.top_accounts_metrics import TopAccountsMetricsSchema from analytics.utils import store_availability from analytics.utils.cache import cache_in_redis FIELDS_WITH_SUBACCOUNT = [ "label_id", "subaccount_id", "label_manager_name", "streams_7_days", "streams_growth_percentage_7_day", "streams_28_days", "streams_growth_percentage_28_day", "streams_all_time", "track_downloads_28_days", "track_downloads_growth_percentage_28_day", "album_downloads_28_days", "album_downloads_growth_percentage_28_day", "aggregated_downloads_7_days", "aggregated_downloads_growth_percentage_7_day", "aggregated_downloads_all_time", ] FIELDS_WITHOUT_SUBACCOUNT = [f for f in FIELDS_WITH_SUBACCOUNT if f != "subaccount_id"] NON_NUMBER_FIELDS = ["label_manager_name"] @cache_in_redis(ttl=cache.ONE_DAY) @tracer.wrap(name="get_top_accounts_metrics") def get_top_accounts_metrics( query_params: Mapping[str, Any], permissions: Mapping[str, Any], ): """Fetch top metrics for accounts. Args: query_params: Dict with distributors, countries, store_ids, label_ids, subaccount_ids, include_subaccounts, parent_company, company_brand, service_tier, label_manager, order_by, order_dir, limit, offset. permissions: Dict with permission_* keys. Returns: oto_response.Response with top metrics payload. """ order_by = query_params["order_by"] order_dir = query_params["order_dir"] fields = ( FIELDS_WITH_SUBACCOUNT if query_params["include_subaccounts"] else FIELDS_WITHOUT_SUBACCOUNT ) if order_by not in fields: raise Exception("Invalid order_by field") if order_dir.upper() not in ORDER_DIRECTIONS: raise Exception("Invalid order_dir value") if order_by not in NON_NUMBER_FIELDS: order_by_expr = f"COALESCE({order_by}, 0)" else: order_by_expr = order_by available_store_ids = _filter_available_store_ids(query_params.get("store_ids", [])) if not available_store_ids: return TopAccountsMetricsSchema.normalized_response( { "items": [], "total_count": 0, "labels_count": 0, "subaccounts_count": 0, } ) query_input = { **permissions, "distributors": query_params["distributors"], "store_ids": available_store_ids, "country_ids": query_params.get("countries") or [], "label_ids": query_params.get("label_ids") or [], "subaccount_ids": query_params.get("subaccount_ids") or [], "parent_company": query_params.get("parent_company") or None, "company_brand": query_params.get("company_brand") or None, "service_tier": query_params.get("service_tier") or None, "label_manager": query_params.get("label_manager") or None, "include_subaccounts": query_params["include_subaccounts"], "order_by": order_by_expr, "order_dir": order_dir, "limit": query_params["limit"], "offset": query_params["offset"], "transfer_product_ownership_enabled": query_params.get( "transfer_product_ownership_enabled", False ), } rows = [format_row(row) for row in TopAccountsMetrics(query_input).execute()] items = [{key: row[key] for key in fields if key in row} for row in rows] total_results = rows[0]["total_results"] if rows else 0 labels_count = rows[0]["labels_count"] if rows else 0 subaccounts_count = rows[0]["subaccounts_count"] if rows else 0 return TopAccountsMetricsSchema.normalized_response( { "items": items, "total_count": total_results, "labels_count": labels_count, "subaccounts_count": subaccounts_count, } ) def _filter_available_store_ids(store_ids): available_store_ids = store_availability.get_store_ids() if not store_ids: return available_store_ids return list(set(store_ids).intersection(available_store_ids))