# Upstash Vector Python SDK
The Upstash Vector Python client
> [!NOTE]
> **This project is in GA Stage.**
>
> The Upstash Professional Support fully covers this project. It receives regular updates, and bug fixes.
> The Upstash team is committed to maintaining and improving its functionality.
## Installation
Install a released version from pip:
```shell
pip3 install upstash-vector
```
## Usage
In order to use this client, head out to [Upstash Console](https://console.upstash.com) and create a vector database.
There, get the `UPSTASH_VECTOR_REST_URL` and the `UPSTASH_VECTOR_REST_TOKEN` from the dashboard.
### Initializing the Index
```python
from upstash_vector import Index
index = Index(url=UPSTASH_VECTOR_REST_URL, token=UPSTASH_VECTOR_REST_TOKEN)
```
or alternatively, initialize from the environment variables
```bash
export UPSTASH_VECTOR_REST_URL [URL]
export UPSTASH_VECTOR_REST_TOKEN [TOKEN]
```
```python
from upstash_vector import Index
index = Index.from_env()
```
### Upsert Vectors
Vectors can be upserted(inserted or updated) into a namespace of an index
to be later queried or fetched.
There are a couple of ways of doing upserts:
```python
# - dense indexes
# - (id, vector, metadata, data)
# - (id, vector, metadata)
# - (id, vector)
index.upsert(
vectors=[
("id1", [0.1, 0.2], {"metadata_field": "metadata_value"}, "data-value"),
("id2", [0.2, 0.2], {"metadata_field": "metadata_value"}),
("id3", [0.3, 0.4]),
]
)
# - sparse indexes
# - (id, sparse_vector, metadata, data)
# - (id, sparse_vector, metadata)
# - (id, sparse_vector)
index.upsert(
vectors=[
("id1", ([0, 1], [0.1, 0.2]), {"metadata_field": "metadata_value"}, "data-value"),
("id2", ([1, 2], [0.2, 0.2]), {"metadata_field": "metadata_value"}),
("id3", ([2, 3, 4], [0.3, 0.4, 0.5])),
]
)
# - hybrid indexes
# - (id, vector, sparse_vector, metadata, data)
# - (id, vector, sparse_vector, metadata)
# - (id, vector, sparse_vector)
index.upsert(
vectors=[
("id1", [0.1, 0.2], ([0, 1], [0.1, 0.2]), {"metadata_field": "metadata_value"}, "data-value"),
("id2", [0.2, 0.2], ([1, 2], [0.2, 0.2]), {"metadata_field": "metadata_value"}),
("id3", [0.3, 0.4], ([2, 3, 4], [0.3, 0.4, 0.5])),
]
)
```
```python
# - dense indexes
# - {"id": id, "vector": vector, "metadata": metadata, "data": data)
# - {"id": id, "vector": vector, "metadata": metadata)
# - {"id": id, "vector": vector, "data": data)
# - {"id": id, "vector": vector}
index.upsert(
vectors=[
{"id": "id4", "vector": [0.1, 0.2], "metadata": {"field": "value"}, "data": "value"},
{"id": "id5", "vector": [0.1, 0.2], "metadata": {"field": "value"}},
{"id": "id6", "vector": [0.1, 0.2], "data": "value"},
{"id": "id7", "vector": [0.5, 0.6]},
]
)
# - sparse indexes
# - {"id": id, "sparse_vector": sparse_vector, "metadata": metadata, "data": data)
# - {"id": id, "sparse_vector": sparse_vector, "metadata": metadata)
# - {"id": id, "sparse_vector": sparse_vector, "data": data)
# - {"id": id, "sparse_vector": sparse_vector}
index.upsert(
vectors=[
{"id": "id4", "sparse_vector": ([0, 1], [0.1, 0.2]), "metadata": {"field": "value"}, "data": "value"},
{"id": "id5", "sparse_vector": ([1, 2], [0.2, 0.2]), "metadata": {"field": "value"}},
{"id": "id6", "sparse_vector": ([2, 3, 4], [0.3, 0.4, 0.5]), "data": "value"},
{"id": "id7", "sparse_vector": ([4], [0.3])},
]
)
# - hybrid indexes
# - {"id": id, "vector": vector, "sparse_vector": sparse_vector, "metadata": metadata, "data": data)
# - {"id": id, "vector": vector, "sparse_vector": sparse_vector, "metadata": metadata)
# - {"id": id, "vector": vector, "sparse_vector": sparse_vector, "data": data)
# - {"id": id, "vector": vector, "sparse_vector": sparse_vector}
index.upsert(
vectors=[
{"id": "id4", "vector": [0.1, 0.2], "sparse_vector": ([0], [0.1]), "metadata": {"field": "value"},
"data": "value"},
{"id": "id5", "vector": [0.1, 0.2], "sparse_vector": ([1, 2], [0.2, 0.2]), "metadata": {"field": "value"}},
{"id": "id6", "vector": [0.1, 0.2], "sparse_vector": ([2, 3, 4], [0.3, 0.4, 0.5]), "data": "value"},
{"id": "id7", "vector": [0.5, 0.6], "sparse_vector": ([4], [0.3])},
]
)
```
```python
from upstash_vector import Vector
from upstash_vector.types import SparseVector
# dense indexes
index.upsert(
vectors=[
Vector(id="id5", vector=[1, 2], metadata={"field": "value"}, data="value"),
Vector(id="id6", vector=[1, 2], metadata={"field": "value"}),
Vector(id="id7", vector=[1, 2], data="value"),
Vector(id="id8", vector=[6, 7]),
]
)
# sparse indexes
index.upsert(
vectors=[
Vector(id="id5", sparse_vector=SparseVector([1], [0.1]), metadata={"field": "value"}, data="value"),
Vector(id="id6", sparse_vector=SparseVector([1, 2], [0.1, 0.2]), metadata={"field": "value"}),
Vector(id="id7", sparse_vector=SparseVector([3, 5], [0.3, 0.3]), data="value"),
Vector(id="id8", sparse_vector=SparseVector([4], [0.2])),
]
)
# hybrid indexes
index.upsert(
vectors=[
Vector(id="id5", vector=[1, 2], sparse_vector=SparseVector([1], [0.1]), metadata={"field": "value"},
data="value"),
Vector(id="id6", vector=[1, 2], sparse_vector=SparseVector([1, 2], [0.1, 0.2]), metadata={"field": "value"}),
Vector(id="id7", vector=[1, 2], sparse_vector=SparseVector([3, 5], [0.3, 0.3]), data="value"),
Vector(id="id8", vector=[6, 7], sparse_vector=SparseVector([4], [0.2])),
]
)
```
If the index is created with an embedding model, raw string data can be upserted.
In this case, the `data` field of the vector will also be set to the `data` passed
below, so that it can be accessed later.
```python
from upstash_vector import Data
res = index.upsert(
vectors=[
Data(id="id5", data="Goodbye World", metadata={"field": "value"}),
Data(id="id6", data="Hello World"),
]
)
```
Also, a namespace can be specified to upsert vectors into it.
When no namespace is provided, the default namespace is used.
```python
index.upsert(
vectors=[
("id1", [0.1, 0.2]),
("id2", [0.3, 0.4]),
],
namespace="ns",
)
```
### Query Vectors
Some number of vectors that are approximately most similar to a given
query vector can be requested from a namespace of an index.
```python
res = index.query(
vector=[0.6, 0.9], # for dense and hybrid indexes
sparse_vector=([0, 1], [0.1, 0.1]), # for sparse and hybrid indexes
top_k=5,
include_vectors=False,
include_metadata=True,
include_data=True,
filter="metadata_f = 'metadata_v'"
)
# List of query results, sorted in the descending order of similarity
for r in res:
print(
r.id, # The id used while upserting the vector
r.score, # The similarity score of this vector to the query vector. Higher is more similar.
r.vector, # The value of the vector, if requested (for dense and hybrid indexes).
r.sparse, # The value of the sparse vector, if requested (for sparse and hybrid indexes).
r.metadata, # The metadata of the vector, if requested and present.
r.data, # The data of the vector, if requested and present.
)
```
If the index is created with an embedding model, raw string data can be queried.
```python
res = index.query(
data="hello",
top_k=5,
include_vectors=False,
include_metadata=True,
include_data=True,
)
```
When a filter is provided, query results are further narrowed down based
on the vectors whose metadata matches with it.
See [Metadata Filtering](https://upstash.com/docs/vector/features/filtering) documentation
for more information regarding the filter syntax.
Also, a namespace can be specified to query from.
When no namespace is provided, the default namespace is used.
```python
res = index.query(
vector=[0.6, 0.9],
top_k=5,
namespace="ns",
)
```
### Fetch Vectors
A set of vectors can be fetched from a namespace of an index.
```python
res = index.fetch(
ids=["id3", "id4"],
include_vectors=False,
include_metadata=True,
include_data=True,
)
# List of fetch results, one for each id passed
for r in res:
if not r: # Can be None, if there is no such vector with the given id
continue
print(
r.id, # The id used while upserting the vector
r.vector, # The value of the vector, if requested (for dense and hybrid indexes).
r.sparse_vector, # The value of the sparse vector, if requested (for sparse and hybrid indexes).
r.metadata, # The metadata of the vector, if requested and present.
r.data, # The metadata of the vector, if requested and present.
)
```
or, for singular fetch:
```python
res = index.fetch(
"id1",
include_vectors=True,
include_metadata=True,
include_data=False,
)
r = res[0]
if r: # Can be None, if there is no such vector with the given id
print(
r.id, # The id used while upserting the vector
r.vector, # The value of the vector, if requested (for dense and hybrid indexes).
r.sparse_vector, # The value of the sparse vector, if requested (for sparse and hybrid indexes).
r.metadata, # The metadata of the vector, if requested and present.
r.data, # The metadata of the vector, if requested and present.
)
```
Also, a namespace can be specified to fetch from.
When no namespace is provided, the default namespace is used.
```python
res = index.fetch(
ids=["id3", "id4"],
namespace="ns",
)
```
### Range Over Vectors
The vectors upserted into a namespace of an index can be scanned
in a page by page fashion.
```python
# Scans the vectors 100 vector at a time,
res = index.range(
cursor="", # Start the scan from the beginning
limit=100,
include_vectors=False,
include_metadata=True,
include_data=True,
)
while res.next_cursor != "":
res = index.range(
cursor=res.next_cursor,
limit=100,
include_vectors=False,
include_metadata=True,
include_data=True,
)
for v in res.vectors:
print(
v.id, # The id used while upserting the vector
v.vector, # The value of the vector, if requested (for dense and hybrid indexes).
v.sparse_vector, # The value of the sparse vector, if requested (for sparse and hybrid indexes).
v.metadata, # The metadata of the vector, if requested and present.
v.data, # The data of the vector, if requested and present.
)
```
Also, a namespace can be specified to range from.
When no namespace is provided, the default namespace is used.
```python
res = index.range(
cursor="",
limit=100,
namespace="ns",
)
```
### Delete Vectors
A list of vectors can be deleted from a namespace of index.
If no such vectors with the given ids exist, this is no-op.
```python
res = index.delete(
ids=["id1", "id2"],
)
print(
res.deleted, # How many vectors are deleted out of the given ids.
)
```
or, for singular deletion:
```python
res = index.delete(
"id1",
)
print(res) # A boolean indicating whether the vector is deleted or not.
```
Also, a namespace can be specified to delete from.
When no namespace is provided, the default namespace is used.
```python
res = index.delete(
ids=["id1", "id2"],
namespace="ns",
)
```
### Update a Vector
Any combination of vector value, sparse vector value, data, or metadata can be updated.
```python
res = index.update(
"id1",
metadata={"new_field": "new_value"},
)
print(res) # A boolean indicating whether the vector is updated or not.
```
Also, a namespace can be specified to update from.
When no namespace is provided, the default namespace is used.
```python
res = index.update(
"id1",
metadata={"new_field": "new_value"},
namespace="ns",
)
```
### Reset the Namespace
All vectors can be removed from a namespace of an index.
```python
index.reset()
```
Also, a namespace can be specified to reset.
When no namespace is provided, the default namespace is used.
```python
index.reset(
namespace="ns",
)
```
All namespaces under the index can be reset with a single call
as well.
```python
index.reset(
all=True,
)
```
### Index Info
Some information regarding the status and type of the index can be requested.
This information also contains per-namespace status.
```python
info = index.info()
print(
info.vector_count, # Total number of vectors across all namespaces
info.pending_vector_count, # Total number of vectors waiting to be indexed across all namespaces
info.index_size, # Total size of the index on disk in bytes
info.dimension, # Vector dimension
info.similarity_function, # Similarity function used
)
for ns, ns_info in info.namespaces.items():
print(
ns, # Name of the namespace
ns_info.vector_count, # Total number of vectors in this namespaces
ns_info.pending_vector_count, # Total number of vectors waiting to be indexed in this namespaces
)
```
### List Namespaces
All the names of active namespaces can be listed.
```python
namespaces = index.list_namespaces()
for ns in namespaces:
print(ns) # name of the namespace
```
### Delete a Namespace
A namespace can be deleted entirely.
If no such namespace exists, and exception is raised.
The default namespaces cannot be deleted.
```python
index.delete_namespace(namespace="ns")
```
# Contributing
## Preparing the environment
This project uses [Poetry](https://python-poetry.org) for packaging and dependency management. Make sure you are able to
create the poetry shell with relevant dependencies.
You will also need a vector database on [Upstash](https://console.upstash.com/).
```commandline
poetry install
```
## Code Formatting
```bash
poetry run ruff format .
```
## Running tests
To run all the tests, make sure the poetry virtual environment activated with all
the necessary dependencies.
Create four Vector Stores on Upstash. First one should have 2 dimensions. Second one should use an embedding model. Set
the necessary environment variables:
- A dense index with 2 dimensions, with cosine similarity
- A dense index with an embedding model
- A sparse index
- A hybrid index with 2 dimensions, with cosine similarity for the dense component.
- A hybrid index with embedding models
```
URL=****
TOKEN=****
EMBEDDING_URL=****
EMBEDDING_TOKEN=****
SPARSE_URL=****
SPARSE_TOKEN=****
HYBRID_URL=****
HYBRID_TOKEN=****
HYBRID_EMBEDDING_URL=****
HYBRID_EMBEDDING_TOKEN=****
```
Then, run the following command to run tests:
```bash
poetry run pytest
```
Raw data
{
"_id": null,
"home_page": "https://github.com/upstash/vector-py",
"name": "upstash-vector",
"maintainer": "Upstash",
"docs_url": null,
"requires_python": "<4.0,>=3.8",
"maintainer_email": "support@upstash.com",
"keywords": "Upstash Vector, Serverless Vector",
"author": "Upstash",
"author_email": "support@upstash.com",
"download_url": "https://files.pythonhosted.org/packages/3c/7a/3e397b785ae7097e385dd47ce9c3d41fa49d72490f2e1c3a921f42492f00/upstash_vector-0.7.0.tar.gz",
"platform": null,
"description": "# Upstash Vector Python SDK\n\nThe Upstash Vector Python client\n\n> [!NOTE] \n> **This project is in GA Stage.**\n>\n> The Upstash Professional Support fully covers this project. It receives regular updates, and bug fixes.\n> The Upstash team is committed to maintaining and improving its functionality.\n\n## Installation\n\nInstall a released version from pip:\n\n```shell\npip3 install upstash-vector\n```\n\n## Usage\n\nIn order to use this client, head out to [Upstash Console](https://console.upstash.com) and create a vector database.\nThere, get the `UPSTASH_VECTOR_REST_URL` and the `UPSTASH_VECTOR_REST_TOKEN` from the dashboard.\n\n### Initializing the Index\n\n```python\nfrom upstash_vector import Index\n\nindex = Index(url=UPSTASH_VECTOR_REST_URL, token=UPSTASH_VECTOR_REST_TOKEN)\n```\n\nor alternatively, initialize from the environment variables\n\n```bash\nexport UPSTASH_VECTOR_REST_URL [URL]\nexport UPSTASH_VECTOR_REST_TOKEN [TOKEN]\n```\n\n```python\nfrom upstash_vector import Index\n\nindex = Index.from_env()\n```\n\n### Upsert Vectors\n\nVectors can be upserted(inserted or updated) into a namespace of an index\nto be later queried or fetched.\n\nThere are a couple of ways of doing upserts:\n\n```python\n# - dense indexes\n# - (id, vector, metadata, data)\n# - (id, vector, metadata)\n# - (id, vector)\nindex.upsert(\n vectors=[\n (\"id1\", [0.1, 0.2], {\"metadata_field\": \"metadata_value\"}, \"data-value\"),\n (\"id2\", [0.2, 0.2], {\"metadata_field\": \"metadata_value\"}),\n (\"id3\", [0.3, 0.4]),\n ]\n)\n\n# - sparse indexes\n# - (id, sparse_vector, metadata, data)\n# - (id, sparse_vector, metadata)\n# - (id, sparse_vector)\nindex.upsert(\n vectors=[\n (\"id1\", ([0, 1], [0.1, 0.2]), {\"metadata_field\": \"metadata_value\"}, \"data-value\"),\n (\"id2\", ([1, 2], [0.2, 0.2]), {\"metadata_field\": \"metadata_value\"}),\n (\"id3\", ([2, 3, 4], [0.3, 0.4, 0.5])),\n ]\n)\n\n# - hybrid indexes\n# - (id, vector, sparse_vector, metadata, data)\n# - (id, vector, sparse_vector, metadata)\n# - (id, vector, sparse_vector)\nindex.upsert(\n vectors=[\n (\"id1\", [0.1, 0.2], ([0, 1], [0.1, 0.2]), {\"metadata_field\": \"metadata_value\"}, \"data-value\"),\n (\"id2\", [0.2, 0.2], ([1, 2], [0.2, 0.2]), {\"metadata_field\": \"metadata_value\"}),\n (\"id3\", [0.3, 0.4], ([2, 3, 4], [0.3, 0.4, 0.5])),\n ]\n)\n```\n\n```python\n# - dense indexes\n# - {\"id\": id, \"vector\": vector, \"metadata\": metadata, \"data\": data)\n# - {\"id\": id, \"vector\": vector, \"metadata\": metadata)\n# - {\"id\": id, \"vector\": vector, \"data\": data)\n# - {\"id\": id, \"vector\": vector} \nindex.upsert(\n vectors=[\n {\"id\": \"id4\", \"vector\": [0.1, 0.2], \"metadata\": {\"field\": \"value\"}, \"data\": \"value\"},\n {\"id\": \"id5\", \"vector\": [0.1, 0.2], \"metadata\": {\"field\": \"value\"}},\n {\"id\": \"id6\", \"vector\": [0.1, 0.2], \"data\": \"value\"},\n {\"id\": \"id7\", \"vector\": [0.5, 0.6]},\n ]\n)\n\n# - sparse indexes\n# - {\"id\": id, \"sparse_vector\": sparse_vector, \"metadata\": metadata, \"data\": data)\n# - {\"id\": id, \"sparse_vector\": sparse_vector, \"metadata\": metadata)\n# - {\"id\": id, \"sparse_vector\": sparse_vector, \"data\": data)\n# - {\"id\": id, \"sparse_vector\": sparse_vector} \nindex.upsert(\n vectors=[\n {\"id\": \"id4\", \"sparse_vector\": ([0, 1], [0.1, 0.2]), \"metadata\": {\"field\": \"value\"}, \"data\": \"value\"},\n {\"id\": \"id5\", \"sparse_vector\": ([1, 2], [0.2, 0.2]), \"metadata\": {\"field\": \"value\"}},\n {\"id\": \"id6\", \"sparse_vector\": ([2, 3, 4], [0.3, 0.4, 0.5]), \"data\": \"value\"},\n {\"id\": \"id7\", \"sparse_vector\": ([4], [0.3])},\n ]\n)\n\n# - hybrid indexes\n# - {\"id\": id, \"vector\": vector, \"sparse_vector\": sparse_vector, \"metadata\": metadata, \"data\": data)\n# - {\"id\": id, \"vector\": vector, \"sparse_vector\": sparse_vector, \"metadata\": metadata)\n# - {\"id\": id, \"vector\": vector, \"sparse_vector\": sparse_vector, \"data\": data)\n# - {\"id\": id, \"vector\": vector, \"sparse_vector\": sparse_vector} \nindex.upsert(\n vectors=[\n {\"id\": \"id4\", \"vector\": [0.1, 0.2], \"sparse_vector\": ([0], [0.1]), \"metadata\": {\"field\": \"value\"},\n \"data\": \"value\"},\n {\"id\": \"id5\", \"vector\": [0.1, 0.2], \"sparse_vector\": ([1, 2], [0.2, 0.2]), \"metadata\": {\"field\": \"value\"}},\n {\"id\": \"id6\", \"vector\": [0.1, 0.2], \"sparse_vector\": ([2, 3, 4], [0.3, 0.4, 0.5]), \"data\": \"value\"},\n {\"id\": \"id7\", \"vector\": [0.5, 0.6], \"sparse_vector\": ([4], [0.3])},\n ]\n)\n```\n\n```python\nfrom upstash_vector import Vector\nfrom upstash_vector.types import SparseVector\n\n# dense indexes\nindex.upsert(\n vectors=[\n Vector(id=\"id5\", vector=[1, 2], metadata={\"field\": \"value\"}, data=\"value\"),\n Vector(id=\"id6\", vector=[1, 2], metadata={\"field\": \"value\"}),\n Vector(id=\"id7\", vector=[1, 2], data=\"value\"),\n Vector(id=\"id8\", vector=[6, 7]),\n ]\n)\n\n# sparse indexes\nindex.upsert(\n vectors=[\n Vector(id=\"id5\", sparse_vector=SparseVector([1], [0.1]), metadata={\"field\": \"value\"}, data=\"value\"),\n Vector(id=\"id6\", sparse_vector=SparseVector([1, 2], [0.1, 0.2]), metadata={\"field\": \"value\"}),\n Vector(id=\"id7\", sparse_vector=SparseVector([3, 5], [0.3, 0.3]), data=\"value\"),\n Vector(id=\"id8\", sparse_vector=SparseVector([4], [0.2])),\n ]\n)\n\n# hybrid indexes\nindex.upsert(\n vectors=[\n Vector(id=\"id5\", vector=[1, 2], sparse_vector=SparseVector([1], [0.1]), metadata={\"field\": \"value\"},\n data=\"value\"),\n Vector(id=\"id6\", vector=[1, 2], sparse_vector=SparseVector([1, 2], [0.1, 0.2]), metadata={\"field\": \"value\"}),\n Vector(id=\"id7\", vector=[1, 2], sparse_vector=SparseVector([3, 5], [0.3, 0.3]), data=\"value\"),\n Vector(id=\"id8\", vector=[6, 7], sparse_vector=SparseVector([4], [0.2])),\n ]\n)\n```\n\nIf the index is created with an embedding model, raw string data can be upserted.\nIn this case, the `data` field of the vector will also be set to the `data` passed\nbelow, so that it can be accessed later.\n\n```python\nfrom upstash_vector import Data\n\nres = index.upsert(\n vectors=[\n Data(id=\"id5\", data=\"Goodbye World\", metadata={\"field\": \"value\"}),\n Data(id=\"id6\", data=\"Hello World\"),\n ]\n)\n```\n\nAlso, a namespace can be specified to upsert vectors into it.\nWhen no namespace is provided, the default namespace is used.\n\n```python\nindex.upsert(\n vectors=[\n (\"id1\", [0.1, 0.2]),\n (\"id2\", [0.3, 0.4]),\n ],\n namespace=\"ns\",\n)\n```\n\n### Query Vectors\n\nSome number of vectors that are approximately most similar to a given\nquery vector can be requested from a namespace of an index.\n\n```python\nres = index.query(\n vector=[0.6, 0.9], # for dense and hybrid indexes\n sparse_vector=([0, 1], [0.1, 0.1]), # for sparse and hybrid indexes \n top_k=5,\n include_vectors=False,\n include_metadata=True,\n include_data=True,\n filter=\"metadata_f = 'metadata_v'\"\n)\n\n# List of query results, sorted in the descending order of similarity\nfor r in res:\n print(\n r.id, # The id used while upserting the vector\n r.score, # The similarity score of this vector to the query vector. Higher is more similar.\n r.vector, # The value of the vector, if requested (for dense and hybrid indexes).\n r.sparse, # The value of the sparse vector, if requested (for sparse and hybrid indexes).\n r.metadata, # The metadata of the vector, if requested and present.\n r.data, # The data of the vector, if requested and present.\n )\n```\n\nIf the index is created with an embedding model, raw string data can be queried.\n\n```python\nres = index.query(\n data=\"hello\",\n top_k=5,\n include_vectors=False,\n include_metadata=True,\n include_data=True,\n)\n```\n\nWhen a filter is provided, query results are further narrowed down based\non the vectors whose metadata matches with it.\n\nSee [Metadata Filtering](https://upstash.com/docs/vector/features/filtering) documentation\nfor more information regarding the filter syntax.\n\nAlso, a namespace can be specified to query from.\nWhen no namespace is provided, the default namespace is used.\n\n```python\nres = index.query(\n vector=[0.6, 0.9],\n top_k=5,\n namespace=\"ns\",\n)\n```\n\n### Fetch Vectors\n\nA set of vectors can be fetched from a namespace of an index.\n\n```python\nres = index.fetch(\n ids=[\"id3\", \"id4\"],\n include_vectors=False,\n include_metadata=True,\n include_data=True,\n)\n\n# List of fetch results, one for each id passed\nfor r in res:\n if not r: # Can be None, if there is no such vector with the given id\n continue\n\n print(\n r.id, # The id used while upserting the vector\n r.vector, # The value of the vector, if requested (for dense and hybrid indexes).\n r.sparse_vector, # The value of the sparse vector, if requested (for sparse and hybrid indexes).\n r.metadata, # The metadata of the vector, if requested and present.\n r.data, # The metadata of the vector, if requested and present.\n )\n```\n\nor, for singular fetch:\n\n```python\nres = index.fetch(\n \"id1\",\n include_vectors=True,\n include_metadata=True,\n include_data=False,\n)\n\nr = res[0]\nif r: # Can be None, if there is no such vector with the given id\n print(\n r.id, # The id used while upserting the vector\n r.vector, # The value of the vector, if requested (for dense and hybrid indexes).\n r.sparse_vector, # The value of the sparse vector, if requested (for sparse and hybrid indexes). \n r.metadata, # The metadata of the vector, if requested and present.\n r.data, # The metadata of the vector, if requested and present.\n )\n```\n\nAlso, a namespace can be specified to fetch from.\nWhen no namespace is provided, the default namespace is used.\n\n```python\nres = index.fetch(\n ids=[\"id3\", \"id4\"],\n namespace=\"ns\",\n)\n```\n\n### Range Over Vectors\n\nThe vectors upserted into a namespace of an index can be scanned\nin a page by page fashion.\n\n```python\n# Scans the vectors 100 vector at a time,\nres = index.range(\n cursor=\"\", # Start the scan from the beginning \n limit=100,\n include_vectors=False,\n include_metadata=True,\n include_data=True,\n)\n\nwhile res.next_cursor != \"\":\n res = index.range(\n cursor=res.next_cursor,\n limit=100,\n include_vectors=False,\n include_metadata=True,\n include_data=True,\n )\n\n for v in res.vectors:\n print(\n v.id, # The id used while upserting the vector\n v.vector, # The value of the vector, if requested (for dense and hybrid indexes).\n v.sparse_vector, # The value of the sparse vector, if requested (for sparse and hybrid indexes).\n v.metadata, # The metadata of the vector, if requested and present.\n v.data, # The data of the vector, if requested and present.\n )\n```\n\nAlso, a namespace can be specified to range from.\nWhen no namespace is provided, the default namespace is used.\n\n```python\nres = index.range(\n cursor=\"\",\n limit=100,\n namespace=\"ns\",\n)\n```\n\n### Delete Vectors\n\nA list of vectors can be deleted from a namespace of index.\nIf no such vectors with the given ids exist, this is no-op.\n\n```python\nres = index.delete(\n ids=[\"id1\", \"id2\"],\n)\n\nprint(\n res.deleted, # How many vectors are deleted out of the given ids.\n)\n```\n\nor, for singular deletion:\n\n```python\nres = index.delete(\n \"id1\",\n)\n\nprint(res) # A boolean indicating whether the vector is deleted or not.\n```\n\nAlso, a namespace can be specified to delete from.\nWhen no namespace is provided, the default namespace is used.\n\n```python\nres = index.delete(\n ids=[\"id1\", \"id2\"],\n namespace=\"ns\",\n)\n```\n\n### Update a Vector\n\nAny combination of vector value, sparse vector value, data, or metadata can be updated.\n\n```python\nres = index.update(\n \"id1\",\n metadata={\"new_field\": \"new_value\"},\n)\n\nprint(res) # A boolean indicating whether the vector is updated or not.\n```\n\nAlso, a namespace can be specified to update from.\nWhen no namespace is provided, the default namespace is used.\n\n```python\nres = index.update(\n \"id1\",\n metadata={\"new_field\": \"new_value\"},\n namespace=\"ns\",\n)\n```\n\n### Reset the Namespace\n\nAll vectors can be removed from a namespace of an index.\n\n```python\nindex.reset() \n```\n\nAlso, a namespace can be specified to reset.\nWhen no namespace is provided, the default namespace is used.\n\n```python\nindex.reset(\n namespace=\"ns\",\n) \n```\n\nAll namespaces under the index can be reset with a single call\nas well.\n\n```python\nindex.reset(\n all=True,\n)\n```\n\n### Index Info\n\nSome information regarding the status and type of the index can be requested.\nThis information also contains per-namespace status.\n\n```python\ninfo = index.info()\nprint(\n info.vector_count, # Total number of vectors across all namespaces\n info.pending_vector_count, # Total number of vectors waiting to be indexed across all namespaces\n info.index_size, # Total size of the index on disk in bytes\n info.dimension, # Vector dimension\n info.similarity_function, # Similarity function used\n)\n\nfor ns, ns_info in info.namespaces.items():\n print(\n ns, # Name of the namespace\n ns_info.vector_count, # Total number of vectors in this namespaces\n ns_info.pending_vector_count, # Total number of vectors waiting to be indexed in this namespaces\n )\n```\n\n### List Namespaces\n\nAll the names of active namespaces can be listed.\n\n```python\nnamespaces = index.list_namespaces()\nfor ns in namespaces:\n print(ns) # name of the namespace\n```\n\n### Delete a Namespace\n\nA namespace can be deleted entirely.\nIf no such namespace exists, and exception is raised.\nThe default namespaces cannot be deleted.\n\n```python\nindex.delete_namespace(namespace=\"ns\")\n```\n\n# Contributing\n\n## Preparing the environment\n\nThis project uses [Poetry](https://python-poetry.org) for packaging and dependency management. Make sure you are able to\ncreate the poetry shell with relevant dependencies.\n\nYou will also need a vector database on [Upstash](https://console.upstash.com/).\n\n```commandline\npoetry install \n```\n\n## Code Formatting\n\n```bash \npoetry run ruff format .\n```\n\n## Running tests\n\nTo run all the tests, make sure the poetry virtual environment activated with all\nthe necessary dependencies.\n\nCreate four Vector Stores on Upstash. First one should have 2 dimensions. Second one should use an embedding model. Set\nthe necessary environment variables:\n\n- A dense index with 2 dimensions, with cosine similarity\n- A dense index with an embedding model\n- A sparse index\n- A hybrid index with 2 dimensions, with cosine similarity for the dense component.\n- A hybrid index with embedding models\n\n```\nURL=****\nTOKEN=****\nEMBEDDING_URL=****\nEMBEDDING_TOKEN=****\nSPARSE_URL=****\nSPARSE_TOKEN=****\nHYBRID_URL=****\nHYBRID_TOKEN=****\nHYBRID_EMBEDDING_URL=****\nHYBRID_EMBEDDING_TOKEN=****\n```\n\nThen, run the following command to run tests:\n\n```bash\npoetry run pytest\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Serverless Vector SDK from Upstash",
"version": "0.7.0",
"project_urls": {
"Homepage": "https://github.com/upstash/vector-py",
"Repository": "https://github.com/upstash/vector-py"
},
"split_keywords": [
"upstash vector",
" serverless vector"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "b5d0f5c1be59b4bcfe0c758865167b13aecc5d6e1d3f0c03bd77529a78c7df44",
"md5": "be2329b745f2669bdc5e35e449694125",
"sha256": "4af6d5cbf03e4d324ae539cbc69c9d9e21551f5d5f15d3e74272131c9732826f"
},
"downloads": -1,
"filename": "upstash_vector-0.7.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "be2329b745f2669bdc5e35e449694125",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.8",
"size": 18008,
"upload_time": "2025-01-08T11:47:46",
"upload_time_iso_8601": "2025-01-08T11:47:46.057666Z",
"url": "https://files.pythonhosted.org/packages/b5/d0/f5c1be59b4bcfe0c758865167b13aecc5d6e1d3f0c03bd77529a78c7df44/upstash_vector-0.7.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "3c7a3e397b785ae7097e385dd47ce9c3d41fa49d72490f2e1c3a921f42492f00",
"md5": "5824fdc90f3a90dd91bff759d4ec1df4",
"sha256": "7b8ad1a4d9ad6e63ff0458379085c6ba8867e0c77069d1596e36c3215e650dbc"
},
"downloads": -1,
"filename": "upstash_vector-0.7.0.tar.gz",
"has_sig": false,
"md5_digest": "5824fdc90f3a90dd91bff759d4ec1df4",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.8",
"size": 17922,
"upload_time": "2025-01-08T11:47:47",
"upload_time_iso_8601": "2025-01-08T11:47:47.158385Z",
"url": "https://files.pythonhosted.org/packages/3c/7a/3e397b785ae7097e385dd47ce9c3d41fa49d72490f2e1c3a921f42492f00/upstash_vector-0.7.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-01-08 11:47:47",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "upstash",
"github_project": "vector-py",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "upstash-vector"
}