alphex
Biological sequence alphabet orderings, and letter-preserving conversions between them.
uv add alphex
Why
Three different amino-acid orderings are in common use, under at least five different names:
| ordering | letters | used by |
|---|---|---|
| ProteinMPNN | ACDEFGHIKLMNPQRSTVWY |
ProteinMPNN, and most "canonical" alphabets |
| AlphaFold | ARNDCQEGHILKMFPSTWYV |
AlphaFold restypes, LG/JTT substitution models, IQ-TREE |
| ESM | LAGVSERTIDPKQNFYMHWC |
ESM3 / ESM-C, at offset 4 |
ProteinMPNN and AlphaFold order have exactly three fixed points — A, S and T. Build a
lookup table from one and label it with the other, and 17 of 20 residues are silently permuted.
The result is shape-valid, dtype-valid, and wrong; nothing raises. That bug has shipped.
An ecosystem census that motivated this package found those three orderings declared at 30
sites across four repositories, in six different sentinel conventions (no sentinel; X at 20;
gap at 20; gap at 0 with residues shifted to 1; gap at 20 with X at 21; X at 20 with gap at
21). Every site was an independent opportunity to get it wrong.
alphex holds one declaration of each, and one way to convert between them.
What it does
from alphex import Policy, SpecialKind, known, perm
# A table from ProteinMPNN order (gap at 20) into ESM's vocabulary.
table = perm(known.MPNN_GAP_21, known.ESM_C, policy=Policy.RAISE)
table.shape # (21,) -- the whole source domain, never just the 20 residues
int(table[0]) # 5 -- 'A'
int(table[20]) # 30 -- the gap, which ESM declares
Four entry points, because four genuinely different things get converted and using the wrong one scrambles letter identity silently:
relation(src, dst) |
classify first: IDENTITY, EXTENSION, PERMUTATION, INCOMPATIBLE, plus lossy and which letters moved |
perm(src, dst, *, policy) |
build the lookup table |
convert(codes, src, dst, *, policy) |
relabel sequence codes |
reindex(data, src, dst, *, policy, axes) |
move a posterior or substitution-matrix axis |
The design commitments
Letters, not indices. The invariant is that the amino acid at each position is unchanged and only its integer moves. Index equality cannot catch this bug class — the broken table and the correct one both round-trip perfectly within themselves.
Every index means something. A declaration must account for every index in [0, size) as a
residue, a named special, or explicitly unclaimed. A table shorter than its domain is how a
JAX gather clamped a gap index onto valine.
No silent defaults. policy is keyword-only and has no default, anywhere. It is keyed per
SpecialKind, so ESM's eight specials cannot collapse onto one destination index without you
writing that down.
No in-band sentinels. Policy.MASK returns a MaskedPerm, a distinct type — because every
in-band marker is a valid index somewhere. -1 selects the last element of the destination
axis; size is clamped rather than rejected by JAX.
Declarations carry provenance. citation is required and must be non-empty. An ordering
without a source is how one gets relabelled.
Names are not identity. Two Alphabets compare equal when their index spaces match,
whatever they are called. That is what makes an alias collision detectable instead of invisible.
CLI and MCP
Optional surfaces, for asking the two questions whose absence let a mislabelled table ship — "which ordering is this?" and "what does the table look like?" — without writing a script.
uv add "alphex[cli]" # or [mcp], or [agent] for both
alphex list # every shipped declaration
alphex show MPNN_GAP_21 # symbols, specials, citation, warnings
alphex relation MPNN_20 AF_20 # classify before converting
alphex perm MPNN_GAP_21 ESM_C # the table, plus a letter-preservation check
alphex lint # declarations with conflated sentinels
Every command takes --json-out. The MCP server (alphex-mcp) exposes the same five as tools —
list_alphabets, show_alphabet, relation, perm, lint — registered through
cisternal, which also ships the using-alphex skill and
project rules to Claude Code, Cursor, Copilot and Antigravity via .praxia/manifest.toml.
Both surfaces answer from one module (alphex._surface) so they cannot drift, and both take a
single uniform policy: the per-SpecialKind mapping form exists precisely so ESM's eight
specials cannot be collapsed onto one index by accident, and squeezing that through a CLI flag
would make doing so easy. Anything needing per-kind policy calls perm directly.
(The mcp extra pulls cisternal, which requires Python ≥3.13. alphex itself supports ≥3.11 and
will keep doing so, so the dependency is marker-gated: below 3.13 the library and CLI work
normally and alphex-mcp exits with a message saying why.)
Dependencies
numpy, and nothing else. That ceiling is the reason this is its own distribution rather than a
module inside a larger library: extras can only add to a base install, never subtract, so the
only way to make "just the alphabets" cheap for a consumer is for it to ship separately.
JAX consumers pass the result through jnp.asarray — the table is a small constant.
Status
Alpha. The value type, the shipped declarations and the conversion kernel are implemented and
tested. Not yet implemented: aliases for degenerate and non-standard residues (B, Z, J,
U, O), the substitution/rate-matrix asset layer, and the plugin registry for third-party
alphabets. The entry-point group names (alphabet_contract.v1.*) are reserved and deliberately
independent of this distribution's name.
Provenance
The orderings are facts about published tools, cited per declaration in known.py: ProteinMPNN
(Dauparas et al. 2022, MIT), AlphaFold residue_constants (Apache-2.0), ESM3/ESM-C
SEQUENCE_VOCAB (MIT). No code from those projects is included or derived from.
MIT licensed.
Metadata
Release files for alphex 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 | Actions |
|---|---|---|---|---|
| alphex-0.1.0.tar.gz | 24.8 kB | With provenance | Details for alphex-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| alphex-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for alphex-0.1.0-py3-none-any.whl |
Total release size: 51.5 kB
Release files / alphex-0.1.0.tar.gz
| Download URL | alphex-0.1.0.tar.gz |
|---|---|
| Size | 24.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c47695d49bab6e0ed9628fe4e89b14670bc5248eafaafec6cf50b0efb62b664f
|
|
BLAKE2b-256 checksum How to use checksums |
e32eff0b88838c29c0307afba89406d6053359ed2d21d67ef6e0076f3e4a5bc2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / alphex-0.1.0-py3-none-any.whl
| Download URL | alphex-0.1.0-py3-none-any.whl |
|---|---|
| Size | 26.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b23435191a44d69f570dd15cf633040d1497e32b6229466c1c2412331ac81503
|
|
BLAKE2b-256 checksum How to use checksums |
57fb34be59510bdcd869b8609676bf75342243d6f38e760eed70c60e3f55960b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logSecurity for alphex 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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for alphex-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logA 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.