tofasta
Convert pandas DataFrames and CSV files to FASTA, with validation that refuses to write malformed output.
FASTA has no formal specification, so every consumer is permissive. Feed BLAST
or MMseqs2 a file with duplicate headers, an empty sequence, or an identifier
containing a space, and you will not get an error. You will get results that are
quietly wrong. tofasta checks for those cases up front and raises instead of
writing.
Install
pip install tofasta
Use
import pandas as pd
from tofasta import to_fasta
df = pd.DataFrame({
"accession": ["96602692", "77cd04d8"],
"sequence": ["MKVLAAGIVL", "GSGEGPREPG"],
})
to_fasta(df, "out.fasta", id="accession", seq="sequence")
>96602692
MKVLAAGIVL
>77cd04d8
GSGEGPREPG
Straight from a CSV:
from tofasta import csv_to_fasta
csv_to_fasta("in.csv", "out.fasta", id="accession", seq="sequence")
Or from the shell:
tofasta in.csv out.fasta --id accession --seq sequence
Both return the number of records written, so you can assert on it.
What it checks
| Problem | Why it matters |
|---|---|
| Duplicate identifiers | Accepted silently by BLAST and MMseqs2, producing wrong results rather than errors |
| Missing or empty identifier | Becomes a headerless or garbage record |
| Missing or empty sequence | Produces a header with no residues |
| Whitespace in an identifier | Parsers stop at the first space, so the identifier is silently truncated |
> in an identifier |
Starts a new record mid-header |
| Line breaks in any field | Corrupts the record structure |
| Whitespace inside a sequence | Usually a stray column or a copy-paste artifact |
| Numeric sequence column | A float column would otherwise be written out as 1.0 |
Residue validation is opt in, via alphabet="protein", "dna", "rna", or any
iterable of permitted characters. It is off by default because real curated data
legitimately contains X at unresolved positions, and a validator that fights
real data gets switched off entirely.
Output is always LF terminated, on every platform.
Options
to_fasta(
df,
path_or_buf, # path, or anything with a .write method
*,
id, # identifier column
seq, # sequence column
description=None, # optional column appended to the header after a space
wrap=None, # wrap sequences at N characters
on_duplicate="raise", # or "warn", or "first"
alphabet=None, # "protein", "dna", "rna", or an iterable of characters
)
On wrapping
Sequences are written on a single line by default. Wrapping at 60 or 80
characters is a widespread convention rather than a rule, and NCBI states only
that lines should be "shorter than 80 characters". No parser written in the last
thirty years cares, because they all concatenate lines until the next >.
Single-line output also keeps MMseqs2's --createdb-mode 1 available, which
soft-links the input instead of copying it and requires single-line records.
Pass wrap=60 if you want the conventional look.
Documentation
Full API reference documentation is available at readthedocs.
Scope
This library writes FASTA. It does not read it. Reading looks symmetric but is not: you would own indexing, compression, malformed-record recovery, and memory behaviour on multi-gigabyte files. Use pyfastx or Biopython for that.
If you need sequence objects, alignment, translation, or other file formats,
you want Biopython. tofasta exists for the narrow case where you already have
a DataFrame and want a correct FASTA file out of it without building
intermediate record objects.
Prior art
Biopython writes FASTA reliably via
SeqIO.write. It requires you to build SeqRecord objects, silently appends
<unknown description> if you forget description="", hard-wraps at 60 with no
way to disable it, and has no DataFrame awareness. tofasta is a smaller,
narrower tool for that specific gap.
Several of the checks here are regression tests against real defects in CDC's
CSV2FASTA browser tool, which emits CRLF
unconditionally and writes a phantom >undefined record with an empty sequence
whenever the identifier is not the first column of the input.
Development
uv sync
uv run pytest
To build the documentation, use the same flags Read the Docs does. The -W and
-j auto both matter: warnings are errors there, and parallel builds surface
extension incompatibilities that a serial build hides.
uv sync --extra docs
uv run python -m sphinx -T -W --keep-going -j auto -b html docs docs/_build/html
Licence
MIT
Metadata
Release files for tofasta 0.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 | |
|---|---|---|---|---|
| tofasta-0.1.0.tar.gz | 77.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tofasta-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 86.4 kB
Release files / tofasta-0.1.0.tar.gz
| Download URL | tofasta-0.1.0.tar.gz |
|---|---|
| Size | 77.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9eca63784b9aa16a465d0137f10d199aa23da1921a68a99a69e99dc571e25439
|
|
BLAKE2b-256 checksum How to use checksums |
5681561d3d80a65c4ec076ec44f13700fe91d54ab7fccd3df6eaa850f8c06750
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / tofasta-0.1.0-py3-none-any.whl
| Download URL | tofasta-0.1.0-py3-none-any.whl |
|---|---|
| Size | 9.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9ce7197baaa0e0c6d7e195b36e90f5fc67840b777596777a2a964e00fce39af8
|
|
BLAKE2b-256 checksum How to use checksums |
d69ccb12f95bef20423fa19008d7666185018541fe23a5ddefcee28900faf21a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for tofasta 0.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.