In-process Python bindings for vastlint VAST XML validation
Project description
vastlint (Python)
High-performance, in-process VAST XML validation for Python backends.
Rule reference: vastlint.org/docs/rules · Web validator: vastlint.org/validate
This package wraps the stable vastlint-ffi C API, backed by the same Rust core used by the CLI, Go binding, Ruby gem, Erlang NIF, MCP server, and web validator. The intended use case is a DSP, SSP, ad server, or trafficking backend that needs to validate VAST XML and return structured linting results to a frontend.
Why this shape
- No subprocess management in your Python app
- No network hop to an external validation service
- Stable JSON-compatible result shape for backend-to-frontend responses
- Same rule coverage and behavior as the rest of the vastlint ecosystem
Install
The package bundles a platform-matched libvastlint shared library inside the wheel, so no compiler or Rust toolchain is needed at install time.
pip install vastlint
You can also point the package at an explicit shared library with VASTLINT_LIB_PATH:
export VASTLINT_LIB_PATH=/absolute/path/to/libvastlint.dylib
For development in this monorepo, it automatically falls back to the sibling vastlint/target/debug and vastlint/target/release outputs.
Usage
import vastlint
result = vastlint.validate(vast_xml)
if result.valid:
print("clean tag")
else:
print(result.summary.errors)
print(result.issues[0].message)
print(result.to_json())
FastAPI / Flask example
from fastapi import FastAPI
from pydantic import BaseModel
import vastlint
app = FastAPI()
class ValidateRequest(BaseModel):
xml: str
wrapper_depth: int = 0
max_wrapper_depth: int = 5
rule_overrides: dict[str, str] | None = None
@app.post("/validate")
def validate(req: ValidateRequest):
result = vastlint.validate(
req.xml,
wrapper_depth=req.wrapper_depth,
max_wrapper_depth=req.max_wrapper_depth,
rule_overrides=req.rule_overrides,
)
return result.to_dict()
The response shape is stable and frontend-friendly:
{
"version": "4.2",
"issues": [
{
"id": "VAST-2.0-inline-impression",
"severity": "error",
"message": "<InLine> must contain at least one <Impression>",
"path": "/VAST/Ad[0]/InLine",
"spec_ref": "IAB VAST 2.0 §2.2.1",
"line": 4,
"col": 3
}
],
"summary": { "errors": 1, "warnings": 0, "infos": 0, "valid": false }
}
API
vastlint.validate(xml, *, wrapper_depth=0, max_wrapper_depth=5, rule_overrides=None) -> Result
vastlint.version() -> str
xml accepts str or bytes. rule_overrides maps rule IDs to severity levels:
result = vastlint.validate(
vast_xml,
rule_overrides={
"VAST-2.0-mediafile-https": "error",
"VAST-4.1-mezzanine-recommended": "off",
},
)
Result exposes .version, .issues (list of Issue), .summary (Summary), .valid, .to_dict(), and .to_json(). All result types are frozen dataclasses.
Performance
Validation runs in-process against the Rust core, so per-tag cost is dominated by the core, not by Python. Numbers below are single-core, single-threaded, and include the full Python round trip (FFI call, JSON result, parse into dataclasses), so they reflect what a caller actually sees.
| Tag size | Median latency | Throughput (1 core) |
|---|---|---|
| 7 KB | 86 µs | ~11,000 tags/sec |
| 17 KB | 0.36 ms | ~2,800 tags/sec |
| 23 KB | 0.57 ms | ~1,700 tags/sec |
| 44 KB | 2.1 ms | ~470 tags/sec |
| 347 KB | 4.7 ms | ~210 tags/sec |
Measured on an Apple M4, single core, 200 tags per size bucket, warm. Production tags typically run 17 to 44 KB. Each validation is independent and holds no shared state, so throughput scales close to linearly across cores with a process pool. Reproduce with scripts/bench.py.
Native library layout
Vendored release libraries live at:
src/vastlint/native/darwin_arm64/libvastlint.dylibsrc/vastlint/native/darwin_amd64/libvastlint.dylibsrc/vastlint/native/linux_arm64/libvastlint.sosrc/vastlint/native/linux_amd64/libvastlint.so
They come from the vastlint-ffi-* tarballs attached to each vastlint GitHub Release. Refresh them with:
./scripts/fetch-libs.sh v0.4.14
License
Apache 2.0.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vastlint-0.6.1.tar.gz.
File metadata
- Download URL: vastlint-0.6.1.tar.gz
- Upload date:
- Size: 1.9 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c9e24c5692ecab3d771f47ec95bb2185b9a08f16126c86d9314c1526cd295726
|
|
| MD5 |
7013b451ab85f85efaaa2d8c0c82d742
|
|
| BLAKE2b-256 |
123e8d1a249d7df6edca3335194be0021a33df2d3204090ed7b52dfb9bb3aeb8
|
Provenance
The following attestation bundles were made for vastlint-0.6.1.tar.gz:
Publisher:
publish-pypi.yml on aleksUIX/vastlint-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vastlint-0.6.1.tar.gz -
Subject digest:
c9e24c5692ecab3d771f47ec95bb2185b9a08f16126c86d9314c1526cd295726 - Sigstore transparency entry: 1876066711
- Sigstore integration time:
-
Permalink:
aleksUIX/vastlint-python@7e233ed44ae7934587baa6c2b6348fdad7a3d91a -
Branch / Tag:
refs/tags/v0.6.1 - Owner: https://github.com/aleksUIX
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@7e233ed44ae7934587baa6c2b6348fdad7a3d91a -
Trigger Event:
push
-
Statement type:
File details
Details for the file vastlint-0.6.1-py3-none-any.whl.
File metadata
- Download URL: vastlint-0.6.1-py3-none-any.whl
- Upload date:
- Size: 1.9 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e25fd4b49dafcb350bb5b0f711f5d46e4f8f7e2e93e9e47e2ff9542dc6bb5ffb
|
|
| MD5 |
3bf5a48eb72f8999586d47d8863fb3ad
|
|
| BLAKE2b-256 |
c57957cd76d071e6eca2ca0f53ee11c094d925f624fe2241abf708332713a6fb
|
Provenance
The following attestation bundles were made for vastlint-0.6.1-py3-none-any.whl:
Publisher:
publish-pypi.yml on aleksUIX/vastlint-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vastlint-0.6.1-py3-none-any.whl -
Subject digest:
e25fd4b49dafcb350bb5b0f711f5d46e4f8f7e2e93e9e47e2ff9542dc6bb5ffb - Sigstore transparency entry: 1876066848
- Sigstore integration time:
-
Permalink:
aleksUIX/vastlint-python@7e233ed44ae7934587baa6c2b6348fdad7a3d91a -
Branch / Tag:
refs/tags/v0.6.1 - Owner: https://github.com/aleksUIX
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@7e233ed44ae7934587baa6c2b6348fdad7a3d91a -
Trigger Event:
push
-
Statement type: