Python bindings for the vacant Rust engine. Asks the authoritative TLD nameservers directly instead of WHOIS — fast, no rate limits, no waiting.
The wheel ships the same Rust engine compiled in, with a small Python facade and a vacant CLI entry point. Lockstep-versioned with the vacant crate: vacant 0.3.x (Python) wraps vacant 0.3.x (Rust) exactly.
Pick the path that matches how you'll use it:
brew install alltuner/tap/vacant # macOS, Linux — native Rust binary
cargo install vacant # any platform with a Rust toolchain
uvx vacant google.com # one-shot, no install (Python wheel)The brew / cargo paths give you the native Rust binary (instant startup, ideal for daily use). uvx runs the Python wheel — convenient when you don't want to install anything, slightly slower to start because it boots a Python interpreter.
pip install vacant
# or with uv:
uv add vacantfrom vacant import check_many, Status
results = check_many(["example.com", "anthropic.com", "totally-made-up-zxqv.cat"])
for r in results:
print(r.domain, r.status.value, r.detail)The on-disk SQLite cache is shared with the Rust CLI — runs against the same ~/.cache/vacant/results.db, so the brew binary and a Python script see each other's results.
from vacant import DiskCache, check_many
cache = DiskCache() # default ~/.cache/vacant/results.db
results = check_many(["example.com"], cache=cache)vacant.check_many calls into the Rust engine via PyO3 (vacant._core). The engine:
- Normalizes the input.
- Looks up cache; returns hits immediately.
- Runs a per-zone precheck (length, charset, reserved labels) from the bundled
rules.toml. - For inputs that pass, asks the parent zone's NS directly. Delegation →
registered; NXDOMAIN/NODATA →unconfirmed(not delegated, not verified). Passverify=Trueto confirmunconfirmednames against the registry's RDAP endpoint, promoting them toavailable(404) orregistered(200, e.g. a held domain).availableonly ever means RDAP-confirmed.
Cache shape, rules format, and verdict semantics are all the engine's — see alltuner/vacant for the source of truth.
The Python package lives in the alltuner/vacant monorepo alongside the Rust engine, so dev commands run from the repo root:
just # menu
just py-develop # build the maturin extension into the local venv
just py-check # ruff + pytest
just py-wheel # build a release wheel locallyMIT — see ../LICENSE.