@@ -72,10 +72,26 @@ def body_from_url(url, accept, auth=None, data=None, debug=False, method=None):
7272
7373# return python struct from JSON output of MG-RAST or Shock API
7474def obj_from_url (url , auth = None , data = None , debug = False , method = None ):
75- result = body_from_url (url , 'application/json' , auth = auth , data = data , debug = debug , method = method )
76- obj = json .loads (result .read ().decode ("utf8" ))
75+ if type (data ) is str :
76+ data = data .encode ("utf8" )
77+ try :
78+ result = body_from_url (url , 'application/json' , auth = auth , data = data , debug = debug , method = method )
79+ read = result .read ()
80+ except : # try one more time ConnectionResetError is incompatible with python2
81+ result = body_from_url (url , 'application/json' , auth = auth , data = data , debug = debug , method = method )
82+ read = result .read ()
83+ if result .headers ["content-type" ] == "application/x-download" or result .headers ["content-type" ] == "application/octet-stream" :
84+ return (read ) # Watch out!
85+ if result .headers ["content-type" ][0 :9 ] == "text/html" : # json decoder won't work
86+ return (read ) # Watch out!
87+ if result .headers ["content-type" ] == "application/json" : # If header is set, this should work
88+ data = read .decode ("utf8" )
89+ obj = json .loads (data )
90+ else :
91+ data = read .decode ("utf8" )
92+ obj = json .loads (data )
7793 if obj is None :
78- sys .stderr .write ("ERROR: return structure not valid json format\n " )
94+ sys .stderr .write ("ERROR: return structure not valid json format\n " + repr ( data ) )
7995 sys .exit (1 )
8096 if len (list (obj .keys ())) == 0 :
8197 if debug :
@@ -86,7 +102,7 @@ def obj_from_url(url, auth=None, data=None, debug=False, method=None):
86102 sys .stderr .write ("ERROR: %s\n " % obj ['ERROR' ])
87103 sys .exit (1 )
88104 if ('error' in obj ) and obj ['error' ]:
89- if isinstance (obj ['error' ], basestring ):
105+ if isinstance (obj ['error' ], str ):
90106 sys .stderr .write ("ERROR:\n %s\n " % obj ['error' ])
91107 else :
92108 sys .stderr .write ("ERROR: %s\n " % obj ['error' ][0 ])
@@ -118,28 +134,44 @@ def async_rest_api(url, auth=None, data=None, debug=False, delay=60):
118134 except :
119135 parameters = {"asynchronous" : 1 }
120136 submit = obj_from_url (url , auth = auth , data = data , debug = debug )
121- # If "status" is nor present, or if "status" is somehow not "submitted"
137+ # If "status" is nor present, or if "status" is somehow not "submitted"
122138# assume this is not an asynchronous call and it's done.
123- if ('status' in submit ) and (submit ['status' ] == 'done' ) and ('url' in submit ):
124- return submit ['data' ]
125- if not (('status' in submit ) and (submit ['status' ] == 'submitted' ) and ('url' in submit )):
139+ if type (submit ) == bytes : # can't decode
140+ try :
141+ return decode ("utf-8" , submit )
142+ except :
143+ return submit
144+ if ('status' in submit ) and (submit ['status' ] != 'submitted' ) and (submit ['status' ] != "processing" ) and ('data' in submit ):
126145 return submit
127- result = obj_from_url (submit ['url' ], debug = debug )
128- try :
129- while result ['status' ] != 'done' :
146+ if not ('url' in submit .keys ()):
147+ return submit
148+ # if not (('status' in submit) and (submit['status'] == 'submitted') and ('url' in submit)):
149+ # return submit # No status, no url and no submitted
150+ result = obj_from_url (submit ['url' ], auth = auth , debug = debug )
151+ if type (result ) is bytes :
152+ return (result )
153+ if 'status' in result .keys ():
154+ while result ['status' ] == 'submitted' or result ['status' ] == "processing" :
130155 if debug :
131156 print ("waiting %d seconds ..." % delay )
132157 time .sleep (delay )
133- result = obj_from_url (submit ['url' ], debug = debug )
134- except KeyError :
158+ result = obj_from_url (submit ['url' ], auth = auth , debug = debug )
159+ if 'url' in result .keys () or 'next' in result .keys (): # does not need to wait
160+ return (result )
161+ try :
135162 print ("Error in response to " + url , file = sys .stderr )
136- print ("Does not contain 'status' field, likely API syntax error" , file = sys .stderr )
137- print (json .dumps (result ), file = sys .stderr )
138- sys .exit (1 )
139- if 'ERROR' in result ['data' ]:
140- sys .stderr .write ("ERROR: %s\n " % result ['data' ]['ERROR' ])
163+ print ("Does not contain 'status' or 'next' field, likely API syntax error" , file = sys .stderr )
141164 print (json .dumps (result ), file = sys .stderr )
142165 sys .exit (1 )
166+ except TypeError : # result isn't json, return it anyway
167+ return (result .decode ("utf8" ))
168+ try :
169+ if 'ERROR' in result ['data' ]:
170+ sys .stderr .write ("ERROR: %s\n " % result ['data' ]['ERROR' ])
171+ print (json .dumps (result ), file = sys .stderr )
172+ sys .exit (1 )
173+ except KeyError : # result doesn't have "data"
174+ return result
143175 return result ['data' ]
144176
145177# POST file to MG-RAST or Shock
@@ -206,14 +238,15 @@ def sparse_to_dense(sMatrix, rmax, cmax):
206238# transform BIOM format to tabbed table
207239# returns max value of matrix
208240def biom_to_tab (biom , hdl , rows = None , use_id = True , col_name = False ):
241+ assert 'matrix_type' in biom .keys (), repr (biom )
209242 if biom ['matrix_type' ] == 'sparse' :
210243 matrix = sparse_to_dense (biom ['data' ], biom ['shape' ][0 ], biom ['shape' ][1 ])
211244 else :
212245 matrix = biom ['data' ]
213246 if col_name :
214- hdl .write ( "\t %s\n " % "\t " .join ([c ['name' ] for c in biom ['columns' ]]) )
247+ hdl .write ("\t %s\n " % "\t " .join ([c ['name' ] for c in biom ['columns' ]]))
215248 else :
216- hdl .write ( "\t %s\n " % "\t " .join ([c ['id' ] for c in biom ['columns' ]]) )
249+ hdl .write ("\t %s\n " % "\t " .join ([c ['id' ] for c in biom ['columns' ]]))
217250 rowmax = []
218251 for i , row in enumerate (matrix ):
219252 name = biom ['rows' ][i ]['id' ]
@@ -223,7 +256,7 @@ def biom_to_tab(biom, hdl, rows=None, use_id=True, col_name=False):
223256 continue
224257 try :
225258 rowmax .append (max (row ))
226- hdl .write ( "%s\t %s\n " % (name , "\t " .join (map (str , row ))) )
259+ hdl .write ("%s\t %s\n " % (name , "\t " .join (map (str , row ))))
227260 except :
228261 try :
229262 hdl .close ()
@@ -254,6 +287,7 @@ def profile_to_matrix(p):
254287 p ['matrix_element_type' ] = 'int'
255288 p ['matrix_element_value' ] = 'abundance'
256289 p ['date' ] = time .strftime ("%Y-%m-%d %H:%M:%S" )
290+ assert 'matrix_type' in p .keys (), repr (p )
257291 if p ['matrix_type' ] == 'sparse' :
258292 p ['data' ] = sparse_to_dense (p ['data' ], p ['shape' ][0 ], p ['shape' ][1 ])
259293 if trim :
@@ -293,6 +327,7 @@ def merge_biom(b1, b2):
293327 "id" : b1 ['id' ]+ '_' + b2 ['id' ],
294328 "type" : b1 ['type' ] }
295329 # make sure we are dense
330+ assert 'matrix_type' in b2 .keys (), repr (b2 )
296331 if b2 ['matrix_type' ] == 'sparse' :
297332 b2 ['data' ] = sparse_to_dense (b2 ['data' ], b2 ['shape' ][0 ], b2 ['shape' ][1 ])
298333 # get lists of ids
@@ -344,14 +379,15 @@ def biom_to_matrix(biom, col_name=False, sig_stats=False):
344379 except KeyError :
345380 rows = [r ['id' ] for r in biom ['rows' ]]
346381# rows = [";".join(r['metadata']['hierarchy']) for r in biom['rows']]
382+ assert "matrix_type" in biom .keys (), repr (biom )
347383 if biom ['matrix_type' ] == 'sparse' :
348384 data = sparse_to_dense (biom ['data' ], len (rows ), len (cols ))
349385 else :
350386 data = biom ['data' ]
351387 if sig_stats and ('significance' in biom ['rows' ][0 ]['metadata' ]) and (len (biom ['rows' ][0 ]['metadata' ]['significance' ]) > 0 ):
352- cols .extend ( [s [0 ] for s in biom ['rows' ][0 ]['metadata' ]['significance' ]] )
388+ cols .extend ([s [0 ] for s in biom ['rows' ][0 ]['metadata' ]['significance' ]] )
353389 for i , r in enumerate (biom ['rows' ]):
354- data [i ].extend ( [s [1 ] for s in r ['metadata' ]['significance' ]] )
390+ data [i ].extend ([s [1 ] for s in r ['metadata' ]['significance' ]] )
355391 return rows , cols , data
356392
357393# transform tabbed table to matrix in json format
@@ -374,7 +410,7 @@ def sub_matrix(matrix, ncols):
374410 return matrix
375411 sub = list ()
376412 for row in matrix :
377- sub .append ( row [:ncols ] )
413+ sub .append (row [:ncols ] )
378414 return sub
379415
380416# return KBase id for MG-RAST id
@@ -407,7 +443,7 @@ def kbids_to_mgids(kbids):
407443def kbid_lookup (ids , reverse = False ):
408444 request = 'mg2kb' if reverse else 'kb2mg'
409445 post = json .dumps ({'ids' : ids }, separators = (',' ,':' ))
410- data = obj_from_url (API_URL + '/job/' + request , data = post )
446+ data = obj_from_url (API_URL + '/job/' + request , auth = auth , data = post )
411447 return data ['data' ]
412448
413449def get_auth_token (opts = None ):
0 commit comments