From 567e6e3645acbda87ea39a6b701dcb3a4490360c Mon Sep 17 00:00:00 2001 From: Ethan Henderson Date: Fri, 23 Jul 2021 16:30:36 +0100 Subject: [PATCH] Extra verification and bug fixes Verify sort metrics better Fix a few bugs --- .gitignore | 2 +- analytix/youtube/analytics.py | 3 ++ analytix/youtube/reports.py | 88 ++++++++++++++++++++++++++++++++++- 3 files changed, 90 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 6a42610..0d304e9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ *.json secrets tests - +testrun.py ### Data ### *.csv diff --git a/analytix/youtube/analytics.py b/analytix/youtube/analytics.py index cfa0cba..86be2ac 100644 --- a/analytix/youtube/analytics.py +++ b/analytix/youtube/analytics.py @@ -165,6 +165,9 @@ def retrieve(self, metrics="all", verify=True, **kwargs): if not isinstance(filters, dict): raise InvalidRequest(f"expected dict of filters, got {type(filters).__name__}") + if not isinstance(sort_by, (tuple, list, set)): + raise InvalidRequest(f"expected tuple, list, or set of sorting metrics, got {type(sort_by).__name__}") + r = self.get_report_type(metrics, dimensions, filters, verify=verify) r.verify(metrics, dimensions, filters, max_results, sort_by) diff --git a/analytix/youtube/reports.py b/analytix/youtube/reports.py index 8f36fe0..90b3352 100644 --- a/analytix/youtube/reports.py +++ b/analytix/youtube/reports.py @@ -363,6 +363,14 @@ def verify(self, metrics, dimensions, filters, max_results, sort_by): if not sort_by: raise InvalidRequest("you must provide at least 1 sort parameter") + if any(not s[0] == "-" for s in sort_by): + raise InvalidRequest( + ( + "you can only sort in descending order for this report type. " + "You can do this by prefixing the sort metrics with '-'" + ) + ) + def __str__(self): return "Playback locations (detailed)" @@ -404,6 +412,14 @@ def verify(self, metrics, dimensions, filters, max_results, sort_by): if not sort_by: raise InvalidRequest("you must provide at least 1 sort parameter") + if any(not s[0] == "-" for s in sort_by): + raise InvalidRequest( + ( + "you can only sort in descending order for this report type. " + "You can do this by prefixing the sort metrics with '-'" + ) + ) + def __str__(self): return "Traffic sources (detailed)" @@ -483,7 +499,11 @@ def __init__(self): (FeatureAmount.ZERO_OR_ONE, {"subscribedStatus"}), ] self.metrics = ("shares",) - self.filters = [(FeatureAmount.ZERO_OR_ONE, {"country", "continent", "subContinent"}), Detail] + self.filters = [ + (FeatureAmount.ZERO_OR_ONE, {"country", "continent", "subContinent"}), + (FeatureAmount.ZERO_OR_ONE, {"video", "group"}), + (FeatureAmount.ANY, {"subscribedStatus"}), + ] def __str__(self): return "Engagement and content sharing" @@ -523,6 +543,14 @@ def verify(self, metrics, dimensions, filters, max_results, sort_by): if not sort_by: raise InvalidRequest("you must provide at least 1 sort parameter") + if any(not s[0] == "-" for s in sort_by): + raise InvalidRequest( + ( + "you can only sort in descending order for this report type. " + "You can do this by prefixing the sort metrics with '-'" + ) + ) + def __str__(self): return "Top videos by region" @@ -542,6 +570,14 @@ def verify(self, metrics, dimensions, filters, max_results, sort_by): if not sort_by: raise InvalidRequest("you must provide at least 1 sort parameter") + if any(not s[0] == "-" for s in sort_by): + raise InvalidRequest( + ( + "you can only sort in descending order for this report type. " + "You can do this by prefixing the sort metrics with '-'" + ) + ) + def __str__(self): return "Top videos by state" @@ -564,6 +600,14 @@ def verify(self, metrics, dimensions, filters, max_results, sort_by): if not sort_by: raise InvalidRequest("you must provide at least 1 sort parameter") + if any(not s[0] == "-" for s in sort_by): + raise InvalidRequest( + ( + "you can only sort in descending order for this report type. " + "You can do this by prefixing the sort metrics with '-'" + ) + ) + def __str__(self): return "Top videos by subscription status" @@ -586,6 +630,14 @@ def verify(self, metrics, dimensions, filters, max_results, sort_by): if not sort_by: raise InvalidRequest("you must provide at least 1 sort parameter") + if any(not s[0] == "-" for s in sort_by): + raise InvalidRequest( + ( + "you can only sort in descending order for this report type. " + "You can do this by prefixing the sort metrics with '-'" + ) + ) + def __str__(self): return "Top videos by YouTube product" @@ -608,6 +660,14 @@ def verify(self, metrics, dimensions, filters, max_results, sort_by): if not sort_by: raise InvalidRequest("you must provide at least 1 sort parameter") + if any(not s[0] == "-" for s in sort_by): + raise InvalidRequest( + ( + "you can only sort in descending order for this report type. " + "You can do this by prefixing the sort metrics with '-'" + ) + ) + def __str__(self): return "Top videos by playback detail" @@ -757,6 +817,14 @@ def verify(self, metrics, dimensions, filters, max_results, sort_by): if not sort_by: raise InvalidRequest("you must provide at least 1 sort parameter") + if any(not s[0] == "-" for s in sort_by): + raise InvalidRequest( + ( + "you can only sort in descending order for this report type. " + "You can do this by prefixing the sort metrics with '-'" + ) + ) + def __str__(self): return "Playback locations for playlists (detailed)" @@ -808,6 +876,14 @@ def verify(self, metrics, dimensions, filters, max_results, sort_by): if not sort_by: raise InvalidRequest("you must provide at least 1 sort parameter") + if any(not s[0] == "-" for s in sort_by): + raise InvalidRequest( + ( + "you can only sort in descending order for this report type. " + "You can do this by prefixing the sort metrics with '-'" + ) + ) + def __str__(self): return "Traffic sources for playlists (detailed)" @@ -927,13 +1003,21 @@ def verify(self, metrics, dimensions, filters, max_results, sort_by): if not sort_by: raise InvalidRequest("you must provide at least 1 sort parameter") + if any(not s[0] == "-" for s in sort_by): + raise InvalidRequest( + ( + "you can only sort in descending order for this report type. " + "You can do this by prefixing the sort metrics with '-'" + ) + ) + def __str__(self): return "Top playlists" class AdPerformance(ReportType): def __init__(self): - self.dimensions = ((FeatureAmount.REQUIRED, {"adType"}), (FeatureAmount.OPTIONAL, {"day"})) + self.dimensions = ((FeatureAmount.REQUIRED, {"adType"}), (FeatureAmount.ANY, {"day"})) self.metrics = ("grossRevenue", "adImpressions", "cpm") self.filters = ( (FeatureAmount.ZERO_OR_ONE, {"video", "group"}),