Sequence Annotation (SeqFeature)
GenBank and EMBL files carry more than a sequence: they annotate it. In Biopython, annotation lives in two places - the SeqRecord annotations dict (whole-sequence metadata) and the features list, where each SeqFeature marks a region of the sequence with location, type, and qualifiers. CDS features, for example, define where genes are and what they encode.
Record-Level Annotations
from Bio import SeqIO
rec = SeqIO.read("gene.gb", "genbank")
print(rec.annotations.get("molecule_type"))
print(rec.annotations.get("source"))
print(rec.id, "|", rec.description[:60])
Features and Locations
for feat in rec.features:
print(feat.type, feat.location.start, "-", feat.location.end)
# CDS 0 - 300
# gene 0 - 300
# source 0 - 301
feat.location is a location object with .start and .end (coordinates in the parent sequence), and feat.location.seq extracts the underlying sequence for that span.
Qualifiers
for feat in rec.features:
if feat.type == "CDS":
gene = feat.qualifiers.get("gene", ["?"])[0]
product = feat.qualifiers.get("product", ["?"])[0]
translation = feat.qualifiers.get("translation", [""])[0]
print(gene, "->", product)
print("protein:", translation[:30], "...")
Qualifiers are dicts of lists (GenBank convention); the .get(..., default)[0] pattern is the standard way to read them safely.
Building Features Programmatically
from Bio.Seq import Seq
from Bio.SeqRecord import SeqRecord
from Bio.SeqFeature import SeqFeature, ExactPosition, FeatureType
feat = SeqFeature(
location=FeatureType("location", ExactPosition(10), ExactPosition(50)),
type="CDS",
qualifiers={"gene": ["demo"], "product": ["demo protein"]},
)
rec = SeqRecord(Seq("A" * 100), id="demo", features=[feat])
print(feat.location, feat.qualifiers["gene"])
Typical Uses
- Extract all CDS translations from a GenBank file (a mini genome annotation pipeline).
- Map a variant coordinate to the feature that spans it.
- Filter records by annotation (source organism, molecule type) before alignment.
Summary
Sequence annotation in Biopython splits into record-level metadata (rec.annotations) and SeqFeature objects on rec.features, each with a location (start/end, extractable as sequence) and qualifiers (dicts of lists). Iterate features, read qualifiers with safe .get defaults, and you can extract genes, products, and translations from any GenBank file.