__init__.py

#

Copyright (C) 2011 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. Subprogram for GoogleCL which handles all requests

#

using the Discovery service

This program uses the Discovery API to take interact with other APIs. It is called when GoogleCL cannot identify a requested service as using gdata. Syntax is generally similar to using gdata services.

General usage (omitting initial 'google'):

help format

Examples: # Creating a new shortened goo.gl URL urlshortener insert --body {"longUrl":""}

# Getting data for a shortened goo.gl URL urlshortener url get

import httplib2
import logging

import googlecl

from apiclient.discovery import build_from_document
from googlecl.discovery import authentication
from googlecl.discovery import output
from googlecl.discovery import data
from googlecl.discovery import docs
import simplejson as json

LOG = logging.getLogger(googlecl.LOGGER_NAME)
DISCOVERY_URI = '%s/discovery/v1/apis/{api}/{apiVersion}/rest'
#
class DiscoveryManager():
#
  def __init__(self, email):
    self.dataManager = data.DefaultManager(email)
    self.docManager = docs.DocManager(self.dataManager.local_apis, self.dataManager.base_url)
#

Primary function for the program

  def run(self, argv):
   try:
#

Executes methods, displays help, and organizes formatting for services using Discovery

Args: cache: A cache, which may already contain objects to be used argv: The arguments, parsed into a list as from the command line

Determines if the help, format, or default is being called

    LOG.debug('Running Discovery...')
    isHelp = argv[0]=='help'
    verbose = False
    if isHelp:
      argv = argv[1:]
      if argv[-1] == '--verbose' or argv[-1] == '-v':
        verbose = True
        argv = argv[:-1]

    http = httplib2.Http()
    
    LOG.debug('Parsing service...')
#

Fetches service, version, docs, etc.

    try:
      servicename, version, doc, args = self.docManager.run(argv, isHelp,
                                                            verbose)
    except TypeError:
      return

    LOG.debug('Managing auth...')
#

Checks if credentials are needed and, if so, whether they are possessed. If not, gets appropriate credentials.

    if 'auth' in doc:
      if '--force-auth' in args:
        args.remove('--force-auth')
        force_auth = True
      else:
        force_auth = False
      http = authentication.authenticate(self.dataManager.email, servicename, doc, http,
        self.dataManager.client_id, self.dataManager.client_secret, force_auth)
#

Builds the service and finds the method

      service = build_from_document(json.dumps(doc), DISCOVERY_URI % self.dataManager.base_url, http=http)
    else:
      service = build_from_document(json.dumps(doc), DISCOVERY_URI % self.dataManager.base_url,
                      developerKey=self.dataManager.devkey2, http=http)
    LOG.debug('Determining task...')
    try:
      metinfo, method, args = getMethod(service, doc, args)
    except:
#

LOG.error('Did not recognize task.')

      return

    LOG.debug('Parsing parameters...')
    try:
      kwargs = self.dataManager.fill_out_options(metinfo, doc, args)
    except TypeError, err:
      raise
      return

    LOG.debug('Executing method...')
    try:
      resp = method(**kwargs).execute()
    except Exception, err:
      LOG.error(err)
      return

    LOG.debug('Displaying output...')
#

Displays formatted output

    output.output(resp, self.dataManager.formatting)
   except Exception, err:
    print 'Uncaught error'
    raise
#
  def apis_list(self):
#

Returns a list of the APIs that may be used

    return [str(d['name']) for d in self.docManager.directory['items']]
#

Locates the method to be executed

def getMethod(service, doc, args):
#

apable of finding some methods implicitly isplays assistance if method isn't identified

rgs: service: The service object being used doc: Documentation describing the service args: List containing the method path to be followed

eturns: A tuple of the meta-info describing the method, the method itself, and the parameters for the method

  obj = doc
  attr = service
  i = 0
  while 'resources' in obj or 'methods' in obj:
    if i < len(args) and 'resources' in obj and args[i] in obj['resources']:
      attr = getattr(attr, args[i])
      obj = obj['resources'][args[i]]
      i=i+1
    elif i < len(args) and 'methods' in obj and args[i] in obj['methods']:
      attr = getattr(attr, args[i])
      obj = obj['methods'][args[i]]
      i=i+1
    elif ('resources' in obj and not 'methods' in obj and
        len(obj['resources'])==1):
      attr = getattr(attr, obj['resources'].keys()[0])
      obj = obj['resources'][obj['resources'].keys()[0]]
    elif 'methods' in obj and not 'resources' in obj and len(obj['methods'])==1:
      attr = getattr(attr, obj['methods'].keys()[0])
      obj = obj['methods'][obj['methods'].keys()[0]]
    else:
      print 'Did not recognize task.'
      if 'methods' in obj:
        LOG.error('Possible methods: ' + ', '.join(obj['methods']))
      if 'resources' in obj:
        LOG.error('Possible resources: ' + ', '.join(obj['resources']))
      return
    if not 'id' in obj:
      attr = attr()
  return obj, attr, args[i:]