Cleaned up OAuth 2.0 support fully using Storage() and updating samples.
This commit is contained in:
@@ -84,9 +84,11 @@ def build(serviceName, version,
|
||||
parameters {api} and {apiVersion} that when filled in
|
||||
produce an absolute URI to the discovery document for
|
||||
that service.
|
||||
developerKey: string, key obtained from https://code.google.com/apis/console
|
||||
developerKey: string, key obtained
|
||||
from https://code.google.com/apis/console
|
||||
model: apiclient.Model, converts to and from the wire format
|
||||
requestBuilder: apiclient.http.HttpRequest, encapsulator for an HTTP request
|
||||
requestBuilder: apiclient.http.HttpRequest, encapsulator for
|
||||
an HTTP request
|
||||
|
||||
Returns:
|
||||
A Resource object with methods for interacting with
|
||||
|
@@ -22,7 +22,10 @@ class HttpRequest(object):
|
||||
"""Encapsulates a single HTTP request.
|
||||
"""
|
||||
|
||||
def __init__(self, http, postproc, uri, method="GET", body=None, headers=None,
|
||||
def __init__(self, http, postproc, uri,
|
||||
method="GET",
|
||||
body=None,
|
||||
headers=None,
|
||||
methodId=None):
|
||||
"""Constructor for an HttpRequest.
|
||||
|
||||
@@ -150,6 +153,7 @@ class RequestMockBuilder(object):
|
||||
model = JsonModel()
|
||||
return HttpRequestMock(None, '{}', model.response)
|
||||
|
||||
|
||||
class HttpMock(object):
|
||||
"""Mock of httplib2.Http"""
|
||||
|
||||
@@ -164,5 +168,10 @@ class HttpMock(object):
|
||||
f.close()
|
||||
self.headers = headers
|
||||
|
||||
def request(self, uri, method="GET", body=None, headers=None, redirections=1, connection_type=None):
|
||||
def request(self, uri,
|
||||
method="GET",
|
||||
body=None,
|
||||
headers=None,
|
||||
redirections=1,
|
||||
connection_type=None):
|
||||
return httplib2.Response(self.headers), self.data
|
||||
|
@@ -18,6 +18,7 @@ import urllib
|
||||
from anyjson import simplejson
|
||||
from errors import HttpError
|
||||
|
||||
|
||||
def _abstract():
|
||||
raise NotImplementedError('You need to override this function')
|
||||
|
||||
|
@@ -25,6 +25,7 @@ import pickle
|
||||
from google.appengine.ext import db
|
||||
from client import Credentials
|
||||
from client import Flow
|
||||
from client import Storage
|
||||
|
||||
|
||||
class FlowProperty(db.Property):
|
||||
@@ -90,7 +91,7 @@ class CredentialsProperty(db.Property):
|
||||
return not value
|
||||
|
||||
|
||||
class StorageByKeyName(object):
|
||||
class StorageByKeyName(Storage):
|
||||
"""Store and retrieve a single credential to and from
|
||||
the App Engine datastore.
|
||||
|
||||
|
@@ -70,6 +70,30 @@ class Flow(object):
|
||||
pass
|
||||
|
||||
|
||||
class Storage(object):
|
||||
"""Base class for all Storage objects.
|
||||
|
||||
Store and retrieve a single credential.
|
||||
"""
|
||||
|
||||
|
||||
def get(self):
|
||||
"""Retrieve credential.
|
||||
|
||||
Returns:
|
||||
apiclient.oauth.Credentials
|
||||
"""
|
||||
_abstract()
|
||||
|
||||
def put(self, credentials):
|
||||
"""Write a credential.
|
||||
|
||||
Args:
|
||||
credentials: Credentials, the credentials to store.
|
||||
"""
|
||||
_abstract()
|
||||
|
||||
|
||||
class OAuth2Credentials(Credentials):
|
||||
"""Credentials object for OAuth 2.0
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
from django.db import models
|
||||
|
||||
from oauth2client.client import Storage as BaseStorage
|
||||
|
||||
class CredentialsField(models.Field):
|
||||
|
||||
@@ -36,3 +36,50 @@ class FlowField(models.Field):
|
||||
|
||||
def get_db_prep_value(self, value):
|
||||
return base64.b64encode(pickle.dumps(value))
|
||||
|
||||
|
||||
class Storage(BaseStorage):
|
||||
"""Store and retrieve a single credential to and from
|
||||
the datastore.
|
||||
|
||||
This Storage helper presumes the Credentials
|
||||
have been stored as a CredenialsField
|
||||
on a db model class.
|
||||
"""
|
||||
|
||||
def __init__(self, model_class, key_name, key_value, property_name):
|
||||
"""Constructor for Storage.
|
||||
|
||||
Args:
|
||||
model: db.Model, model class
|
||||
key_name: string, key name for the entity that has the credentials
|
||||
key_value: string, key value for the entity that has the credentials
|
||||
property_name: string, name of the property that is an CredentialsProperty
|
||||
"""
|
||||
self.model_class = model_class
|
||||
self.key_name = key_name
|
||||
self.key_value = key_value
|
||||
self.property_name = property_name
|
||||
|
||||
def get(self):
|
||||
"""Retrieve Credential from datastore.
|
||||
|
||||
Returns:
|
||||
oauth2client.Credentials
|
||||
"""
|
||||
query = {self.key_name: self.key_value}
|
||||
entity = self.model_class.objects.filter(*query)[0]
|
||||
credential = getattr(entity, self.property_name)
|
||||
if credential and hasattr(credential, 'set_store'):
|
||||
credential.set_store(self.put)
|
||||
return credential
|
||||
|
||||
def put(self, credentials):
|
||||
"""Write a Credentials to the datastore.
|
||||
|
||||
Args:
|
||||
credentials: Credentials, the credentials to store.
|
||||
"""
|
||||
entity = self.model_class(self.key_name=self.key_value)
|
||||
setattr(entity, self.property_name, credentials)
|
||||
entity.save()
|
||||
|
@@ -10,8 +10,10 @@ __author__ = 'jcgregorio@google.com (Joe Gregorio)'
|
||||
|
||||
import pickle
|
||||
|
||||
from client import Storage as BaseStorage
|
||||
|
||||
class Storage(object):
|
||||
|
||||
class Storage(BaseStorage):
|
||||
"""Store and retrieve a single credential to and from a file."""
|
||||
|
||||
def __init__(self, filename):
|
||||
@@ -23,10 +25,13 @@ class Storage(object):
|
||||
Returns:
|
||||
apiclient.oauth.Credentials
|
||||
"""
|
||||
f = open(self.filename, 'r')
|
||||
credentials = pickle.loads(f.read())
|
||||
f.close()
|
||||
credentials.set_store(self.put)
|
||||
try:
|
||||
f = open(self.filename, 'r')
|
||||
credentials = pickle.loads(f.read())
|
||||
f.close()
|
||||
credentials.set_store(self.put)
|
||||
except:
|
||||
credentials = None
|
||||
return credentials
|
||||
|
||||
def put(self, credentials):
|
||||
@@ -38,5 +43,3 @@ class Storage(object):
|
||||
f = open(self.filename, 'w')
|
||||
f.write(pickle.dumps(credentials))
|
||||
f.close()
|
||||
|
||||
|
||||
|
@@ -23,111 +23,16 @@ other example apps in the same directory.
|
||||
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
|
||||
__all__ = ["run"]
|
||||
|
||||
import socket
|
||||
import sys
|
||||
import BaseHTTPServer
|
||||
import logging
|
||||
|
||||
from optparse import OptionParser
|
||||
from oauth2client.file import Storage
|
||||
|
||||
try:
|
||||
from urlparse import parse_qsl
|
||||
except ImportError:
|
||||
from cgi import parse_qsl
|
||||
|
||||
# TODO(jcgregorio)
|
||||
# - docs
|
||||
# - error handling
|
||||
|
||||
HOST_NAME = 'localhost'
|
||||
PORT_NUMBERS = [8080, 8090]
|
||||
|
||||
class ClientRedirectServer(BaseHTTPServer.HTTPServer):
|
||||
"""A server to handle OAuth 2.0 redirects back to localhost.
|
||||
|
||||
Waits for a single request and parses the query parameters
|
||||
into query_params and then stops serving.
|
||||
"""
|
||||
query_params = {}
|
||||
|
||||
class ClientRedirectHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
"""A handler for OAuth 2.0 redirects back to localhost.
|
||||
|
||||
Waits for a single request and parses the query parameters
|
||||
into the servers query_params and then stops serving.
|
||||
"""
|
||||
|
||||
def do_GET(s):
|
||||
"""Handle a GET request
|
||||
|
||||
Checks the query parameters and if an error
|
||||
occurred print a message of failure, otherwise
|
||||
indicate success.
|
||||
"""
|
||||
s.send_response(200)
|
||||
s.send_header("Content-type", "text/html")
|
||||
s.end_headers()
|
||||
query = s.path.split('?', 1)[-1]
|
||||
query = dict(parse_qsl(query))
|
||||
s.server.query_params = query
|
||||
s.wfile.write("<html><head><title>Authentication Status</title></head>")
|
||||
if 'error' in query:
|
||||
s.wfile.write("<body><p>The authentication request failed.</p>")
|
||||
else:
|
||||
s.wfile.write("<body><p>You have successfully authenticated</p>")
|
||||
s.wfile.write("</body></html>")
|
||||
|
||||
def log_message(self, format, *args):
|
||||
"""Do not log messages to stdout while running as a command line program."""
|
||||
pass
|
||||
|
||||
def run(flow, filename):
|
||||
def run(flow, storage):
|
||||
"""Core code for a command-line application.
|
||||
"""
|
||||
parser = OptionParser()
|
||||
parser.add_option("-f", "--file", dest="filename",
|
||||
default=filename, help="write credentials to FILE", metavar="FILE")
|
||||
|
||||
# The support for localhost is a work in progress and does not
|
||||
# work at this point.
|
||||
#parser.add_option("-p", "--no_local_web_server", dest="localhost",
|
||||
# action="store_false",
|
||||
# default=True,
|
||||
# help="Do not run a web server on localhost to handle redirect URIs")
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
#if options.localhost:
|
||||
# server_class = BaseHTTPServer.HTTPServer
|
||||
# try:
|
||||
# port_number = PORT_NUMBERS[0]
|
||||
# httpd = server_class((HOST_NAME, port_number), ClientRedirectHandler)
|
||||
# except socket.error:
|
||||
# port_number = PORT_NUMBERS[1]
|
||||
# try:
|
||||
# httpd = server_class((HOST_NAME, port_number), ClientRedirectHandler)
|
||||
# except socket.error:
|
||||
# options.localhost = False
|
||||
# redirect_uri = 'http://%s:%s/' % (HOST_NAME, port_number)
|
||||
#else:
|
||||
# redirect_uri = 'oob'
|
||||
|
||||
redirect_uri = 'oob'
|
||||
|
||||
authorize_url = flow.step1_get_authorize_url(redirect_uri)
|
||||
authorize_url = flow.step1_get_authorize_url('oob')
|
||||
|
||||
print 'Go to the following link in your browser:'
|
||||
print authorize_url
|
||||
print
|
||||
|
||||
#if options.localhost:
|
||||
# httpd.handle_request()
|
||||
# if 'error' in httpd.query_params:
|
||||
# sys.exit('Authentication request was rejected.')
|
||||
# if 'code' in httpd.query_params:
|
||||
# code = httpd.query_params['code']
|
||||
#else:
|
||||
accepted = 'n'
|
||||
while accepted.lower() == 'n':
|
||||
accepted = raw_input('Have you authorized me? (y/n) ')
|
||||
@@ -135,5 +40,9 @@ def run(flow, filename):
|
||||
|
||||
credentials = flow.step2_exchange(code)
|
||||
|
||||
Storage(options.filename).put(credentials)
|
||||
print "You have successfully authenticated."
|
||||
storage.put(credentials)
|
||||
credentials.set_store(storage.put)
|
||||
|
||||
print 'You have successfully authenticated.'
|
||||
|
||||
return credentials
|
||||
|
@@ -4,7 +4,11 @@ try:
|
||||
import settings # Assumed to be in the same directory.
|
||||
except ImportError:
|
||||
import sys
|
||||
sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
|
||||
sys.stderr.write("""Error: Can't find the file 'settings.py' in the
|
||||
directory containing %r. It appears you've customized things. You'll
|
||||
have to run django-admin.py, passing it your settings module.
|
||||
(If the file settings.py does indeed exist, it's causing an ImportError
|
||||
somehow.)\n""" % __file__)
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@@ -45,7 +45,8 @@ class MainHandler(webapp.RequestHandler):
|
||||
@login_required
|
||||
def get(self):
|
||||
user = users.get_current_user()
|
||||
credentials = StorageByKeyName(Credentials, user.user_id(), 'credentials').get()
|
||||
credentials = StorageByKeyName(
|
||||
Credentials, user.user_id(), 'credentials').get()
|
||||
|
||||
if credentials:
|
||||
http = httplib2.Http()
|
||||
@@ -87,7 +88,8 @@ class OAuthHandler(webapp.RequestHandler):
|
||||
flow = pickle.loads(memcache.get(user.user_id()))
|
||||
if flow:
|
||||
credentials = flow.step2_exchange(self.request.params)
|
||||
StorageByKeyName(Credentials, user.user_id(), 'credentials').put(credentials)
|
||||
StorageByKeyName(
|
||||
Credentials, user.user_id(), 'credentials').put(credentials)
|
||||
self.redirect("/")
|
||||
else:
|
||||
pass
|
||||
|
@@ -11,28 +11,43 @@ latest content and then adds a new entry.
|
||||
|
||||
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
|
||||
|
||||
from apiclient.discovery import build
|
||||
from oauth2client.file import Storage
|
||||
|
||||
import httplib2
|
||||
import pickle
|
||||
import pprint
|
||||
|
||||
from apiclient.discovery import build
|
||||
from oauth2client.file import Storage
|
||||
from oauth2client.client import OAuth2WebServerFlow
|
||||
from oauth2client.tools import run
|
||||
|
||||
# Uncomment the next line to get very detailed logging
|
||||
#httplib2.debuglevel = 4
|
||||
|
||||
|
||||
def main():
|
||||
credentials = Storage('buzz.dat').get()
|
||||
storage = Storage('buzz.dat')
|
||||
credentials = storage.get()
|
||||
if not credentials:
|
||||
flow = OAuth2WebServerFlow(
|
||||
client_id='433807057907.apps.googleusercontent.com',
|
||||
client_secret='jigtZpMApkRxncxikFpR+SFg',
|
||||
scope='https://www.googleapis.com/auth/buzz',
|
||||
user_agent='buzz-cmdline-sample/1.0',
|
||||
domain='anonymous',
|
||||
xoauth_displayname='Buzz Client Example App'
|
||||
)
|
||||
credentials = run(flow, storage)
|
||||
|
||||
http = httplib2.Http()
|
||||
http = credentials.authorize(http)
|
||||
|
||||
p = build("buzz", "v1", http=http, developerKey="AIzaSyDRRpR3GS1F1_jKNNM9HCNd2wJQyPG3oN0")
|
||||
p = build("buzz", "v1", http=http,
|
||||
developerKey="AIzaSyDRRpR3GS1F1_jKNNM9HCNd2wJQyPG3oN0")
|
||||
activities = p.activities()
|
||||
|
||||
# Retrieve the first two activities
|
||||
activitylist = activities.list(max_results='2', scope='@self', userId='@me').execute()
|
||||
activitylist = activities.list(
|
||||
max_results='2', scope='@self', userId='@me').execute()
|
||||
print "Retrieved the first two activities"
|
||||
|
||||
# Retrieve the next two activities
|
||||
@@ -45,14 +60,16 @@ def main():
|
||||
"data": {
|
||||
'title': 'Testing insert',
|
||||
'object': {
|
||||
'content': u'Just a short note to show that insert is working. ☄',
|
||||
'content':
|
||||
u'Just a short note to show that insert is working. ☄',
|
||||
'type': 'note'}
|
||||
}
|
||||
}
|
||||
activity = activities.insert(userId='@me', body=new_activity_body).execute()
|
||||
print "Added a new activity"
|
||||
|
||||
activitylist = activities.list(max_results='2', scope='@self', userId='@me').execute()
|
||||
activitylist = activities.list(
|
||||
max_results='2', scope='@self', userId='@me').execute()
|
||||
|
||||
# Add a comment to that activity
|
||||
comment_body = {
|
||||
|
@@ -1,37 +0,0 @@
|
||||
# Copyright (C) 2010 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Do the OAuth 2.0 Web Server dance.
|
||||
|
||||
Do the OAuth 2.0 Web Server dance for
|
||||
a command line application. Store the generated
|
||||
credentials in a common file that is used by
|
||||
other example apps in the same directory.
|
||||
"""
|
||||
|
||||
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
|
||||
|
||||
from oauth2client.client import OAuth2WebServerFlow
|
||||
from oauth2client.tools import run
|
||||
|
||||
flow = OAuth2WebServerFlow(
|
||||
client_id='433807057907.apps.googleusercontent.com',
|
||||
client_secret='jigtZpMApkRxncxikFpR+SFg',
|
||||
scope='https://www.googleapis.com/auth/buzz',
|
||||
user_agent='buzz-cmdline-sample/1.0',
|
||||
domain='anonymous',
|
||||
xoauth_displayname='Buzz Client Example App'
|
||||
)
|
||||
|
||||
run(flow, 'buzz.dat')
|
56
samples/oauth2/latitude/latitude.py
Normal file
56
samples/oauth2/latitude/latitude.py
Normal file
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/python2.4
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2010 Google Inc. All Rights Reserved.
|
||||
|
||||
"""Simple command-line example for Latitude.
|
||||
|
||||
Command-line application that sets the users
|
||||
current location.
|
||||
"""
|
||||
|
||||
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
|
||||
|
||||
import httplib2
|
||||
|
||||
from apiclient.discovery import build
|
||||
from oauth2client.file import Storage
|
||||
from oauth2client.client import OAuth2WebServerFlow
|
||||
from oauth2client.tools import run
|
||||
|
||||
# Uncomment to get detailed logging
|
||||
#httplib2.debuglevel = 4
|
||||
|
||||
|
||||
def main():
|
||||
storage = Storage('latitude.dat')
|
||||
credentials = storage.get()
|
||||
|
||||
if not credentials:
|
||||
flow = OAuth2WebServerFlow(
|
||||
client_id='433807057907.apps.googleusercontent.com',
|
||||
client_secret='jigtZpMApkRxncxikFpR+SFg',
|
||||
scope='https://www.googleapis.com/auth/latitude',
|
||||
user_agent='latitude-cmdline-sample/1.0',
|
||||
xoauth_displayname='Latitude Client Example App')
|
||||
|
||||
credentials = run(flow, storage)
|
||||
|
||||
http = httplib2.Http()
|
||||
http = credentials.authorize(http)
|
||||
|
||||
p = build("latitude", "v1", http=http)
|
||||
|
||||
body = {
|
||||
"data": {
|
||||
"kind": "latitude#location",
|
||||
"latitude": 37.420352,
|
||||
"longitude": -122.083389,
|
||||
"accuracy": 130,
|
||||
"altitude": 35
|
||||
}
|
||||
}
|
||||
print p.currentLocation().insert(body=body).execute()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@@ -11,22 +11,30 @@ latest content and then adds a new entry.
|
||||
|
||||
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
|
||||
|
||||
import httplib2
|
||||
|
||||
from apiclient.discovery import build
|
||||
from oauth2client.file import Storage
|
||||
|
||||
import httplib2
|
||||
from oauth2client.client import OAuth2WebServerFlow
|
||||
from oauth2client.tools import run
|
||||
|
||||
# Uncomment to get low level HTTP logging
|
||||
#httplib2.debuglevel = 4
|
||||
|
||||
# Uncomment to get logging
|
||||
#import logging
|
||||
#logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
|
||||
def main():
|
||||
credentials = Storage('moderator.dat').get()
|
||||
storage = Storage('moderator.dat')
|
||||
credentials = storage.get()
|
||||
|
||||
if not credentials:
|
||||
flow = OAuth2WebServerFlow(
|
||||
client_id='433807057907.apps.googleusercontent.com',
|
||||
client_secret='jigtZpMApkRxncxikFpR+SFg',
|
||||
scope='https://www.googleapis.com/auth/moderator',
|
||||
user_agent='moderator-cmdline-sample/1.0',
|
||||
xoauth_displayname='Moderator Client Example App')
|
||||
|
||||
credentials = run(flow, storage)
|
||||
|
||||
http = httplib2.Http()
|
||||
http = credentials.authorize(http)
|
||||
|
@@ -1,35 +0,0 @@
|
||||
# Copyright (C) 2010 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Do the OAuth 2.0 Web Server dance.
|
||||
|
||||
Do the OAuth 2.0 Web Server dance for
|
||||
a command line application. Store the generated
|
||||
credentials in a common file that is used by
|
||||
other example apps in the same directory.
|
||||
"""
|
||||
|
||||
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
|
||||
|
||||
from oauth2client.client import OAuth2WebServerFlow
|
||||
from oauth2client.tools import run
|
||||
|
||||
flow = OAuth2WebServerFlow(
|
||||
client_id='433807057907.apps.googleusercontent.com',
|
||||
client_secret='jigtZpMApkRxncxikFpR+SFg',
|
||||
scope='https://www.googleapis.com/auth/moderator',
|
||||
user_agent='moderator-cmdline-sample/1.0',
|
||||
xoauth_displayname='Moderator Client Example App')
|
||||
|
||||
run(flow, 'moderator.dat')
|
59
samples/oauth2/urlshortener/main.py
Normal file
59
samples/oauth2/urlshortener/main.py
Normal file
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/python2.4
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2010 Google Inc. All Rights Reserved.
|
||||
|
||||
"""Simple command-line example for Google URL Shortener API.
|
||||
|
||||
Command-line application that shortens a URL.
|
||||
"""
|
||||
|
||||
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
|
||||
|
||||
import httplib2
|
||||
import pprint
|
||||
|
||||
from apiclient.discovery import build
|
||||
from oauth2client.file import Storage
|
||||
from oauth2client.client import OAuth2WebServerFlow
|
||||
from oauth2client.tools import run
|
||||
|
||||
# Uncomment to get detailed logging
|
||||
#httplib2.debuglevel = 4
|
||||
|
||||
|
||||
def main():
|
||||
storage = Storage('urlshortener.dat')
|
||||
credentials = storage.get()
|
||||
|
||||
if not credentials:
|
||||
flow = OAuth2WebServerFlow(
|
||||
client_id='433807057907.apps.googleusercontent.com',
|
||||
client_secret='jigtZpMApkRxncxikFpR+SFg',
|
||||
scope='https://www.googleapis.com/auth/urlshortener',
|
||||
user_agent='urlshortener-cmdline-sample/1.0',
|
||||
xoauth_displayname='URL Shortener Client Example App')
|
||||
|
||||
credentials = run(flow, storage)
|
||||
|
||||
http = httplib2.Http()
|
||||
http = credentials.authorize(http)
|
||||
|
||||
# Build the url shortener service
|
||||
service = build("urlshortener", "v1", http=http,
|
||||
developerKey="AIzaSyDRRpR3GS1F1_jKNNM9HCNd2wJQyPG3oN0")
|
||||
url = service.url()
|
||||
|
||||
# Create a shortened URL by inserting the URL into the url collection.
|
||||
body = {"longUrl": "http://code.google.com/apis/urlshortener/" }
|
||||
resp = url.insert(body=body).execute()
|
||||
pprint.pprint(resp)
|
||||
|
||||
shortUrl = resp['id']
|
||||
|
||||
# Convert the shortened URL back into a long URL
|
||||
resp = url.get(shortUrl=shortUrl).execute()
|
||||
pprint.pprint(resp)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Reference in New Issue
Block a user