Skip to main content

veep — Python SDK for Vector Panda

Search your vectors in five minutes.

Install

pip install veep[pandas]

Requires Python 3.9+. pip install veep works on its own (only requests is mandatory). The quickstart below uses two extras: [samples] for the bundled text encoder (~22MB ONNX model + onnxruntime), and [pandas] for the parquet upload helper. NumPy, pandas, and PyArrow are otherwise optional — install them only if you use those upload modes.

Quickstart

Five steps. Copy-paste the whole block — it runs end-to-end against real embeddings, no sentence-transformers install required.

# pip install veep[samples,pandas]

from veep import VP, samples

# 1. Sign in. Opens your browser for a one-time OAuth handshake (works in
#    terminals, Jupyter, and SSH) and saves credentials to
#    ~/.veep/credentials.json so subsequent runs reuse them — see the
#    Authentication section below for the API-key alternative.
#    During private beta you'll need an invite — request access at https://vectorpanda.com.
vp = VP.login()

# 2. Create a collection.
vp.collections.create("quickstart", tier="hot")

# 3. Upload the bundled corpus: ~5,000 popular movies (titles + genre +
#    plot summary, sourced from English Wikipedia), pre-embedded with
#    sentence-transformers/all-MiniLM-L6-v2 (384-dim, cosine-normalized).
#    upsert() blocks until the data is queryable — typically a few
#    seconds on a fast connection. Returns an UploadResult with the
#    server-side filename, byte size, and status='created'.
vp.vectors.upsert("quickstart", dataframe=samples.dataframe())

# 4. Encode an arbitrary sentence with the bundled model and search by
#    meaning. The corpus is plot text; titles/years/genres come back as
#    metadata. Try any prompt — "a heist crew steals from a casino",
#    "an astronaut stranded on mars", "boxer comes back from injury".
results = vp.vectors.query(
    "quickstart",
    vector=samples.encode("a hobbit destroys a magic ring"),
    top_k=5,
)

# 5. Print results — top 5 should all be Lord of the Rings adaptations.
for r in results:
    title = r.metadata.get("title")
    year  = r.metadata.get("year")
    print(f"  {r.score:.4f}  {title} ({year})")

That's it. You're searching real embeddings against real movie plots. upsert blocks until the collection is queryable, so step 4 always sees the data from step 3 — no manual polling. samples.encode(text) uses a bundled INT8-quantized ONNX export of the same model the corpus was built with, so build-time and runtime agree on the embedding space.

The plot text is sourced from English Wikipedia under CC BY-SA 4.0 — see veep/_sample_data/ATTRIBUTION.md in the package for the full notice.

Upload Modes

Pick whichever shape your data already has:

# pandas DataFrame with id + vector + optional metadata columns
import pandas as pd
df = pd.DataFrame({"id": ids, "vector": list(embeddings), "category": tags})
vp.vectors.upsert("col", dataframe=df)

# Parquet / CSV / JSONL file on disk
vp.vectors.upsert("col", "embeddings.parquet")

# pyarrow Table — useful when you've already loaded with pyarrow
import pyarrow.parquet as pq
tbl = pq.read_table("embeddings.parquet")
vp.vectors.upsert("col", table=tbl)

All three serialize through the same chunked-upload pipeline — pandas and pyarrow modes write a temp parquet under the hood, so RAM cost is bounded by the dataset itself plus one chunk in flight.

# Inline list of dicts — for one-off small batches (under ~1000 vectors).
# Goes straight to the WAL rather than the artifact pipeline; latency is
# sub-second but the collection won't materialize as a query target until
# at least one of the modes above has run.
vp.vectors.upsert("col", vectors=[
    {"id": "abc", "vector": [0.1, 0.2, ...], "metadata": {"color": "red"}},
])

Authentication

Four ways to connect — pick whichever fits your workflow:

# Option 1: Interactive device-flow login (the quickstart form — terminals,
# Jupyter, SSH). Opens your browser for Google or GitHub sign-in. Saves
# credentials to ~/.veep/credentials.json so future runs skip the browser step.
vp = VP.login()

# Option 2: Reuse saved credentials from a prior login()
vp = VP.from_creds()

# Option 3: Explicit API key — paste from the dashboard
vp = VP(api_key="veep_live_...")

# Option 4: Environment variable
# export VEEP_API_KEY=veep_live_...
vp = VP()

login() uses the same device authorization pattern as gh auth login — it works in terminals, Jupyter notebooks, and remote SSH sessions. The verification URL is clickable in notebooks. Use it when copy-pasting an API key isn't convenient (CI runners that read from a vault, transient containers, etc.).

For programmatic flows (CLIs that want to email the verification link via a different transport, embedded contexts that handle the URL with custom UI, automated tests), VP.login() accepts an on_device_code callback that fires once with (device_code, verification_url) after the SDK gets them from the server and before polling starts:

def show_url(device_code: str, url: str) -> None:
    # send the URL via your preferred channel (Slack, email, custom UI, etc.)
    print(f"Visit {url} to authorize this session.")

vp = VP.login(host="https://api.vectorpanda.com", on_device_code=show_url)

When on_device_code is set, the SDK suppresses its default stdout output of the URL — the callback is the canonical surface for that information.

# Full options
vp = VP(
    api_key="your_key",        # or set VEEP_API_KEY env var
    host="https://...",         # optional, defaults to Vector Panda cloud
    timeout=120,                # request timeout in seconds
    verbose=True,               # log what the client is doing in plain English
)

# Save credentials for later
vp.save()                       # writes to ~/.veep/credentials.json

Collections

# Create a collection (with schema for instant processing)
col = vp.collections.create(
    "products",
    tier="hot",
    id_field="product_id",
    vector_field="embedding",
)

# Or create without schema (auto-detected from first upload)
col = vp.collections.create("products", tier="hot")

# List all collections
for col in vp.collections.list():
    count = col.vector_count if col.vector_count is not None else "—"
    size = f"{col.storage_gb:.1f} GB" if col.storage_gb is not None else "—"
    print(f"{col.name}: {count} vectors, {size}")

# Get details about one collection
col = vp.collections.get("products")
print(col.dimension, col.status)

# Check processing status
status = vp.collections.status("products")  # "ready", "processing", "unknown", "error"

# Delete a collection (permanent)
vp.collections.delete("products")

Querying

results = vp.vectors.query(
    "products",
    vector=[0.1, 0.2, ...],          # your query vector
    top_k=10,                          # max results (default: 10)
    min_score=0.7,                     # only return results with score >= this (cosine 0-1)
    metric="cosine",                   # "cosine", "euclidean", "dot_product"
    with_metadata=True,                # return metadata fields
)

for r in results:
    print(f"{r.key}: {r.score:.4f}{r.metadata}")

# Batch queries (up to 100 at once)
batch = vp.vectors.query_batch([
    {"collection": "products", "vector": query_vec_1, "top_k": 5},
    {"collection": "products", "vector": query_vec_2, "top_k": 5},
])
for query_results in batch:
    print(f"Got {len(query_results)} results")

# Fetch a single vector by key (the key from a query result)
result = vp.vectors.fetch("products", "12345")
if result.found:
    print(f"Vector: {result.vector[:5]}...")
    print(f"Metadata: {result.metadata}")

File Management

# Replace an existing file (idempotent: same content = no-op)
result = vp.vectors.replace("products", "product_embeddings.parquet")

# List uploaded files
for f in vp.vectors.list_files("products"):
    print(f"{f.name}: {f.size} bytes, modified {f.modified}")

# Delete an uploaded file
vp.vectors.delete("products", "old_embeddings.parquet")

Schema

After uploading files, Vector Panda auto-detects which columns hold your vector keys and embeddings. You can inspect and confirm the schema:

schema = vp.schema.get("products")
print(schema.state)         # "analyzing" or "confirmed"
print(schema.vector_field)  # e.g., "embedding"
print(schema.id_field)      # e.g., "product_id"

# Confirm or override the detected schema
vp.schema.confirm("products", id_field="product_id", vector_field="embedding")

Index Parameters

For advanced use, pass index-specific parameters to queries:

results = vp.vectors.query(
    "products",
    vector=query_vec,
    use_index="pca",
    index_params={"pca": {"reduced_dimensions": 64, "candidate_multiplier": 10}},
)

Health Check

if vp.ping():
    print("Vector Panda is up")

Verbose Mode

Turn on verbose=True to see what the client is doing:

vp = VP(api_key="...", verbose=True)
vp.collections.list()
# veep: Connected to https://api.vectorpanda.com
# veep: Listing collections...
# veep: Found 3 collection(s).

Error Handling

Every error tells you what happened and what to do about it:

from veep import VP
from veep.exceptions import (
    CollectionNotFoundError,
    CollectionAlreadyExistsError,
    CollectionNotReadyError,
    AuthError,
    ValidationError,
)

try:
    vp.collections.get("nonexistent")
except CollectionNotFoundError as e:
    print(e)
    # Collection 'nonexistent' not found.
    # Use vp.collections.list() to see available collections.
Exception When
AuthError Invalid or missing API key
ValidationError Bad parameter (name, vector, etc.)
CollectionNotFoundError Collection doesn't exist
CollectionAlreadyExistsError Collection already exists
CollectionNotReadyError Collection is still ingesting. From query/fetch: retry shortly. From upsert: ingest pipeline didn't finish before wait_seconds / upload_timeout; do not retry upsert (creates duplicate state) — call vp.collections.status(name) and contact support if stuck
UploadError File not found or unreadable
FileAlreadyExistsError File exists (use replace)
TimeoutError Request timed out (e.g., HTTP 504)
ServerError Server-side failure (HTTP 5xx). Includes status_code
QueryError (Deprecated, retained for backwards compat — server errors now raise ServerError)

Configuration

Environment Variable Description
VEEP_API_KEY Default API key
VEEP_HOST Default API host

Beta Status

Vector Panda is in private beta. pip install veep works for everyone, but creating an account currently requires an invite — request one at vectorpanda.com. If you already have an API key, everything in this README is live.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

veep-0.5.27.tar.gz (29.2 MB view details)

Uploaded Source

Built Distribution

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

veep-0.5.27-py3-none-any.whl (29.2 MB view details)

Uploaded Python 3

File details

Details for the file veep-0.5.27.tar.gz.

File metadata

  • Download URL: veep-0.5.27.tar.gz
  • Upload date:
  • Size: 29.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for veep-0.5.27.tar.gz
Algorithm Hash digest
SHA256 489c9d3123d50d4d9a704511e29107ddb182d3b7ec28886c68af24b72aae9457
MD5 a661df3090e2500f0aef2a525bf1d96c
BLAKE2b-256 2b92274310e0e15c36847d3c6aa1d61f7553c9f0ae2ecb1fb25aeaaf66e2d628

See more details on using hashes here.

File details

Details for the file veep-0.5.27-py3-none-any.whl.

File metadata

  • Download URL: veep-0.5.27-py3-none-any.whl
  • Upload date:
  • Size: 29.2 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for veep-0.5.27-py3-none-any.whl
Algorithm Hash digest
SHA256 ffa6856143c325a1d4f1f23e005ff96899777600ff37c4579bd667fd19e7bf7a
MD5 86a2d0a23681ac9f2c69009a78c6b409
BLAKE2b-256 78760309e030c6abc59d73445b90db03d053088c388e525d4196a7ab8800ba75

See more details on using hashes here.

Release history Release notifications | RSS feed

0.5.33

2 files

0.5.32

2 files

0.5.30

2 files

0.5.29

2 files

This release

0.5.27 This release

2 files

0.5.21

2 files

0.5.12

2 files

0.5.11

2 files

0.4.4

2 files

0.4.3

2 files

0.4.2

2 files

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