Skip to main content

Vector-Embedded Retrieval Archive document and retrieval engine

Project description

vera-doc

vera-doc is VERA's embedded storage and search engine. It stores ready-made text chunks in a portable SQLite .vera file and provides transactional CRUD, embeddings, metadata filters, keyword search, vector search, hybrid search, corpus search, and rebuildable library indexes.

It intentionally contains no PDF parsing, OCR, source extraction, chunking, MCP, CLI, or desktop dependencies. Applications extract and chunk content before calling vera-doc. The separate vera-extract package provides the standard PDF pipeline.

Install

python -m pip install vera-doc

Python 3.10 or newer is required. The default hashing embedder needs no model download or API key.

Quick start

from vera import ChunkRecord, VeraDatabase

records = [
    ChunkRecord(
        id="pipe-requirement",
        text="The minimum pipe diameter is 12 inches.",
        metadata={
            "source_filename": "manual.pdf",
            "page_start": 42,
            "heading_path": "Chapter 4 > Pipe Design",
        },
    )
]

with VeraDatabase.create("manual.vera") as database:
    database.add(records)

with VeraDatabase.open("manual.vera") as database:
    results = database.search(
        text="minimum pipe size",
        mode="hybrid",
        top_k=5,
    )

for result in results:
    print(result.score, result.record.text)

VeraDatabase.open() is read-only by default. Use mode="write" when adding, updating, or deleting records.

What is stored in a .vera file?

A VERA 0.2 file is one SQLite database containing:

manual.vera
├── vera_metadata       Format, embedding configuration, archive metadata
├── chunks              Final searchable text and JSON metadata
├── embeddings          One float32 vector per chunk
├── chunks_fts          SQLite FTS5 keyword index
├── attachments         Optional opaque binary payloads
└── chunk_attachments   Typed links from chunks to attachments

The core schema is conceptually:

CREATE TABLE chunks (
    chunk_id      TEXT PRIMARY KEY,
    text          TEXT NOT NULL,
    metadata_json TEXT NOT NULL,
    created_at    TEXT NOT NULL,
    updated_at    TEXT NOT NULL
);

CREATE TABLE embeddings (
    chunk_id        TEXT PRIMARY KEY REFERENCES chunks(chunk_id),
    model_name      TEXT NOT NULL,
    model_dimension INTEGER NOT NULL,
    vector          BLOB NOT NULL,
    vector_format   TEXT NOT NULL,
    created_at      TEXT NOT NULL
);

CREATE TABLE attachments (
    attachment_id TEXT PRIMARY KEY,
    mime_type     TEXT NOT NULL,
    filename      TEXT,
    data          BLOB NOT NULL,
    hash          TEXT NOT NULL,
    metadata_json TEXT NOT NULL,
    created_at    TEXT NOT NULL
);

Pages, headings, citations, bounding boxes, and source identity are optional chunk metadata. Original files and extracted images may be stored as opaque attachments. vera-doc stores these values but does not interpret or extract them.

Public objects

ChunkRecord

The only indexed record type:

ChunkRecord(
    id: str,
    text: str,
    metadata: Mapping[str, JSONValue] = {},
    vector: Sequence[float] | None = None,
    attachments: tuple[AttachmentRef, ...] = (),
)
  • id is a non-empty caller-controlled identifier.
  • text is final chunk text. vera-doc never splits or cleans it.
  • metadata may contain any JSON-compatible object.
  • vector may contain a precomputed embedding. When omitted, the configured embedding function embeds text.
  • attachments links the chunk to stored attachments.

Records are immutable. IDs, text, metadata, vectors, and attachment references are validated when the object is created or written.

AttachmentRecord

An optional opaque binary payload:

AttachmentRecord(
    id: str,
    data: bytes,
    media_type: str,
    filename: str | None = None,
    checksum: str | None = None,
    metadata: Mapping[str, JSONValue] = {},
)

The SHA-256 checksum is computed automatically. If a checksum is supplied, it must match the bytes. Attachments are not embedded or searchable.

AttachmentRef

Links a chunk to an attachment:

AttachmentRef(
    attachment_id="source-pdf",
    role="source",
)

The role is caller-defined. Common roles include source, figure, and viewer_data.

QueryResult

Returned by VeraDatabase.search():

QueryResult(
    record: ChunkRecord,
    score: float,
    semantic_score: float | None,
    keyword_score: float | None,
)

Call result.as_dict() for a JSON-compatible result without the raw vector.

EmbeddingFunction

A structural protocol for custom embedders:

class EmbeddingFunction:
    model_name: str
    dimension: int

    def embed(self, texts: list[str]) -> numpy.ndarray:
        ...

The same model and dimension must be used for stored records and text queries.

VeraDatabase methods

Create and open

VeraDatabase.create(
    path,
    *,
    embedding_function=None,
    model="hashing",
    metadata=None,
    overwrite=False,
)

VeraDatabase.open(
    path,
    *,
    mode="read",
    embedding_function=None,
)

create() publishes a valid database atomically. It raises FileExistsError unless overwrite=True. Both methods return context managers.

Add records

database.add(records)

Inserts an iterable of ChunkRecord objects. Existing IDs raise DuplicateRecordError. The chunk row, embedding, FTS row, and attachment links are written in one transaction.

Insert or replace records

database.upsert(records)

Inserts new IDs and replaces existing records. Replacement updates text, metadata, embedding, keyword index, and attachment links together.

Retrieve records

database.get(
    ids=None,
    *,
    where=None,
    limit=None,
)

Returns ChunkRecord objects, including their vectors and attachment links. where performs exact equality matching on top-level metadata keys:

records = database.get(where={"discipline": "civil"})

Delete records

deleted_count = database.delete(
    ids=None,
    *,
    where=None,
)

Deleting a chunk also deletes its embedding, keyword-index row, and attachment links. It does not delete the attachments themselves.

Search

database.search(
    *,
    text=None,
    vector=None,
    mode="hybrid",
    where=None,
    top_k=10,
)

Supported modes:

  • keyword uses SQLite FTS5 and BM25 ranking.
  • semantic uses cosine similarity against stored vectors.
  • hybrid independently normalizes semantic and keyword scores, then combines them with equal weight.

Semantic search accepts query text or a compatible precomputed vector. Keyword and hybrid search require text.

Attachments

database.put_attachments(attachments, upsert=False)
attachment = database.get_attachment("source-pdf")
database.delete_attachment("source-pdf")

Referenced attachments cannot be deleted until their chunk links are removed. Missing attachments raise RecordNotFoundError.

Archive metadata

metadata = database.metadata
database.set_metadata({"project": "stormwater"})

Archive metadata is a JSON-compatible object separate from per-chunk metadata.

Transactions

with database.transaction():
    database.put_attachments(attachments)
    database.add(records)

The entire block commits together. An exception rolls it back. Nested transactions are intentionally rejected.

Inspection and validation

info = database.inspect()
report = database.validate()

Inspection reports the format, model, dimension, counts, and archive metadata. Validation checks SQLite integrity, required tables and metadata, embedding and FTS parity, vector lengths, JSON payloads, foreign keys, and attachment hashes.

Close

database.close()

Context managers call close() automatically.

Exceptions

  • DuplicateRecordErroradd() received an existing ID.
  • RecordNotFoundError — a chunk references an unknown attachment or a requested attachment does not exist.
  • ReadOnlyError — a mutation was attempted after a read-only open.
  • Standard FileNotFoundError, FileExistsError, TypeError, and ValueError are used for ordinary path and validation failures.

Optional attachments example

from vera import (
    AttachmentRecord,
    AttachmentRef,
    ChunkRecord,
    VeraDatabase,
)

source = AttachmentRecord(
    id="source-pdf",
    data=pdf_bytes,
    media_type="application/pdf",
    filename="manual.pdf",
    metadata={"role": "source"},
)

chunk = ChunkRecord(
    id="chunk-1",
    text="The final, already-extracted chunk.",
    metadata={"page_start": 42},
    attachments=(AttachmentRef("source-pdf", role="source"),),
)

with VeraDatabase.create("manual.vera") as database:
    with database.transaction():
        database.put_attachments([source])
        database.add([chunk])

Custom embeddings

import numpy as np

from vera import ChunkRecord, VeraDatabase


class MyEmbedder:
    model_name = "example/my-embedder"
    dimension = 2

    def embed(self, texts: list[str]) -> np.ndarray:
        return np.asarray([[1.0, 0.0] for _ in texts], dtype=np.float32)


embedder = MyEmbedder()

with VeraDatabase.create(
    "custom.vera",
    embedding_function=embedder,
) as database:
    database.add([ChunkRecord(id="one", text="Example text")])

with VeraDatabase.open(
    "custom.vera",
    embedding_function=embedder,
) as database:
    results = database.search(text="example", mode="semantic")

Callers may instead provide ChunkRecord.vector and search with a query vector.

Libraries of .vera files

VeraCorpus searches a directory of .vera files as one corpus:

from vera import VeraCorpus

with VeraCorpus.open("./library", recursive=True) as corpus:
    results = corpus.search("detention requirements", top_k=5)

For larger libraries, create a persistent derived index:

from vera import (
    build_library_index,
    library_index_status,
    update_library_index,
)

build_library_index("./library", recursive=True)
print(library_index_status("./library"))
update_library_index("./library")

The .vera-index/ directory is rebuildable. Individual .vera files remain the source of truth.

Legacy document API

VeraDocument remains a read-oriented compatibility facade for VERA 0.1, the CLI, the desktop app, and citation-oriented workflows:

from vera import VeraDocument

with VeraDocument.open("manual.vera") as document:
    results = document.search(
        "detention requirements",
        mode="hybrid",
        top_k=5,
        context_chunks=1,
    )

New applications that create or mutate databases should use VeraDatabase.

Package source structure

src/vera/
├── __init__.py          Public exports
├── models.py            Chunk, attachment, and query value objects
├── database.py          Transactional vector-database facade
├── document.py          Legacy/read-oriented compatibility facade
├── corpus.py            Multi-file corpus search
├── collection.py        Persistent library index
└── core/
    ├── schema.py        SQLite schema and format versions
    ├── validation.py    Integrity and contract validation
    ├── embeddings.py    Embedders and vector serialization
    ├── search.py        Legacy search implementation
    ├── inspection.py    Legacy inspection helpers
    ├── access.py        Legacy page/asset/region access
    └── figures.py       Legacy figure access

Source extraction lives under packages/vera-extract, and MCP integration lives under packages/vera-mcp.

Format and API references

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

vera_doc-0.2.0.tar.gz (36.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vera_doc-0.2.0-py3-none-any.whl (42.9 kB view details)

Uploaded Python 3

File details

Details for the file vera_doc-0.2.0.tar.gz.

File metadata

  • Download URL: vera_doc-0.2.0.tar.gz
  • Upload date:
  • Size: 36.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for vera_doc-0.2.0.tar.gz
Algorithm Hash digest
SHA256 98841d6cd884dbd56d12bb138ece137e0c19117405bb292ff840354414a61652
MD5 3c27bb00df7afd34e184dfb04147f6c0
BLAKE2b-256 3c72e6c5f147f974a4f13dd8a1a051ee6f2314cebc9b6c5d5ee250f912fae880

See more details on using hashes here.

File details

Details for the file vera_doc-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: vera_doc-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 42.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for vera_doc-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e7292ca494ec5e68ff27d928dfa365c6c51c506c810a95308775ce2160131116
MD5 cf2b7f6ff51b19675c990343a5248035
BLAKE2b-256 e69f54d74e43c824471a3de126d7f88775de981b635ef9df9fd8a4d3b963558d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page