docsv0.5.1

Module urna

The urna Python package in 0.5.1, its seven public names, what the pip wheel ships, what needs a repo checkout, and how to install it.

The urna package opens, searches and builds .urna files from Python. It is a pyo3 binding over the same Rust reader and writer the urna binary uses, so a file built in Python opens in the CLI and the other way around.

Install

pip install "urna[embed]"
FactValue
Distributionurna on PyPI
Version0.5.1 (read from the Rust crate version at build time)
Python3.12 or newer
Wheelsone cp312-abi3 wheel per platform: Linux x86_64 and aarch64 (manylinux_2_34, glibc 2.34 or newer), macOS universal2, Windows x86_64. No sdist
Core dependenciesnone
Extra embednumpy>=1.26, tokenizers>=0.20. Only urna.embed_potion needs them
LicenseMIT

Without the embed extra you can open, search, validate and build files, but you cannot embed text with the bundled potion table.

The wheel needs no urna setup: it ships its own offline embedder and table. It also installs a console command named urna that is not the Rust binary. See The wheel's urna command before you put both on the same PATH.

Check the installed version with the standard library. The module has no __version__ attribute.

import importlib.metadata

importlib.metadata.version("urna")  # "0.5.1"

Public names

__all__ lists seven names.

NameKindSignatureReturns
openfunctionopen(path)UrnaFile
buildfunctionsee urna.buildstr, the output_path
chunk_idfunctionchunk_id(canonical_text, source_uri, byte_start, byte_end, chunker_version)"sha256:<64 hex>"
potion_model_pathfunctionpotion_model_path()str or None
UrnaFileclassopened with urna.open
SearchHitclassreturned by the search methodssee hits
RetrieveHitclassreturned by UrnaFile.retrievesee hits

from urna import * imports open, which shadows the builtin open in your namespace. Prefer import urna.

urna.open

urna.open(path: str) -> UrnaFile

Maps the file read-only and validates it before returning. Same as urna.UrnaFile.open(path). The path must be a str: a pathlib.Path raises TypeError, so wrap it with str(). Every failure to open is a ValueError. The full contract is on the UrnaFile page.

urna.chunk_id

urna.chunk_id(canonical_text: str, source_uri: str, byte_start: int, byte_end: int, chunker_version: str) -> str

Computes the chunk_id the writer derives for a chunk with these inputs, so you can deduplicate before calling urna.build. The preimage is SHA-256 over the domain string urna:chunk_id:v1 and a newline, then the length-prefixed canonical_text, the length-prefixed source_uri, byte_start and byte_end as little-endian u64, and the length-prefixed chunker_version. The full layout is in hashes.

chunk_id validates nothing: it accepts byte_end smaller than byte_start, which urna.build rejects. A negative offset raises OverflowError. Chunk ids inside a legacy .nest file were derived under an older domain and do not match this function.

urna.potion_model_path

urna.potion_model_path() -> str | None

Returns the directory of the potion-base-8M table bundled in the wheel (<site-packages>/urna/models/potion-base-8M). In a repo checkout it returns None, because the checkout keeps the table under python/forge/models/potion-base-8M/.

What the wheel contains

Path in the wheelRole
urna/__init__.pythe public module
urna/_urna.abi3.so (.pyd on Windows)the pyo3 extension, imported as urna._urna
urna/embed_potion.pythe offline potion embedder, see Embedders
urna/_cli.pythe urna console script, see The wheel's urna command
urna/models/potion-base-8M/the vendored potion table (7 files, model.safetensors is about 30 MB)

Nothing else from the repo's python/ directory is in the wheel.

Wheel or checkout

The repo's python/ directory holds more than the wheel ships: the builder pipeline, the model fingerprint, the lexical embedder, the forge helpers. Those import only from a checkout with python/ on sys.path.

SymbolFrom the wheelFrom a checkout
open, build, chunk_id, UrnaFile, SearchHit, RetrieveHitimport urnaimport urna
potion_model_path()returns the bundled table dirreturns None
PotionEmbedder, potion_embedder, default_embedderfrom urna.embed_potion import ...from forge.embed_potion import ...
StaticEmbedder, embed_one, lexical_embeddernot shippedfrom forge.embed_default import ..., from forge import lexical_embedder
ChunkSpec, chunk_text, EmbeddingCache, BuildConfig, Pipelinenot shippedfrom builder import ...
compute_model_fingerprint, fingerprint_to_model_hash, resolve_model_dir and the rest of model_fingerprintnot shippedfrom model_fingerprint import ...
forge.retrieve.retrieve, build_demonot shippedfrom forge.retrieve import ...
neighbor_contextnot shippedfrom graph_context import neighbor_context
manifest_items, frame_resolvernot shippedfrom forge.forge_manifest import ...
console verbsurna <verb>python python/urna_cli.py <verb>

In a checkout, urna.embed_potion does not exist: import urna.embed_potion raises ModuleNotFoundError, because there urna is a plain module, not a package. Code meant to run in both layouts tries the wheel import first and falls back to forge.embed_potion, as examples/quickstart/quickstart.py does.

The checkout-only modules are documented on Builder pipeline (checkout only), including how to build the extension into python/_urna.so.

Behavior every call shares

  • Every error raised by the Rust side is a ValueError. TypeError and OverflowError come only from converting your arguments. See Errors.
  • No call releases the GIL. Python threads that share one process search one at a time.
  • Files are read-only. The only way to write is urna.build, which writes a whole new file.

Continue with UrnaFile.

On this page