read_fasta_stream
read_fasta_stream is the streaming counterpart to
protfasta.read_fasta(). It takes an identical set of arguments,
but instead of reading the whole file and returning a fully-materialised
dict or list, it returns a generator that yields one
sanitized record at a time. This keeps peak memory bounded and makes it
possible to process FASTA files far larger than RAM (tens or hundreds of
millions of sequences).
At its simplest:
import protfasta
for header, sequence in protfasta.read_fasta_stream('huge.fasta'):
# process each record on the fly
if len(sequence) > 1000:
print(header, len(sequence))
Because a lazily-produced result cannot be a dictionary, the
dict-versus-list distinction of read_fasta collapses:
read_fasta_stream yields (header, sequence) tuples by default, or
[header, sequence] lists when return_list=True.
read_fasta vs read_fasta_stream
The two functions share the same signature and apply the same sanitization steps in the same order. Choose between them based on the size of the file and the shape of result you need:
protfasta.read_fasta()loads the file and returns every record at once as adictorlist. Use it whenever the dataset fits comfortably in memory - it is the more convenient interface and lets you index and re-iterate the result freely.
read_fasta_streamyields records one at a time and never holds more than a single record’s sequence data in memory. Use it for files that do not fit in memory, or when you only need a single pass over the records.
What differs under streaming
The full parameter set of protfasta.read_fasta() is supported, but
a few arguments behave slightly differently because a stream never sees
the whole file up front:
Return type.
return_list=False(default) yields(header, sequence)tuples;return_list=Trueyields[header, sequence]lists. There is no dictionary return type.When errors are raised. All argument validation is eager - an invalid keyword combination raises immediately, before any record is produced. Data-dependent failures, however, are inherent to streaming and are raised mid-iteration, at the offending record: a duplicate header, a duplicate record or sequence under a
'fail'action, or an invalid residue underinvalid_sequence_action='fail'/'convert'.verbose output. Per-total summaries (for example, “removed 5 of 100 duplicate records”) can only be reported once the generator has been fully consumed, so they are emitted at exhaustion rather than up front.
output_filename. When provided, each sanitized record is teed to disk as it is yielded. The output file is therefore only complete once the generator has been fully consumed, and it must differ from the input
filename.
Memory characteristics
Peak memory is O(single record) for the sequence data itself. The
duplicate- and uniqueness-handling actions add auxiliary bookkeeping
that grows with the number of records (headers plus 16-byte sequence
digests - never whole sequences), so they are still far lighter than a
full load. When expect_unique_header=False and every duplicate
action is 'ignore', no bookkeeping is allocated at all and memory is
flat regardless of file size.
Basic usage
import protfasta
for header, sequence in protfasta.read_fasta_stream('huge.fasta'):
if len(sequence) > 1000:
print(header, len(sequence))
Using a header parser
As with read_fasta, the optional header_parser argument is a
callable (str) -> str applied to every raw header. This is commonly
used to extract a UniProt accession from a structured header:
import protfasta
def uniprot_id(header):
# '>sp|P12345|NAME_HUMAN ...' -> 'P12345'
return header.split('|')[1]
for acc, seq in protfasta.read_fasta_stream('uniprot.fasta',
header_parser=uniprot_id):
...
Sanitizing on the fly
Every sanitization option available to read_fasta works while
streaming. For example, to stream a very large file while converting
non-standard residues and dropping duplicate sequences:
import protfasta
stream = protfasta.read_fasta_stream('huge.fasta',
invalid_sequence_action='convert',
duplicate_sequence_action='remove')
for header, seq in stream:
...
Streaming filter + write
You can stream through an input file, keep only the records you care about, and write them out in bounded memory:
import protfasta
keep = []
for header, seq in protfasta.read_fasta_stream('huge.fasta'):
if 100 <= len(seq) <= 500:
keep.append([header, seq])
protfasta.write_fasta(keep, 'filtered.fasta')
Alternatively, let read_fasta_stream write the sanitized output for
you as it goes via output_filename - just remember the file is only
complete once the generator has been fully consumed:
import protfasta
stream = protfasta.read_fasta_stream('huge.fasta',
invalid_sequence_action='convert',
output_filename='clean.fasta')
# fully consume the stream so the output file is written in full
for header, seq in stream:
...
For usage examples see the Examples page. Full API documentation is shown below.
Documentation
- protfasta.read_fasta_stream(filename: str, expect_unique_header: bool = False, header_parser: Callable[[str], str] | None = None, check_header_parser: bool = True, duplicate_sequence_action: str = 'ignore', duplicate_record_action: str = 'ignore', invalid_sequence_action: str = 'fail', alignment: bool = False, return_list: bool = False, output_filename: str | None = None, correction_dictionary: dict[str, str] | None = None, verbose: bool = False, silence_warnings: bool = False) Iterator[tuple[str, str] | list[str]][source]
Stream a FASTA file record-by-record, sanitizing as it goes.
This is the streaming counterpart to
read_fasta(). It takes the same arguments but, instead of loading the whole file and returning a dictionary or list, it returns a generator that yields one sanitized record at a time. This keeps peak memory bounded and makes it possible to process files far larger than RAM:for header, seq in read_fasta_stream('huge.fasta'): ...
Warning
The duplicate/uniqueness-checking defaults differ from
read_fasta(). To keep streaming flat in memory by default, this function defaults toexpect_unique_header=Falseandduplicate_record_action='ignore', whereasread_fasta()defaults toexpect_unique_header=Trueandduplicate_record_action='fail'. As a result, duplicate headers and duplicate records are not detected by default when streaming. This is deliberate: those checks each costO(records)memory (a running set of headers / digests), which would defeat the point of a streamer built for files larger than RAM. Re-enable them explicitly (e.g.expect_unique_header=True) if you need them – a one-time warning will then flag the memory cost. See the Memory section below.Because a lazily-produced result cannot be a dictionary, the dict-versus-list distinction of
read_fasta()collapses: this function yields(header, sequence)tuples by default, or[header, sequence]lists when return_list isTrue.Memory
By default this function is flat in memory: only one record is held at a time and no per-record bookkeeping is kept, so peak memory is independent of file size and files far larger than RAM stream fine. This is why the duplicate/uniqueness-checking defaults differ from
read_fasta()(see the warning above).The duplicate/uniqueness checks are still available, but each needs to remember what it has already seen, so enabling one adds
O(records)auxiliary state (hundreds of MB or more on very large files):expect_unique_header=Truekeeps a running set of every header;duplicate_record_actionin('fail', 'remove')keeps a running header -> sequence-digest map;duplicate_sequence_actionin('fail', 'remove')keeps a running set of sequence digests.
Whenever a memory-growing check is enabled a one-time warning is emitted (suppress it with
silence_warnings=True).All argument validation is performed eagerly, at call time, so bad keyword combinations raise immediately (before iteration begins). Data-dependent errors – a duplicate header, a duplicate record or sequence under a
'fail'action, or an invalid residue – are inherent to streaming and are therefore raised mid-iteration, at the offending record, rather than up front.The same processing steps as
read_fasta()are applied, in the same order (header uniqueness, duplicate records, duplicate sequences, invalid residues). Seeread_fasta()for a full description of each argument; the notes below cover only where streaming differs.- Parameters:
filename (str) – Path to the FASTA file to read.
expect_unique_header (bool, optional) – As in
read_fasta(), but defaults to ``False`` here so that streaming is flat in memory by default. WhenTruea running set of seen headers is kept (O(records)memory), and the defaultduplicate_record_action='ignore'is promoted to'fail'(unique headers already preclude duplicate records), soTrueworks on its own. DefaultFalse.header_parser (callable or None, optional) – As in
read_fasta(). DefaultNone.check_header_parser (bool, optional) – As in
read_fasta(). DefaultTrue.duplicate_sequence_action (str, optional) – As in
read_fasta(). The'fail'and'remove'variants keep a running set of 16-byte sequence digests (never whole sequences), i.e.O(records)memory. Default'ignore'.duplicate_record_action (str, optional) – As in
read_fasta(), but defaults to ``’ignore’`` here so that streaming is flat in memory by default. The'fail'and'remove'variants keep a running header-to-digest map (O(records)memory). Default'ignore'.invalid_sequence_action (str, optional) – As in
read_fasta(). Every mode is a per-record decision and streams without extra state. Default'fail'.alignment (bool, optional) – As in
read_fasta(). DefaultFalse.return_list (bool, optional) – If
True, yield[header, sequence]lists (matching the internal format ofread_fasta()withreturn_list=True); otherwise yield(header, sequence)tuples. DefaultFalse.output_filename (str or None, optional) – If provided, each sanitized record is written to this path as it is yielded (60 residues per line, as in
write_fasta()). The file is only complete once the generator has been fully consumed. Must differ from filename.correction_dictionary (dict or None, optional) – As in
read_fasta(). DefaultNone.verbose (bool, optional) – If
True, print an opening message and, once the generator is exhausted, a summary of removed/converted counts. Per-total summaries are only emitted at exhaustion because a stream never sees the file total up front. DefaultFalse.silence_warnings (bool, optional) – If
True, suppress the one-time warning emitted when a memory-growing duplicate/uniqueness check is enabled (see the Memory section above). DefaultFalse.
- returns:
A generator yielding
(header, sequence)tuples (or[header, sequence]lists when return_list isTrue) in file order. Sequences are upper-cased and sanitized.- rtype:
Iterator[tuple[str, str]] or Iterator[list[str]]
- raises ProtfastaException:
Eagerly, for invalid argument combinations; lazily (during iteration) for data-dependent failures.
See also
read_fastaLoad and return the whole file as a dict or list.
write_fastaWrite sequences out to a FASTA file.