PageRenderTime 54ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/tool_shed/scripts/api/common.py

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