From 78a1447c1270d0334646210e23dd824c68146088 Mon Sep 17 00:00:00 2001 From: Omar Jarjur Date: Tue, 7 Mar 2017 16:48:04 -0800 Subject: [PATCH 1/3] Fix a bug where an unbounded number of credentials wrappers got added. This fixes #1251, where the fact that we were sharing a single `httplib2.Http` instance caused each request to add an additional credentials wrapper around that single instance. That, in turn, caused a `RuntimeError: maximum recursion depth ...` error message once too many API calls had been made. --- google/datalab/utils/_http.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/google/datalab/utils/_http.py b/google/datalab/utils/_http.py index 03e057680..82166db4f 100644 --- a/google/datalab/utils/_http.py +++ b/google/datalab/utils/_http.py @@ -19,6 +19,7 @@ from past.builtins import basestring from builtins import object +import copy import datetime import json import urllib.request, urllib.parse, urllib.error @@ -119,8 +120,11 @@ def request(url, args=None, data=None, headers=None, method=None, if method is None: method = 'GET' + # Make a copy of the shared http instance in case we need to modify + # it (e.g. by adding credentials) below. + http = copy.copy(Http.http) + # Authorize with credentials if given - http = Http.http if credentials is not None: http = credentials.authorize(http) if stats is not None: From 4606f7fda6c7cafc462223709251491b6c062a3e Mon Sep 17 00:00:00 2001 From: Omar Jarjur Date: Tue, 7 Mar 2017 16:59:06 -0800 Subject: [PATCH 2/3] Only copy the http instance when we need to --- google/datalab/utils/_http.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/google/datalab/utils/_http.py b/google/datalab/utils/_http.py index 82166db4f..adbaf4d3c 100644 --- a/google/datalab/utils/_http.py +++ b/google/datalab/utils/_http.py @@ -120,12 +120,12 @@ def request(url, args=None, data=None, headers=None, method=None, if method is None: method = 'GET' - # Make a copy of the shared http instance in case we need to modify - # it (e.g. by adding credentials) below. - http = copy.copy(Http.http) + http = Http.http # Authorize with credentials if given if credentials is not None: + # Make a copy of the shared http instance before we modify it. + http = copy.copy(http) http = credentials.authorize(http) if stats is not None: stats['duration'] = datetime.datetime.utcnow() From 732f5dd98ae6b9e4275f46f6b972520010995d9c Mon Sep 17 00:00:00 2001 From: Omar Jarjur Date: Fri, 10 Mar 2017 14:26:12 -0800 Subject: [PATCH 3/3] Include the fix for authorizing HTTP requests in the older `datalab` module --- datalab/utils/_http.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/datalab/utils/_http.py b/datalab/utils/_http.py index a07f51db7..0da443ed3 100644 --- a/datalab/utils/_http.py +++ b/datalab/utils/_http.py @@ -19,6 +19,7 @@ from past.builtins import basestring from builtins import object +import copy import datetime import json import urllib.request, urllib.parse, urllib.error @@ -119,9 +120,12 @@ def request(url, args=None, data=None, headers=None, method=None, if method is None: method = 'GET' - # Authorize with credentials if given. http = Http.http + + # Authorize with credentials if given. if credentials is not None: + # Make a copy of the shared http instance before we modify it. + http = copy.copy(http) http = credentials.authorize(http) if stats is not None: stats['duration'] = datetime.datetime.utcnow()