Skip to main content

Overview

This page documents all the Python types, dataclasses, and enums used in the VecLabs SDK. These types provide strong typing and data validation for vector operations.

Import

from solvec.types import (
    DistanceMetric,
    UpsertRecord,
    QueryMatch,
    QueryResponse,
    UpsertResponse,
    CollectionStats,
    VerificationResult
)

Enums

DistanceMetric

Distance metric for vector similarity calculations.
class DistanceMetric(str, Enum):
    COSINE = "cosine"
    EUCLIDEAN = "euclidean"
    DOT = "dot"

Values

COSINE
str
Cosine similarity. Recommended for most use cases, especially with normalized embeddings.Formula: cos(θ) = (A · B) / (||A|| × ||B||)Range: -1 to 1 (higher is more similar)
EUCLIDEAN
str
Euclidean distance (L2 distance).Formula: distance = √(Σ(ai - bi)²)Range: 0 to ∞ (lower is more similar, but SDK returns normalized score)
DOT
str
Dot product similarity.Formula: dot = Σ(ai × bi)Range: -∞ to ∞ (higher is more similar)

Example

from solvec import SolVec
from solvec.types import DistanceMetric

sv = SolVec(network="devnet")

# Using enum
col = sv.collection("vectors", dimensions=768, metric=DistanceMetric.COSINE)

# Using string (automatically converted)
col = sv.collection("vectors", dimensions=768, metric="cosine")

Request Types

UpsertRecord

Dataclass representing a single vector to be upserted.
@dataclass
class UpsertRecord:
    id: str
    values: list[float]
    metadata: dict[str, Any] = field(default_factory=dict)

Fields

id
str
required
Unique identifier for the vector. Maximum 64 characters.Common patterns:
  • "doc_123" - Document ID
  • "mem_20240315_001" - Memory with timestamp
  • "user_456_pref" - User-specific data
values
list[float]
required
The embedding vector. Length must match the collection’s dimensions.
metadata
dict[str, Any]
default:"{}"
Optional metadata to store with the vector. Can contain any JSON-serializable values.Common metadata:
  • text - Original text that was embedded
  • timestamp - When the vector was created
  • user_id - Associated user
  • category - Classification or tag

Example

from solvec import SolVec
from solvec.types import UpsertRecord

sv = SolVec(network="devnet")
col = sv.collection("memories", dimensions=3)

# Create record
record = UpsertRecord(
    id="mem_001",
    values=[0.1, 0.2, 0.3],
    metadata={
        "text": "User prefers dark mode",
        "category": "preference",
        "timestamp": 1678901234
    }
)

# Upsert
col.upsert([record])

# Or use dict directly (both work)
col.upsert([{
    "id": "mem_002",
    "values": [0.4, 0.5, 0.6],
    "metadata": {"text": "Another memory"}
}])

Response Types

QueryMatch

Dataclass representing a single match from a query.
@dataclass
class QueryMatch:
    id: str
    score: float
    metadata: dict[str, Any] = field(default_factory=dict)
    values: Optional[list[float]] = None

Fields

id
str
The vector ID that matched the query.
score
float
Similarity score. Higher is more similar.
  • For cosine: 0 to 1 (typically)
  • For euclidean: normalized score
  • For dot product: can be any value
metadata
dict[str, Any]
Vector metadata (included if include_metadata=True in query).
values
list[float] | None
The embedding vector values (included if include_values=True in query). Usually None to save bandwidth.

Example

results = col.query(vector=[0.1, 0.2, 0.3], top_k=5)

for match in results.matches:
    print(f"ID: {match.id}")
    print(f"Score: {match.score:.4f}")
    print(f"Text: {match.metadata.get('text', 'N/A')}")
    print()

QueryResponse

Dataclass representing the complete response from a query.
@dataclass
class QueryResponse:
    matches: list[QueryMatch]
    namespace: str

Fields

matches
list[QueryMatch]
List of matching vectors, sorted by score in descending order (highest score first).
namespace
str
The collection name that was queried.

Example

results = col.query(vector=[0.1, 0.2, 0.3], top_k=3)

print(f"Found {len(results.matches)} matches in '{results.namespace}'")
print(f"Top result: {results.matches[0].id} with score {results.matches[0].score}")

# Iterate through matches
for i, match in enumerate(results.matches, 1):
    print(f"{i}. {match.id} - {match.score:.3f}")

UpsertResponse

Dataclass representing the response from an upsert operation.
@dataclass
class UpsertResponse:
    upserted_count: int

Fields

upserted_count
int
Number of vectors successfully upserted (inserted or updated).

Example

vectors = [
    {"id": "v1", "values": [0.1, 0.2, 0.3]},
    {"id": "v2", "values": [0.4, 0.5, 0.6]}
]

response = col.upsert(vectors)
print(f"Successfully upserted {response.upserted_count} vectors")

if response.upserted_count != len(vectors):
    print("Warning: Some vectors failed to upsert")

CollectionStats

Dataclass containing collection statistics and metadata.
@dataclass
class CollectionStats:
    vector_count: int
    dimension: int
    metric: DistanceMetric
    name: str
    merkle_root: str
    last_updated: int
    is_frozen: bool

Fields

vector_count
int
Total number of vectors currently in the collection.
dimension
int
Vector dimensions for this collection.
metric
DistanceMetric
Distance metric being used (cosine, euclidean, or dot).
name
str
Collection name.
merkle_root
str
Current Merkle root hash (64-character hex string). Used for integrity verification against on-chain data.
last_updated
int
Unix timestamp (seconds) of the last update to this collection.
is_frozen
bool
Whether the collection is frozen (read-only). Frozen collections cannot be modified but provide stronger immutability guarantees.

Example

stats = col.describe_index_stats()

print(f"Collection: {stats.name}")
print(f"Vectors: {stats.vector_count}")
print(f"Dimensions: {stats.dimension}")
print(f"Metric: {stats.metric.value}")
print(f"Merkle root: {stats.merkle_root[:16]}...")
print(f"Last updated: {stats.last_updated}")
print(f"Frozen: {stats.is_frozen}")

# Check if collection has data
if stats.vector_count == 0:
    print("Collection is empty")

VerificationResult

Dataclass containing the results of a blockchain verification.
@dataclass
class VerificationResult:
    verified: bool
    on_chain_root: str
    local_root: str
    match: bool
    vector_count: int
    solana_explorer_url: str
    timestamp: int

Fields

verified
bool
Whether the verification process completed successfully.
on_chain_root
str
Merkle root hash stored on the Solana blockchain (64-character hex string).
local_root
str
Merkle root hash computed locally from current collection data (64-character hex string).
match
bool
Whether on_chain_root matches local_root. If True, the collection data is verified to be intact and unmodified.
vector_count
int
Number of vectors that were included in the verification.
solana_explorer_url
str
Link to Solana Explorer to view the on-chain verification transaction.
timestamp
int
Verification timestamp in milliseconds since Unix epoch.

Example

result = col.verify()

if result.verified and result.match:
    print("✓ Collection verified successfully!")
    print(f"✓ {result.vector_count} vectors verified")
    print(f"✓ On-chain root: {result.on_chain_root[:16]}...")
    print(f"✓ View on Solana Explorer: {result.solana_explorer_url}")
else:
    print("✗ Verification failed!")
    print(f"Local root:    {result.local_root}")
    print(f"On-chain root: {result.on_chain_root}")
    print("Data may have been tampered with!")

Type Usage Examples

Complete Type-Safe Example

from solvec import SolVec
from solvec.types import (
    DistanceMetric,
    UpsertRecord,
    QueryResponse,
    CollectionStats,
    VerificationResult
)

# Initialize client
sv = SolVec(network="devnet")
col = sv.collection(
    "typed-collection",
    dimensions=3,
    metric=DistanceMetric.COSINE
)

# Upsert with type safety
records: list[UpsertRecord] = [
    UpsertRecord(
        id="vec_1",
        values=[1.0, 0.0, 0.0],
        metadata={"label": "first"}
    ),
    UpsertRecord(
        id="vec_2",
        values=[0.0, 1.0, 0.0],
        metadata={"label": "second"}
    )
]

upsert_response = col.upsert(records)
print(f"Upserted: {upsert_response.upserted_count}")

# Query with type annotations
query_response: QueryResponse = col.query(
    vector=[1.0, 0.0, 0.0],
    top_k=5
)

for match in query_response.matches:
    print(f"{match.id}: {match.score:.3f}")

# Get stats
stats: CollectionStats = col.describe_index_stats()
print(f"Collection has {stats.vector_count} vectors")

# Verify on-chain
verification: VerificationResult = col.verify()
if verification.match:
    print("Data integrity confirmed!")

Metadata Filtering Example

from solvec import SolVec
from datetime import datetime

sv = SolVec(network="devnet")
col = sv.collection("events", dimensions=768)

# Insert with rich metadata
col.upsert([
    {
        "id": "evt_1",
        "values": [...],  # embedding
        "metadata": {
            "text": "User logged in",
            "type": "authentication",
            "user_id": "user_123",
            "timestamp": int(datetime.now().timestamp()),
            "severity": "info"
        }
    },
    {
        "id": "evt_2",
        "values": [...],
        "metadata": {
            "text": "Failed login attempt",
            "type": "authentication",
            "user_id": "user_456",
            "timestamp": int(datetime.now().timestamp()),
            "severity": "warning"
        }
    }
])

# Query with metadata filter
results = col.query(
    vector=[...],
    top_k=10,
    filter={
        "type": "authentication",
        "user_id": "user_123"
    }
)

for match in results.matches:
    print(f"{match.metadata['text']} - {match.metadata['severity']}")

Error Handling Example

from solvec import SolVec
from solvec.types import UpsertRecord

sv = SolVec(network="devnet")
col = sv.collection("test", dimensions=3)

try:
    # This will raise ValueError - dimension mismatch
    record = UpsertRecord(
        id="bad_vector",
        values=[1.0, 2.0],  # Only 2 dimensions, need 3!
        metadata={}
    )
    col.upsert([record])
except ValueError as e:
    print(f"Error: {e}")

try:
    # This will also raise ValueError
    col.query(
        vector=[1.0, 2.0, 3.0, 4.0],  # Wrong dimensions!
        top_k=5
    )
except ValueError as e:
    print(f"Query error: {e}")

Type Hints

All SDK functions use proper type hints for better IDE support:
from typing import Optional
from solvec import SolVec
from solvec.types import QueryResponse, UpsertResponse

def search_memories(
    query_vector: list[float],
    limit: int = 10,
    category: Optional[str] = None
) -> QueryResponse:
    """Search for similar memories."""
    sv = SolVec(network="devnet")
    col = sv.collection("memories", dimensions=len(query_vector))
    
    filter_dict = {"category": category} if category else None
    
    return col.query(
        vector=query_vector,
        top_k=limit,
        filter=filter_dict
    )

def store_memory(
    memory_id: str,
    embedding: list[float],
    text: str
) -> UpsertResponse:
    """Store a new memory."""
    sv = SolVec(network="devnet")
    col = sv.collection("memories", dimensions=len(embedding))
    
    return col.upsert([{
        "id": memory_id,
        "values": embedding,
        "metadata": {"text": text}
    }])

Build docs developers (and LLMs) love