@@ -72,13 +72,24 @@ 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- if result .headers ["content-type" ] == "application/x-download" :
77- return (result .read ())
75+ try :
76+ result = body_from_url (url , 'application/json' , auth = auth , data = data , debug = debug , method = method )
77+ read = result .read ()
78+ except : # try one more time ConnectionResetError is incompatible with python2
79+ result = body_from_url (url , 'application/json' , auth = auth , data = data , debug = debug , method = method )
80+ read = result .read ()
81+ if result .headers ["content-type" ] == "application/x-download" or result .headers ["content-type" ] == "application/octet-stream" :
82+ return (read ) # Watch out!
83+ if result .headers ["content-type" ][0 :9 ] == "text/html" : # json decoder won't work
84+ return (read ) # Watch out!
85+ if result .headers ["content-type" ] == "application/json" : # If header is set, this should work
86+ data = read .decode ("utf8" )
87+ obj = json .loads (data )
7888 else :
79- obj = json .loads (result .read ().decode ("utf8" ))
89+ data = read .decode ("utf8" )
90+ obj = json .loads (data )
8091 if obj is None :
81- sys .stderr .write ("ERROR: return structure not valid json format\n " )
92+ sys .stderr .write ("ERROR: return structure not valid json format\n " + repr ( data ) )
8293 sys .exit (1 )
8394 if len (list (obj .keys ())) == 0 :
8495 if debug :
@@ -121,33 +132,44 @@ def async_rest_api(url, auth=None, data=None, debug=False, delay=60):
121132 except :
122133 parameters = {"asynchronous" : 1 }
123134 submit = obj_from_url (url , auth = auth , data = data , debug = debug )
124- # If "status" is nor present, or if "status" is somehow not "submitted"
135+ # If "status" is nor present, or if "status" is somehow not "submitted"
125136# assume this is not an asynchronous call and it's done.
126- if ('status' in submit ) and (submit ['status' ] != 'submitted' ) and ('data' in submit ):
127- return submit ['data' ]
137+ if type (submit ) == bytes : # can't decode
138+ try :
139+ return decode ("utf-8" , submit )
140+ except :
141+ return submit
142+ if ('status' in submit ) and (submit ['status' ] != 'submitted' ) and (submit ['status' ] != "processing" ) and ('data' in submit ):
143+ return submit
144+ if not ('url' in submit .keys ()):
145+ return submit
128146# if not (('status' in submit) and (submit['status'] == 'submitted') and ('url' in submit)):
129147# return submit # No status, no url and no submitted
130148 result = obj_from_url (submit ['url' ], auth = auth , debug = debug )
131- try :
132- while result ['status' ] == 'submitted' :
149+ if type (result ) is bytes :
150+ return (result )
151+ if 'status' in result .keys ():
152+ while result ['status' ] == 'submitted' or result ['status' ] == "processing" :
133153 if debug :
134154 print ("waiting %d seconds ..." % delay )
135155 time .sleep (delay )
136156 result = obj_from_url (submit ['url' ], auth = auth , debug = debug )
137- except KeyError :
157+ if 'url' in result .keys () or 'next' in result .keys (): # does not need to wait
158+ return (result )
159+ try :
138160 print ("Error in response to " + url , file = sys .stderr )
139- print ("Does not contain 'status' field, likely API syntax error" , file = sys .stderr )
161+ print ("Does not contain 'status' or 'next' field, likely API syntax error" , file = sys .stderr )
140162 print (json .dumps (result ), file = sys .stderr )
141163 sys .exit (1 )
142164 except TypeError : # result isn't json, return it anyway
143165 return (result .decode ("utf8" ))
144- try :
166+ try :
145167 if 'ERROR' in result ['data' ]:
146168 sys .stderr .write ("ERROR: %s\n " % result ['data' ]['ERROR' ])
147169 print (json .dumps (result ), file = sys .stderr )
148170 sys .exit (1 )
149171 except KeyError : # result doesn't have "data"
150- return result
172+ return result
151173 return result ['data' ]
152174
153175# POST file to MG-RAST or Shock
@@ -214,14 +236,15 @@ def sparse_to_dense(sMatrix, rmax, cmax):
214236# transform BIOM format to tabbed table
215237# returns max value of matrix
216238def biom_to_tab (biom , hdl , rows = None , use_id = True , col_name = False ):
239+ assert 'matrix_type' in biom .keys (), repr (biom )
217240 if biom ['matrix_type' ] == 'sparse' :
218241 matrix = sparse_to_dense (biom ['data' ], biom ['shape' ][0 ], biom ['shape' ][1 ])
219242 else :
220243 matrix = biom ['data' ]
221244 if col_name :
222- hdl .write ( "\t %s\n " % "\t " .join ([c ['name' ] for c in biom ['columns' ]]) )
245+ hdl .write ("\t %s\n " % "\t " .join ([c ['name' ] for c in biom ['columns' ]]))
223246 else :
224- hdl .write ( "\t %s\n " % "\t " .join ([c ['id' ] for c in biom ['columns' ]]) )
247+ hdl .write ("\t %s\n " % "\t " .join ([c ['id' ] for c in biom ['columns' ]]))
225248 rowmax = []
226249 for i , row in enumerate (matrix ):
227250 name = biom ['rows' ][i ]['id' ]
@@ -231,7 +254,7 @@ def biom_to_tab(biom, hdl, rows=None, use_id=True, col_name=False):
231254 continue
232255 try :
233256 rowmax .append (max (row ))
234- hdl .write ( "%s\t %s\n " % (name , "\t " .join (map (str , row ))) )
257+ hdl .write ("%s\t %s\n " % (name , "\t " .join (map (str , row ))))
235258 except :
236259 try :
237260 hdl .close ()
@@ -262,6 +285,7 @@ def profile_to_matrix(p):
262285 p ['matrix_element_type' ] = 'int'
263286 p ['matrix_element_value' ] = 'abundance'
264287 p ['date' ] = time .strftime ("%Y-%m-%d %H:%M:%S" )
288+ assert 'matrix_type' in p .keys (), repr (p )
265289 if p ['matrix_type' ] == 'sparse' :
266290 p ['data' ] = sparse_to_dense (p ['data' ], p ['shape' ][0 ], p ['shape' ][1 ])
267291 if trim :
@@ -301,6 +325,7 @@ def merge_biom(b1, b2):
301325 "id" : b1 ['id' ]+ '_' + b2 ['id' ],
302326 "type" : b1 ['type' ] }
303327 # make sure we are dense
328+ assert 'matrix_type' in b2 .keys (), repr (b2 )
304329 if b2 ['matrix_type' ] == 'sparse' :
305330 b2 ['data' ] = sparse_to_dense (b2 ['data' ], b2 ['shape' ][0 ], b2 ['shape' ][1 ])
306331 # get lists of ids
@@ -352,14 +377,15 @@ def biom_to_matrix(biom, col_name=False, sig_stats=False):
352377 except KeyError :
353378 rows = [r ['id' ] for r in biom ['rows' ]]
354379# rows = [";".join(r['metadata']['hierarchy']) for r in biom['rows']]
380+ assert "matrix_type" in biom .keys (), repr (biom )
355381 if biom ['matrix_type' ] == 'sparse' :
356382 data = sparse_to_dense (biom ['data' ], len (rows ), len (cols ))
357383 else :
358384 data = biom ['data' ]
359385 if sig_stats and ('significance' in biom ['rows' ][0 ]['metadata' ]) and (len (biom ['rows' ][0 ]['metadata' ]['significance' ]) > 0 ):
360- cols .extend ( [s [0 ] for s in biom ['rows' ][0 ]['metadata' ]['significance' ]] )
386+ cols .extend ([s [0 ] for s in biom ['rows' ][0 ]['metadata' ]['significance' ]] )
361387 for i , r in enumerate (biom ['rows' ]):
362- data [i ].extend ( [s [1 ] for s in r ['metadata' ]['significance' ]] )
388+ data [i ].extend ([s [1 ] for s in r ['metadata' ]['significance' ]] )
363389 return rows , cols , data
364390
365391# transform tabbed table to matrix in json format
@@ -382,7 +408,7 @@ def sub_matrix(matrix, ncols):
382408 return matrix
383409 sub = list ()
384410 for row in matrix :
385- sub .append ( row [:ncols ] )
411+ sub .append (row [:ncols ] )
386412 return sub
387413
388414# return KBase id for MG-RAST id
0 commit comments