Clean up doc strings and unused imports

This commit is contained in:
Joe Gregorio
2011-02-16 15:32:39 -05:00
parent 1b63a69935
commit 7c22ab2f41
8 changed files with 78 additions and 65 deletions

View File

@@ -14,12 +14,10 @@
"""Client for discovery based APIs """Client for discovery based APIs
A client library for Google's discovery A client library for Google's discovery based APIs.
based APIs.
""" """
__author__ = 'jcgregorio@google.com (Joe Gregorio)' __author__ = 'jcgregorio@google.com (Joe Gregorio)'
__all__ = [ __all__ = [
'build', 'build_from_document' 'build', 'build_from_document'
] ]
@@ -48,8 +46,9 @@ DISCOVERY_URI = ('https://www.googleapis.com/discovery/v0.2beta1/describe/'
def key2param(key): def key2param(key):
""" """Converts key names into parameter names.
max-results -> max_results
For example, converting "max-results" -> "max_results"
""" """
result = [] result = []
key = list(key) key = list(key)
@@ -106,10 +105,10 @@ def build(serviceName, version,
resp, content = http.request(requested_url) resp, content = http.request(requested_url)
service = simplejson.loads(content) service = simplejson.loads(content)
fn = os.path.join(os.path.dirname(__file__), "contrib", fn = os.path.join(os.path.dirname(__file__), 'contrib',
serviceName, "future.json") serviceName, 'future.json')
try: try:
f = file(fn, "r") f = file(fn, 'r')
future = f.read() future = f.read()
f.close() f.close()
except IOError: except IOError:
@@ -275,9 +274,9 @@ def createResource(http, baseUrl, model, requestBuilder,
docs = ['A description of how to use this function\n\n'] docs = ['A description of how to use this function\n\n']
for arg in argmap.iterkeys(): for arg in argmap.iterkeys():
required = "" required = ''
if arg in required_params: if arg in required_params:
required = " (required)" required = ' (required)'
docs.append('%s - A parameter%s\n' % (arg, required)) docs.append('%s - A parameter%s\n' % (arg, required))
setattr(method, '__doc__', ''.join(docs)) setattr(method, '__doc__', ''.join(docs))
@@ -363,7 +362,7 @@ def createResource(http, baseUrl, model, requestBuilder,
if futureDesc and 'methods' in futureDesc: if futureDesc and 'methods' in futureDesc:
for methodName, methodDesc in futureDesc['methods'].iteritems(): for methodName, methodDesc in futureDesc['methods'].iteritems():
if 'next' in methodDesc and methodName in resourceDesc['methods']: if 'next' in methodDesc and methodName in resourceDesc['methods']:
createNextMethod(Resource, methodName + "_next", createNextMethod(Resource, methodName + '_next',
resourceDesc['methods'][methodName], resourceDesc['methods'][methodName],
methodDesc['next']) methodDesc['next'])

View File

@@ -23,7 +23,7 @@ class HttpRequest(object):
""" """
def __init__(self, http, postproc, uri, def __init__(self, http, postproc, uri,
method="GET", method='GET',
body=None, body=None,
headers=None, headers=None,
methodId=None): methodId=None):
@@ -139,7 +139,7 @@ class RequestMockBuilder(object):
""" """
self.responses = responses self.responses = responses
def __call__(self, http, postproc, uri, method="GET", body=None, def __call__(self, http, postproc, uri, method='GET', body=None,
headers=None, methodId=None): headers=None, methodId=None):
"""Implements the callable interface that discovery.build() expects """Implements the callable interface that discovery.build() expects
of requestBuilder, which is to build an object compatible with of requestBuilder, which is to build an object compatible with
@@ -169,7 +169,7 @@ class HttpMock(object):
self.headers = headers self.headers = headers
def request(self, uri, def request(self, uri,
method="GET", method='GET',
body=None, body=None,
headers=None, headers=None,
redirections=1, redirections=1,

View File

@@ -8,7 +8,6 @@ Utilities for making it easier to work with OAuth.
__author__ = 'jcgregorio@google.com (Joe Gregorio)' __author__ = 'jcgregorio@google.com (Joe Gregorio)'
import copy import copy
import datetime
import httplib2 import httplib2
import logging import logging
import oauth2 as oauth import oauth2 as oauth
@@ -18,9 +17,9 @@ import urlparse
from anyjson import simplejson from anyjson import simplejson
try: try:
from urlparse import parse_qs, parse_qsl from urlparse import parse_qsl
except ImportError: except ImportError:
from cgi import parse_qs, parse_qsl from cgi import parse_qsl
class Error(Exception): class Error(Exception):
@@ -137,7 +136,7 @@ class OAuthCredentials(Credentials):
req = oauth.Request.from_consumer_and_token( req = oauth.Request.from_consumer_and_token(
self.consumer, self.token, http_method=method, http_url=uri) self.consumer, self.token, http_method=method, http_url=uri)
req.sign_request(signer, self.consumer, self.token) req.sign_request(signer, self.consumer, self.token)
if headers == None: if headers is None:
headers = {} headers = {}
headers.update(req.to_header()) headers.update(req.to_header())
if 'user-agent' in headers: if 'user-agent' in headers:
@@ -210,7 +209,7 @@ class FlowThreeLegged(Flow):
resp, content = client.request(uri, 'POST', headers=headers, resp, content = client.request(uri, 'POST', headers=headers,
body=body) body=body)
if resp['status'] != '200': if resp['status'] != '200':
logging.error('Failed to retrieve temporary authorization: %s' % content) logging.error('Failed to retrieve temporary authorization: %s', content)
raise RequestError('Invalid response %s.' % resp['status']) raise RequestError('Invalid response %s.' % resp['status'])
self.request_token = dict(parse_qsl(content)) self.request_token = dict(parse_qsl(content))
@@ -247,7 +246,7 @@ class FlowThreeLegged(Flow):
uri = _oauth_uri('access', self.discovery, self.params) uri = _oauth_uri('access', self.discovery, self.params)
resp, content = client.request(uri, 'POST', headers=headers) resp, content = client.request(uri, 'POST', headers=headers)
if resp['status'] != '200': if resp['status'] != '200':
logging.error('Failed to retrieve access token: %s' % content) logging.error('Failed to retrieve access token: %s', content)
raise RequestError('Invalid response %s.' % resp['status']) raise RequestError('Invalid response %s.' % resp['status'])
oauth_params = dict(parse_qsl(content)) oauth_params = dict(parse_qsl(content))

View File

@@ -14,8 +14,7 @@
"""Utilities for Google App Engine """Utilities for Google App Engine
Utilities for making it easier to use OAuth 2.0 Utilities for making it easier to use OAuth 2.0 on Google App Engine.
on Google App Engine.
""" """
__author__ = 'jcgregorio@google.com (Joe Gregorio)' __author__ = 'jcgregorio@google.com (Joe Gregorio)'
@@ -29,8 +28,9 @@ from client import Storage
class FlowProperty(db.Property): class FlowProperty(db.Property):
"""Utility property that allows easy """App Engine datastore Property for Flow.
storage and retreival of an
Utility property that allows easy storage and retreival of an
oauth2client.Flow""" oauth2client.Flow"""
# Tell what the user type is. # Tell what the user type is.
@@ -60,8 +60,9 @@ class FlowProperty(db.Property):
class CredentialsProperty(db.Property): class CredentialsProperty(db.Property):
"""Utility property that allows easy """App Engine datastore Property for Credentials.
storage and retrieval of
Utility property that allows easy storage and retrieval of
oath2client.Credentials oath2client.Credentials
""" """
@@ -109,9 +110,9 @@ class StorageByKeyName(Storage):
key_name: string, key name for the entity that has the credentials key_name: string, key name for the entity that has the credentials
property_name: string, name of the property that is an CredentialsProperty property_name: string, name of the property that is an CredentialsProperty
""" """
self.model = model self._model = model
self.key_name = key_name self._key_name = key_name
self.property_name = property_name self._property_name = property_name
def get(self): def get(self):
"""Retrieve Credential from datastore. """Retrieve Credential from datastore.
@@ -119,8 +120,8 @@ class StorageByKeyName(Storage):
Returns: Returns:
oauth2client.Credentials oauth2client.Credentials
""" """
entity = self.model.get_or_insert(self.key_name) entity = self._model.get_or_insert(self._key_name)
credential = getattr(entity, self.property_name) credential = getattr(entity, self._property_name)
if credential and hasattr(credential, 'set_store'): if credential and hasattr(credential, 'set_store'):
credential.set_store(self.put) credential.set_store(self.put)
return credential return credential
@@ -131,6 +132,6 @@ class StorageByKeyName(Storage):
Args: Args:
credentials: Credentials, the credentials to store. credentials: Credentials, the credentials to store.
""" """
entity = self.model.get_or_insert(self.key_name) entity = self._model.get_or_insert(self._key_name)
setattr(entity, self.property_name, credentials) setattr(entity, self._property_name, credentials)
entity.put() entity.put()

View File

@@ -113,12 +113,12 @@ class OAuth2Credentials(Credentials):
the OAuth2WebServerFlow. the OAuth2WebServerFlow.
Args: Args:
token_uri: string, URI of token endpoint token_uri: string, URI of token endpoint.
client_id: string, client identifier client_id: string, client identifier.
client_secret: string, client secret client_secret: string, client secret.
access_token: string, access token access_token: string, access token.
token_expiry: datetime, when the access_token expires token_expiry: datetime, when the access_token expires.
refresh_token: string, refresh token refresh_token: string, refresh token.
user_agent: string, The HTTP User-Agent to provide for this application. user_agent: string, The HTTP User-Agent to provide for this application.
@@ -178,14 +178,16 @@ class OAuth2Credentials(Credentials):
'user-agent': self.user_agent, 'user-agent': self.user_agent,
'content-type': 'application/x-www-form-urlencoded' 'content-type': 'application/x-www-form-urlencoded'
} }
resp, content = http_request(self.token_uri, method='POST', body=body, headers=headers) resp, content = http_request(
self.token_uri, method='POST', body=body, headers=headers)
if resp.status == 200: if resp.status == 200:
# TODO(jcgregorio) Raise an error if loads fails? # TODO(jcgregorio) Raise an error if loads fails?
d = simplejson.loads(content) d = simplejson.loads(content)
self.access_token = d['access_token'] self.access_token = d['access_token']
self.refresh_token = d.get('refresh_token', self.refresh_token) self.refresh_token = d.get('refresh_token', self.refresh_token)
if 'expires_in' in d: if 'expires_in' in d:
self.token_expiry = datetime.timedelta(seconds = int(d['expires_in'])) + datetime.datetime.now() self.token_expiry = datetime.timedelta(
seconds = int(d['expires_in'])) + datetime.datetime.now()
else: else:
self.token_expiry = None self.token_expiry = None
if self.store is not None: if self.store is not None:
@@ -195,7 +197,8 @@ class OAuth2Credentials(Credentials):
raise RequestError('Invalid response %s.' % resp['status']) raise RequestError('Invalid response %s.' % resp['status'])
def authorize(self, http): def authorize(self, http):
""" """Authorize an httplib2.Http instance with these credentials.
Args: Args:
http: An instance of httplib2.Http http: An instance of httplib2.Http
or something that acts like it. or something that acts like it.
@@ -232,7 +235,7 @@ class OAuth2Credentials(Credentials):
else: else:
headers['user-agent'] = self.user_agent headers['user-agent'] = self.user_agent
resp, content = request_orig(uri, method, body, headers, resp, content = request_orig(uri, method, body, headers,
redirections, connection_type) redirections, connection_type)
if resp.status == 401: if resp.status == 401:
logging.info("Refreshing because we got a 401") logging.info("Refreshing because we got a 401")
self._refresh(request_orig) self._refresh(request_orig)
@@ -252,18 +255,20 @@ class OAuth2WebServerFlow(Flow):
""" """
def __init__(self, client_id, client_secret, scope, user_agent, def __init__(self, client_id, client_secret, scope, user_agent,
authorization_uri='https://www.google.com/accounts/o8/oauth2/authorization', auth_uri='https://www.google.com/accounts/o8/oauth2/authorization',
token_uri='https://www.google.com/accounts/o8/oauth2/token', token_uri='https://www.google.com/accounts/o8/oauth2/token',
**kwargs): **kwargs):
"""Constructor for OAuth2WebServerFlow """Constructor for OAuth2WebServerFlow
Args: Args:
client_id: string, client identifier client_id: string, client identifier.
client_secret: string client secret client_secret: string client secret.
scope: string, scope of the credentials being requested scope: string, scope of the credentials being requested.
user_agent: string, HTTP User-Agent to provide for this application. user_agent: string, HTTP User-Agent to provide for this application.
authorization_uri: string, URI for authorization endpoint auth_uri: string, URI for authorization endpoint. For convenience
token_uri: string, URI for token endpoint defaults to Google's endpoints but any OAuth 2.0 provider can be used.
token_uri: string, URI for token endpoint. For convenience
defaults to Google's endpoints but any OAuth 2.0 provider can be used.
**kwargs: dict, The keyword arguments are all optional and required **kwargs: dict, The keyword arguments are all optional and required
parameters for the OAuth calls. parameters for the OAuth calls.
""" """
@@ -271,7 +276,7 @@ class OAuth2WebServerFlow(Flow):
self.client_secret = client_secret self.client_secret = client_secret
self.scope = scope self.scope = scope
self.user_agent = user_agent self.user_agent = user_agent
self.authorization_uri = authorization_uri self.auth_uri = auth_uri
self.token_uri = token_uri self.token_uri = token_uri
self.params = kwargs self.params = kwargs
self.redirect_uri = None self.redirect_uri = None
@@ -298,7 +303,7 @@ class OAuth2WebServerFlow(Flow):
'scope': self.scope, 'scope': self.scope,
} }
query.update(self.params) query.update(self.params)
parts = list(urlparse.urlparse(self.authorization_uri)) parts = list(urlparse.urlparse(self.auth_uri))
query.update(dict(parse_qsl(parts[4]))) # 4 is the index of the query part query.update(dict(parse_qsl(parts[4]))) # 4 is the index of the query part
parts[4] = urllib.urlencode(query) parts[4] = urllib.urlencode(query)
return urlparse.urlunparse(parts) return urlparse.urlunparse(parts)
@@ -324,8 +329,8 @@ class OAuth2WebServerFlow(Flow):
'scope': self.scope 'scope': self.scope
}) })
headers = { headers = {
'user-agent': self.user_agent, 'user-agent': self.user_agent,
'content-type': 'application/x-www-form-urlencoded' 'content-type': 'application/x-www-form-urlencoded'
} }
h = httplib2.Http() h = httplib2.Http()
resp, content = h.request(self.token_uri, method='POST', body=body, headers=headers) resp, content = h.request(self.token_uri, method='POST', body=body, headers=headers)
@@ -340,8 +345,8 @@ class OAuth2WebServerFlow(Flow):
logging.info('Successfully retrieved access token: %s' % content) logging.info('Successfully retrieved access token: %s' % content)
return OAuth2Credentials(access_token, self.client_id, self.client_secret, return OAuth2Credentials(access_token, self.client_id, self.client_secret,
refresh_token, token_expiry, self.token_uri, refresh_token, token_expiry, self.token_uri,
self.user_agent) self.user_agent)
else: else:
logging.error('Failed to retrieve access token: %s' % content) logging.error('Failed to retrieve access token: %s' % content)
raise RequestError('Invalid response %s.' % resp['status']) raise RequestError('Invalid response %s.' % resp['status'])

View File

@@ -1,3 +1,13 @@
# Copyright 2010 Google Inc. All Rights Reserved.
"""OAuth 2.0 utilities for Django.
Utilities for using OAuth 2.0 in conjunction with
the Django datastore.
"""
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
import oauth2client import oauth2client
import base64 import base64
import pickle import pickle
@@ -31,7 +41,6 @@ class FlowField(models.Field):
return 'VARCHAR' return 'VARCHAR'
def to_python(self, value): def to_python(self, value):
print "In to_python", value
if value is None: if value is None:
return None return None
if isinstance(value, oauth2client.client.Flow): if isinstance(value, oauth2client.client.Flow):

View File

@@ -17,21 +17,22 @@ class Storage(BaseStorage):
"""Store and retrieve a single credential to and from a file.""" """Store and retrieve a single credential to and from a file."""
def __init__(self, filename): def __init__(self, filename):
self.filename = filename self._filename = filename
def get(self): def get(self):
"""Retrieve Credential from file. """Retrieve Credential from file.
Returns: Returns:
apiclient.oauth.Credentials oauth2client.client.Credentials
""" """
try: try:
f = open(self.filename, 'r') f = open(self._filename, 'r')
credentials = pickle.loads(f.read()) credentials = pickle.loads(f.read())
f.close() f.close()
credentials.set_store(self.put) credentials.set_store(self.put)
except: except:
credentials = None credentials = None
return credentials return credentials
def put(self, credentials): def put(self, credentials):
@@ -40,6 +41,6 @@ class Storage(BaseStorage):
Args: Args:
credentials: Credentials, the credentials to store. credentials: Credentials, the credentials to store.
""" """
f = open(self.filename, 'w') f = open(self._filename, 'w')
f.write(pickle.dumps(credentials)) f.write(pickle.dumps(credentials))
f.close() f.close()

View File

@@ -14,14 +14,13 @@
"""Command-line tools for authenticating via OAuth 2.0 """Command-line tools for authenticating via OAuth 2.0
Do the OAuth 2.0 Web Server dance for Do the OAuth 2.0 Web Server dance for a command line application. Stores the
a command line application. Stores the generated generated credentials in a common file that is used by other example apps in
credentials in a common file that is used by the same directory.
other example apps in the same directory.
""" """
__author__ = 'jcgregorio@google.com (Joe Gregorio)' __author__ = 'jcgregorio@google.com (Joe Gregorio)'
__all__ = ["run"] __all__ = ['run']
def run(flow, storage): def run(flow, storage):