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 | Provenance | Actions |
|---|---|---|---|---|
| fastapy-1.1.0.tar.gz | 20.7 kB | Without provenance | Details for fastapy-1.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| fastapy-1.1.0-py3-none-any.whl | Python 3 | none | any | Details for fastapy-1.1.0-py3-none-any.whl |
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
|
Security for fastapy 1.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.