Skip to main content

vecxx

Python Build Status Node.js Build Status

Fast C++ implementations of vectorizers for machine learning models, with bindings in Python and JS/TS.

This includes a straighforward, cross-platform C++ implementation of common approaches to vectorization to integers, required for most types of DNNs to convert sentences into tensors. It also supports native subword BPE based on fastBPE with additional support for preprocessing transforms of strings during decode, either as native functors or from the bound languages. It also supports extra (special) tokens that can be passed through.

For BPE, the library supports execution of models that were trained either using subword-nmt or fastBPE (or any other system which shares the file format).

To support fast load times, vecxx vocabs can be compiled to a perfect hash and persisted to disk. When constructing the objects from the compiled directory, the loading will use memory mapping. For a BPE vocab, a non-compiled load that takes 24 milliseconds, may take only 200 microseconds after compilation.

Handling of prefix and suffix tokens

The API supports passing in a vector of tokens for prefixing the data, and for suffixing. These are passed as a [] in Python, and std::vector<std::string> in C++. Note that for prefixing, the prefix tokens will always be present, but when converting to integer ids, if the output buffer is presized and is too short to fill the tokens, the library currently will not overwrite the last values in the buffer to the end tokens. The rationale is that, typically an end suffix will be something marking an end-of-sentence or utterance, but since the result is truncated, the end was not actually reached. Future versions of the library may change this

Handling of multiple input sentences

The library supports converting multiple sentences into a "stack" of tokens with a fixed output size. This may be useful for batching or using N-best lists as input. The results from the ID stack are contiguous 1D arrays. They will typically be reshaped in user code:

nbests = [t.split() for t in text]
ids, lengths = vec.convert_to_ids_stack(nbests, len(nbests)*args.mxlen)
ids = np.array(ids).reshape(1, len(nbests), -1)
example = {args.feature: ids, 'lengths': np.array(lengths).reshape(1, -1)}

C++

#include "vecxx/vecxx.h"

std::vector<std::string> SENTENCE = {
	"My", "name", "is", "Dan", ".", "I", "am", "from", "Ann", "Arbor",
	",", "Michigan", ",", "in", "Washtenaw", "County"
};

int main(int argc, char** argv) {
    std::string vocab_file(argv[1]);
    std::string codes_file(argv[2]);
    auto v = new BPEVocab(vocab_file, codes_file);
    VocabVectorizer vec(v);
    for (auto p : vec.convert_to_pieces(SENTENCE)) {
    	std::cout << p << std::endl;
    }

    std::vector<int> ids;
    int l;
    std::tie(ids, l) = vec.convert_to_ids(SENTENCE);
    for (auto p : ids) {
    	std::cout << p << std::endl;
    }

    delete v;
    return 0;
}

Vocab compilation

The initial load of the vocab is typically relatively fast, as it just reads in text files. However, if we need much lower latency, we can optionally compile the internal data structures to memory-mapped perfect hashes.

Once compiled pass the compiled target folder in as both the vocab_file and codes_file.

  auto v = new BPEVocab(vocab_file, codes_file);
  v->compile_vocab(compiled_dir);
  delete v;
  return 0;

Python bindings

The Python bindings are written with pybind11.

You can install the python bindings using pip:

pip install vecxx

Using BPE vectorizer from Python

Converting sentences to lower-case subword BPE tokens as integers from the vocabulary. Note that a python native string transform can be used to transform each token prior to subword tokenization. Tokens from either the BPE vocab or special tokens (like <GO> and <EOS>) can be applied to the beginning and end of the sequence. If a second argument is provided to convert_to_ids this will indicate a padded length required for the tensor

    from vecxx import *
    bpe = BPEVocab(
        vocab_file=os.path.join(TEST_DATA, "vocab.30k"),
        codes_file=os.path.join(TEST_DATA, "codes.30k")
    )
    vec = VocabVectorizer(bpe, transform=str.lower, emit_begin_tok=["<GO>"], emit_end_tok=["<EOS>"])
    padd_vec, unpadded_len = vec.convert_to_ids("My name is Dan . I am from Ann Arbor , Michigan , in Washtenaw County".split(), 256)

The result of this will be:

[1, 30, 265, 14, 2566, 5, 8, 158, 63, 10940, 525, 18637, 7, 3685, 7, 18, 14242, 1685, 2997, 4719, 2, 0, ..., 0]

Vocab compilation

As in the C++ example, we can optionally compile the internal data structures to memory-mapped perfect hashes. Once compiled they can be read in the same way.

>>> import vecxx
>>> b = vecxx.BPEVocab('/data/reddit/vocab.30k', '/data/reddit/codes.30k', extra_tokens=["[CLS]", "[MASK]"])
>>> b.compile_vocab('blah')
>>> b2 = vecxx.BPEVocab('blah', 'blah')

JS/TS bindings

The Javascript bindings are provided by using the Node-API API.

A thin TypeScript wrapper provides a typed API that closely matches the underlying (and Python) APIs.

Using BPE vectorizer from TypeScript

import { BPEVocab, VocabVectorizer } from 'vecxx';
import { join } from 'path';

const testDir = join(__dirname, 'test_data');
const bpe = new BPEVocab(join(testDir, 'vocab.30k'), join(testDir, 'codes.30k'));
const vectorizer = new VocabVectorizer(bpe, {
    transform: (s: string) => s.toLowerCase(),
    emitBeginToken: ['<GO>'],
    emitEndToken: ['<EOS>']
});
const sentence = `My name is Dan . I am from Ann Arbor , Michigan , in Washtenaw County`;
const { ids, size } = vectorizer.convertToIds(sentence.split(/\s+/), 256);

Docker

Sample Dockerfiles are provided that can be used for sandbox development/testing.

docker build -t vecxx-python -f py.Dockerfile .
docker run -it vecxx-python
docker build -t vecxx-node -f node.Dockerfile .
docker run -it vecxx-node
# ...
var vecxx = require('dist/index.js')

Metadata

Release files for vecxx 0.0.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for vecxx 0.0.5
File Size Uploaded Provenance Actions
vecxx-0.0.5.tar.gz 9.6 kB Without provenance Details for vecxx-0.0.5.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for vecxx 0.0.5
File Actions
vecxx-0.0.5-cp39-cp39-manylinux2010_x86_64.whl CPython 3.9 CPython 3.9 Linux glibc 2.12+ x86-64 Details for vecxx-0.0.5-cp39-cp39-manylinux2010_x86_64.whl
vecxx-0.0.5-cp39-cp39-manylinux2010_i686.whl CPython 3.9 CPython 3.9 Linux glibc 2.12+ x86-32 Details for vecxx-0.0.5-cp39-cp39-manylinux2010_i686.whl
vecxx-0.0.5-cp39-cp39-macosx_10_9_x86_64.whl CPython 3.9 CPython 3.9 macOS 10.9+ x86-64 Details for vecxx-0.0.5-cp39-cp39-macosx_10_9_x86_64.whl
vecxx-0.0.5-cp38-cp38-win_amd64.whl CPython 3.8 CPython 3.8 Windows x86-64 Details for vecxx-0.0.5-cp38-cp38-win_amd64.whl
vecxx-0.0.5-cp38-cp38-win32.whl CPython 3.8 CPython 3.8 Windows x86-32 Details for vecxx-0.0.5-cp38-cp38-win32.whl
vecxx-0.0.5-cp38-cp38-manylinux2010_x86_64.whl CPython 3.8 CPython 3.8 Linux glibc 2.12+ x86-64 Details for vecxx-0.0.5-cp38-cp38-manylinux2010_x86_64.whl
vecxx-0.0.5-cp38-cp38-manylinux2010_i686.whl CPython 3.8 CPython 3.8 Linux glibc 2.12+ x86-32 Details for vecxx-0.0.5-cp38-cp38-manylinux2010_i686.whl
vecxx-0.0.5-cp38-cp38-macosx_10_9_x86_64.whl CPython 3.8 CPython 3.8 macOS 10.9+ x86-64 Details for vecxx-0.0.5-cp38-cp38-macosx_10_9_x86_64.whl
vecxx-0.0.5-cp37-cp37m-win_amd64.whl CPython 3.7 CPython 3.7 pymalloc Windows x86-64 Details for vecxx-0.0.5-cp37-cp37m-win_amd64.whl
vecxx-0.0.5-cp37-cp37m-win32.whl CPython 3.7 CPython 3.7 pymalloc Windows x86-32 Details for vecxx-0.0.5-cp37-cp37m-win32.whl
vecxx-0.0.5-cp37-cp37m-manylinux2010_x86_64.whl CPython 3.7 CPython 3.7 pymalloc Linux glibc 2.12+ x86-64 Details for vecxx-0.0.5-cp37-cp37m-manylinux2010_x86_64.whl
vecxx-0.0.5-cp37-cp37m-manylinux2010_i686.whl CPython 3.7 CPython 3.7 pymalloc Linux glibc 2.12+ x86-32 Details for vecxx-0.0.5-cp37-cp37m-manylinux2010_i686.whl
vecxx-0.0.5-cp37-cp37m-macosx_10_9_x86_64.whl CPython 3.7 CPython 3.7 pymalloc macOS 10.9+ x86-64 Details for vecxx-0.0.5-cp37-cp37m-macosx_10_9_x86_64.whl
vecxx-0.0.5-cp36-cp36m-win_amd64.whl CPython 3.6 CPython 3.6 pymalloc Windows x86-64 Details for vecxx-0.0.5-cp36-cp36m-win_amd64.whl
vecxx-0.0.5-cp36-cp36m-win32.whl CPython 3.6 CPython 3.6 pymalloc Windows x86-32 Details for vecxx-0.0.5-cp36-cp36m-win32.whl
vecxx-0.0.5-cp36-cp36m-manylinux2010_x86_64.whl CPython 3.6 CPython 3.6 pymalloc Linux glibc 2.12+ x86-64 Details for vecxx-0.0.5-cp36-cp36m-manylinux2010_x86_64.whl
vecxx-0.0.5-cp36-cp36m-manylinux2010_i686.whl CPython 3.6 CPython 3.6 pymalloc Linux glibc 2.12+ x86-32 Details for vecxx-0.0.5-cp36-cp36m-manylinux2010_i686.whl
vecxx-0.0.5-cp36-cp36m-macosx_10_9_x86_64.whl CPython 3.6 CPython 3.6 pymalloc macOS 10.9+ x86-64 Details for vecxx-0.0.5-cp36-cp36m-macosx_10_9_x86_64.whl

Total release size: 3.3 MB

Release files / vecxx-0.0.5.tar.gz

Download URL vecxx-0.0.5.tar.gz
Size 9.6 kB
Tags Source
SHA-256 checksum
How to use checksums
f3f04147178840793cbe268ac648b8eac23b5ecc96118be3b52e4bec12e10f71
BLAKE2b-256 checksum
How to use checksums
374a286394338986a4e70bbf953c1a8348cdb355b8146262d8009681e996279b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / vecxx-0.0.5-cp39-cp39-manylinux2010_x86_64.whl

Download URL vecxx-0.0.5-cp39-cp39-manylinux2010_x86_64.whl
Size 205.5 kB
Tags CPython 3.9 Linux glibc 2.12+ x86-64
SHA-256 checksum
How to use checksums
6e23bb89a73704b88ff112a60906d1379f9bdcf60967b80729d44a030d588100
BLAKE2b-256 checksum
How to use checksums
3f12e9e5793eba7c469ac50ed6d56b01c5b43f68bc5e395b6dc0d85941854da9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / vecxx-0.0.5-cp39-cp39-manylinux2010_i686.whl

Download URL vecxx-0.0.5-cp39-cp39-manylinux2010_i686.whl
Size 217.5 kB
Tags CPython 3.9 Linux glibc 2.12+ x86-32
SHA-256 checksum
How to use checksums
cc78f1d4f4c0190a30c49088f7e8cb69e3bc22dcc0e3f0ad1c617779a99a7c65
BLAKE2b-256 checksum
How to use checksums
3b7645e3f9aa8f2399e6a5c7c5012f65c3eb5ec4573ad44a6ae81a4497195fa5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / vecxx-0.0.5-cp39-cp39-macosx_10_9_x86_64.whl

Download URL vecxx-0.0.5-cp39-cp39-macosx_10_9_x86_64.whl
Size 189.8 kB
Tags CPython 3.9 macOS 10.9+ x86-64
SHA-256 checksum
How to use checksums
c36c9d3a6793ee5bf22946c40a20c2ebd641d242f02c837187d09ae74df1a7fa
BLAKE2b-256 checksum
How to use checksums
2d6e81a332347d820617779f37383f031f36e20bf6c27e3165210e43cc250dd9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / vecxx-0.0.5-cp38-cp38-win_amd64.whl

Download URL vecxx-0.0.5-cp38-cp38-win_amd64.whl
Size 151.1 kB
Tags CPython 3.8 Windows x86-64
SHA-256 checksum
How to use checksums
6073e542076b1ac505fe9a096382cc42350b23968b69dbd7ff100b66b8cfedaa
BLAKE2b-256 checksum
How to use checksums
21c75db78128ee6875d2d0ade0ad645eb448583c63c8dc8ed49ac57f0156fea5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / vecxx-0.0.5-cp38-cp38-win32.whl

Download URL vecxx-0.0.5-cp38-cp38-win32.whl
Size 130.9 kB
Tags CPython 3.8 Windows x86-32
SHA-256 checksum
How to use checksums
20c3663690a54fd48294a5f071555ded0250708e8254a8a97981a28bbb3206ec
BLAKE2b-256 checksum
How to use checksums
a82365bea1fad30375612be34a41879545afccd4b45d529177c51283196a1e44
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / vecxx-0.0.5-cp38-cp38-manylinux2010_x86_64.whl

Download URL vecxx-0.0.5-cp38-cp38-manylinux2010_x86_64.whl
Size 205.2 kB
Tags CPython 3.8 Linux glibc 2.12+ x86-64
SHA-256 checksum
How to use checksums
a3e0ca51d4a41bddfb693ba5f545c5e175326731fceced3098560a3cb502d3d2
BLAKE2b-256 checksum
How to use checksums
f4e7221a85b8ce1e502a9b1cd5837c624a4c238aadcbde3ba47574a923a24e19
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / vecxx-0.0.5-cp38-cp38-manylinux2010_i686.whl

Download URL vecxx-0.0.5-cp38-cp38-manylinux2010_i686.whl
Size 216.8 kB
Tags CPython 3.8 Linux glibc 2.12+ x86-32
SHA-256 checksum
How to use checksums
b7932f349cd18a96979b41aa72433f6c80e45a74707415f6f20d5c42c224ad1e
BLAKE2b-256 checksum
How to use checksums
d7865678a0724e6d3473a126708db1b747925a2bdb609c9c594368e844fa6350
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / vecxx-0.0.5-cp38-cp38-macosx_10_9_x86_64.whl

Download URL vecxx-0.0.5-cp38-cp38-macosx_10_9_x86_64.whl
Size 189.5 kB
Tags CPython 3.8 macOS 10.9+ x86-64
SHA-256 checksum
How to use checksums
396e1656108fce294e4f8478761a000a89f4c8c9820f06f5055a628c64ae6916
BLAKE2b-256 checksum
How to use checksums
ce1ce66e5f9997e9f7ad4657ca5a484450adb7d36730c019408087f5760b0866
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / vecxx-0.0.5-cp37-cp37m-win_amd64.whl

Download URL vecxx-0.0.5-cp37-cp37m-win_amd64.whl
Size 151.4 kB
Tags CPython 3.7 CPython 3.7 pymalloc Windows x86-64
SHA-256 checksum
How to use checksums
ded4ff9a9a40d9bfb475acb2f00c6d954768fbc3e88c58bc115394fb4ffd72c0
BLAKE2b-256 checksum
How to use checksums
056f1399dde7a7da746f42a2e25e31ab468b3df8ae80b5ab474a8a3add5b0d98
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / vecxx-0.0.5-cp37-cp37m-win32.whl

Download URL vecxx-0.0.5-cp37-cp37m-win32.whl
Size 132.1 kB
Tags CPython 3.7 CPython 3.7 pymalloc Windows x86-32
SHA-256 checksum
How to use checksums
b58a684dc01b762df86a79d2b5ef6897f7b4753462c3824b567fa9893dfc8792
BLAKE2b-256 checksum
How to use checksums
29aed65c5793920cef1387f8991394e670a83c31752c74c92586accc404cb6f7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / vecxx-0.0.5-cp37-cp37m-manylinux2010_x86_64.whl

Download URL vecxx-0.0.5-cp37-cp37m-manylinux2010_x86_64.whl
Size 210.0 kB
Tags CPython 3.7 CPython 3.7 pymalloc Linux glibc 2.12+ x86-64
SHA-256 checksum
How to use checksums
70121253657d0fcbc4df73c3480a79d4cb0bed32dfd34a86ac1242d1d3e475da
BLAKE2b-256 checksum
How to use checksums
69d49499ed6331b02d2b80225aee1c0aec2d5dead06231d0e3acd712e5ee8a61
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / vecxx-0.0.5-cp37-cp37m-manylinux2010_i686.whl

Download URL vecxx-0.0.5-cp37-cp37m-manylinux2010_i686.whl
Size 223.7 kB
Tags CPython 3.7 CPython 3.7 pymalloc Linux glibc 2.12+ x86-32
SHA-256 checksum
How to use checksums
f2e76da9b54c41d37dd569a725b0f1c96496bc108c039d7a15c0b56999271c2b
BLAKE2b-256 checksum
How to use checksums
22285501ec038768da55f63fec0b89eb171e00cde325a1b3787d3163e2a3995e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / vecxx-0.0.5-cp37-cp37m-macosx_10_9_x86_64.whl

Download URL vecxx-0.0.5-cp37-cp37m-macosx_10_9_x86_64.whl
Size 187.0 kB
Tags CPython 3.7 CPython 3.7 pymalloc macOS 10.9+ x86-64
SHA-256 checksum
How to use checksums
5433efb1a2ea547a6b834a13dcd7be140cc76658a718459b59d8f0c0f181449b
BLAKE2b-256 checksum
How to use checksums
d8bafa0da3b1b20fa9dda9716bdedaa065284835d41f687a2f24dc92894759dd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / vecxx-0.0.5-cp36-cp36m-win_amd64.whl

Download URL vecxx-0.0.5-cp36-cp36m-win_amd64.whl
Size 152.7 kB
Tags CPython 3.6 CPython 3.6 pymalloc Windows x86-64
SHA-256 checksum
How to use checksums
8b568c253164dc0096186d79088806715a1fce67900011ebbc13909f05cf60db
BLAKE2b-256 checksum
How to use checksums
5dba42120f3039708f359ab69f2eb4270f28f3fef47a3dec3fb425044b1a393a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / vecxx-0.0.5-cp36-cp36m-win32.whl

Download URL vecxx-0.0.5-cp36-cp36m-win32.whl
Size 133.2 kB
Tags CPython 3.6 CPython 3.6 pymalloc Windows x86-32
SHA-256 checksum
How to use checksums
34efff26b01ccce68b3345293b36d7f41dbedd9138cd016bafcece7860c353bb
BLAKE2b-256 checksum
How to use checksums
fdd0680a9cab7ef202efb44c40b1c893d1f2bdf664ce1dae18f5f92d83d6deea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / vecxx-0.0.5-cp36-cp36m-manylinux2010_x86_64.whl

Download URL vecxx-0.0.5-cp36-cp36m-manylinux2010_x86_64.whl
Size 210.0 kB
Tags CPython 3.6 CPython 3.6 pymalloc Linux glibc 2.12+ x86-64
SHA-256 checksum
How to use checksums
cff1dd8e241a466f42e5b852975d0d787d1bdcf2eede05bf0bb071bd898a58cb
BLAKE2b-256 checksum
How to use checksums
d64fe7c7bad432c94fcbe2b41f53e525a8a04d12ab39dc0983b31340212941a4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / vecxx-0.0.5-cp36-cp36m-manylinux2010_i686.whl

Download URL vecxx-0.0.5-cp36-cp36m-manylinux2010_i686.whl
Size 223.7 kB
Tags CPython 3.6 CPython 3.6 pymalloc Linux glibc 2.12+ x86-32
SHA-256 checksum
How to use checksums
6c9df46c6de495f14949fae832d6d48e5a77f65040b39736fdf41f843b39e8e0
BLAKE2b-256 checksum
How to use checksums
c5cfca2c149c6ba111f0c793f5864b9ffe84acd7799754bc2c24187eb2f6e5b7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / vecxx-0.0.5-cp36-cp36m-macosx_10_9_x86_64.whl

Download URL vecxx-0.0.5-cp36-cp36m-macosx_10_9_x86_64.whl
Size 187.1 kB
Tags CPython 3.6 CPython 3.6 pymalloc macOS 10.9+ x86-64
SHA-256 checksum
How to use checksums
57cf7f5edf0a0812a65710594f5c3cbf918c47eb211d86021f61d1ae3fc101d0
BLAKE2b-256 checksum
How to use checksums
9bf19c5c52cbc5307e646449b2807d3b0b95cf6300092150ff9810f3ae3087df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Security for vecxx 0.0.5

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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page