I've solved the meaty bits of this bioinformatics problem, albeit a bit clumsily I think. In particular I've messed around with manipulating the fasta info into a form Biopython's SeqIO.parse() will accept and it screams to be optimized.

So there is my question to you. How can I better save the HTTP response from Uniprot into something that is easily parsed by SeqIO.parse()?

Stephen Wist 
to solve this problem: http://rosalind.info/problems/mprt/

import sys, re # IO and motif finding
import urllib3 # get protein fasta from uniprot
from Bio import SeqIO, Seq # fasta parsing and manipulation

if len(sys.argv)<2: 
    print("need at least one uniprotID")

f = open("ros.fa", "w")
http = urllib3.PoolManager() # urllib3 takes care of stuff here

# get fasta of all given uniprotIDs
for item in sys.argv[1:]:
    url = "http://www.uniprot.org/uniprot/" + item + ".fasta"
    req = http.request("GET", url)
    byte_string = req.data 
    string = byte_string.decode("utf-8")
    f.write(string) # BioPython SeqIO.parse() won't work on the 
                    # decoded byte_string

print(  "\nreq.data:\n", req.data,
        "\ndecoded req.data:\n", string)

pattern = re.compile("[N][^P][S|T][^P]")
for seq in SeqIO.parse("ros.fa", "fasta"):
# keeping this here, it might be useful
# [(m.start(0), m.end(0)) for m in re.finditer(pattern, string)]
    for match in re.finditer(pattern, str(seq.seq)):
        print(match.start(0) + 1)
  • \$\begingroup\$ How many requests to you plan to make at a given time? \$\endgroup\$ Sep 6, 2017 at 1:49
  • \$\begingroup\$ No more than 15 \$\endgroup\$ Sep 6, 2017 at 12:47

2 Answers 2


When cracking argv, you have an opportunity to use argparse if you wish.

Please bury all this code under def main():, rather than creating lots of top-level globals like f.

Rather than f = open() ... f.close(), you might phrase it this way:

with open('ros.fa', 'w') as f:

There are some comments you might elide. The identifier string is accurate, but a bit vague. Might be better to elide the temp variables:


Overall, this code looks like it gets the job done.


Repeated requests in a short amount of time will get your IP address blocked on some servers even if you are using an API. If you do eventually want to scale this one route you may want try is downloading the whole proteome and parsing that into a dict then pickling that and accessing it as you need. This will also give you a significant performance boost. However you'll need will need to update your database as time goes on.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.