Come posso parlare con UniProt tramite HTTP in Python?
-
23-08-2019 - |
Domanda
Sto cercando di ottenere alcuni risultati da UniProt, che è un database di proteine (i dettagli non sono importanti).Sto cercando di utilizzare uno script che traduca da un tipo di ID a un altro.Sono stato in grado di farlo manualmente sul browser, ma non potevo farlo in Python.
In http://www.uniprot.org/faq/28 ci sono alcuni script di esempio.Ho provato quello Perl e sembra funzionare, quindi il problema sono i miei tentativi con Python.Lo script (funzionante) è:
## tool_example.pl ##
use strict;
use warnings;
use LWP::UserAgent;
my $base = 'http://www.uniprot.org';
my $tool = 'mapping';
my $params = {
from => 'ACC', to => 'P_REFSEQ_AC', format => 'tab',
query => 'P13368 P20806 Q9UM73 P97793 Q17192'
};
my $agent = LWP::UserAgent->new;
push @{$agent->requests_redirectable}, 'POST';
print STDERR "Submitting...\n";
my $response = $agent->post("$base/$tool/", $params);
while (my $wait = $response->header('Retry-After')) {
print STDERR "Waiting ($wait)...\n";
sleep $wait;
print STDERR "Checking...\n";
$response = $agent->get($response->base);
}
$response->is_success ?
print $response->content :
die 'Failed, got ' . $response->status_line .
' for ' . $response->request->uri . "\n";
Le mie domande sono:
1) Come lo faresti in Python?
2) Sarò in grado di "ridimensionarlo" in modo massiccio (ovvero utilizzare molte voci nel campo della query)?
Soluzione
domanda 1:
Questo può essere fatto usando gli urllib di Python:
import urllib, urllib2
import time
import sys
query = ' '.join(sys.argv)
# encode params as a list of 2-tuples
params = ( ('from','ACC'), ('to', 'P_REFSEQ_AC'), ('format','tab'), ('query', query))
# url encode them
data = urllib.urlencode(params)
url = 'http://www.uniprot.org/mapping/'
# fetch the data
try:
foo = urllib2.urlopen(url, data)
except urllib2.HttpError, e:
if e.code == 503:
# blah blah get the value of the header...
wait_time = int(e.hdrs.get('Retry-after', 0))
print 'Sleeping %i seconds...' % (wait_time,)
time.sleep(wait_time)
foo = urllib2.urlopen(url, data)
# foo is a file-like object, do with it what you will.
foo.read()
Altri suggerimenti
Probabilmente faresti meglio a utilizzare il servizio di riferimento incrociato dell'identificatore di proteine dell'EBI per convertire un set di ID in un altro.Ha un'ottima interfaccia REST.
http://www.ebi.ac.uk/Tools/picr/
Dovrei anche menzionare che UniProt ha a disposizione ottimi servizi web.Tuttavia, se per qualche motivo sei costretto a utilizzare semplici richieste http, probabilmente non è utile.
Supponiamo che tu stia utilizzando Python 2.5.Possiamo usare httplib per chiamare direttamente il sito web:
import httplib, urllib
querystring = {}
#Build the query string here from the following keys (query, format, columns, compress, limit, offset)
querystring["query"] = ""
querystring["format"] = "" # one of html | tab | fasta | gff | txt | xml | rdf | rss | list
querystring["columns"] = "" # the columns you want comma seperated
querystring["compress"] = "" # yes or no
## These may be optional
querystring["limit"] = "" # I guess if you only want a few rows
querystring["offset"] = "" # bring on paging
##From the examples - query=organism:9606+AND+antigen&format=xml&compress=no
##Delete the following and replace with your query
querystring = {}
querystring["query"] = "organism:9606 AND antigen"
querystring["format"] = "xml" #make it human readable
querystring["compress"] = "no" #I don't want to have to unzip
conn = httplib.HTTPConnection("www.uniprot.org")
conn.request("GET", "/uniprot/?"+ urllib.urlencode(querystring))
r1 = conn.getresponse()
if r1.status == 200:
data1 = r1.read()
print data1 #or do something with it
Potresti quindi creare una funzione per creare la stringa di query e dovresti essere assente.
controllalo bioservices
.interfacciano molti database tramite Python.https://pythonhosted.org/bioservices/_modules/bioservices/uniprot.html
conda install bioservices --yes
in complemento alla risposta di O.rka:
Domanda 1:
from bioservices import UniProt
u = UniProt()
res = u.get_df("P13368 P20806 Q9UM73 P97793 Q17192".split())
Ciò restituisce un dataframe con tutte le informazioni su ciascuna voce.
Domanda 2: stessa risposta.Questo dovrebbe aumentare.
Disclaimer:Sono l'autore di bioservizi
C'è un pacchetto Python in pip che fa esattamente quello che vuoi
pip install uniprot-mapper