Description
Using the google.auth.default()
helper to access credentials for the default service account on App Engine standard works great, but does not allow one to use auth scopes beyond the default scopes for the Python 3.7 and 3.8 runtimes. This is different to how the old 2.7 runtime works.
This app works on 2.7, fails with an exception on 3.8:
# main.py, requires flask, google-api-python-client
import flask
from googleapiclient import discovery
app = flask.Flask(__name__)
@app.route('/')
def home():
service = discovery.build('drive', 'v3')
request = service.files().list()
response = request.execute()
return response
On 3.8 the error is
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://www.googleapis.com/drive/v3/files?alt=json returned "Insufficient Permission: Request had insufficient authentication scopes.">"
The problem is that google.auth.default()
returns an instance of the Compute Engine credentials for Python 3, and that class does not allow changing scopes.
The credentials class uses the metadata service to get an access token. On App Engine standard the metadata service also allows one to request an access token with additional scopes (I haven't checked if this is also possible on Compute Engine or Flex). I have an implementation of ServiceAccountCredentials
that supports requesting a token with additional scopes, which works on App Engine standard Python 3.
https://gist.github.com/davidwtbuxton/525924b7f06f56b8530947d55bad1c21
With that code, the service discovery can request the required scopes:
credentials = ServiceAccountCredentials()
service = discovery.build('drive', 'v3', credentials=credentials)
It would be cool if we could get this supported using google.auth.default()
for Python 3 on App Engine standard. In particular it simplifies a lot of code that may mess around loading credentials from a JSON file or similar.
Would a PR for this feature be accepted?
Thanks,
David