fastapy
A lightweight Python package to read and write sequence records in FASTA format, with support for compressed files and no external dependencies.
Key features
- No dependencies: Uses only the Python standard library.
- Streaming: Reads and writes records one by one without loading entire files into memory.
- Compression: Reads gzip, bzip2, and ZIP files; writes gzip and bzip2 files.
- Path support: Accepts string paths and
pathlib.Pathobjects.
Installation
Requires Python 3.8 or later. Install from PyPI:
pip install fastapy
Or install directly from GitHub:
pip install "git+https://github.com/aziele/fastapy.git"
Because fastapy has no third-party dependencies, you can also use it directly by downloading or cloning the repository:
git clone https://github.com/aziele/fastapy.git
cd fastapy
python
>>> import fastapy
Quick start
Read a FASTA file and save sequences of at least 100 residues to a compressed file:
import fastapy
records = (
record
for record in fastapy.parse("input.fasta")
if len(record) >= 100
)
count = fastapy.write(records, "filtered.fasta.gz")
print(f"Wrote {count} records")
Records are processed one by one without loading the entire file into memory.
Usage
| Object or function | Purpose |
|---|---|
Record(id, seq, desc=None) |
Create a record from an identifier, sequence, and optional description |
parse(filename) |
Iterate over records in a plain or compressed FASTA file |
parse_handle(handle) |
Iterate over FASTA records from an open text handle |
read(filename) |
Return the first record from a FASTA file |
to_dict(records) |
Create a dictionary mapping sequence identifiers to records |
write(records, destination, wrap=70) |
Write records to a file or text handle and return the number written |
Reading records
Use parse() to iterate over FASTA records:
import fastapy
for record in fastapy.parse("input.fasta"):
print(record.id, len(record), record.desc)
Input can be a filename or pathlib.Path. Compression is selected from the extension: .gz or .gzip (gzip), .bz2 (bzip2), or .zip (ZIP). For ZIP archives, the first entry is read and must be a FASTA text file.
For an open text handle, use parse_handle():
with open("input.fasta") as handle:
for record in fastapy.parse_handle(handle):
print(record.id)
Reading the first record
Use read() to return the first record. Additional records are ignored; a file containing no records raises ValueError.
record = fastapy.read("input.fasta")
print(record.id)
Working with records
A Record stores a sequence identifier (id), sequence (seq), and optional description (desc). The description property returns the complete FASTA header, including >.
record = fastapy.Record(id="seq1", seq="MRELEAKAT", desc="Example protein")
print(record.id) # seq1
print(record.seq) # MRELEAKAT
print(record.desc) # Example protein
print(record.description) # >seq1 Example protein
print(len(record)) # 9
print("LEA" in record) # True
Iterating over a record yields its sequence characters. Use print(record) to display FASTA, or record.format() to obtain a FASTA string:
print(record.format(wrap=3), end="")
# >seq1 Example protein
# MRE
# LEA
# KAT
The default line width is 70 characters. Use wrap=0 or wrap=None for no wrapping.
Storing records in a list or dictionary
Use a list for repeated access or positional indexing:
records = list(fastapy.parse("input.fasta"))
print(records[0].id) # First record
print(records[-1].id) # Last record
Use to_dict() to index records by identifier. Duplicate identifiers raise ValueError.
records = fastapy.to_dict(fastapy.parse("input.fasta"))
print(records["seq1"]) # Replace with an identifier from your file
Both approaches store all records in memory.
Writing records
Use write() to save a single record or an iterable of records to a filename, pathlib.Path, or open text handle. The function returns the number of records written.
# Write a single record
record = fastapy.Record(id="seq1", seq="ATCG")
fastapy.write(record, "sequence.fasta")
# Write a list of records
records = [record, fastapy.Record(id="seq2", seq="GGTA")]
count = fastapy.write(records, "sequences.fasta", wrap=80)
print(count) # 2
# Write records stored in a dictionary
records_by_id = fastapy.to_dict(records)
fastapy.write(records_by_id.values(), "sequences.fasta.gz")
# Write directly from a generator
fastapy.write(fastapy.parse("input.fasta"), "output.fasta.bz2", wrap=0)
Compression and options:
- Output compression is selected from the extension:
.gzor.gzipfor gzip, and.bz2for bzip2. - ZIP output is not supported; a
.zipdestination raisesValueError. - Sequences are wrapped to 70 characters by default. Use
wrap=0orwrap=Nonefor no wrapping. - Existing output files are overwritten.
- When you pass an open text handle,
write()does not close it.
with open("sequences.fasta", "w") as handle:
fastapy.write(records, handle)
Testing
From the repository root, run:
pip install pytest
pytest
License
Distributed under the terms of the GNU General Public License, version 3.
Metadata
Release files for fastapy 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fastapy-1.1.0.tar.gz | 20.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fastapy-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 39.3 kB
Release files / fastapy-1.1.0.tar.gz
| Download URL | fastapy-1.1.0.tar.gz |
|---|---|
| Size | 20.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b54c2b480bc3a60bb7066a73bbc8ed7ba8fdc2744734b52e563a6ea2e87edd5c
|
|
BLAKE2b-256 checksum How to use checksums |
d7eed27d2483724f96a75f9a50c0e96dc556f7e0a60bf3708a923985cad5893d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.6
|
Release files / fastapy-1.1.0-py3-none-any.whl
| Download URL | fastapy-1.1.0-py3-none-any.whl |
|---|---|
| Size | 18.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0e7e390aad77e1e05f7b1ee450c15e0ebdd5610ce2e29e82a23d1ec1396961eb
|
|
BLAKE2b-256 checksum How to use checksums |
828157cc4762983e39c078544fd6eeb7b21c88dbec7ceefb0bd6a57ecce30a4e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.6
|