PageRenderTime 42ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/scripts/api/common.py

https://bitbucket.org/galaxy/galaxy-central/
Python | 193 lines | 151 code | 10 blank | 32 comment | 15 complexity | 600ea4d6bae0e9a01552eb8a00a195b0 MD5 | raw file
Possible License(s): CC-BY-3.0
  1. """
  2. Common methods used by the API sample scripts.
  3. """
  4. import json
  5. import logging
  6. import os
  7. import sys
  8. import urllib2
  9. from Crypto.Cipher import Blowfish
  10. log = logging.getLogger( __name__ )
  11. def make_url( api_key, url, args=None ):
  12. """
  13. Adds the API Key to the URL if it's not already there.
  14. """
  15. if args is None:
  16. args = []
  17. argsep = '&'
  18. if '?' not in url:
  19. argsep = '?'
  20. if '?key=' not in url and '&key=' not in url:
  21. args.insert( 0, ( 'key', api_key ) )
  22. return url + argsep + '&'.join( [ '='.join( t ) for t in args ] )
  23. def get( api_key, url ):
  24. """
  25. Do the actual GET.
  26. """
  27. url = make_url( api_key, url )
  28. try:
  29. return json.loads( urllib2.urlopen( url ).read() )
  30. except ValueError, e:
  31. print "URL did not return JSON data: %s" % e
  32. sys.exit(1)
  33. def post( api_key, url, data ):
  34. """
  35. Do the actual POST.
  36. """
  37. url = make_url( api_key, url )
  38. req = urllib2.Request( url, headers = { 'Content-Type': 'application/json' }, data = json.dumps( data ) )
  39. return json.loads( urllib2.urlopen( req ).read() )
  40. def put( api_key, url, data ):
  41. """
  42. Do the actual PUT
  43. """
  44. url = make_url( api_key, url )
  45. req = urllib2.Request( url, headers = { 'Content-Type': 'application/json' }, data = json.dumps( data ))
  46. req.get_method = lambda: 'PUT'
  47. return json.loads( urllib2.urlopen( req ).read() )
  48. def __del( api_key, url, data ):
  49. """
  50. Do the actual DELETE
  51. """
  52. url = make_url( api_key, url )
  53. req = urllib2.Request( url, headers = { 'Content-Type': 'application/json' }, data = json.dumps( data ))
  54. req.get_method = lambda: 'DELETE'
  55. return json.loads( urllib2.urlopen( req ).read() )
  56. def display( api_key, url, return_formatted=True ):
  57. """
  58. Sends an API GET request and acts as a generic formatter for the JSON response.
  59. """
  60. try:
  61. r = get( api_key, url )
  62. except urllib2.HTTPError, e:
  63. print e
  64. print e.read( 1024 ) # Only return the first 1K of errors.
  65. sys.exit( 1 )
  66. if type( r ) == unicode:
  67. print 'error: %s' % r
  68. return None
  69. if not return_formatted:
  70. return r
  71. elif type( r ) == list:
  72. # Response is a collection as defined in the REST style.
  73. print 'Collection Members'
  74. print '------------------'
  75. for n, i in enumerate(r):
  76. # All collection members should have a name in the response.
  77. # url is optional
  78. if 'url' in i:
  79. print '#%d: %s' % (n+1, i.pop( 'url' ) )
  80. if 'name' in i:
  81. print ' name: %s' % i.pop( 'name' )
  82. for k, v in i.items():
  83. print ' %s: %s' % ( k, v )
  84. print ''
  85. print '%d element(s) in collection' % len( r )
  86. elif type( r ) == dict:
  87. # Response is an element as defined in the REST style.
  88. print 'Member Information'
  89. print '------------------'
  90. for k, v in r.items():
  91. print '%s: %s' % ( k, v )
  92. elif type( r ) == str:
  93. print r
  94. else:
  95. print 'response is unknown type: %s' % type( r )
  96. def submit( api_key, url, data, return_formatted=True ):
  97. """
  98. Sends an API POST request and acts as a generic formatter for the JSON response.
  99. 'data' will become the JSON payload read by Galaxy.
  100. """
  101. try:
  102. r = post( api_key, url, data )
  103. except urllib2.HTTPError, e:
  104. if return_formatted:
  105. print e
  106. print e.read( 1024 )
  107. sys.exit( 1 )
  108. else:
  109. return 'Error. '+ str( e.read( 1024 ) )
  110. if not return_formatted:
  111. return r
  112. print 'Response'
  113. print '--------'
  114. if type( r ) == list:
  115. # Currently the only implemented responses are lists of dicts, because
  116. # submission creates some number of collection elements.
  117. for i in r:
  118. if type( i ) == dict:
  119. if 'url' in i:
  120. print i.pop( 'url' )
  121. else:
  122. print '----'
  123. if 'name' in i:
  124. print ' name: %s' % i.pop( 'name' )
  125. for k, v in i.items():
  126. print ' %s: %s' % ( k, v )
  127. else:
  128. print i
  129. else:
  130. print r
  131. def update( api_key, url, data, return_formatted=True ):
  132. """
  133. Sends an API PUT request and acts as a generic formatter for the JSON response.
  134. 'data' will become the JSON payload read by Galaxy.
  135. """
  136. try:
  137. r = put( api_key, url, data )
  138. except urllib2.HTTPError, e:
  139. if return_formatted:
  140. print e
  141. print e.read( 1024 )
  142. sys.exit( 1 )
  143. else:
  144. return 'Error. '+ str( e.read( 1024 ) )
  145. if not return_formatted:
  146. return r
  147. print 'Response'
  148. print '--------'
  149. print r
  150. def delete( api_key, url, data, return_formatted=True ):
  151. """
  152. Sends an API DELETE request and acts as a generic formatter for the JSON response.
  153. 'data' will become the JSON payload read by Galaxy.
  154. """
  155. try:
  156. r = __del( api_key, url, data )
  157. except urllib2.HTTPError, e:
  158. if return_formatted:
  159. print e
  160. print e.read( 1024 )
  161. sys.exit( 1 )
  162. else:
  163. return 'Error. '+ str( e.read( 1024 ) )
  164. if not return_formatted:
  165. return r
  166. print 'Response'
  167. print '--------'
  168. print r
  169. def encode_id( config_id_secret, obj_id ):
  170. """
  171. utility method to encode ID's
  172. """
  173. id_cipher = Blowfish.new( config_id_secret )
  174. # Convert to string
  175. s = str( obj_id )
  176. # Pad to a multiple of 8 with leading "!"
  177. s = ( "!" * ( 8 - len(s) % 8 ) ) + s
  178. # Encrypt
  179. return id_cipher.encrypt( s ).encode( 'hex' )