Back to List

Querying Biology Databases via API

Learn to call NCBI and UniProt REST APIs with the requests library to fetch gene and protein information.

Intermediate
|
75min
|
Verified (2026-06)
APIRESTNCBIUniProtrequestsJSON
Progress0/12 (0%)

Querying Biology Databases via API

After Completing This Topic

You'll be able to call NCBI and UniProt APIs using Python's requests library, extract needed data from JSON responses, and query multiple genes in a loop.


What Is an API?

You've probably searched for genes on the NCBI website before. Type "EGFR" into the search bar and a gene information page appears. Behind the scenes, your browser sends a request to the NCBI server, and the server sends back a response.

API (Application Programming Interface) is doing this same process with code. Instead of a browser, Python sends the request, and instead of HTML, you receive structured data (JSON) as the response.

Lab analogy โ€” just as you insert a sample and press a button to get results from an instrument, you put a gene name into an API and get information out. The only difference is that code presses the button automatically instead of a person.

The requests Library

bash
pip install requests
python
import requests
response = requests.get("https://api.github.com")
print(f"Status code: {response.status_code}")
print(f"Response data: {response.json()}")

requests.get(URL) โ€” sends a GET request to the URL. It's the same as entering a URL in a web browser.

Status codes:

  • 200 โ€” Success
  • 404 โ€” URL not found
  • 429 โ€” Too many requests (rate limit)
  • 500 โ€” Internal server error

JSON: The API Response Format

Most APIs respond in JSON format. It's almost identical in structure to a Python dictionary:

json
{
  "gene": "EGFR",
  "organism": "Homo sapiens",
  "chromosome": "7",
  "aliases": ["ERBB1", "HER1"]
}

Working with JSON responses in Python:

python
import requests
response = requests.get("https://rest.uniprot.org/uniprotkb/P04637.json")
data = response.json()
print(f"Protein: {data['proteinDescription']['recommendedName']['fullName']['value']}")
print(f"Organism: {data['organism']['scientificName']}")
print(f"Sequence length: {data['sequence']['length']}")

response.json() โ€” converts the JSON response to a Python dictionary. Then access values with data["key"].

Practical: Fetching Protein Info from UniProt API

python
import requests
def get_protein_info(uniprot_id: str) -> dict:
url = f"https://rest.uniprot.org/uniprotkb/{uniprot_id}.json"
response = requests.get(url)
if response.status_code != 200:
print(f"Error: {uniprot_id} โ€” status code {response.status_code}")
return {}
data = response.json()
return {
"id": uniprot_id,
"name": data["proteinDescription"]["recommendedName"]["fullName"]["value"],
"organism": data["organism"]["scientificName"],
"length": data["sequence"]["length"],
}
info = get_protein_info("P04637")
print(info)

By wrapping it in a function, you can query multiple proteins in a loop:

python
ids = ["P04637", "P00533", "P38398"]
results = []
for uid in ids:
info = get_protein_info(uid)
if info:
results.append(info)
print(f" โœ“ {info['name']} ({info['length']} aa)")
print(f"\nTotal {len(results)} queries completed")

Practical: NCBI E-utilities

NCBI provides an API called E-utilities. You can search genes, download sequences, and search publications โ€” all with code.

python
import requests
gene_name = "BRCA1"
url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"
params = {
"db": "gene",
"term": f"{gene_name}[Gene Name] AND Homo sapiens[Organism]",
"retmode": "json",
}
response = requests.get(url, params=params)
data = response.json()
gene_ids = data["esearchresult"]["idlist"]
print(f"{gene_name} search results: {gene_ids}")

params โ€” passes URL parameters as a dictionary. requests automatically appends ?db=gene&term=... to the URL.

API Etiquette: Rate Limiting

APIs can't be called infinitely. You need intervals between requests to avoid overloading the server:

python
import time
import requests
ids = ["P04637", "P00533", "P38398", "Q13315", "P42336"]
for uid in ids:
info = get_protein_info(uid)
if info:
print(f" {info['name']}")
time.sleep(0.5)

time.sleep(0.5) โ€” wait 0.5 seconds. NCBI recommends about 3 requests per second, UniProt about 10. This is like shared equipment etiquette in the lab โ€” if one person monopolizes it, nobody else can use it.

API Keys

Some APIs require an API key. NCBI E-utilities works without one, but registering a key increases the rate limit from 3 to 10 requests per second.

python
params = {
"db": "gene",
"term": "TP53[Gene Name]",
"retmode": "json",
"api_key": "YOUR_API_KEY_HERE",
}

Never put API keys directly in your code. Store them in environment variables or separate config files, and don't commit them to Git.

Error Handling

API calls can fail due to network issues or invalid IDs:

python
import requests
def safe_api_call(url: str, params: dict = None) -> dict:
try:
response = requests.get(url, params=params, timeout=10)
response.raise_for_status()
return response.json()
except requests.exceptions.Timeout:
print("Request timed out โ€” try again later")
return {}
except requests.exceptions.HTTPError as e:
print(f"HTTP error: {e}")
return {}

timeout=10 โ€” give up if no response within 10 seconds. Prevents the program from hanging forever when the server is slow.

Try It Yourself (Faded Example)

Fill in the blanks to complete a code that fetches protein sequence length from the UniProt API.

Fill in the Blankspython
import
url = "https://rest.uniprot.org/uniprotkb/P04637.json"
response = requests.(url)
if response.status_code == :
data = response.()
length = data["sequence"]["length"]
print(f"Sequence length: {length} aa")

Common Errors & Solutions

Q: I get ConnectionError or Timeout

Check your internet connection. The server might be temporarily down. Try again after time.sleep(5), or run it later.

Q: KeyError โ€” can't get values from JSON

The API response structure might differ from your expectation. Print the full response with print(json.dumps(data, indent=2)) to check the actual key structure. Or use data.get("key", "not found") to return a default when the key doesn't exist.

Q: API response comes as HTML

The URL might be a webpage address (for browsers), not an API address. Check the API documentation for the correct endpoint. URLs containing /api/ or .json are typically API endpoints.

Q: 429 Too Many Requests error

You're sending too many requests too quickly. Increase the interval with time.sleep(1). NCBI recommends registering an API key.

๐Ÿ’ฌ Questions & Comments

0 comments

You can post without signing in. Guest comments cannot be edited or deleted by their author.

0/2000

Loading...