Skip to main content

Fast fuzzy search over biological sequences (C++ core, Python bindings)

Project description

seqtree

PyPI Python License CI Docs

Fast fuzzy search over biological sequences (amino-acid or nucleotide), as a C++ core with a minimal Python binding. Build an immutable index once, then search single queries or massive batches in parallel.

Two search engines over one trie:

  • seqtm — branch-and-bound enumeration. Exact per-type edit caps (max_subs / max_ins / max_dels) and a fast Hamming-only path. Best for small edit distances (UMI collapse, error correction, CDR3/epitope matching).
  • seqtrie — full-width edit-distance DP carried down the trie. Honours the max_penalty score budget only; it ignores the per-type edit caps. Use it when the budget is the whole specification.

engine="auto" always picks seqtm, because it is the only engine that enforces the caps you asked for. Results are payload-agnostic: (ref_id, score, n_subs, n_ins, n_dels). Downstream libraries map ref_id back to their own payloads (V gene, MHC, counts) and filter.

Beyond search, seqtree ships:

  • Substitution matrices — built-in identity, BLOSUM45, BLOSUM62, BLOSUM80, PAM250, PAM100, and structural — a Miyazawa–Jernigan interaction-strength matrix: each residue's strength q(a)=mean_b e(a,b) is read off the MJ contact potential, so substitutions between residues of like interaction strength are cheap. It separates strong (hydrophobic F W C L Y M I V) from weak (polar/charged S Q D E K) interactors — the strong/weak-interactor axis of TCR-recognition models (Košmrlj et al., PNAS 2008; MJ contact energies from Miyazawa & Jernigan, J Mol Biol 1996) — letting dissimilar-but-chemically-equivalent loops align. Plus custom matrices via SubstitutionMatrix.from_similarity (Gram penalty s(a,a)+s(b,b)−2·s(a,b)).
  • E-values / significance — calibrate hit counts against a background control repertoire (load_control + evalues), the TCRNET approach on a finite-sample footing. See the E-value guide.
  • Calibrated cutoffsthreshold_for_evalue inverts the E-value into the score cutoff that achieves it, per query. A fixed cutoff is not a calibrated one: a control repertoire is dense near germline and sparse among rare junctions, so the same threshold buys a common query far more chance neighbours than a rare one.
  • Gap-block alignmentgapblock restricts alignment to one contiguous indel, which is the right model for a V(D)J junction and, measured against unrestricted affine alignment, is exactly optimal on 98.8% of genuinely related pairs at a calibrated gap_open. A gap prior (central_prior, profile_prior, frame_prior) chooses where the block goes — a sequence score alone cannot. score_matrix scores a whole query set against a whole reference set in one GIL-released C++ call (532 M pairs/s on 16 cores; numpy.asarray wraps the result with no copy), the shape a prototype-distance embedding needs.
  • Pairwise alignment without BioPythonseqtree.pairwise is Needleman–Wunsch (mode="global") and Smith–Waterman (mode="local") with affine or linear gaps, on the raw log-odds scale. It is a drop-in for Bio.Align.PairwiseAligner — verified against it as an oracle across three matrices, ten gap/mode settings and sixty sequence shapes with zero disagreements — and 65–87× faster, since there is no Python in the per-pair loop. dist_matrix gives d = s(a,a) + s(b,b) − 2·s(a,b) directly. BioPython is a test-only dependency; seqtree still needs nothing at runtime.
  • Plain edit distancesseqtree.distance is unweighted hamming and levenshtein (unit costs, no matrix, no alphabet) for when you just need a number, not a scored alignment. hamming_matrix / levenshtein_matrix score a whole set against a whole set in one GIL-released C++ call (numpy.asarray wraps the result with no copy) — no python-Levenshtein or rapidfuzz dependency needed. Hamming requires equal lengths (it raises otherwise); comparison is case-sensitive.
  • Island profilesIslandProfile.fit builds a position weight matrix over a set of frame-aligned junctions (an island) and scores a query column by column against the island consensus, as a non-negative penalty that flows through threshold_for_evalue unchanged. At a repertoire-scale cutoff it recovers 48.5% of held-out members against 37.6% for min-over-members; at a loose cutoff the two are indistinguishable, so it earns its keep only where the cutoff is strict.

Install

pip install seqtree       # prebuilt wheels for CPython 3.10–3.13

Prebuilt wheels cover Linux x86-64, macOS arm64 (Apple Silicon), and Windows x86-64. There are no Intel/x86-64 macOS wheels — Intel Macs build from source (see below), which just needs a C++17 compiler and CMake (pulled in automatically by the build).

Build from source

bash setup.sh            # repo-local .venv + editable install
bash setup.sh --tests    # + pytest
bash setup.sh --bench     # + benchmark deps (huggingface_hub, psutil)

Quickstart

import seqtree

idx = seqtree.Index.build(["CASSLAPGATNEKLFF", "CASSLELGATNEKLFF"], alphabet="aa")

p = seqtree.SearchParams(max_subs=2, engine="seqtm")
for hit in idx.search("CASSLAPGATNEKLFF", p):
    print(hit.ref_id, hit.score, hit.n_subs)

# parallel batch (releases the GIL)
results = idx.search_batch(queries, p, threads=0)   # 0 = all cores

# matrix-weighted budget
pm = seqtree.SearchParams(matrix="BLOSUM62", max_penalty=12, engine="seqtrie")
top = idx.search_top("CASSLAPGATNEKLFF", pm, k=5)

# alignment on demand
aln = idx.align(0, "CASSLELGATNEKLFF", p)
print(aln.aligned_query, aln.aligned_ref, aln.ops)

# batch-vs-batch (auto-indexes the larger set)
pairs = seqtree.pairwise_batch(query_set, db_set, p, alphabet="aa")

# E-values against a background control repertoire (TCRNET-style significance)
control = seqtree.load_control("human_trb_aa", size=1_000_000)
target = seqtree.Index.build(vdjdb_cdr3s, alphabet="aa")
for q, r in zip(queries, seqtree.evalues(target, control, queries, p)):
    if r["p_enrichment"] < 1e-3:
        print(q, r["E"], r["n_target"], r["n_control"])

# ...and the cutoff that achieves a target E, per query (-1 = unreachable at this control size)
ceiling = seqtree.SearchParams(max_subs=14, max_penalty=50, matrix="BLOSUM62", engine="seqtm")
thetas = seqtree.threshold_for_evalue(target, control, queries, ceiling, e_target=0.05)

# one contiguous gap block, placed by a prior rather than by the score alone
from seqtree.gapblock import GapBlockIndex, central_prior, embed_in_frame

gbi = GapBlockIndex(cdr3s, "aa", d_max=2)
mat = seqtree.SubstitutionMatrix.blosum62()
for ref_id, score, block_len, block_pos in gbi.search(
        "CASSLGQAYEQYF", 40, mat, gap_open=2 * mat.scale(),
        gap_prior=central_prior(int(1.5 * mat.scale()))):
    ...

# a fixed frame column makes gap placement transitive -- and a column index, hence a PWM, possible
embed_in_frame("CASSGQAYEQYF", width=14, c=4)      # 'CASS--GQAYEQYF'

# a whole query set vs a whole reference set, in one GIL-released C++ call
from seqtree.gapblock import score_matrix, IslandProfile
sm = score_matrix(clonotypes, prototypes, mat, gap_open=2 * mat.scale(), threads=0)
import numpy as np
distances = np.asarray(sm)                          # (len(clonotypes), len(prototypes)) int32, zero-copy

# a position weight matrix over an island, still a non-negative penalty (feeds threshold_for_evalue)
profile = IslandProfile.fit(island_members)
profile.score("CASSLGQAYEQYF")                      # 0 on the consensus, > 0 for deviations

# ordinary pairwise alignment -- Needleman-Wunsch / Smith-Waterman, no BioPython
from seqtree.pairwise import align, score, dist_matrix
score("CASSLGQAYEQYF", "CASSPGQAYEQF", mat)                    # global, BLAST defaults (11/1)
score("WWWAAAWWW", "KKKAAAKKK", mat, mode="local")             # Smith-Waterman
score("AAA", "AAAAA", mat, gap_open=5, gap_extend=5)           # linear gaps: open == extend
aln = align("CASSLGQAYEQYF", "CASSPGQAYEQF", mat)              # + aligned strings and ops

d = np.asarray(dist_matrix(v_genes, v_genes, mat, threads=0))  # s(a,a)+s(b,b)-2s(a,b), zero diagonal

# plain edit distances -- unweighted Hamming / Levenshtein, no matrix, no dependency
from seqtree.distance import hamming, levenshtein, hamming_matrix, levenshtein_matrix
hamming("CASSLGQYF", "CASSPGQYF")                             # 1  (equal length only)
levenshtein("kitten", "sitting")                             # 3
h = np.asarray(hamming_matrix(umis, umis, threads=0))        # (len, len) int32, zero-copy

Tests

cmake -S . -B build -G Ninja -DSEQTREE_TESTS=ON
cmake --build build
ctest --test-dir build           # C++ unit tests
pytest tests/python              # Python tests

Benchmarks

python bench/bench_gnuplot.py        # throughput / scaling / matrix / collisions → SVG (needs gnuplot)
python bench/bench.py                # recall vs ground truth (real VDJdb data)
python bench/bench_evalue.py         # true E-value benchmark (target vs background control)
python bench/bench_evalue_matrix.py  # significance across reference/control/query/scope grid
python bench/bench_epitope.py        # epitope detection-complexity (GIL vs NLV)
python bench/bench_gapblock.py       # the gap-freedom ladder: fixed centre → prior → flat → affine
python bench/bench_score_matrix.py   # dense batch gap-block throughput (µs/pair, M pairs/s, RSS)

Figures (throughput, scaling, matrix-scoring overhead, collisions, E-value matrix, epitope detection) and the full methodology are in the benchmarks docs. Set RUN_BENCHMARK=1 for the large tiers.

Development

This repo follows git-flow:

  • master — stable, release-ready; CI + docs deploy run here.
  • dev — integration branch for day-to-day work.
  • feature branches branch off dev and merge back via PR; releases merge devmaster.

Roadmap (affine gaps, position-specific matrices, succinct memory packing) lives in docs/roadmap.rst. Control-set E-values already ship — see the E-value guide.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

seqtree-0.5.0.tar.gz (1.8 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

seqtree-0.5.0-cp313-cp313-win_amd64.whl (1.6 MB view details)

Uploaded CPython 3.13Windows x86-64

seqtree-0.5.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.8 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

seqtree-0.5.0-cp313-cp313-macosx_11_0_arm64.whl (1.6 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

seqtree-0.5.0-cp312-cp312-win_amd64.whl (1.6 MB view details)

Uploaded CPython 3.12Windows x86-64

seqtree-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.8 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

seqtree-0.5.0-cp312-cp312-macosx_11_0_arm64.whl (1.6 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

seqtree-0.5.0-cp311-cp311-win_amd64.whl (1.6 MB view details)

Uploaded CPython 3.11Windows x86-64

seqtree-0.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.8 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

seqtree-0.5.0-cp311-cp311-macosx_11_0_arm64.whl (1.6 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

seqtree-0.5.0-cp310-cp310-win_amd64.whl (1.6 MB view details)

Uploaded CPython 3.10Windows x86-64

seqtree-0.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.8 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

seqtree-0.5.0-cp310-cp310-macosx_11_0_arm64.whl (1.6 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

Details for the file seqtree-0.5.0.tar.gz.

File metadata

  • Download URL: seqtree-0.5.0.tar.gz
  • Upload date:
  • Size: 1.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for seqtree-0.5.0.tar.gz
Algorithm Hash digest
SHA256 28cf00a64dba792b6c4b0f61d95db0cbf8e5f7695f594ac4faddf635f193e4d4
MD5 5f54222a4d74b9235508a3f053d7b52f
BLAKE2b-256 8dbb97d131c1657967462bd90581fa8a2cb1300ff4e3989841c21be069e1a51a

See more details on using hashes here.

Provenance

The following attestation bundles were made for seqtree-0.5.0.tar.gz:

Publisher: publish.yml on antigenomics/seqtree

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seqtree-0.5.0-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: seqtree-0.5.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 1.6 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for seqtree-0.5.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 8f8b6ace0fc78de8686c047ae82780e8a6d3d8e6b15f5185df5b54af4ca7a0a0
MD5 38081ce87ee59b01fe27a563fe21bfee
BLAKE2b-256 dfac588569f01c1e5020d3829419a4d1f7c4be798798e5604b85682712bb5415

See more details on using hashes here.

Provenance

The following attestation bundles were made for seqtree-0.5.0-cp313-cp313-win_amd64.whl:

Publisher: publish.yml on antigenomics/seqtree

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seqtree-0.5.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for seqtree-0.5.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9ae3823430036e379cfdf0e3a48d4d6634245549c4660cb71b028b73d9ca9757
MD5 1cb5a53d151b2001dffc45188d311eb1
BLAKE2b-256 3ccf5c819fa6d8851aa61b7b8d216a915dff9c1182275c4ff30dba3638f55aa0

See more details on using hashes here.

Provenance

The following attestation bundles were made for seqtree-0.5.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on antigenomics/seqtree

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seqtree-0.5.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for seqtree-0.5.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 719e5494b8ba9103957364b1fd4dc7b8666b670bfc208e2e4dc196e712d3cbf0
MD5 06e0e4b6572228318180cbc8389d1a1c
BLAKE2b-256 92882df63a4a3270170008aeb5541544d73d48c3c0f40487e280624467a30fd2

See more details on using hashes here.

Provenance

The following attestation bundles were made for seqtree-0.5.0-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: publish.yml on antigenomics/seqtree

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seqtree-0.5.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: seqtree-0.5.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 1.6 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for seqtree-0.5.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 e76dd232df4f040b5af585a22294e47f56e52df976a0b4d7af05b9e4f06c92be
MD5 c02c131b86d0538f184d2d17b4576913
BLAKE2b-256 039049364531c6b82a9fbf711e058bd47c0e4665435ae59db814113463715841

See more details on using hashes here.

Provenance

The following attestation bundles were made for seqtree-0.5.0-cp312-cp312-win_amd64.whl:

Publisher: publish.yml on antigenomics/seqtree

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seqtree-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for seqtree-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 30c64c0fa61d41965172b519b1986a53c281bce612e526fe6c9b3db3310cd5b8
MD5 8f79ebdbf7f8edf4036986c78e8de9fb
BLAKE2b-256 d1407625047920ac48dffaeaf98fe207a528cd8bbabb67f47adcb54b920c3b6e

See more details on using hashes here.

Provenance

The following attestation bundles were made for seqtree-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on antigenomics/seqtree

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seqtree-0.5.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for seqtree-0.5.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3439587f2280a1884e791c51bf600570d89a1baaab18866a439fbfe2fd91886c
MD5 2b1d18222414e60f4addc17ad9ce4c6c
BLAKE2b-256 89ac9e0676ac19dbf7cebadf1a9cc32d326473de0e78e770749491d8c6a11a92

See more details on using hashes here.

Provenance

The following attestation bundles were made for seqtree-0.5.0-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: publish.yml on antigenomics/seqtree

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seqtree-0.5.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: seqtree-0.5.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 1.6 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for seqtree-0.5.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 4b284e23ac777a0676881f30ad17a63712cf8ec79af4491f8430c8fe1b69d70e
MD5 d115d62dcf2bbd0429efb6947b9af747
BLAKE2b-256 48608a85c00e9b09000b631b50d51f30a41338cdd2be7304a4a4fba7a1d0c7f3

See more details on using hashes here.

Provenance

The following attestation bundles were made for seqtree-0.5.0-cp311-cp311-win_amd64.whl:

Publisher: publish.yml on antigenomics/seqtree

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seqtree-0.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for seqtree-0.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 dc520be776adee59eaad547b5fe392fdde639204e72e3b45b14df1108f7614b0
MD5 c07dc01e56b2e04c25a8714514c70264
BLAKE2b-256 2484b06c02564cbd1de058a4552042c9b34c52ac23001a7e27a34dee1e373943

See more details on using hashes here.

Provenance

The following attestation bundles were made for seqtree-0.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on antigenomics/seqtree

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seqtree-0.5.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for seqtree-0.5.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 51e3929423676d40e0f21669b4961be93c4c81307a786ae0f42ef534ba7d4e1e
MD5 27f2e266089730dbf2624e5e1a509479
BLAKE2b-256 dd86779fa8458ea2738b9f7a1bd0f8eeb401a6388d39fa8bb7a771909e917b9e

See more details on using hashes here.

Provenance

The following attestation bundles were made for seqtree-0.5.0-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: publish.yml on antigenomics/seqtree

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seqtree-0.5.0-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: seqtree-0.5.0-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 1.6 MB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for seqtree-0.5.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 7b64f3328ec7355fcfb69bfbb74d7c01429ef37e21a62979996676059337fe16
MD5 bfb5da51bda93e0866d66ecd06c2204e
BLAKE2b-256 e46be7cf74f3785409f8d6f0be7193c18f67d73f8bbd90ec94bd9c44c107c11c

See more details on using hashes here.

Provenance

The following attestation bundles were made for seqtree-0.5.0-cp310-cp310-win_amd64.whl:

Publisher: publish.yml on antigenomics/seqtree

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seqtree-0.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for seqtree-0.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 45b5d026e8f9afbe28cf4cc70d38d1aecab80bd1248a6d65adea1aa8fb6c8f72
MD5 0c5838f4ecb47d12f91b1b8d66664759
BLAKE2b-256 47447240cddad9de156c292aae97b2c33d7162ca0fee59a4ceed232c8bc33012

See more details on using hashes here.

Provenance

The following attestation bundles were made for seqtree-0.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on antigenomics/seqtree

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seqtree-0.5.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for seqtree-0.5.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 80168668be4d31db61170308ebdbf78d8ca0b91dcb1e95d6081b0aad6ccac7ea
MD5 26b7d8af16ffe56aabd224d9b6ed1c7c
BLAKE2b-256 d2cec58f6842cfdb8d429d362e1d86d2469afcc1fcd1506c73ec9c4f3d5a3682

See more details on using hashes here.

Provenance

The following attestation bundles were made for seqtree-0.5.0-cp310-cp310-macosx_11_0_arm64.whl:

Publisher: publish.yml on antigenomics/seqtree

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page