Repository: pypi/warehouse

Issue:
Trending Projects are not updated
I think in the past month that I've been looking at pypi.org (and even before that), the "Trending Projects" haven't changed.



Discussion:
Looking further, as someone not familiar with the codebase, it seems like the `compute_trending` task isn't setup to run every day or something like that.


Potentially another reason for #3252.
https://github.com/pypa/warehouse/blob/ed8d6a03d86e794b83ccd4e41d0c5b6b7865b8bf/warehouse/packaging/__init__.py#L112-L115
```
pypi-warehouse-worker-beat-856f489568-kjc9b worker-beat [2018-03-28 03:00:00,064: INFO/MainProcess] Loading 1 tasks
pypi-warehouse-worker-beat-856f489568-kjc9b worker-beat [2018-03-28 03:00:00,071: INFO/MainProcess] Scheduler: Sending due task warehouse.packaging.tasks.compute_trending() (warehouse.packaging.tasks.compute_trending)
```

I do see the task being enqueued.
```
pypi-warehouse-worker-7b6dddfb-tlm4s worker FileNotFoundError: [Errno 2] No such file or directory: '/app/gcloud.json'
```

Looks like pathing is goof'd! will fixup!
That was half the issue :)

Second half is they changed the API! https://github.com/GoogleCloudPlatform/google-cloud-python/blob/cd9b89ead0be95827c9eac5a9a8c5d8fdaee3cae/bigquery/CHANGELOG.md#interface-changes--breaking-changes-1

```
pypi-warehouse-worker-5c996d6869-6hbkc worker [2018-03-28 16:03:30,528: ERROR/ForkPoolWorker-2] Task warehouse.packaging.tasks.compute_trending[e6d5d345-bfb9-4fd1-a535-af52c2b1a495] raised unexpected: AttributeError("'Client' object has no attribute 'run_sync_query'",)
pypi-warehouse-worker-5c996d6869-6hbkc worker Traceback (most recent call last):
pypi-warehouse-worker-5c996d6869-6hbkc worker   File "/opt/warehouse/lib/python3.6/site-packages/celery/app/trace.py", line 374, in trace_task
pypi-warehouse-worker-5c996d6869-6hbkc worker     R = retval = fun(*args, **kwargs)
pypi-warehouse-worker-5c996d6869-6hbkc worker   File "/opt/warehouse/src/warehouse/tasks.py", line 70, in __call__
pypi-warehouse-worker-5c996d6869-6hbkc worker     return super().__call__(*(self.get_request(),) + args, **kwargs)
pypi-warehouse-worker-5c996d6869-6hbkc worker   File "/opt/warehouse/lib/python3.6/site-packages/celery/app/trace.py", line 629, in __protected_call__
pypi-warehouse-worker-5c996d6869-6hbkc worker     return self.run(*args, **kwargs)
pypi-warehouse-worker-5c996d6869-6hbkc worker   File "/opt/warehouse/src/warehouse/tasks.py", line 58, in run
pypi-warehouse-worker-5c996d6869-6hbkc worker     return original_run(*args, **kwargs)
pypi-warehouse-worker-5c996d6869-6hbkc worker   File "/opt/warehouse/src/warehouse/packaging/tasks.py", line 21, in compute_trending
pypi-warehouse-worker-5c996d6869-6hbkc worker     query = bq.run_sync_query(
pypi-warehouse-worker-5c996d6869-6hbkc worker AttributeError: 'Client' object has no attribute 'run_sync_query'
```
(@pradyunsg -- *good catch* and thanks for the report!)

Resolving patch:
diff --git a/warehouse/packaging/tasks.py b/warehouse/packaging/tasks.py
--- a/warehouse/packaging/tasks.py
+++ b/warehouse/packaging/tasks.py
@@ -18,7 +18,7 @@
 @tasks.task(ignore_result=True, acks_late=True)
 def compute_trending(request):
     bq = request.find_service(name="gcloud.bigquery")
-    query = bq.run_sync_query(
+    query = bq.query(
         """ SELECT project,
                    IF(
                         STDDEV(downloads) > 0,
@@ -56,21 +56,11 @@ def compute_trending(request):
             ORDER BY zscore DESC
         """.format(table=request.registry.settings["warehouse.trending_table"])
     )
-    query.use_legacy_sql = False
-    query.run()
 
     zscores = {}
-    page_token = None
-    while True:
-        rows, total_rows, page_token = query.fetch_data(
-            max_results=1000,
-            page_token=page_token,
-        )
-
-        zscores.update(dict(rows))
-
-        if not page_token:
-            break
+    for row in query.result():
+        row = dict(row)
+        zscores[row["project"]] = row["zscore"]
 
     # We're going to "reset" all of our zscores to a steady state where they
     # are all equal to ``None``. The next query will then set any that have a


Test patch:
diff --git a/tests/unit/packaging/test_tasks.py b/tests/unit/packaging/test_tasks.py
--- a/tests/unit/packaging/test_tasks.py
+++ b/tests/unit/packaging/test_tasks.py
@@ -13,6 +13,8 @@
 import pretend
 import pytest
 
+from google.cloud.bigquery import Row
+
 from warehouse.cache.origin import IOriginCache
 from warehouse.packaging.models import Project
 from warehouse.packaging.tasks import compute_trending
@@ -30,18 +32,22 @@ def test_computes_trending(self, db_request, with_purges):
         ]
 
         results = iter([
-            ([(projects[1].normalized_name, 2)], 2, "blah"),
-            ([(projects[2].normalized_name, -1)], 2, None),
+            Row(
+                (projects[1].normalized_name, 2),
+                {'project': 0, 'zscore': 1},
+            ),
+            Row(
+                (projects[2].normalized_name, -1),
+                {'project': 0, 'zscore': 1},
+            ),
         ])
         query = pretend.stub(
-            use_legacy_sql=True,
-            run=pretend.call_recorder(lambda: None),
-            fetch_data=pretend.call_recorder(
-                lambda max_results, page_token: next(results),
+            result=pretend.call_recorder(
+                lambda *a, **kw: results,
             )
         )
         bigquery = pretend.stub(
-            run_sync_query=pretend.call_recorder(lambda q: query),
+            query=pretend.call_recorder(lambda q: query),
         )
 
         cacher = pretend.stub(purge=pretend.call_recorder(lambda keys: None))
@@ -62,7 +68,7 @@ def find_service(iface=None, name=None):
 
         compute_trending(db_request)
 
-        assert bigquery.run_sync_query.calls == [
+        assert bigquery.query.calls == [
             pretend.call(""" SELECT project,
                    IF(
                         STDDEV(downloads) > 0,
@@ -100,8 +106,7 @@ def find_service(iface=None, name=None):
             ORDER BY zscore DESC
         """),
         ]
-        assert not query.use_legacy_sql
-        assert query.run.calls == [pretend.call()]
+        assert query.result.calls == [pretend.call()]
         assert (cacher.purge.calls ==
                 ([pretend.call(["trending"])] if with_purges else []))