PageRenderTime 29ms CodeModel.GetById 16ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/scripts/api/common.py

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