NCBI BLAST+ wrapper with automatic binary downloading and caching.
Project description
LocalBLAST
NCBI BLAST+ wrapper with automatic binary downloading and caching.
Quick Start
pip install localblast
from localblast import blastn, makeblastdb
# Create a BLAST database (binaries auto-download on first use)
# makeblastdb creates multiple files with a shared prefix, e.g.:
# - db/mydb.nsq, db/mydb.nhr, db/mydb.nin (for nucleotide)
# - db/mydb.psq, db/mydb.phr, db/mydb.pin (for protein)
# The "out" parameter is the file prefix (NOT the directory path).
# Using "db/mydb" creates files in the "db/" directory with prefix "mydb".
makeblastdb("sequences.fasta", dbtype="nucl", out="db/mydb", title="My Sequences")
# Run BLAST search
# Use the same file prefix as the db parameter
# Result is always a list (one record per query sequence in the FASTA file)
result = blastn("query.fasta", "db/mydb", evalue=0.001, num_threads=4) # Use 4 CPU threads
# Access results
for record in result: # Iterate over results (one per query sequence)
for alignment in record.alignments:
for hsp in alignment.hsps:
print(f"{alignment.hit_id}: e-value={hsp.expect}")
Features
- Automatic binary management: Downloads BLAST+ 2.17.0+ binaries to
.localblast/bin/on first use - Cross-platform: Supports Windows, macOS, and Linux (x86_64 and aarch64)
- BioPython integration: Returns BioPython Blast record objects for easy result parsing
- Cache management: Version-aware caching with manual control
- Environment override: Use custom binaries via
LOCALBLAST_*environment variables - Custom cache location: Control binary cache directory with
LOCALBLAST_CACHE_DIR
Common Workflows
Complete blastn Workflow
Here's a comprehensive example showing the full workflow from database creation to result processing:
from localblast import blastn, makeblastdb, get_version, get_bin_cache_dir, clear_bin_cache
import os
# ============================================================================
# STEP 1: Optional - Binary Cache Management
# ============================================================================
# Check BLAST+ version
version = get_version()
print(f"Using BLAST+ version: {version}")
# View cache location (defaults to .localblast/bin/)
cache_dir = get_bin_cache_dir()
print(f"Binary cache: {cache_dir}")
# Force re-download if needed (e.g., corrupted binaries)
# clear_bin_cache()
# ============================================================================
# STEP 2: Optional - Use System-Installed BLAST+
# ============================================================================
# If you have BLAST+ already installed, set environment variables:
# os.environ["LOCALBLAST_BLASTN"] = "/usr/local/bin/blastn"
# os.environ["LOCALBLAST_MAKEBLASTDB"] = "/usr/local/bin/makeblastdb"
# Or set custom cache directory:
# os.environ["LOCALBLAST_CACHE_DIR"] = "/path/to/cache"
# ============================================================================
# STEP 3: Create BLAST Database
# ============================================================================
# BLAST databases consist of multiple files with a shared prefix.
# For nucleotide databases (dbtype="nucl"):
# - {prefix}.nsq = sequence data
# - {prefix}.nhr = header data
# - {prefix}.nin = index data
#
# The makeblastdb function returns the database prefix path.
db_path = makeblastdb(
input="sequences.fasta", # Required: input FASTA file
dbtype="nucl", # Required: "nucl" or "prot"
out="my_db", # Optional: database prefix (default: input stem)
title="My Custom Database", # Optional: database title
parse_seqids=True, # Optional: parse sequence IDs (default: True)
# Additional BLAST+ arguments:
hash_index=True, # Create hash index for faster queries
# ... any other makeblastdb parameter
)
# Returns: "my_db"
# Creates: my_db.nsq, my_db.nhr, my_db.nin
# ============================================================================
# STEP 4: Run BLAST Search
# ============================================================================
# Run BLAST and get parsed BioPython results
result = blastn(
# Required parameters
query="query.fasta", # Query FASTA file path
db=db_path, # Database prefix (from step 3)
# Common optional parameters
evalue=0.001, # E-value threshold (default: 10.0)
max_target_seqs=10, # Max number of hits to keep (default: 10)
num_threads=4, # Number of CPU threads (default: 1)
# Optional: Save to file instead of parsing in-memory
# out="results.xml", # Output file path
# outfmt=5, # Output format (5 = XML)
# Additional BLAST+ arguments (underscore → hyphen conversion)
word_size=11, # Word size for initial matches
gapopen=5, # Gap opening penalty
gapextend=2, # Gap extension penalty
reward=2, # Match reward score
penalty=-3, # Mismatch penalty score
strand="both", # Query strand to search ("plus", "minus", "both")
# ... any other blastn parameter
)
# If `out` is specified, returns None and writes to file
# If `out` is not specified, returns list of BioPython Blast record objects (one per query sequence)
# ============================================================================
# STEP 5: Process Results
# ============================================================================
# Result is always a list (one element per query sequence in FASTA)
for record in result:
# Access query information
print(f"Query: {record.query}")
print(f"Query length: {record.query_length}")
# Iterate through hits (alignments)
for alignment in record.alignments:
hit_id = alignment.hit_id # Hit sequence ID
hit_def = alignment.hit_def # Hit definition/description
hit_length = alignment.length # Hit sequence length
# Each hit may have multiple HSPs (High-scoring Segment Pairs)
for hsp in alignment.hsps:
evalue = hsp.expect # E-value (lower = better)
bitscore = hsp.bits # Bit score (higher = better)
identity_pct = (hsp.identities / hsp.align_length) * 100
print(f"{hit_id}: {identity_pct:.1f}% identity, "
f"e-value={evalue:.2e}, bitscore={bitscore:.1f}")
Key points:
- BLAST databases are created once and reused for multiple queries
- The database prefix (
db_pathfrommakeblastdb) is passed to BLAST functions - Results are always returned as a list (one element per query sequence in the input FASTA)
- Set
outparameter to save results to file instead of parsing in-memory - Underscores in parameter names are automatically converted to hyphens for BLAST+
Other BLAST Programs
The interface is identical across all BLAST programs. Only the function name and typical use cases differ:
from localblast import blastp, blastx, tblastn, tblastx
# blastp: Protein vs Protein
result = blastp(
query="proteins.fasta",
db="protein_db",
evalue=1e-5,
max_target_seqs=50
)
# Result is always a list (one per query sequence)
for record in result:
print(f"Query: {record.query}")
# blastx: Translated nucleotide query vs protein database
# Use: Find potential proteins in nucleotide sequences
result = blastx(
query="transcripts.fasta",
db="protein_db",
evalue=0.001
)
# tblastn: Protein query vs translated nucleotide database
# Use: Find encoding genes for a protein in a genome
result = tblastn(
query="protein.fasta",
db="genome_db",
evalue=0.001
)
# tblastx: Translated query vs translated database
# Use: Compare coding sequences when frame shifts are likely
result = tblastx(
query="transcripts.fasta",
db="transcriptome_db",
evalue=0.001
)
Saving and Loading Results
from localblast import blastn
from localblast.parsers import parse_xml_file
# Save to file (doesn't parse in-memory)
blastn(
query="query.fasta",
db="my_db",
out="results.xml", # Output file path
outfmt=5 # XML format
)
# Parse saved file later
result = parse_xml_file("results.xml")
# Or parse XML string directly
from localblast.parsers import parse_xml
with open("results.xml") as f:
result = parse_xml(f.read())
Custom Cache Directory
Control where BLAST+ binaries are cached using the LOCALBLAST_CACHE_DIR environment variable:
Default behavior:
- Binaries are cached in
.localblast/bin/in the current working directory
Custom cache location:
# Set custom cache directory (bash/zsh)
export LOCALBLAST_CACHE_DIR=/opt/blast-cache
# Or in Python
import os
os.environ["LOCALBLAST_CACHE_DIR"] = "/opt/blast-cache"
from localblast import blastn
Use cases:
- Shared cache: Point to a network drive or shared directory for team environments
- Limited disk space: Redirect to a partition with more space
- Testing/isolation: Use temporary directories to avoid polluting project directories
- CI/CD: Set to a consistent location across build environments
Note: The cache directory must exist and be writable. If LOCALBLAST_CACHE_DIR is not set, the default .localblast directory is used.
API Reference
BLAST Search Functions
blastn(query, db, *, out=None, evalue=10.0, max_target_seqs=10, num_threads=1, **kwargs)
Run nucleotide BLAST search.
Parameters:
query(str | Path): Path to query FASTA filedb(str | Path): Path to BLAST database (prefix)out(str | Path, optional): Output file path. If not provided, returns parsed resultsevalue(float): Expectation value threshold (default: 10.0)max_target_seqs(int): Maximum number of aligned sequences to keep (default: 10)num_threads(int): Number of threads (default: 1)**kwargs: Additional BLAST+ arguments (e.g.,word_size,gapopen,gapextend)
Returns:
list[BioPython Blast record]ifoutis None (one record per query sequence)- None if
outis specified
Example:
result = blastn("query.fasta", "nt_db", evalue=0.001, word_size=11)
# result is a list - iterate over it
for record in result:
for alignment in record.alignments:
...
blastp(query, db, *, out=None, evalue=10.0, max_target_seqs=10, num_threads=1, **kwargs)
Run protein BLAST search.
Parameters: Same as blastn
Returns: Same as blastn
blastx(query, db, *, out=None, evalue=10.0, max_target_seqs=10, num_threads=1, **kwargs)
Run translated query BLAST (nucleotide query → protein database).
Parameters: Same as blastn
Returns: Same as blastn
tblastn(query, db, *, out=None, evalue=10.0, max_target_seqs=10, num_threads=1, **kwargs)
Run translated database BLAST (protein query → nucleotide database).
Parameters: Same as blastn
Returns: Same as blastn
tblastx(query, db, *, out=None, evalue=10.0, max_target_seqs=10, num_threads=1, **kwargs)
Run translated query vs translated database BLAST.
Parameters: Same as blastn
Returns: Same as blastn
Database Creation
makeblastdb(input, *, dbtype="nucl", out=None, title=None, parse_seqids=True, **kwargs)
Create a BLAST database from input sequences.
Parameters:
input(str | Path): Path to input FASTA filedbtype(str): Database type - "nucl" or "prot" (default: "nucl")out(str | Path, optional): Output database name/prefix (default: input stem)title(str, optional): Database titleparse_seqids(bool): Parse sequence IDs (default: True)**kwargs: Additional makeblastdb arguments
Returns:
- str: Database prefix path (relative or absolute)
Note: BLAST databases consist of multiple files with extensions like .nsq,
.nhr, .nin (for nucleotide) or .psq, .phr, .pin (for protein). The
returned value is the prefix shared by all these files. Use this prefix as the
db parameter in BLAST search functions.
Example:
db_path = makeblastdb(
"sequences.fasta",
dbtype="nucl",
title="My Custom Database",
hash_index=True # Additional argument
)
Utility Functions
get_exe(name)
Get path to a BLAST+ executable, downloading if needed.
Parameters:
name(str): Executable name (e.g., "blastn", "makeblastdb")
Returns:
- str: Full path to the executable
Raises:
ValueError: If executable name is unknownRuntimeError: If executable cannot be found
get_version()
Get BLAST+ version from cached/system binary.
Returns:
- str: Version string (e.g., "2.17.0+")
Raises:
RuntimeError: If version cannot be determined
get_bin_cache_dir()
Get the binary cache directory for BLAST+ executables.
Returns:
- Path: Binary cache directory path
Environment Variables:
LOCALBLAST_CACHE_DIR: Override the default cache directory location
Example:
import os
os.environ["LOCALBLAST_CACHE_DIR"] = "/custom/cache/path"
from localblast import get_bin_cache_dir
cache_dir = get_bin_cache_dir() # Returns /custom/cache/path
clear_bin_cache()
Clear the cached BLAST+ binaries (forces re-download on next use).
Example:
from localblast import clear_bin_cache
clear_bin_cache() # Prints "Cleared cache: .localblast/bin"
Parsers
parse_xml(xml_text)
Parse BLAST XML output string using BioPython.
Parameters:
xml_text(str): BLAST XML output string (outfmt=5)
Returns:
- BioPython Blast record object
Example:
from localblast.parsers import parse_xml
result = parse_xml(xml_string)
parse_xml_file(file_path)
Parse BLAST XML file using BioPython.
Parameters:
file_path(str): Path to BLAST XML output file
Returns:
- BioPython Blast record object
Example:
from localblast.parsers import parse_xml_file
result = parse_xml_file("blast_output.xml")
Working with BioPython Results
All BLAST functions return a list of BioPython Blast record objects (one per query sequence). Key attributes:
Record Level
# Result is always a list - iterate over query results
for record in result:
record.query # Query sequence ID
record.query_length # Query sequence length
record.application # BLAST program name
record.version # BLAST version
record.date # Run date
Alignments (Hits)
for record in result:
for alignment in record.alignments:
alignment.hit_id # Hit sequence ID
alignment.hit_def # Hit definition
alignment.length # Hit sequence length
alignment.accession # Accession number
High-Scoring Pairs (HSPs)
for record in result:
for alignment in record.alignments:
for hsp in alignment.hsps:
hsp.expect # E-value
hsp.bits # Bit score
hsp.score # Raw score
hsp.identities # Number of identical positions
hsp.positives # Number of positive-scoring positions
hsp.align_length # Alignment length
hsp.query # Query sequence string
hsp.sbjct # Subject (hit) sequence string
hsp.query_start # Start position in query
hsp.query_end # End position in query
hsp.sbjct_start # Start position in subject
hsp.sbjct_end # End position in subject
Example: Extract Top Hits
result = blastn("query.fasta", "nt_db", evalue=0.001)
# Process all query results
top_hits = []
for record in result:
for alignment in record.alignments:
best_hsp = alignment.hsps[0] # First HSP is best
top_hits.append({
"query": record.query,
"id": alignment.hit_id,
"evalue": best_hsp.expect,
"bitscore": best_hsp.bits,
"identity_pct": (best_hsp.identities / best_hsp.align_length) * 100
})
# Sort by e-value
top_hits.sort(key=lambda x: x["evalue"])
Additional BLAST Arguments
Pass any BLAST+ argument via **kwargs. Underscores are converted to dashes:
result = blastn(
"query.fasta",
"nt_db",
evalue=0.001,
# Additional arguments (underscore → dash conversion):
word_size=11,
gapopen=5,
gapextend=2,
reward=2,
penalty=-3,
dust="yes" # Enable dust filtering
)
Common arguments:
task: "blastn", "blastn-short", "megablast", "dc-megablast"strand: "plus", "minus", "both"query_loc: "start-stop" range on querydb_soft_mask: Filtering algorithm for databasedb_hard_mask: Filtering algorithm for databasematrix: Substitution matrix (for protein searches)gapopen,gapextend: Gap penalties
Platform Support
| Platform | Architecture | Status |
|---|---|---|
| Windows | x86_64 | Supported |
| Linux | x86_64 | Supported |
| macOS | x86_64 | Supported |
| macOS | aarch64 (Apple Silicon) | Supported |
| Linux | aarch64 | Supported |
Troubleshooting
Binaries not found
If BLAST+ executables cannot be found:
- Check binary cache directory:
.localblast/bin/ - Clear cache and re-download:
from localblast import clear_bin_cache; clear_bin_cache() - Set environment variable to custom binary:
export LOCALBLAST_BLASTN=/path/to/blastn - Set custom cache location:
export LOCALBLAST_CACHE_DIR=/path/to/cache
Download fails
If download from NCBI FTP fails:
- Check internet connection
- Verify NCBI FTP is accessible: https://ftp.ncbi.nlm.nih.gov/blast/executables/blast+/LATEST/
- Manually download and extract to
.localblast/bin/
ImportError for BioPython
If you see ImportError: No module named 'Bio':
pip install biopython
# or
uv add biopython
License
This package provides a wrapper for NCBI BLAST+. BLAST+ is in the public domain.
References
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file localblast-0.1.0-py3-none-any.whl.
File metadata
- Download URL: localblast-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
23aa4f256cbea0e4b80090c87be1814e1f77080d19f91487816db68f80de0170
|
|
| MD5 |
5b89a46c87ff0c96bd483267ff1ba806
|
|
| BLAKE2b-256 |
756935d159ce9cc2d268149324986c2041b518a07844ab2ae21f3f4cbfbd6df6
|
Provenance
The following attestation bundles were made for localblast-0.1.0-py3-none-any.whl:
Publisher:
release.yml on IVB-Generative-Biology/localblast
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
localblast-0.1.0-py3-none-any.whl -
Subject digest:
23aa4f256cbea0e4b80090c87be1814e1f77080d19f91487816db68f80de0170 - Sigstore transparency entry: 832734238
- Sigstore integration time:
-
Permalink:
IVB-Generative-Biology/localblast@ccb6ea8034c0c380a7a05d6372e980d8dde7d233 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/IVB-Generative-Biology
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ccb6ea8034c0c380a7a05d6372e980d8dde7d233 -
Trigger Event:
release
-
Statement type: