I'm integrating the Google Drive API in my Flask app, but I'm having trouble testing it locally in a development server.
Here is the code, from these Google docs:
SCOPES = ['https://www.googleapis.com/auth/drive']
CLIENT_SECRETS_FILE = 'credentials.json'
TOKEN_FILE = 'token.json'
def upload_file():
creds = None
if os.path.exists(TOKEN_FILE):
creds = Credentials.from_authorized_user_file(TOKEN_FILE, SCOPES)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
creds = flow.run_local_server(port=0)
with open(TOKEN_FILE, 'w') as token:
token.write(creds.to_json())
(imports and subsequent Google Drive upload code not included for brevity)
The issue is, when I run this on a dynamic port as above, I get this error, due to the fact that the random port it chooses is not registered with GCloud:
Error 400: redirect_uri_mismatch
When I change the port to one that is registered in GCloud, such as 8080, it gives me this error:
OSError: [WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted
Is there any way to test this in a development server or do I have to deploy it?
I instituted the Google Drive API per Google's documentation, verified that my credentials.json matches the information in GCloud, and used this function to try and upload a .docx to Google Drive. I expected it to upload a document, but it errored out on this line:
creds = flow.run_local_server(port=0)
Flask is for web applications. Your using code for an installed app hense the term InstalledAppFlow
.
@app.route('/authorize')
def authorize():
# Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps.
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
CLIENT_SECRETS_FILE, scopes=SCOPES)
# The URI created here must exactly match one of the authorized redirect URIs
# for the OAuth 2.0 client, which you configured in the API Console. If this
# value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch'
# error.
flow.redirect_uri = flask.url_for('oauth2callback', _external=True)
authorization_url, state = flow.authorization_url(
# Enable offline access so that you can refresh an access token without
# re-prompting the user for permission. Recommended for web server apps.
access_type='offline')
# Store the state so the callback can verify the auth server response.
flask.session['state'] = state
return flask.redirect(authorization_url)