Repository: googleapis/google-api-python-client

Issue:
BatchHttpRequest does not check for existence of an accesstoken before calling apply()
@nathanielmanistaatgoogle @jonparrott 

To repro:

```
from googleapiclient.discovery import build
from oauth2client.client import GoogleCredentials

def foo(b, a, r):
   pass

def main():
    api = build('servicemanagement', 'v1', credentials=GoogleCredentials.from_stream('static/service_account.json'))
    batch = api.new_batch_http_request(callback=foo)
    batch.add(api.services().list())
    batch.execute()
```

You will get something like 

  File "/usr/local/google/home/elibixby/gobrepos/devrel/apps/cloud/free-trial-tour/project_utils/apis.py", line 45, in enable_async
    batch.execute()
  File "/usr/local/google/home/elibixby/envs/iliad/local/lib/python2.7/site-packages/oauth2client/util.py", line 137, in positional_wrapper
    return wrapped(_args, *_kwargs)
  File "/usr/local/google/home/elibixby/envs/iliad/local/lib/python2.7/site-packages/googleapiclient/http.py", line 1325, in execute
    self._execute(http, self._order, self._requests)
  File "/usr/local/google/home/elibixby/envs/iliad/local/lib/python2.7/site-packages/googleapiclient/http.py", line 1249, in _execute
    body = self._serialize_request(request)
  File "/usr/local/google/home/elibixby/envs/iliad/local/lib/python2.7/site-packages/googleapiclient/http.py", line 1120, in _serialize_request
    request.http.request.credentials.apply(headers)
  File "/usr/local/google/home/elibixby/envs/iliad/local/lib/python2.7/site-packages/oauth2client/client.py", line 676, in apply
    headers['Authorization'] = 'Bearer ' + self.access_token
TypeError: cannot concatenate 'str' and 'NoneType' objects

FYI my pip freeze is:

```
Flask==0.10.1
Flask-SeaSurf==0.2.2
Jinja2==2.8
MarkupSafe==0.23
Werkzeug==0.11.5
argparse==1.2.1
google-api-python-client==1.5.0
httplib2==0.9.2
itsdangerous==0.24
oauth2client==2.0.1
pyasn1==0.1.9
pyasn1-modules==0.0.8
requirements-dev.txt==0.0.0
rsa==3.4.2
simplejson==3.8.2
six==1.10.0
talisman==0.1.0
uritemplate==0.6
wsgiref==0.1.2
```



Discussion:
I have the same issue.

I'm happy to review any PRs to fix this issue.


Resolving patch:
diff --git a/googleapiclient/http.py b/googleapiclient/http.py
--- a/googleapiclient/http.py
+++ b/googleapiclient/http.py
@@ -1394,6 +1394,14 @@ def execute(self, http=None):
     if http is None:
       raise ValueError("Missing a valid http object.")
 
+    # Special case for OAuth2Credentials-style objects which have not yet been
+    # refreshed with an initial access_token.
+    if getattr(http.request, 'credentials', None) is not None:
+      creds = http.request.credentials
+      if not getattr(creds, 'access_token', None):
+        LOGGER.info('Attempting refresh to obtain initial access_token')
+        creds.refresh(http)
+
     self._execute(http, self._order, self._requests)
 
     # Loop over all the requests and check for 401s. For each 401 request the


Test patch:
diff --git a/tests/test_http.py b/tests/test_http.py
--- a/tests/test_http.py
+++ b/tests/test_http.py
@@ -1072,6 +1072,34 @@ def test_execute_request_body(self):
       header = parts[1].splitlines()[1]
       self.assertEqual('Content-Type: application/http', header)
 
+  def test_execute_initial_refresh_oauth2(self):
+    batch = BatchHttpRequest()
+    callbacks = Callbacks()
+    cred = MockCredentials('Foo')
+
+    # Pretend this is a OAuth2Credentials object
+    cred.access_token = None
+
+    http = HttpMockSequence([
+      ({'status': '200',
+        'content-type': 'multipart/mixed; boundary="batch_foobarbaz"'},
+       BATCH_SINGLE_RESPONSE),
+    ])
+
+    cred.authorize(http)
+
+    batch.add(self.request1, callback=callbacks.f)
+    batch.execute(http=http)
+
+    self.assertEqual({'foo': 42}, callbacks.responses['1'])
+    self.assertIsNone(callbacks.exceptions['1'])
+
+    self.assertEqual(1, cred._refreshed)
+
+    self.assertEqual(1, cred._authorized)
+
+    self.assertEqual(1, cred._applied)
+
   def test_execute_refresh_and_retry_on_401(self):
     batch = BatchHttpRequest()
     callbacks = Callbacks()