Skip to main content

vastlint (Python)

High-performance, in-process VAST XML validation for Python backends.

Rule reference: vastlint.org/docs/rules · Web validator: vastlint.org/validate · Test a live tag URL: vastlint.org/tester · Inspect wrapper chains: vastlint.org/inspect

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())

Need a link instead of raw output? The vastlint CLI can upload a validation report (rule IDs, severities, and locations; never the input XML) and print a public URL you can paste into Slack, tickets, or PRs:

vastlint check tag.xml --share
# https://vastlint.org/r/<id>

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.dylib
  • src/vastlint/native/darwin_amd64/libvastlint.dylib
  • src/vastlint/native/linux_arm64/libvastlint.so
  • src/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.

Metadata

Release files for vastlint 0.14.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 vastlint 0.14.5
File Size Uploaded Provenance
vastlint-0.14.5.tar.gz 2.1 MB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for vastlint 0.14.5
File Interpreter ABI Platform
vastlint-0.14.5-py3-none-any.whl Python 3 none any Details

Total release size: 4.2 MB

Release files / vastlint-0.14.5.tar.gz

Download URL vastlint-0.14.5.tar.gz
Size 2.1 MB
Tags Source
SHA-256 checksum
How to use checksums
87ba8a00cc276aa7da76232f1066783a04833f7623c1261c1acb5b2bcdf6ff19
BLAKE2b-256 checksum
How to use checksums
5a56b924ce386d4e53fd4df2712cb4701aad54c563e3a6092fd95a91130843d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 13, 2026.

Transparency log

Release files / vastlint-0.14.5-py3-none-any.whl

Download URL vastlint-0.14.5-py3-none-any.whl
Size 2.1 MB
Tags Python 3
SHA-256 checksum
How to use checksums
5574b4f5b2bc498fbcb07f75c1a14facfe5677673e0a1f8cfa579e9ad91bb627
BLAKE2b-256 checksum
How to use checksums
80eca49b03f2fcb410e135608a4b12b7f6a4f4df051e0ee271d14fd4a606b6c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 13, 2026.

Transparency log

Security for vastlint 0.14.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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for vastlint-0.14.5.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 13, 2026.

Transparency log

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.

Release history Release notifications | RSS feed

This release

0.14.5 This release

2 release files Full provenance

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