Skip to content

Commit

Permalink
Create quickstart_web.py file
Browse files Browse the repository at this point in the history
Add sample for quickstart guide that shows how to create a simple Python app that uses the Flask web application framework.
  • Loading branch information
AndyDiamondstein committed Sep 29, 2017
1 parent 5193a5a commit 5b036f3
Showing 1 changed file with 167 additions and 0 deletions.
167 changes: 167 additions & 0 deletions python/quickstart_web.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# -*- coding: utf-8 -*-

import os

import flask
import google.oauth2.credentials
import google_auth_oauthlib.flow
import googleapiclient.discovery

# The CLIENT_SECRETS_FILE variable specifies the name of a file that contains
# the OAuth 2.0 information for this application, including its client_id and
# client_secret.
CLIENT_SECRETS_FILE = "client_secret.json"

# This OAuth 2.0 access scope allows for full read/write access to the
# authenticated user's account and requires requests to use an SSL connection.
SCOPES = ['https://www.googleapis.com/auth/youtube.force-ssl']
API_SERVICE_NAME = 'youtube'
API_VERSION = 'v3'

app = flask.Flask(__name__)
# Note: A secret key is included in the sample so that it works, but if you
# use this code in your application please replace this with a truly secret
# key. See http://flask.pocoo.org/docs/0.12/quickstart/#sessions.
app.secret_key = 'REPLACE ME - this value is here as a placeholder.'


@app.route('/')
def index():
if 'credentials' not in flask.session:
return flask.redirect('authorize')

# Load the credentials from the session.
credentials = google.oauth2.credentials.Credentials(
**flask.session['credentials'])

client = googleapiclient.discovery.build(
API_SERVICE_NAME, API_VERSION, credentials=credentials)
return channels_list_by_username(client,
part='snippet,contentDetails,statistics',
forUsername='GoogleDevelopers')


@app.route('/authorize')
def authorize():
# Create a 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)
flow.redirect_uri = flask.url_for('oauth2callback', _external=True)
authorization_url, state = flow.authorization_url(
# This parameter enables offline access which gives your application
# both an access and refresh token.
access_type='offline',
# This parameter enables incremental auth.
include_granted_scopes='true')

# Store the state in the session so that the callback can verify that
# the authorization server response.
flask.session['state'] = state

return flask.redirect(authorization_url)


@app.route('/oauth2callback')
def oauth2callback():
# Specify the state when creating the flow in the callback so that it can
# verify the authorization server response.
state = flask.session['state']
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
CLIENT_SECRETS_FILE, scopes=SCOPES, state=state)
flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

# Use the authorization server's response to fetch the OAuth 2.0 tokens.
authorization_response = flask.request.url
flow.fetch_token(authorization_response=authorization_response)

# Store the credentials in the session.
# ACTION ITEM for developers:
# Store user's access and refresh tokens in your data store if
# incorporating this code into your real app.
credentials = flow.credentials
flask.session['credentials'] = {
'token': credentials.token,
'refresh_token': credentials.refresh_token,
'token_uri': credentials.token_uri,
'client_id': credentials.client_id,
'client_secret': credentials.client_secret,
'scopes': credentials.scopes
}

return flask.redirect(flask.url_for('index'))

def print_response(response):
if response:
return flask.jsonify(**response)
else:
return ('This request does not return a response. For these samples, ' +
'this is generally true for requests that delete resources, ' +
'such as <code>playlists.delete()</code>, but it is also ' +
'true for some other methods, such as <code>videos.rate()</code>.')

# Build a resource based on a list of properties given as key-value pairs.
# Leave properties with empty values out of the inserted resource.
def build_resource(properties):
resource = {}
for p in properties:
# Given a key like "snippet.title", split into "snippet" and "title", where
# "snippet" will be an object and "title" will be a property in that object.
prop_array = p.split('.')
ref = resource
for pa in range(0, len(prop_array)):
is_array = False
key = prop_array[pa]

# For properties that have array values, convert a name like
# "snippet.tags[]" to snippet.tags, and set a flag to handle
# the value as an array.
if key[-2:] == '[]':
key = key[0:len(key)-2:]
is_array = True

if pa == (len(prop_array) - 1):
# Leave properties without values out of inserted resource.
if properties[p]:
if is_array:
ref[key] = properties[p].split(',')
else:
ref[key] = properties[p]
elif key not in ref:
# For example, the property is "snippet.title", but the resource does
# not yet have a "snippet" object. Create the snippet object here.
# Setting "ref = ref[key]" means that in the next time through the
# "for pa in range ..." loop, we will be setting a property in the
# resource's "snippet" object.
ref[key] = {}
ref = ref[key]
else:
# For example, the property is "snippet.description", and the resource
# already has a "snippet" object.
ref = ref[key]
return resource

# Remove keyword arguments that are not set
def remove_empty_kwargs(**kwargs):
good_kwargs = {}
if kwargs is not None:
for key, value in kwargs.iteritems():
if value:
good_kwargs[key] = value
return good_kwargs

def channels_list_by_username(client, **kwargs):
kwargs = remove_empty_kwargs(**kwargs) # See full sample for function
response = client.channels().list(
**kwargs
).execute()

return print_response(response)



if __name__ == '__main__':
# When running locally, disable OAuthlib's HTTPs verification. When
# running in production *do not* leave this option enabled.
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
app.run('localhost', 8090, debug=True)

0 comments on commit 5b036f3

Please sign in to comment.