PageRenderTime 44ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 1ms

/src/googlecl/discovery/__init__.py

http://googlecl.googlecode.com/
Python | 177 lines | 150 code | 3 blank | 24 comment | 2 complexity | 69af9b8144cf10758b53cdc09ceee214 MD5 | raw file
  1. # Copyright (C) 2011 Google Inc.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. """Subprogram for GoogleCL which handles all requests
  15. using the Discovery service
  16. This program uses the Discovery API to take interact with other APIs.
  17. It is called when GoogleCL cannot identify a requested service as using gdata.
  18. Syntax is generally similar to using gdata services.
  19. General usage (omitting initial 'google'):
  20. > <service> <method path> <parameters>
  21. > help <service> <path>
  22. > format <service> <method path>
  23. Examples:
  24. # Creating a new shortened goo.gl URL
  25. urlshortener insert --body {"longUrl":"<longUrl>"}
  26. # Getting data for a shortened goo.gl URL
  27. urlshortener url get <shortUrl>
  28. """
  29. import httplib2
  30. import logging
  31. import googlecl
  32. from apiclient.discovery import build_from_document
  33. from googlecl.discovery import authentication
  34. from googlecl.discovery import output
  35. from googlecl.discovery import data
  36. from googlecl.discovery import docs
  37. import simplejson as json
  38. LOG = logging.getLogger(googlecl.LOGGER_NAME)
  39. DISCOVERY_URI = '%s/discovery/v1/apis/{api}/{apiVersion}/rest'
  40. class DiscoveryManager():
  41. def __init__(self, email):
  42. self.dataManager = data.DefaultManager(email)
  43. self.docManager = docs.DocManager(self.dataManager.local_apis, self.dataManager.base_url)
  44. def run(self, argv):
  45. try:
  46. """Primary function for the program
  47. Executes methods, displays help, and organizes formatting for services
  48. using Discovery
  49. Args:
  50. cache: A cache, which may already contain objects to be used
  51. argv: The arguments, parsed into a list as from the command line
  52. """
  53. # Determines if the help, format, or default is being called
  54. LOG.debug('Running Discovery...')
  55. isHelp = argv[0]=='help'
  56. verbose = False
  57. if isHelp:
  58. argv = argv[1:]
  59. if argv[-1] == '--verbose' or argv[-1] == '-v':
  60. verbose = True
  61. argv = argv[:-1]
  62. http = httplib2.Http()
  63. LOG.debug('Parsing service...')
  64. # Fetches service, version, docs, etc.
  65. try:
  66. servicename, version, doc, args = self.docManager.run(argv, isHelp,
  67. verbose)
  68. except TypeError:
  69. return
  70. LOG.debug('Managing auth...')
  71. # Checks if credentials are needed and, if so, whether they are possessed.
  72. # If not, gets appropriate credentials.
  73. if 'auth' in doc:
  74. if '--force-auth' in args:
  75. args.remove('--force-auth')
  76. force_auth = True
  77. else:
  78. force_auth = False
  79. http = authentication.authenticate(self.dataManager.email, servicename, doc, http,
  80. self.dataManager.client_id, self.dataManager.client_secret, force_auth)
  81. # Builds the service and finds the method
  82. service = build_from_document(json.dumps(doc), DISCOVERY_URI % self.dataManager.base_url, http=http)
  83. else:
  84. service = build_from_document(json.dumps(doc), DISCOVERY_URI % self.dataManager.base_url,
  85. developerKey=self.dataManager.devkey2, http=http)
  86. LOG.debug('Determining task...')
  87. try:
  88. metinfo, method, args = getMethod(service, doc, args)
  89. except:
  90. #LOG.error('Did not recognize task.')
  91. return
  92. LOG.debug('Parsing parameters...')
  93. try:
  94. kwargs = self.dataManager.fill_out_options(metinfo, doc, args)
  95. except TypeError, err:
  96. raise
  97. return
  98. LOG.debug('Executing method...')
  99. try:
  100. resp = method(**kwargs).execute()
  101. except Exception, err:
  102. LOG.error(err)
  103. return
  104. LOG.debug('Displaying output...')
  105. # Displays formatted output
  106. output.output(resp, self.dataManager.formatting)
  107. except Exception, err:
  108. print 'Uncaught error'
  109. raise
  110. def apis_list(self):
  111. # Returns a list of the APIs that may be used
  112. return [str(d['name']) for d in self.docManager.directory['items']]
  113. def getMethod(service, doc, args):
  114. """ Locates the method to be executed
  115. Capable of finding some methods implicitly
  116. Displays assistance if method isn't identified
  117. Args:
  118. service: The service object being used
  119. doc: Documentation describing the service
  120. args: List containing the method path to be followed
  121. Returns:
  122. A tuple of the meta-info describing the method,
  123. the method itself, and the parameters for the method
  124. """
  125. obj = doc
  126. attr = service
  127. i = 0
  128. while 'resources' in obj or 'methods' in obj:
  129. if i < len(args) and 'resources' in obj and args[i] in obj['resources']:
  130. attr = getattr(attr, args[i])
  131. obj = obj['resources'][args[i]]
  132. i=i+1
  133. elif i < len(args) and 'methods' in obj and args[i] in obj['methods']:
  134. attr = getattr(attr, args[i])
  135. obj = obj['methods'][args[i]]
  136. i=i+1
  137. elif ('resources' in obj and not 'methods' in obj and
  138. len(obj['resources'])==1):
  139. attr = getattr(attr, obj['resources'].keys()[0])
  140. obj = obj['resources'][obj['resources'].keys()[0]]
  141. elif 'methods' in obj and not 'resources' in obj and len(obj['methods'])==1:
  142. attr = getattr(attr, obj['methods'].keys()[0])
  143. obj = obj['methods'][obj['methods'].keys()[0]]
  144. else:
  145. print 'Did not recognize task.'
  146. if 'methods' in obj:
  147. LOG.error('Possible methods: ' + ', '.join(obj['methods']))
  148. if 'resources' in obj:
  149. LOG.error('Possible resources: ' + ', '.join(obj['resources']))
  150. return
  151. if not 'id' in obj:
  152. attr = attr()
  153. return obj, attr, args[i:]