"""Logic for retrieving channel metrics.""" from typing import Any, Dict, Mapping from analytics.constants import cache from analytics.logic import data_availability from analytics.logic.parallel import parallel from analytics.logic.permissions import has_full_access_on_permissions from analytics.logic.stores import add_outage_error_to_stores from analytics.queries.format import format_row from analytics.queries.videos import ChannelMetrics from analytics.schemas.channel_metrics import ( AllTimeChannelMetricsSchema, ChannelMetricsSchema, ) from analytics.utils import store_availability from analytics.utils.cache import cache_in_redis @cache_in_redis(ttl=cache.ONE_DAY) def get_channel_metrics( query_params: Mapping[str, Any], permissions: Mapping[str, Any], ) -> Dict: """Return metrics for YouTube channel_id.""" # an empty response, but with sources response_body = { "sources": add_outage_error_to_stores(store_availability.get_video_sources()), "aggregate_channel_metrics": {}, "channel_metrics": [], } # channels are visible only to employees and vendors if ( not has_full_access_on_permissions(permissions) and not permissions["permission_label_ids"] ): return ChannelMetricsSchema.normalized_response(response_body) if not query_params["store_ids"]: query_params["store_ids"] = store_availability.get_video_store_ids() else: query_params["store_ids"] = list( set(query_params["store_ids"]).intersection( store_availability.get_video_store_ids() ) ) if query_params.get( "all_time" ): # this branch is for /all-time-channel-metrics/ if query_params.get("country_ids"): query_params[ "table_name" ] = "VIEWS_BY_CHANNEL_COUNTRY_FEED_DISTRIBUTOR_ROLLUP" else: query_params["table_name"] = "VIEWS_BY_CHANNEL_FEED_DISTRIBUTOR_ROLLUP" result = ChannelMetrics({**query_params, **permissions}).execute() all_time_channel_metrics = [format_row(data_point) for data_point in result] response_body["all_time_channel_metrics"] = ( all_time_channel_metrics[0] if all_time_channel_metrics else {} ) final_response = AllTimeChannelMetricsSchema.normalized_response(response_body) else: # this branch is for /channel-metrics/ if query_params.get("country_ids"): query_params[ "table_name" ] = "VIEWS_BY_CHANNEL_COUNTRY_FEED_DISTRIBUTOR_DAILY" else: query_params["table_name"] = "VIEWS_BY_CHANNEL_FEED_DISTRIBUTOR_DAILY" query_params["is_timeseries"] = False aggregate_channel_metrics_query = ChannelMetrics( {**query_params, **permissions} ) query_params["is_timeseries"] = True channel_metrics_query = ChannelMetrics({**query_params, **permissions}) requests = { "channel_metrics": { "func": channel_metrics_query.execute, "args": (), }, "aggregate_channel_metrics": { "func": aggregate_channel_metrics_query.execute, "args": (), }, } result = parallel(requests) channel_metrics = [ format_row(data_point) for data_point in result.message["channel_metrics"] ] aggregate_channel_metrics = [ format_row(data_point) for data_point in result.message["aggregate_channel_metrics"] ] response_body["channel_metrics"] = channel_metrics response_body["aggregate_channel_metrics"] = ( aggregate_channel_metrics[0] if aggregate_channel_metrics else {} ) final_response = ChannelMetricsSchema.normalized_response(response_body) return final_response