Skip to content

Commit

Permalink
[Discovery] Add year time range for metrics endpoints [C-3753] (#7676)
Browse files Browse the repository at this point in the history
Co-authored-by: Nikki Kang <kangaroo233@gmail.com>
  • Loading branch information
nicoback2 and nicoback authored Feb 22, 2024
1 parent c104b7e commit dc41e93
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from src.models.metrics.aggregate_daily_unique_users_metrics import (
AggregateDailyUniqueUsersMetrics,
)
from src.queries.get_trailing_metrics import _get_aggregate_route_metrics_trailing_month
from src.queries.get_trailing_metrics import _get_aggregate_route_metrics_trailing
from src.utils.db_session import get_db

limit = 2
Expand Down Expand Up @@ -44,7 +44,7 @@ def test_get_aggregate_route_metrics_trailing_month(app):
]
)

aggregate_metrics = _get_aggregate_route_metrics_trailing_month(session)
aggregate_metrics = _get_aggregate_route_metrics_trailing(session, "month")

assert aggregate_metrics["unique_count"] == 5
assert aggregate_metrics["summed_unique_count"] == 7
Expand Down
22 changes: 14 additions & 8 deletions packages/discovery-provider/src/api/v1/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from src.queries.get_historical_route_metrics import get_historical_route_metrics
from src.queries.get_personal_route_metrics import get_personal_route_metrics
from src.queries.get_plays_metrics import get_plays_metrics
from src.queries.get_trailing_metrics import get_aggregate_route_metrics_trailing_month
from src.queries.get_trailing_metrics import get_aggregate_route_metrics_trailing
from src.utils.redis_cache import cache
from src.utils.redis_metrics import (
get_aggregate_metrics_info,
Expand Down Expand Up @@ -68,6 +68,10 @@
"month": ["day", "week"],
"all_time": ["month", "week"],
}
valid_bucket_sizes_with_year = {
**valid_bucket_sizes,
"all_time": ["month", "week"],
}


personal_route_metrics_parser = reqparse.RequestParser()
Expand Down Expand Up @@ -158,12 +162,14 @@ def get(self):
return response


@ns.route("/aggregates/routes/trailing/month", doc=False)
@ns.route("/aggregates/routes/trailing/<string:time_range>", doc=False)
class AggregateRouteMetricsTrailingMonth(Resource):
@cache(ttl_sec=30 * 60)
def get(self):
"""Gets aggregated route metrics for the last trailing 30 days"""
metrics = get_aggregate_route_metrics_trailing_month()
def get(self, time_range):
"""Gets aggregated route metrics for the last trailing week, month, or year"""
if time_range != "month" and time_range != "year" and time_range != "week":
abort_bad_path_param("time_range", ns)
metrics = get_aggregate_route_metrics_trailing(time_range)
response = success_response(metrics)
return response

Expand All @@ -184,11 +190,11 @@ class AggregateRouteMetrics(Resource):
@cache(ttl_sec=30 * 60)
def get(self, time_range):
"""Gets aggregated route metrics based on time range and bucket size"""
if time_range not in valid_bucket_sizes:
if time_range not in valid_bucket_sizes_with_year:
abort_bad_path_param("time_range", ns)

args = aggregate_route_metrics_parser.parse_args()
valid_buckets = valid_bucket_sizes[time_range]
valid_buckets = valid_bucket_sizes_with_year[time_range]
bucket_size = args.get("bucket_size") or valid_buckets[0]

if bucket_size not in valid_buckets:
Expand All @@ -213,7 +219,7 @@ class AggregateAppMetricsTrailing(Resource):
@cache(ttl_sec=30 * 60)
def get(self, time_range):
"""Gets aggregated app metrics based on time range and bucket size"""
if time_range not in valid_bucket_sizes:
if time_range not in valid_bucket_sizes_with_year:
abort_bad_path_param("time_range", ns)

args = aggregate_app_metrics_parser.parse_args()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def _get_aggregate_route_metrics(session, time_range, bucket_size):
today = date.today()
seven_days_ago = today - timedelta(days=7)
thirty_days_ago = today - timedelta(days=30)
one_year_ago = today - timedelta(days=365)
first_day_of_month = today.replace(day=1)

if time_range == "week":
Expand Down Expand Up @@ -195,6 +196,59 @@ def _get_aggregate_route_metrics(session, time_range, bucket_size):
{},
)

metrics = []
for timestamp, counts in unique_count_records.items():
if timestamp in total_count_records:
metrics.append(
{
"timestamp": timestamp,
"unique_count": counts["unique"],
"summed_unique_count": counts["summed_unique"],
"total_count": total_count_records[timestamp],
}
)
return metrics
raise exceptions.ArgumentError("Invalid bucket_size for time_range")
if time_range == "year":
if bucket_size == "month":
unique_counts = (
session.query(
AggregateMonthlyUniqueUsersMetric.timestamp,
AggregateMonthlyUniqueUsersMetric.count,
AggregateMonthlyUniqueUsersMetric.summed_count,
)
.filter(
AggregateMonthlyUniqueUsersMetric.timestamp < first_day_of_month
)
.filter(one_year_ago <= AggregateMonthlyUniqueUsersMetric.timestamp)
.order_by(asc("timestamp"))
.all()
)
unique_count_records = ft.reduce(
lambda acc, curr: acc.update(
{str(curr[0]): {"unique": curr[1], "summed_unique": curr[2] or 0}}
)
or acc,
unique_counts,
{},
)

total_counts = (
session.query(
AggregateMonthlyTotalUsersMetric.timestamp,
AggregateMonthlyTotalUsersMetric.count,
)
.filter(AggregateMonthlyTotalUsersMetric.timestamp < first_day_of_month)
.filter(one_year_ago <= AggregateMonthlyTotalUsersMetric.timestamp)
.order_by(asc("timestamp"))
.all()
)
total_count_records = ft.reduce(
lambda acc, curr: acc.update({str(curr[0]): curr[1]}) or acc,
total_counts,
{},
)

metrics = []
for timestamp, counts in unique_count_records.items():
if timestamp in total_count_records:
Expand Down
18 changes: 17 additions & 1 deletion packages/discovery-provider/src/queries/get_app_name_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def get_aggregate_app_metrics(time_range, limit):
Returns app name metrics for a given time range
Args:
time_range: one of "week", "month", "all_time"
time_range: one of "week", "month", "year", or "all_time"
limit: number The max number of apps to return
Returns:
[{ name: string, count: number }, ...]
Expand All @@ -108,6 +108,7 @@ def _get_aggregate_app_metrics(session, time_range, limit):
today = date.today()
seven_days_ago = today - timedelta(days=7)
thirty_days_ago = today - timedelta(days=30)
one_year_ago = today - timedelta(days=365)

if time_range == "week":
query = (
Expand Down Expand Up @@ -135,6 +136,21 @@ def _get_aggregate_app_metrics(session, time_range, limit):
.limit(limit)
.all()
)
elif time_range == "year":
query = (
session.query(
AggregateMonthlyAppNameMetric.application_name,
func.sum(AggregateMonthlyAppNameMetric.count).label("count"),
)
.filter(one_year_ago <= AggregateDailyAppNameMetric.timestamp)
.filter(AggregateMonthlyAppNameMetric.timestamp < today)
.group_by(AggregateMonthlyAppNameMetric.application_name)
.order_by(
desc("count"), asc(AggregateMonthlyAppNameMetric.application_name)
)
.limit(limit)
.all()
)
elif time_range == "all_time":
query = (
session.query(
Expand Down
20 changes: 13 additions & 7 deletions packages/discovery-provider/src/queries/get_trailing_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,41 @@
logger = logging.getLogger(__name__)


def get_aggregate_route_metrics_trailing_month():
def get_aggregate_route_metrics_trailing(time_range):
"""
Returns trailing count and unique count for all routes in the last trailing 30 days
Returns trailing count and unique count for all routes in the last trailing month or year
Accepts: time_range = 'month' or 'year' or 'week'
Returns:
{ unique_count, total_count }
"""
db = db_session.get_db_read_replica()
with db.scoped_session() as session:
return _get_aggregate_route_metrics_trailing_month(session)
return _get_aggregate_route_metrics_trailing(session, time_range or "month")


def _get_aggregate_route_metrics_trailing_month(session):
def _get_aggregate_route_metrics_trailing(session, time_range):
today = date.today()
thirty_days_ago = today - timedelta(days=30)
if time_range == "year":
days_ago = today - timedelta(days=365)
elif time_range == "week":
days_ago = today - timedelta(days=7)
else:
days_ago = today - timedelta(days=30)

counts = (
session.query(
func.sum(AggregateDailyUniqueUsersMetrics.count),
func.sum(AggregateDailyUniqueUsersMetrics.summed_count),
)
.filter(thirty_days_ago <= AggregateDailyUniqueUsersMetrics.timestamp)
.filter(days_ago <= AggregateDailyUniqueUsersMetrics.timestamp)
.filter(AggregateDailyUniqueUsersMetrics.timestamp < today)
.first()
)

total_count = (
session.query(func.sum(AggregateDailyTotalUsersMetrics.count))
.filter(thirty_days_ago <= AggregateDailyTotalUsersMetrics.timestamp)
.filter(days_ago <= AggregateDailyTotalUsersMetrics.timestamp)
.filter(AggregateDailyTotalUsersMetrics.timestamp < today)
.first()
)
Expand Down

0 comments on commit dc41e93

Please sign in to comment.