🧬 BLAST - Using PYTHON! 🧬

Code

Blast Python Code Snippet

Description

This Python script uses Biopython to run a BLAST search against NCBI nucleotide database. By inputting a DNA sequence, the script connects to NCBI, runs BLAST, saves the results in XML format, and extracts the top 5 matches — showing the organism name, sequence length, best E-value, and accession number.
Read the full blog about BLAST →
YouTube Watch BLAST Tutorial on YouTube

Code Explanation

YouTube Watch Code Explanation on YouTube
Step 1: Imports & Server Check

import os
import csv
import requests
from datetime import datetime
from Bio.Blast import NCBIWWW, NCBIXML

def check_ncbi_server(url="https://blast.ncbi.nlm.nih.gov/Blast.cgi"):
    try:
        response = requests.get(url, timeout=5)
        return response.status_code == 200
    except Exception as e:
        print("Unable to reach NCBI BLAST server:", e)
        return False
    

Explanation:
1–5: Import libraries for file handling, CSV export, server check, timestamps, and BLAST.
7–14: Function check_ncbi_server ensures NCBI BLAST is reachable before running queries.

Step 2: Sequence Validation

def validate_sequence(sequence, seq_type):
    if seq_type == "dna":
        valid_chars = set("ATGCN")
    elif seq_type == "rna":
        valid_chars = set("AUGCN")
    elif seq_type == "protein":
        valid_chars = set("ACDEFGHIKLMNPQRSTVWYBXZ")
    else:
        return False
    
    return all(base in valid_chars for base in sequence)
    

Explanation:
1–9: Validates whether the sequence contains correct characters for DNA, RNA, or proteins.
11: Returns True only if all characters are valid.

Step 3: Run BLAST Query

def run_blast(sequence, program="blastn", database="nr", hitlist_size=10):
    try:
        print(f"\nRunning {program} against {database} database...")
        result_handle = NCBIWWW.qblast(program, database, sequence, hitlist_size=hitlist_size)

        blast_records = NCBIXML.parse(result_handle)
        results = []

        for blast_record in blast_records:
            for alignment in blast_record.alignments:
                for hsp in alignment.hsps:
                    results.append({
                        "title": alignment.title,
                        "length": alignment.length,
                        "e_value": hsp.expect,
                        "score": hsp.score,
                        "identities": hsp.identities,
                        "query_start": hsp.query_start,
                        "query_end": hsp.query_end,
                    })
        return results[:hitlist_size]
    except Exception as e:
        print("Error running BLAST:", e)
        return []
    

Explanation:
1: Function to run BLAST with program, database, and hit limit.
4–5: Submits the query using Biopython.
7–19: Loops through results, extracts key details, and stores them.
20–23: Returns results or an empty list if error occurs.

Step 4: Save Results

def save_results(results, filename, filetype="txt"):
    if filetype == "txt":
        with open(filename, "w") as f:
            if results:
                for i, r in enumerate(results, 1):
                    f.write(f"Result {i}:\n")
                    f.write(f"Title: {r['title']}\n")
                    f.write(f"Length: {r['length']}\n")
                    f.write(f"E-value: {r['e_value']}\n")
                    f.write(f"Score: {r['score']}\n")
                    f.write(f"Identities: {r['identities']}\n")
                    f.write(f"Query range: {r['query_start']} - {r['query_end']}\n")
                    f.write("-"*40 + "\n")
            else:
                f.write("No results found.\n")

    elif filetype == "csv":
        with open(filename, "w", newline="") as f:
            writer = csv.DictWriter(f, fieldnames=["title", "length", "e_value", "score", "identities", "query_start", "query_end"])
            writer.writeheader()
            writer.writerows(results if results else [])

    print(f"\nāœ… Results saved as {os.path.basename(filename)} at {os.path.abspath(filename)}")
    

Explanation:
1: Function saves results in TXT or CSV format.
3–14: Writes human-readable text.
16–20: Writes structured CSV for spreadsheets.
22: Confirms where the file was saved.

Step 5: Main Program Flow

if __name__ == "__main__":
    if not check_ncbi_server():
        print("NCBI BLAST server is not reachable. Try again later.")
        exit()

    job_name = input("Enter job name (optional): ").strip() or "BLAST_result"
    seq_type = input("Enter sequence type (DNA/RNA/Protein): ").strip().lower()
    sequence = input("Enter your sequence: ").strip().upper()

    if not validate_sequence(sequence, seq_type):
        print("āŒ Invalid sequence for given type.")
        exit()

    print("\nAvailable BLAST programs:")
    print("1. blastn   (DNA/RNA → DNA)")
    print("2. blastp   (Protein → Protein)")
    print("3. blastx   (DNA/RNA → Protein)")
    print("4. tblastn  (Protein → DNA)")
    print("5. tblastx  (DNA/RNA → Translated DNA)")
    program = {"1": "blastn","2": "blastp","3": "blastx","4": "tblastn","5": "tblastx"}.get(input("Choose (1-5): "), "blastn")

    print("\nAvailable databases:")
    print("1. nr  | 2. nt  | 3. refseq_protein  | 4. refseq_rna  | 5. pdb")
    database = {"1": "nr","2": "nt","3": "refseq_protein","4": "refseq_rna","5": "pdb"}.get(input("Choose (1-5): "), "nr")

    try:
        hitlist_size = int(input("\nEnter number of hits (default 10): ").strip())
    except ValueError:
        hitlist_size = 10

    results = run_blast(sequence, program=program, database=database, hitlist_size=hitlist_size)

    filetype = input("\nChoose output file type (txt/csv): ").strip().lower() or "txt"
    save_path = input("Enter folder path to save (blank=current dir): ").strip() or os.getcwd()
    if not os.path.exists(save_path): save_path = os.getcwd()

    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    filename = os.path.join(save_path, f"{job_name}_{timestamp}.{filetype}")
    save_results(results, filename, filetype)
    

Explanation:
2–5: Check server availability.
7–11: Get job name, sequence type, and sequence.
13–15: Validate sequence.
17–23: User selects BLAST program.
25–29: User selects database.
31–34: Number of hits input (default 10).
36: Run BLAST with chosen settings.
38–44: Ask file type, save path, and validate path.
46–47: Add timestamp to avoid overwriting and save results.

Output of Code

The output below shows the top 5 BLAST results for the provided DNA sequence, including organism name, sequence length, E-value, Scores, Identities and accession number.

Note: Click on the pictue zoom in to get better view or you can download the image by using the button at the bottom of image.

Note: If you find any error in the code or have any suggestion please feel free to ask me on contact page or use following social media links to connet with me.

🧬 Thank you for Visiting! 🧬