Resulta que me tocou meter unha función de recursividade no noso servidor de modelado de GPCRs, e penso que como exemplo pode ser bastante útil.
O problema
No formulario de entrada aceptamos secuencias crudas en FASTA, ou ben identificadores Uniprot. Así que a función inicial era básicamente
def retrieve_url(url):
import urllib2
#url is something like
#http://www.uniprot.org/uniprot/IDXXX.fasta
try:
my_response = urllib2.urlopen(url)
return "".join(my_response.readlines())
except urllib2.HTTPError:
return False
Bastante simple: unha función anterior pásalle a esta o url depurado, despóis de comprobar si efectivamente é un ID válido de Uniprot. Esta función chama a Uniprot (que sigue o estándar REST), e obtén a secuencia en FASTA.Bastantes secuencias empezaron a fallar, porque o servidor de Uniprot contestaba con un "300", a secuencia xa non se atopaba ahí, senón que a moveran a outra ID. Por outra parte, algo bastante habitual nesas bases de datos.
A solución
Fácilmente se deduce que hai que obter a nova ubicación do recurso movido, e ir outra vez a por él. Como xa temos a función que recupera FASTAS de Uniprot, ímola chamar desde sí mesma, e se o recurso volve dar un erro 300, vólvese a chamar ata que chega a un erro diferente ou ó FASTA apropiado
def retrieve_url(url):
import urllib2
try:
my_response = urllib2.urlopen(url)
return "".join(my_response.readlines())
except urllib2.HTTPError, error:
if error.code == 300: #Moved with multiple choices
new_resource = error.info().getheader("Location")
my_response = urllib2.urlopen(server + new_resource).readline()
new_url = "http://www.uniprot.org/uniprot/uniprot/" + \
my_response.split("|")[1] + ".fasta"
return retrieve_url(new_url)
else:
return False