skip to Main Content

In one of my scripts, I utilized the following block of code to query for the ID of a protein using another type of ID:

import os
import sys
import urllib.request

uniprot = 'A0A0M3KKX3'
url = 'https://www.uniprot.org/uploadlists/'
params = {
'from': 'ACC',
'to': 'PDB_ID',
'format': 'tab',
'query': uniprot,
'species': 'human'
     }

dat = urllib.parse.urlencode(params)
dat = dat.encode('utf-8')
req = urllib.request.Request(url, dat)
with urllib.request.urlopen(req) as f:
    response = f.read()

For the past few months, code involving this method has worked reliably, allowing me to build my algorithm on top of these features. However, as of last night, running the same code, I received the following error:

Traceback (most recent call last):
  File "\wsl.localhostUbuntuhomedefrondevillecFASTAtest.py", line 21, in <module>
    with urllib.request.urlopen(req) as f:
  File "C:UserschrisAppDataLocalProgramsPythonPython310liburllibrequest.py", line 216, in urlopen
    return opener.open(url, data, timeout)
  File "C:UserschrisAppDataLocalProgramsPythonPython310liburllibrequest.py", line 525, in open
    response = meth(req, response)
  File "C:UserschrisAppDataLocalProgramsPythonPython310liburllibrequest.py", line 634, in http_response
    response = self.parent.error(
  File "C:UserschrisAppDataLocalProgramsPythonPython310liburllibrequest.py", line 563, in error
    return self._call_chain(*args)
  File "C:UserschrisAppDataLocalProgramsPythonPython310liburllibrequest.py", line 496, in _call_chain
    result = func(*args)
  File "C:UserschrisAppDataLocalProgramsPythonPython310liburllibrequest.py", line 643, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 405: Not Allowed

How would I go about fixing this issue?

2

Answers


  1. I’ve just hit the same issue – Uniprot have launched a new website and series of services. For now the old ones are available at legacy.uniprot.org

    Short term fix

    Use https://legacy.uniprot.org/uploadlists/ as the URL in your code. This is working in my code for a similar query (uniprotID -> gene name)

    Longer term fix

    Probably best to migrate to the new ID Mapping service, which is documented here:
    https://www.uniprot.org/help/id_mapping

    You are now required to make an ID Mapping request, which returns a job ID, then poll for the result, there is some sample python code at the bottom of the docs: https://www.uniprot.org/help/id_mapping#python-example (reproduced below)

    import requests
    import time
    import json
    
    POLLING_INTERVAL = 3
    API_URL = "https://rest.uniprot.org"
    
    
    def submit_id_mapping(fromDB, toDB, ids):
        r = requests.post(
            f"{API_URL}/idmapping/run", data={"from": fromDB, "to": toDB, "ids": ids},
        )
        r.raise_for_status()
        return r.json()["jobId"]
    
    
    def get_id_mapping_results(job_id):
        while True:
            r = requests.get(f"{API_URL}/idmapping/status/{job_id}")
            r.raise_for_status()
            job = r.json()
            if "jobStatus" in job:
                if job["jobStatus"] == "RUNNING":
                    print(f"Retrying in {POLLING_INTERVAL}s")
                    time.sleep(POLLING_INTERVAL)
                else:
                    raise Exception(job["jobStatus"])
            else:
                return job
    
    
    job_id = submit_id_mapping(
        fromDB="UniProtKB_AC-ID", toDB="ChEMBL", ids=["P05067", "P12345"]
    )
    results = get_id_mapping_results(job_id)
    print(json.dumps(results, indent=2))
    
    Login or Signup to reply.
  2. You can now use the Unipressed package by Michael Milton (@multimeric) to do ID mapping in Python, see the announcement. This package also works with UniProt’s new in 2022 REST API.

    Example from original post using Unipressed:

    from unipressed import IdMappingClient
    request = IdMappingClient.submit(
        source="UniProtKB_AC-ID", dest="PDB", ids={"A0A0M3KKX3"}
    )
    list(request.each_result())
    

    Result:

    [{'from': 'A0A0M3KKX3', 'to': '4U7N'},
     {'from': 'A0A0M3KKX3', 'to': '4U7O'},
     {'from': 'A0A0M3KKX3', 'to': '4ZKI'}]
    

    See an example of using it to do ID mapping of three human genes to UniProt identifier / accession code here. That post also has links for more information about the Unipressed package and advice for working out source and destination (dest) details.

    See more examples of using Unipressed to access Uniprot’s new REST API here in my reply to Biostar’s post ‘Accessing UNIPROT using REST API’, and at the bottom here includes making a Pandas dataframe from the ‘from – to’ results.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search