AsyncIndex¶
AsyncIndex is the asynchronous twin of Index: the
same data-plane methods, each an async def. Use it inside an async with
block. Get one by awaiting pinecone.AsyncPinecone.index(), which resolves
the host for you:
from pinecone import AsyncPinecone
pc = AsyncPinecone(api_key="your-api-key")
async with await pc.index("my-index") as idx:
stats = await idx.describe_index_stats()
Or construct one directly with the index host and an API key, no client needed:
from pinecone import AsyncIndex
async with AsyncIndex(
host="my-index-abc123.svc.pinecone.io",
api_key="your-api-key",
) as idx:
stats = await idx.describe_index_stats()
Leaving the async with block, or calling
close(), releases the HTTP
connection pool.
Method groups:
Documents:
documents, anAsyncDocumentsnamespace for schema-based indexes (upsert,search,fetch,delete,update,list,batch_upsert). See AsyncDocuments below.Vectors:
upsert(),upsert_from_dataframe(),upsert_records(),query(),query_namespaces(),fetch(),fetch_by_metadata(),update(),delete(),list(),list_paginated()Stats:
describe_index_stats()Legacy Records API (legacy integrated indexes):
search(),search_records()Namespaces:
create_namespace(),describe_namespace(),delete_namespace(),list_namespaces(),list_namespaces_paginated()Bulk import:
start_import(),describe_import(),cancel_import(),list_imports(),list_imports_paginated()
- class pinecone.async_client.async_index.AsyncIndex(*, host, api_key=None, additional_headers=None, timeout=30.0, proxy_url=None, proxy_headers=None, ssl_ca_certs=None, ssl_verify=True, source_tag=None, connection_pool_maxsize=0, _limiter_registry=None)[source]¶
Bases:
objectAsynchronous data plane client targeting a specific Pinecone index.
An index’s data plane is where its records live, and this is the client that reads and writes them. Reach one with
await pc.index(name="article-search"), or construct it here from a host URL when you already know the host and want to skip the describe-index lookup that resolving a name costs. Every method is anasync def;Indexis the blocking twin.Only errors specific to a single method are documented on that method. For the exception hierarchy every method shares, see Error handling.
- Parameters:
host (str) – The index-specific data plane host URL. A scheme you include is kept as given;
"http://"is sent in cleartext and emits aRuntimeWarningunless the host is a loopback or RFC 1918 IP address,localhost, or*.localhost.api_key (str | None) – Pinecone API key. Falls back to
PINECONE_API_KEYenv var.additional_headers (Mapping[str, str] | None) – Extra headers included in every request. A name matching one of the SDK’s own headers, in any capitalization, replaces it.
timeout (float) – Request timeout in seconds. Defaults to
30.0.proxy_url (str | None) – HTTP proxy URL for outgoing requests.
ssl_ca_certs (str | None) – Path to a CA certificate bundle for SSL verification.
ssl_verify (bool) – Whether to verify SSL certificates. Defaults to
True.source_tag (str | None) – Tag appended to the User-Agent string for request attribution.
connection_pool_maxsize (int) – Maximum number of connections to keep in the pool.
0(default) uses httpx defaults._limiter_registry (_AdaptiveLimiterRegistry | None)
- Raises:
PineconeValueError – If no API key can be resolved or the host is invalid, or the key is not a valid HTTP header value (blank, or with a trailing newline).
FileNotFoundError – If
ssl_ca_certsnames a path that does not exist, so a mistyped path cannot leave you silently verifying against the default trust store instead. The connection pool is built lazily, so this is raised on the first request rather than at construction. A bundle that exists but cannot be parsed as a certificate raisesssl.SSLErrorat the same point.
Examples
from pinecone import AsyncPinecone async with AsyncPinecone(api_key="your-api-key") as pc: async with await pc.index(name="article-search") as idx: stats = await idx.describe_index_stats() print(stats.total_vector_count)
See also
Index— the same surface, blocking. Sync vs async clients — which lane to pick.- __init__(*, host, api_key=None, additional_headers=None, timeout=30.0, proxy_url=None, proxy_headers=None, ssl_ca_certs=None, ssl_verify=True, source_tag=None, connection_pool_maxsize=0, _limiter_registry=None)[source]¶
- property documents: AsyncDocuments¶
Entry point for document operations on a schema-based index.
A schema-based index stores JSON records instead of raw vectors. Reach the document operations —
upsert,search,fetchand the rest — through here; the vector methods on this class (upsert(),query()) are for a vector-based index. The same instance is returned on every access, and reaching it does not await.- Returns:
AsyncDocumentsnamespace instance.
Examples
>>> from pinecone import AsyncIndex >>> idx = AsyncIndex(host="article-search-abc123.svc.pinecone.io", api_key="...") >>> idx.documents AsyncDocuments()
See also
AsyncDocuments— every document operation, with an example each.
- async upsert_records(*, records, namespace, timeout=None)[source]¶
Upsert text records into a legacy integrated index (legacy Records API).
Serves legacy integrated indexes, created with
create_for_model(): the server embeds each record’s text with the index’s model. On a document index usedocumentsinstead. Upserts apply asynchronously, so a record may not be searchable immediately.- Parameters:
records (list[dict[str, Any]]) – Records to write, each with an
_id(orid) string plus the fields to store, e.g.{"_id": "article-101", "text": "Vector databases for search."}. The index embeds the field its embed configuration maps and stores the rest with the record. A record giving both_idandidkeeps_id.namespace (str) – Target namespace, e.g.
"articles-en". Required: the legacy Records API has no implicit default namespace, so pass"__default__"to write to it.timeout (float | None) – Per-request timeout in seconds, e.g.
10.0. Overrides the client-level default for this call only.
- Returns:
UpsertRecordsResponsewhoserecord_countis the number of records the client sent.- Raises:
PineconeValueError – If namespace is not a non-empty string, records is empty, or a record has no
_id/idfield or one that is not a string. Raised before any request is made.- Return type:
Examples
response = await idx.upsert_records( namespace="articles-en", records=[ {"_id": "article-101", "text": "Vector databases for search."}, {"_id": "article-102", "text": "RAG combines search with LLMs."}, ], ) print(response.record_count)
- async upsert(*, vectors, namespace='', batch_size=None, show_progress=True, max_concurrency=8, timeout=None, total_timeout=None)[source]¶
Upsert a batch of vectors into a namespace.
Serves indexes created with
dimension/metricand legacy integrated indexes; on a document index usedocumentsinstead. A vector whose ID already exists in the namespace is overwritten. Each request is capped on both vector count and encoded size, and wide vectors or large metadata usually hit the size cap first, so passbatch_sizeto split a long sequence into requests that stay under both.- Parameters:
vectors (Sequence[Vector | tuple[str, Sequence[float]] | tuple[str, Sequence[float], Mapping[str, Any]] | Mapping[str, Any]]) – Vectors to upsert. Each element can be a
Vector, a tuple of(id, values)or(id, values, metadata), or a dict withid,values, and optionalsparse_values/metadatakeys.namespace (str) – Target namespace, e.g.
"articles-en". Defaults to the index’s default namespace.batch_size (int | None) – Split vectors into chunks of this size and send one request per chunk, e.g.
100.None(default) sends every vector in one request. Must be a positive integer.show_progress (bool) – When
True(default) andtqdmis installed, display a progress bar that advances as batches complete. No effect whenbatch_sizeisNone.max_concurrency (int) – Most batch requests this call keeps in flight at once, e.g.
16. Defaults to8. Only used whenbatch_sizeis set. A process-wide limit per host also applies and holds concurrency lower when the host pushes back; see Bulk ingest.timeout (float | None) – Timeout in seconds for one attempt of one request, e.g.
30.0. A batch is retried on its own under the client’s retry policy, so this does not bound the whole call.None(default) uses the client-level default.total_timeout (float | None) – Deadline in seconds for the whole batched operation, e.g.
600.0. Only used whenbatch_sizeis set. On expiry no further batches are submitted, batches already in flight are awaited, and unsent batches are reported infailed_items.None(default) means no deadline. Zero or a negative value raisesPineconeValueError.
- Returns:
UpsertResponsewithupserted_count. Withbatch_sizeset, a failed batch does not raise:has_errors,errorsandfailed_itemsreport what did not land, andfailed_itemscan be passed straight back toupsert().response_infothen carries the aggregate LSN of the successful batches, orNoneif no LSN headers came back.- Raises:
PineconeTypeError – If a vector element is not one of the forms listed above.
PineconeValueError – If a vector element is malformed, batch_size is not a positive integer, or max_concurrency is out of range.
PayloadTooLargeError – If
batch_sizeisNoneand the request exceeds the server’s cap on encoded size. Set abatch_sizeand retry.ApiError – If
batch_sizeisNoneand the request exceeds the server’s cap on vectors per request.
- Return type:
Examples
All three vector forms are interchangeable within one call. The values below are truncated to three floats for the page; pass your index’s full dimension.
from pinecone import Vector response = await idx.upsert( vectors=[ Vector(id="article-101", values=[0.012, -0.087, 0.153]), ("article-102", [0.045, 0.021, -0.064]), {"id": "article-103", "values": [0.091, -0.032, 0.178]}, ], namespace="articles-en", ) print(response.upserted_count)
For a sequence too long for one request (
embeddingsbelow being your whole list of vectors), setbatch_sizeand resend what did not land:response = await idx.upsert( vectors=embeddings, namespace="articles-en", batch_size=100, ) if response.has_errors: await idx.upsert(vectors=response.failed_items, namespace="articles-en")
See also
upsert_records(): text in, embedded server-side, for a legacy integrated index.upsert_from_dataframe(): the same write from a pandas DataFrame, batched for you.start_import(): millions of vectors from cloud storage, server-side and asynchronous.
- async upsert_from_dataframe(df, namespace=None, batch_size=500, show_progress=True, timeout=None, *, max_concurrency=None, total_timeout=None, on_error=None)[source]¶
Upsert vectors from a pandas DataFrame, in batches.
Serves indexes created with
dimension/metricand legacy integrated indexes; on a document index usedocumentsinstead. Each row becomes one vector, and the rows are sent throughupsert()withbatch_sizeset, so a batch that fails is reported on the response rather than raised unless you passon_error="raise".pandasis not an SDK dependency; install it yourself.- Parameters:
df (pd.DataFrame) – A
pandas.DataFramewithidandvaluescolumns and, optionally,sparse_valuesandmetadatacolumns. A missing cell (NoneorNaN) in an optional column leaves that field off the vector.namespace (str | None) – Target namespace, e.g.
"articles-en".None(default) targets the index’s default namespace.batch_size (int) – Rows per upsert request, e.g.
100. Defaults to500. Lower it for wide vectors or large metadata.show_progress (bool) – When
True(default) andtqdmis installed, display a progress bar that advances as batches complete.timeout (float | None) – Timeout in seconds for one attempt of one batch’s request, e.g.
30.0. A batch is retried on its own under the client’s retry policy, so this does not bound the whole call.None(default) uses the client-level default.max_concurrency (int | None) – Most batch requests this call keeps in flight at once, e.g.
16.None(default) uses8. A process-wide limit per host also applies and holds concurrency lower when the host pushes back; see Bulk ingest.total_timeout (float | None) – Deadline in seconds for the whole ingest, e.g.
600.0. On expiry no further batches are submitted, batches already in flight are awaited, and unsent rows are reported infailed_items.None(default) means no deadline. Zero or a negative value raisesPineconeValueError.on_error (str | None) – What to do when some batches fail.
"collect"(Nonebehaves the same) returns the response witherrorsandfailed_itemsfilled in. This holds when every batch fails too: nothing raises, so checkresponse.has_errors."raise"raises the lowest-indexed batch failure once every batch has settled, with the partial response on the exception’sresponseattribute.
- Returns:
UpsertResponsewithupserted_counttotalled across the batches that landed, plushas_errors,errorsandfailed_itemsfor the ones that did not.failed_itemscan be passed straight back toupsert().- Raises:
RuntimeError – If
pandasis not installed.PineconeValueError – If df is not a
pandas.DataFrameor lacks anidorvaluescolumn, batch_size is not a positive integer, max_concurrency is out of range, or on_error is not"collect"or"raise".PineconeTimeoutError – If
on_error="raise"and a batch exhausted its retries on timeout.
- Return type:
Examples
A
metadatacolumn is optional; where it is present its dict lands on the vector as written. The values below are truncated to three floats for the page; pass your index’s full dimension.import pandas as pd df = pd.DataFrame([ { "id": "article-101", "values": [0.012, -0.087, 0.153], "metadata": {"topic": "science", "year": 2024}, }, { "id": "article-102", "values": [0.045, 0.021, -0.064], "metadata": {"topic": "technology", "year": 2024}, }, ]) response = await idx.upsert_from_dataframe( df, namespace="articles-en", batch_size=100, ) if response.has_errors: await idx.upsert(vectors=response.failed_items, namespace="articles-en")
See also
upsert(): the same batched write from a list of vectors, with nopandasdependency.start_import(): millions of vectors from cloud storage, server-side and asynchronous.
- async query(*, top_k, vector=None, id=None, namespace='', filter=None, include_values=False, include_metadata=False, sparse_vector=None, scan_factor=None, max_candidates=None, timeout=None)[source]¶
Query a namespace for the nearest neighbors of a vector you supply.
Serves indexes created with
dimension/metricand legacy integrated indexes; on a document index usedocumentsinstead. You supply the query vector; nothing is embedded for you. Pass a dense vector, a sparse_vector, both for a hybrid query, or the id of a stored vector to use as the query.- Parameters:
top_k (int) – Number of results to return, e.g.
5. The server caps it.vector (list[float] | None) – Dense query vector, at your index’s dimension.
id (str | None) – ID of a stored vector to use as the query, e.g.
"article-101". Cannot be combined with vector or sparse_vector.namespace (str) – Namespace to query, e.g.
"articles-en". Defaults to the index’s default namespace.filter (dict[str, Any] | None) – Metadata filter expression restricting which vectors are searched, e.g.
{"year": {"$gte": 2020}}.include_values (bool) – Return each match’s vector values.
False(default) keeps the response small.include_metadata (bool) – Return each match’s metadata. Set it when you need the fields you filtered on back in the result.
sparse_vector (SparseValues | dict[str, Any] | None) – Sparse query vector with indices and values, e.g.
{"indices": [17, 42], "values": [0.4, 0.9]}. Combine it with vector for a hybrid query on a dense index with thedotproductmetric.scan_factor (float | None) – Recall/latency trade for dense indexes on dedicated read nodes: a multiplier on how much of the index is scanned. Above 1 scans more and favors recall; below 1 scans less and favors latency. Omit to let the server choose.
max_candidates (int | None) – Recall/latency trade for dense indexes on dedicated read nodes: caps how many candidates are reranked before top_k is taken. Must be at least top_k.
timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
QueryResponsewithmatches(ordered from most to least similar, each carryingidandscore),namespace, andusage.- Raises:
PineconeValueError – If top_k is not positive or exceeds the server’s maximum, if id is combined with vector or sparse_vector, if none of vector, id, or sparse_vector is given, or if id is not a legal vector ID. Raised before any request is sent.
ApiError – If scan_factor or max_candidates is set on an index that does not run on dedicated read nodes, or on a sparse index.
- Return type:
Examples
Query vectors are truncated to three floats on this page; pass your index’s full dimension.
response = await idx.query( top_k=5, vector=[0.012, -0.087, 0.153], namespace="articles-en", ) for match in response.matches: print(match.id, match.score)
A
filternarrows the search before ranking, andinclude_metadatareturns the fields it selected on:response = await idx.query( top_k=5, vector=[0.012, -0.087, 0.153], namespace="movies-en", filter={"genre": "comedy", "year": {"$gte": 2020}}, include_metadata=True, ) for match in response.matches: print(match.id, match.score, match.metadata["genre"])
See also
search(): the same search on a legacy integrated index, where you pass text and the server embeds it.query_namespaces(): the same query fanned out over several namespaces, merged into one ranking.
- async query_namespaces(*, vector=None, namespaces, metric, top_k=None, filter=None, include_values=False, include_metadata=False, sparse_vector=None, scan_factor=None, max_candidates=None, timeout=None)[source]¶
Query several namespaces at once and merge them into one ranking.
Serves indexes created with
dimension/metricand legacy integrated indexes. Runs onequery()per namespace concurrently, then merges the results so you get the overall top-k rather than top-k per namespace. The merge ranks by metric, which the client does not read off the index, so pass the metric the index was created with.- Parameters:
vector (list[float] | None) – Dense query vector. Omit it on a sparse index and pass sparse_vector instead.
namespaces (list[str]) – Namespaces to query, e.g.
["articles-en", "articles-fr"]. Must be non-empty; duplicates are removed while preserving order.metric (str) – Metric the index was created with:
"cosine","euclidean", or"dotproduct". A wrong metric is not rejected; the merged ranking just comes out in the wrong order.top_k (int | None) – Number of results to return after merging, e.g.
10. Defaults to 10. Each namespace is queried for this many.filter (dict[str, Any] | None) – Metadata filter expression applied to every namespace, e.g.
{"year": {"$gte": 2020}}.include_values (bool) – Return each match’s vector values.
include_metadata (bool) – Return each match’s metadata.
sparse_vector (SparseValues | dict[str, Any] | None) – Sparse query vector with indices and values. Required on a sparse index, where vector is omitted.
scan_factor (float | None) – Recall/latency trade for dense indexes on dedicated read nodes, applied to every namespace. See
query().max_candidates (int | None) – Candidate cap for dense indexes on dedicated read nodes, applied per namespace. Must be at least top_k.
timeout (float | None) – Per-request timeout in seconds, applied to each namespace’s query rather than to the call as a whole.
- Returns:
QueryNamespacesResultswith the mergedmatches,usagetotalled over every namespace, andns_usagekeyed by namespace name. A match does not record which namespace produced it, so query one namespace at a time when you need that.- Raises:
PineconeValueError – If namespaces is empty, if both vector and sparse_vector are absent or empty, or if metric is not one of
"cosine","euclidean", or"dotproduct". Raised before any request is sent.ApiError – If any one namespace’s query fails. The first failure propagates and the merged result is lost, so retry the whole call.
- Return type:
Examples
The query vector is truncated to three floats on this page; pass your index’s full dimension.
results = await idx.query_namespaces( vector=[0.012, -0.087, 0.153], namespaces=["articles-en", "articles-fr", "articles-de"], metric="cosine", top_k=10, ) for match in results.matches: print(match.id, match.score)
On a sparse index, pass sparse_vector instead and rank by
"dotproduct":results = await idx.query_namespaces( sparse_vector={"indices": [17, 42, 108], "values": [0.4, 0.9, 0.2]}, namespaces=["articles-en", "articles-fr"], metric="dotproduct", top_k=10, )
See also
query(): one namespace, and the only form that takes an id as the query.
- async fetch(*, ids, namespace='', timeout=None)[source]¶
Fetch vectors by their IDs, exactly as stored.
Serves indexes created with
dimension/metricand legacy integrated indexes; on a document index usedocumentsinstead. A lookup, not a search: nothing is ranked and no score is returned. An ID that is not in the namespace is silently absent from the result, so compare the keys you got back against the ones you asked for.- Parameters:
ids (list[str]) – Vector IDs to fetch, e.g.
["article-101", "article-102"]. Must be non-empty.namespace (str) – Namespace to fetch from, e.g.
"articles-en". Defaults to the index’s default namespace.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
FetchResponsewithvectors, a map of ID toVectorholding values and metadata as stored, plusnamespaceandusage. IDs the namespace does not hold are absent from the map rather than raising.- Raises:
PineconeValueError – If ids is empty or holds an ID that is empty, non-ASCII, contains a NUL, or is longer than the API allows. Raised before any request is sent.
- Return type:
Examples
wanted = ["article-101", "article-102"] response = await idx.fetch(ids=wanted, namespace="articles-en") for vid, vec in response.vectors.items(): print(vid, vec.metadata) print("not in this namespace:", set(wanted) - set(response.vectors))
See also
fetch_by_metadata(): when you know the metadata you want rather than the IDs.query(): when you want the nearest vectors rather than named ones.
- async fetch_by_metadata(*, filter, namespace='', limit=None, pagination_token=None, timeout=None)[source]¶
Fetch one page of the vectors whose metadata matches a filter.
Serves indexes created with
dimension/metricand legacy integrated indexes; on a document index usedocumentsinstead. A lookup, not a search: matches are not ranked and carry no score. One page is returned per call, so followpagination.nextto reach the rest.- Parameters:
filter (dict[str, Any]) – Metadata filter expression, e.g.
{"year": {"$gte": 2020}}. Must carry at least one condition; an empty filter is rejected rather than treated as “match everything”.namespace (str) – Namespace to fetch from, e.g.
"movies-en". Defaults to the index’s default namespace.limit (int | None) – Maximum number of vectors in this page, e.g.
100. Omit to let the server choose the page size.pagination_token (str | None) –
pagination.nextfrom the previous response.None(default) fetches the first page.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
FetchByMetadataResponsewithvectorsas stored, plusnamespace,usage, andpagination, which holds the next page’s token innextand isNoneon the last page.- Raises:
PineconeValueError – If filter is empty or limit is not a positive integer within the API’s maximum page size. Raised before any request is sent.
- Return type:
Examples
response = await idx.fetch_by_metadata( filter={"genre": "comedy", "year": {"$gte": 2020}}, namespace="movies-en", ) for vid, vec in response.vectors.items(): print(vid, vec.metadata)
See also
fetch(): when you already know the IDs.query(): when you want the nearest vectors to a query rather than every vector a filter admits.Pagination: walking every page.
- async delete(*, ids=None, delete_all=False, filter=None, namespace='', timeout=None)[source]¶
Delete vectors from a namespace by ID, by filter, or all of them.
Serves indexes created with
dimension/metricand legacy integrated indexes; on a document index usedocumentsinstead. Pass exactly one selector: ids, filter, ordelete_all=True. The delete is irreversible, and IDs the namespace does not hold are ignored rather than reported, so a successful call is not evidence anything was deleted.- Parameters:
ids (list[str] | None) – Vector IDs to delete, e.g.
["article-101", "article-102"].delete_all (bool) – Delete every vector in namespace. The namespace itself survives;
delete_namespace()removes that too.filter (dict[str, Any] | None) – Metadata filter expression selecting what to delete, e.g.
{"status": {"$eq": "retracted"}}. Must carry at least one condition. The client refuses ids alongside filter, because the server would apply the filter alone and delete everything it matches rather than the intersection; to delete the intersection,query()with the filter first and delete the IDs you get back.namespace (str) – Namespace to delete from, e.g.
"articles-en". Defaults to the index’s default namespace.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
None. A successful delete returns no payload.
- Raises:
PineconeValueError – If zero or more than one selector is given, if filter is empty, or if an ID is not a legal vector ID. Raised before any request is sent.
- Return type:
None
Examples
By ID:
await idx.delete( ids=["article-101", "article-102"], namespace="articles-en", )
By metadata filter, which deletes every vector the filter admits:
await idx.delete( filter={"status": {"$eq": "retracted"}}, namespace="articles-en", )
Emptying a whole namespace cannot be undone:
await idx.delete(delete_all=True, namespace="articles-staging")
See also
delete_namespace(): removes the namespace along with everything in it, wheredelete_all=Trueempties it and leaves it in place.
- async update(*, id=None, values=None, sparse_values=None, set_metadata=None, namespace='', filter=None, dry_run=False, timeout=None)[source]¶
Patch one vector by ID, or patch metadata across a filter.
Serves indexes created with
dimension/metricand legacy integrated indexes; on a document index usedocumentsinstead. A partial update: fields you do not mention keep the values they had, soset_metadata={"year": 2021}leaves every other metadata key in place. Pass exactly one selector, id or filter; a by-filter update is metadata-only, since values and sparse_values belong to one record. The write applies asynchronously, so a read straight afterwards can still see the old value.- Parameters:
id (str | None) – ID of the one vector to patch, e.g.
"article-101".values (list[float] | None) – Replacement dense values, at your index’s dimension. Only with id.
sparse_values (SparseValues | dict[str, Any] | None) – Replacement sparse vector, with
indicesandvalues. Only with id.set_metadata (dict[str, Any] | None) – Metadata keys to set or overwrite, e.g.
{"year": 2021}. Keys you omit are left as they are; this never clears a field.namespace (str) – Namespace to target, e.g.
"movies-en". Defaults to the index’s default namespace.filter (dict[str, Any] | None) – Metadata filter expression selecting which vectors to patch, e.g.
{"genre": {"$eq": "drama"}}. Must carry at least one condition.dry_run (bool) – Report how many records the filter would touch without writing anything. Ignored for a by-ID update. Run it first when the filter is broader than you can check by eye.
timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
UpdateResponsewhosematched_recordscounts the records the filter matched, which underdry_runare the records that would have been patched. It isNonefor a by-ID update, which reports no count.- Raises:
PineconeValueError – If both or neither of id and filter are given, if filter is combined with values or sparse_values, if filter is empty, or if id is not a legal vector ID. Raised before any request is sent.
- Return type:
Examples
Replacing one vector’s values, truncated here to three floats:
await idx.update( id="article-101", values=[0.012, -0.087, 0.153], namespace="articles-en", )
Patching metadata across a filter.
dry_runreports the reach first, and thegenreof every patched record survives untouched:preview = await idx.update( filter={"genre": {"$eq": "drama"}}, set_metadata={"reviewed": True}, namespace="movies-en", dry_run=True, ) print(preview.matched_records) await idx.update( filter={"genre": {"$eq": "drama"}}, set_metadata={"reviewed": True}, namespace="movies-en", )
See also
upsert(): replaces a whole vector rather than patching it, and creates it if the ID is new.
- async search(*, namespace, top_k=None, inputs=None, vector=None, id=None, filter=None, fields=None, rerank=None, match_terms=None, query=None, timeout=None)[source]¶
Search records by text, vector, or ID, optionally reranking (legacy Records API).
Give exactly one query source. Text in inputs needs a legacy integrated index, created with
create_for_model(), whose model embeds it server-side. A vector or id query also works on an index created withdimension/metric, thoughquery()is the usual call there. On a document index usedocumentsinstead.- Parameters:
namespace (str) – Namespace to search, e.g.
"articles-en". Required: pass"__default__"to search the default namespace.top_k (int) – Number of results to return, at least 1, e.g.
10. Required unless query is given.inputs (SearchInputs | dict[str, Any] | None) – Text for the index’s model to embed, e.g.
{"text": "trail running shoes"}.SearchInputsgives typed keys and IDE completion.vector (list[float] | dict[str, Any] | None) – Query vector. A
list[float]is a dense query; a dict withvalues,sparse_indicesand/orsparse_valuesis a sparse or hybrid one.SearchQueryVectoris the typed helper.id (str | None) – ID of a stored record whose vector is the query, e.g.
"article-101".filter (dict[str, Any] | None) – Metadata filter, e.g.
{"category": {"$eq": "footwear"}}.fields (list[str] | None) – Record fields to return in each hit, e.g.
["title", "text"].Nonereturns every stored field.rerank (RerankConfig | dict[str, Any] | None) – Rerank the hits in the same call. Needs
modelandrank_fields;top_n,parametersandqueryare optional.RerankConfiggives IDE completion.match_terms (dict[str, Any] | None) – Require hits to contain query terms, e.g.
{"strategy": "all", "terms": ["running", "shoes"]}. Valid only with inputs, on a sparse index whose model supports it; the server names the supported model when it refuses.timeout (float | None) – Per-request timeout in seconds, e.g.
10.0. Overrides the client-level default for this call only.query (SearchQuery | dict[str, Any] | None) – The older nested form of this call:
top_kplus one query source in one mapping. Pass the fields directly instead.
- Returns:
SearchRecordsResponsewhoseresult.hitsrun from most to least relevant. Read eachHitashit.id,hit.scoreandhit.fields.usagereports read units, plus embedding tokens and rerank units when those stages ran.- Raises:
PineconeValueError – If namespace is not a non-empty string, top_k is missing or below 1, no query source is given, a vector dict has an unsupported key, or rerank lacks
modelorrank_fields. Raised before any request is made.TypeError – If
queryis combined with any of the flat keyword arguments it replaces (top_k,inputs,vector,id,filter,match_terms), so pass one form or the other, not both; or ifqueryis neither aSearchQuerynor a mapping.
- Return type:
Examples
Text in, embedded server-side. The hits nest one level down, under
result:response = await idx.search( namespace="articles-en", top_k=10, inputs={"text": "benefits of vector databases for search"}, fields=["title", "text"], ) for hit in response.result.hits: print(hit.id, hit.score, hit.fields["title"])
Reranking in the same call retrieves
top_khits and returns thetop_nthe reranker scores highest:response = await idx.search( namespace="articles-en", top_k=50, inputs={"text": "benefits of vector databases"}, rerank={ "model": "bge-reranker-v2-m3", "rank_fields": ["text"], "top_n": 5, }, )
See also
query(): search with a vector you embedded yourself.Inference.rerank(): rerank results that came from somewhere other than this index.
- async search_records(*, namespace, top_k=None, inputs=None, vector=None, id=None, filter=None, fields=None, rerank=None, match_terms=None, query=None, timeout=None)[source]¶
Alias for
search()(legacy Records API), kept for callers written against 9.x.Every argument, return value and error is
search()’s. Call that one in new code.
- async list_paginated(*, prefix=None, limit=None, pagination_token=None, namespace='', timeout=None)[source]¶
Fetch one page of vector IDs, holding the pagination token yourself.
Serves indexes created with
dimension/metricand legacy integrated indexes; on a document index usedocumentsinstead. Returns IDs only, without values or metadata.list()walks the pages for you; use this one when you need to keep the token between calls.- Parameters:
prefix (str | None) – Return only IDs starting with this prefix, e.g.
"article-2024#". Must be ASCII, without a NUL character, and no longer than the API allows. The empty prefix matches everything.limit (int | None) – Maximum number of IDs in this page, e.g.
50. Must be a positive integer within the API’s maximum page size.Noneuses the server’s default page size.pagination_token (str | None) –
pagination.nextfrom the previous response.None(default) fetches the first page.namespace (str) – Namespace to list from, e.g.
"articles-en". Defaults to the default namespace.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
ListResponsewhosevectorsareListItementries carrying only anid, plusnamespace,usage, andpagination.pagination.nextis the token for the following page; the last page carries no token.- Raises:
PineconeValueError – If prefix or limit is not legal. Raised before any request is sent.
- Return type:
Examples
response = await idx.list_paginated( prefix="article-2024#", limit=50, namespace="articles-en", ) for item in response.vectors: print(item.id) next_token = response.pagination.next if response.pagination else None
See also
list(): the same listing with the token handled for you.fetch(): the vectors behind those IDs.Pagination: how the SDK pages generally.
- list(*, prefix=None, limit=None, namespace='', timeout=None)[source]¶
List vector IDs in a namespace, a page at a time.
Serves indexes created with
dimension/metricand legacy integrated indexes; on a document index usedocumentsinstead. Returns IDs only, without values or metadata. Yields one page per iteration and follows the pagination tokens itself. Nothing is requested until you iterate, so a bad prefix or limit is not reported until then either.- Parameters:
prefix (str | None) – Return only IDs starting with this prefix, e.g.
"article-2024#". Must be ASCII, without a NUL character, and no longer than the API allows. The empty prefix matches everything.limit (int | None) – Maximum number of IDs per page, e.g.
50. Must be a positive integer within the API’s maximum page size.Noneuses the server’s default page size.namespace (str) – Namespace to list from, e.g.
"articles-en". Defaults to the default namespace.timeout (float | None) – Per-request timeout in seconds, applied to each underlying page request. Overrides the client-level default for this call only.
- Yields:
ListResponseper page, whosevectorscarry the IDs. A page with no IDs is skipped rather than yielded.- Raises:
PineconeValueError – If prefix or limit is not legal. Raised on first iteration, not at the call.
- Return type:
Examples
async for page in idx.list(prefix="article-2024#", namespace="articles-en"): ids = [item.id for item in page.vectors] fetched = await idx.fetch(ids=ids, namespace="articles-en") for vid, vec in fetched.vectors.items(): print(vid, vec.metadata)
See also
list_paginated(): one page, with the token in your hands.fetch(): the vectors behind a page of IDs.Pagination: how the SDK pages generally.
- async describe_index_stats(*, filter=None, timeout=None)[source]¶
Report vector counts per namespace, dimension, and fullness for this index.
Works on every kind of index, including document indexes. The counts lag writes, so a record just upserted may not be counted yet.
- Parameters:
- Returns:
DescribeIndexStatsResponsewithtotal_vector_count,dimension,index_fullness, andnamespaces, which maps each namespace name to aNamespaceSummarycarrying itsvector_count. The default namespace appears under"__default__".- Raises:
ApiError – If filter is non-empty.
- Return type:
Examples
stats = await idx.describe_index_stats() print(stats.dimension, stats.index_fullness) for name, summary in stats.namespaces.items(): print(name, summary.vector_count)
See also
list_namespaces(): per-namespace record counts alongside each namespace’s schema andsize_bytes.
- async create_namespace(*, name, schema=None)[source]¶
Create a named namespace in the index.
Optional: upserting into a name that does not exist yet creates the namespace. Create one explicitly when it must exist before any data lands in it, or to choose which metadata fields it indexes. Not idempotent: an existing name raises
ConflictError.- Parameters:
name (str) – Name for the new namespace, e.g.
"movies-en". Must be non-empty ASCII without the NUL character, and no longer than the API’s maximum name length.__default__is reserved and cannot be created. On an index created withdimension/metricit names the namespace requests address when they omit one, which always exists; on a document index, upserting documents into__default__creates it.schema (dict[str, Any] | None) – Optional metadata-index configuration,
{"fields": {<field>: {"filterable": True}}}. Omitting it does not mean “index everything”: the namespace inherits the index’s own metadata-index configuration. Supply schema to index exactly the fields listed in this namespace. Each field must setfilterabletoTrue; to leave a field unindexed, omit it fromfields.
- Returns:
NamespaceDescriptionwith the namespacename,record_count,schema,indexed_fieldsandsize_bytes.- Raises:
PineconeValueError – If name violates the rules above, or schema is malformed. Raised before any request is sent.
ConflictError – a namespace of that name already exists.
- Return type:
Examples
ns = await idx.create_namespace(name="movies-en") print(ns.name, ns.record_count, ns.size_bytes)
Naming the filterable fields up front overrides what the namespace would otherwise inherit from the index:
ns = await idx.create_namespace( name="movies-fr", schema={"fields": {"genre": {"filterable": True}}}, ) print(ns.indexed_fields)
See also
describe_namespace(): the same description for a namespace that already exists.list_namespaces(): the namespaces the index already has.
- async describe_namespace(*, name=None, **kwargs)[source]¶
Describe a namespace by name.
Rate limited per index. To describe more than one namespace, use
list_namespaces(), which returns a whole page of descriptions per request.- Parameters:
name (str) – Name of the namespace to describe, e.g.
"movies-en". Must be non-empty ASCII without the NUL character, and no longer than the API’s maximum name length. On an index created withdimension/metric, pass__default__to describe the namespace requests address when they omit one. On a document index__default__is an ordinary name, so describing it raisesNotFoundErroruntil documents are upserted into it.kwargs (str)
- Returns:
NamespaceDescriptionwith the namespacename,record_count,schema,indexed_fieldsandsize_bytes.size_bytesis approximate.- Raises:
PineconeValueError – If name violates the rules above. Raised before any request is sent.
TypeError – If unexpected keyword arguments are passed.
NotFoundError – no namespace of that name exists on the index.
RateLimitError – this operation’s per-index limit was exceeded. Use
list_namespaces()to describe many namespaces.
- Return type:
Examples
ns = await idx.describe_namespace(name="movies-en") print(ns.name, ns.record_count, ns.size_bytes)
On an index created with
dimension/metric, the namespace that unnamespaced requests address answers to__default__:ns = await idx.describe_namespace(name="__default__") print(ns.record_count)
See also
list_namespaces(): every namespace, a page of descriptions per request.
- async delete_namespace(*, name=None, timeout=None, **kwargs)[source]¶
Delete a namespace and everything in it.
Irreversible: every record in the namespace is deleted, and the namespace itself stops existing. To empty a namespace but keep it, use
delete()withdelete_all=True.- Parameters:
- Returns:
None. A successful delete returns no payload.
- Raises:
PineconeValueError – If name violates the rules above. Raised before any request is sent.
TypeError – If unexpected keyword arguments are passed.
NotFoundError – no namespace of that name exists on the index.
- Return type:
None
Examples
await idx.delete_namespace(name="movies-deprecated")
See also
delete():delete_all=Trueempties a namespace and leaves it in place.
- async list_namespaces_paginated(*, prefix=None, limit=None, pagination_token=None)[source]¶
Fetch one page of namespace descriptions, holding the token yourself.
list_namespaces()walks the pages for you; reach for this one when you need to persist the token between calls or hand it to a caller of your own.- Parameters:
prefix (str | None) – Return only namespaces whose names start with this prefix, e.g.
"movies-". Same character rules as namespace names; the empty prefix matches every namespace.limit (int | None) – Maximum number of namespaces in this page, e.g.
50.None(default) lets the server choose.pagination_token (str | None) –
pagination.nextfrom the previous response.None(default) fetches the first page.
- Returns:
ListNamespacesResponsewithnamespaces(each aNamespaceDescription),total_countacross every page, andpagination, whosenextisNoneon the last page.- Raises:
PineconeValueError – If prefix or limit is out of range. Raised before any request is sent.
- Return type:
Examples
response = await idx.list_namespaces_paginated(prefix="movies-", limit=10) for ns in response.namespaces: print(ns.name, ns.record_count, ns.size_bytes) next_token = response.pagination.next if response.pagination else None
See also
list_namespaces(): the same listing with the token handled for you.Pagination: how the SDK pages generally.
- list_namespaces(*, prefix=None, limit=None)[source]¶
List every namespace, a page at a time.
Yields one
ListNamespacesResponseper page and follows the pagination tokens itself, so nothing is requested until you iterate. Each page describes many namespaces in one request, so prefer this over repeateddescribe_namespace()calls, which are rate limited per index.- Parameters:
- Yields:
ListNamespacesResponseper page, each carryingnamespacesofNamespaceDescription. A page with no namespaces is skipped rather than yielded.- Raises:
PineconeValueError – If prefix or limit is out of range. Raised on first iteration, not at the call.
- Return type:
Examples
async for page in idx.list_namespaces(prefix="movies-"): for ns in page.namespaces: print(ns.name, ns.record_count, ns.size_bytes)
See also
list_namespaces_paginated(): one page, with the token in your hands.describe_namespace(): one namespace, when you know its name.Pagination: how the SDK pages generally.
- async start_import(uri, *, error_mode=None, integration_id=None)[source]¶
Start a server-side bulk import of vectors from cloud storage.
Returns as soon as the server accepts the import, not when it finishes: poll
describe_import()for the outcome. Imports work on indexes created withdimension/metricand on document indexes; the server refuses them on an index with integrated embedding (a legacy integrated index, or a document index with anembedfield).- Parameters:
uri (str) – Directory prefix holding the Parquet files, not a single file. Three forms are accepted:
s3://for Amazon S3,gs://for Google Cloud Storage, and anhttps://URL naming an Azure Blob Storage container.s3://additionally requires that the index itself be hosted on AWS.error_mode (str | None) – How to handle a record the import cannot read.
"continue"skips it and imports the rest;"abort"ends the whole import at the first such record. Case-insensitive. Defaults to"abort"when omitted, so an unreadable record fails the import unless you opt into skipping.integration_id (str | None) – ID of a storage integration in your project that grants Pinecone read access to a private bucket. Its cloud provider must match the scheme of uri.
- Returns:
StartImportResponsewithid, the handle the other import methods take.- Raises:
PineconeValueError – If error_mode is supplied but is neither
"continue"nor"abort". Raised before any HTTP request is made.ApiError – If the server rejects uri (for example, an
s3://URI on an index not hosted on AWS) or the index uses integrated embedding.
- Return type:
Examples
Starting an import and waiting it out is on you; three of the five statuses are terminal:
import asyncio response = await idx.start_import(uri="s3://article-embeddings/2024/") import_op = await idx.describe_import(response.id) while import_op.status not in ("Completed", "Failed", "Cancelled"): await asyncio.sleep(10) import_op = await idx.describe_import(response.id) print(import_op.status, import_op.records_imported)
error_mode="continue"finishes the import around records it cannot read, rather than stopping at the first one:response = await idx.start_import( uri="s3://article-embeddings/2024/", error_mode="continue", )
Note
uri must name a directory of Parquet files following Pinecone’s import schema. See the import guide for that schema and the supported storage formats.
See also
describe_import(): progress and the terminal status.cancel_import(): stops an import that is still running.upsert(): writes vectors directly, for data too small to need an import.
- async describe_import(id)[source]¶
Describe a bulk import operation by ID.
- Parameters:
id (str | int) – The
idstart_import()returned, e.g."1". Anintis accepted and converted to a string.- Returns:
ImportModelwithstatus("Pending","InProgress","Failed","Completed", or"Cancelled"; the last three are terminal),percent_complete,records_imported,uri, anderrorwhen it failed.- Raises:
PineconeTypeError – If id is neither a
strnor anint.PineconeValueError – If id is empty or too long. Raised before any HTTP request is made.
- Return type:
Examples
import_op = await idx.describe_import("1") print(import_op.status, import_op.percent_complete) if import_op.status == "Failed": print(import_op.error)
See also
start_import(): starts an import and returns theidthese methods take.list_imports(): every import on the index, when you do not have anid.
- async cancel_import(id)[source]¶
Cancel a bulk import operation by ID.
- Parameters:
id (str | int) – The
idstart_import()returned, e.g."1". Anintis accepted and converted to a string.- Returns:
None. Poll
describe_import()to see the import reach"Cancelled".- Raises:
PineconeTypeError – If id is neither a
strnor anint.PineconeValueError – If id is empty or too long. Raised before any HTTP request is made.
- Return type:
None
Examples
await idx.cancel_import("1")
See also
start_import(): starts an import and returns theidthese methods take.list_imports(): every import on the index, when you do not have anid.
- list_imports(*, limit=None, pagination_token=None)[source]¶
List every bulk import on this index, following pagination.
Yields
ImportModelobjects rather than pages, and fetches the next page as you exhaust the current one, so nothing is requested until you iterate. See Pagination.- Parameters:
- Yields:
ImportModelfor each import operation.- Raises:
ApiError – If a page request fails part-way through the listing; the imports already yielded are still yours, the rest are not.
- Return type:
Examples
async for imp in idx.list_imports(): print(imp.id, imp.status, imp.uri)
See also
list_imports_paginated(): one page at a time, with the token in your hands.describe_import(): one import, when you know itsid.
- async list_imports_paginated(*, limit=None, pagination_token=None)[source]¶
Fetch one page of bulk imports, holding the token yourself.
list_imports()walks the pages for you; use this one when you need to persist the token between calls. See Pagination.- Parameters:
- Returns:
ImportListyou can iterate for this page’sImportModelobjects, withpagination.nextholding the token for the following page orNoneon the last one.- Return type:
Examples
page = await idx.list_imports_paginated(limit=10) for imp in page: print(imp.id, imp.status) next_token = page.pagination.next if page.pagination else None
See also
list_imports(): the same listing with the token handled for you.
- async close()[source]¶
Close the underlying HTTP client and release its resources.
Calls on a closed index fail. Prefer
async withover calling this by hand, which closes the client even if the body raises.- Returns:
None.
- Return type:
None
Examples
async with await pc.index(name="article-search") as idx: await idx.upsert( vectors=[("article-101", [0.012, -0.087, 0.153])], namespace="articles-en", )
- async __aenter__()[source]¶
Enter the async context manager, returning this index.
- Returns:
This
AsyncIndexinstance.- Return type:
Examples
async with await pc.index(name="article-search") as idx: await idx.upsert( vectors=[("article-101", [0.012, -0.087, 0.153])], namespace="articles-en", )
AsyncDocuments¶
- class pinecone.async_client.documents.AsyncDocuments(*, http, host)[source]¶
Bases:
objectDocument data-plane operations for a schema-based index.
A schema-based index stores JSON documents instead of raw vectors. Every document carries the reserved
_idkey; every other key is a field of your own, either declared in the index schema or free-form metadata. Accessed viadocuments. Not constructed directly; the parentAsyncIndexbuilds and caches its own instance on first access.On a vector-based index, use the vector methods on
AsyncIndexitself (upsert(),query()) rather than this namespace. Every method here is keyword-only. A positional argument raisesPineconeValueErrorlisting the accepted keywords, and a misspelled keyword raisesTypeErrorsuggesting the one you meant.Examples
On an index whose schema declares
embeddingas a 1536-dimensiondense_vectorandtitleas a full-textstring:from pinecone import AsyncPinecone pc = AsyncPinecone(api_key="your-api-key") idx = await pc.index(name="articles-en") async with idx: await idx.documents.upsert( namespace="published", documents=[ { "_id": "article-101", "embedding": [0.1] * 1536, "title": "Intro to vectors", } ], )
See also
Error handling: the exceptions any of these methods can raise, and which ones are worth retrying.
- Parameters:
http (AsyncHTTPClient)
host (str)
- async upsert(*, namespace, documents, timeout=None)[source]¶
Upsert documents into a namespace.
Each document must include an
_idfield (a unique, non-empty ASCII string). If a document with the same_idalready exists in the namespace, it is overwritten.The index schema decides which other fields a document must carry; read it with
pc.indexes.describe(name).schema. Everydense_vectorfield is required, and so is everystringfield declared withembed, because Pinecone embeds its text on write.sparse_vectorfields,stringfields with onlysparse_embedor full-text search, and metadata are optional. Each document also needs at least one searchable schema field: a vector field, or astringfield with full-text search,embedorsparse_embed. The server rejects a document that breaks either rule with a 400 that names the document and the fields it needs.Pinecone applies the upsert asynchronously, so documents may not be immediately visible to
search()orfetch().- Parameters:
namespace (str) – Target namespace (required, non-empty).
documents (Sequence[Mapping[str, Any] | DocumentRecord]) – The documents to upsert. Each element is a dict with an
_idkey or aDocumentRecord. The server limits a request by document count (a lower count on an index with anembedorsparse_embedfield) and by encoded size, so documents that carry large fields, such as high-dimensional dense vectors, fit fewer per request. For large lists, or documents of unknown size, usebatch_upsert(), which handles the size limit.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only. Must be greater than zero.
- Returns:
UpsertDocumentsResponsewith the count of documents accepted for upsert.usage.embed_total_tokenscounts the tokens Pinecone embedded forembedandsparse_embedfields;usageisNonewhen the upsert embedded no text.- Raises:
PineconeValueError – If
namespaceis empty,documentsis empty or longer than one request accepts, or any document has a missing, empty, non-string, non-ASCII, overlong, or duplicate_id; the message names the offending document’s position. Also raised iftimeoutis zero or negative.ApiError – If a document lacks a field its schema requires (400).
PayloadTooLargeError – If one request exceeds the server’s cap on encoded request size, which a request within the document-count limit can still do. Send fewer documents per request, or use
batch_upsert().
- Return type:
Examples
On an index whose schema declares
embeddingas a 1536-dimensiondense_vectorandtitleas a full-textstring, every document carriesembeddingandtitleis optional:response = await idx.documents.upsert( namespace="published", documents=[ {"_id": "article-101", "embedding": [0.1] * 1536, "title": "Vector basics"}, {"_id": "article-102", "embedding": [0.2] * 1536}, ], ) print(response.upserted_count)
See also
batch_upsert(): for upserting large document lists in parallel batches.upsert(): for indexes where you provide your own vectors.
- async batch_upsert(*, namespace, documents, batch_size=50, max_concurrency=None, show_progress=True, timeout=None, total_timeout=None)[source]¶
Upsert a large list of documents in parallel batches.
Splits documents into chunks of batch_size and submits them through the host’s admission gate. Concurrency is bounded by max_concurrency and by the host’s adaptive concurrency limit, whichever is lower, so a struggling backend applies backpressure instead of being handed every batch at once. Per-batch HTTP failures are captured in the returned
BatchResultrather than raised, so one failed batch does not abort the rest; retry only the failures by passingresult.failed_itemsback in.Requests are limited by encoded size as well as document count. When the server rejects a batch as too large (HTTP 413), the batch is halved and each half resent, recursively, so documents of any size are sent without choosing a batch_size by trial and error. A single document that is itself over the limit cannot be split: it is reported in
result.failed_itemswithretryable=False. A split batch can land in part:failed_itemslists only the pieces that were rejected, and severalresult.errorsrows can share onebatch_index.- Parameters:
namespace (str) – Target namespace (required, non-empty).
documents (Sequence[Mapping[str, Any] | DocumentRecord]) – Documents to upsert. Each element is a dict with an
_idkey or aDocumentRecord; IDs must be unique across the whole list. Each document must also carry everydense_vectorfield and everystringfield declared withembed;sparse_vectorfields,sparse_embed-only or full-text-onlystringfields, and metadata are optional, but each document needs at least one searchable schema field (seeupsert()). One document that breaks these rules fails its whole batch with a 400, recorded inresult.errorswithretryable=False; fix the documents before resending.batch_size (int) – Maximum documents per request. Defaults to 50. On an index with an
embedorsparse_embedfield, the server accepts fewer documents per request, and a batch over that count fails with a 400 instead of being split; the default fits within it. A batch the server rejects as too large by encoded size is halved and resent, so on any other index a batch_size above what fits by size is safe, at the cost of the rejected requests.max_concurrency (int | None) – Upper bound on concurrent requests.
None(default) means 8. The admission gate’s adaptive limit for the host applies on top of whatever is passed.show_progress (bool) – Display a progress bar when
tqdmis installed. Defaults toTrue.timeout (float | None) – Per-request timeout in seconds applied to each batch’s request, not to the whole call. Must be greater than zero.
total_timeout (float | None) – Deadline in seconds for the whole batched upsert, as opposed to timeout, which bounds a single attempt of a single batch. On expiry no further batches are submitted, and the un-submitted ones are reported in
result.failed_itemsso they can be retried.None(default) means no deadline. See the note below for whatresult.timed_outdoes and does not tell you.
- Returns:
BatchResultwith aggregated success and failure counts. Per-batch server rejections are not raised: each is recorded inresult.errorsand the affected documents inresult.failed_items. APayloadTooLargeErrorinresult.errorsbelongs to a single document over the server’s size cap; resending it or lowering batch_size fails the same way, so shrink that document instead.- Raises:
PineconeValueError – If
namespaceis empty,documentsis empty or contains an invalid or duplicate_id, orbatch_sizeormax_concurrencyis outside its accepted range. Also raised iftimeoutortotal_timeoutis zero or negative.- Return type:
Examples
On an index whose schema declares
embeddingas adense_vectorandtitleas a full-textstring, wherevectorsholds one embedding per article:documents = [ {"_id": f"article-{i}", "embedding": vector, "title": f"Article {i}"} for i, vector in enumerate(vectors) ] result = await idx.documents.batch_upsert( namespace="published", documents=documents, batch_size=100, max_concurrency=8, total_timeout=60.0, ) print(result.successful_item_count, result.failed_item_count) if result.timed_out: result = await idx.documents.batch_upsert( namespace="published", documents=result.failed_items, batch_size=100, )
Note
Batches already in flight when total_timeout expires are awaited and never cancelled, because dropping one client-side would not stop the host from applying it. So
result.timed_outisTrueonly when something was actually left unsent; if the in-flight batches were the last ones and all landed, the upsert succeeded late rather than failing. Time spent waiting for the host’s admission gate counts against the budget, so a throttled host can consume it without a request being sent.See also
upsert(): for a document list that fits in one request.How bulk ingest behaves: choosing a batch size and concurrency, and reading the gate counters on the result.
- async search(*, namespace, score_by, top_k, include_fields=None, filter=None, timeout=None)[source]¶
Search documents in a namespace using one or more scoring methods.
Ranks documents by the clauses in
score_byand returns thetop_kbest. A clause scores by dense or sparse vector similarity, BM25 text relevance, a Lucene query string, or similarity to query text that Pinecone embeds with the model of a field declared withembedorsparse_embed.- Parameters:
namespace (str) – Namespace to search (required, non-empty).
score_by (Sequence[TextQuery | QueryStringQuery | DenseVectorQuery | SparseVectorQuery | EmbedQuery | SparseEmbedQuery | Mapping[str, Any]]) – Scoring methods to rank documents by, as a list. Wrap a single clause as
[clause]. Items are typed variants (TextQuery,QueryStringQuery,DenseVectorQuery,SparseVectorQuery,EmbedQuery,SparseEmbedQuery) or plain dicts with atypekey. A dict clause with a key its type does not define, such asboost, is rejected with aPineconeValueErrorrather than dropped.textandquery_stringclauses may be combined; adense_vector,sparse_vector,embedorsparse_embedclause must appear alone. Combined clauses are OR’d, not AND’d: a document that matches any clause is returned, and one that matches several scores the sum of the scores from each clause it matches. Atextclause naming severalfieldsworks the same way across those fields. Repeating a clause, naming a field twice, or writing one query as both atextand aquery_stringclause scores it once, so repeating a clause does not up-weight it. To weight a term, give it a^Nboost in aQueryStringQuery, such astitle:entropy^5; atextclause has no boost. To require several terms together, useANDinside oneQueryStringQuery.top_k (int) – Number of top-ranked documents to return.
include_fields (Sequence[str] | None) – Document fields to include in each match. Omitting it (the default) or passing
[]returns only_idand_score;["*"]returns every field, even alongside other names.fetch()is the opposite: there, omitting the argument returns every field. Naming a field declared withstore_text: falseis rejected by the server with a400, since its text is not stored;["*"]leaves it out.filter (Mapping[str, Any] | None) –
Filter expression restricting the documents searched, or
None. Which operators a predicate may use depends on the field it names:A data field, one the schema declares to be searched (a vector field, or a string declared with
full_text_search,embedorsparse_embed), rejects comparison operators such as$eqwith a400. Of these, a string whose text is stored and searchable takes the text-match operators: one declared withfull_text_search, or withembedorsparse_embedand the defaultstore_text(the server turns full-text search on for it). Astore_text=Falsestring does not, and neither does a vector field. The operators are$match_phrase(the words as a contiguous, ordered phrase),$match_all(every word, in any order) and$match_any(at least one word).A metadata field, one the schema does not declare or declares only for filtering (an integer, float, boolean, string list, or a string with no search configuration), takes the comparison, set and logical operators (
$eq,$in,$gteand so on). A text-match operator on it is rejected with a400.
The two kinds combine under
$and.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only. Must be greater than zero.
- Returns:
SearchDocumentsResponsewithmatches(ordered from most to least similar),namespace, andusage, whoseembed_total_tokenscounts the query tokens Pinecone embedded when the server reports it. Each match is aDocument, reached asdoc.id,doc.score, anddoc.<field>for the fieldsinclude_fieldsasked for.- Raises:
PineconeValueError – If
namespaceis empty,score_byis empty, has more clauses than one request accepts, or combines a vector,embedorsparse_embedclause with any other clause, ortop_kis outside its accepted range. Also raised iftimeoutis zero or negative.PineconeTypeError – If
top_kis not an integer (a bool is not accepted),score_byis not a list of clauses (wrap a single clause as[clause]), holds an item that is neither a dict nor one of the six clause types (such as aSearchQuery),filteris not a dict (call.to_dict()on a filter-builderCondition), orinclude_fieldsis a barestrrather than a list.
- Return type:
Examples
from pinecone import TextQuery response = await idx.documents.search( namespace="published", top_k=5, score_by=[TextQuery(query="machine learning", fields=["content"])], include_fields=["title", "content"], filter={"category": {"$eq": "tech"}}, ) for doc in response.matches: print(doc.id, doc.score)
Filter on a schema field with a text-match operator (here
titleis a string field declared withfull_text_search):response = await idx.documents.search( namespace="published", top_k=5, score_by=[TextQuery(query="machine learning", fields=["content"])], filter={"title": {"$match_phrase": "machine learning"}}, )
- async fetch(*, namespace, ids=None, filter=None, include_fields=None, pagination_token=None, limit=None, timeout=None)[source]¶
Fetch documents from a namespace by ID or by metadata filter.
Exactly one of
idsorfiltermust be provided. A filtered fetch returns matching documents a page at a time, withresponse.paginationcarrying the token for the next page.- Parameters:
namespace (str) – Namespace to fetch from (required, non-empty).
ids (Sequence[str] | None) – Document IDs to fetch. IDs that do not exist are omitted from the result rather than raising. Mutually exclusive with
filter.filter (Mapping[str, Any] | None) –
Non-empty filter expression selecting the documents to fetch. Mutually exclusive with
ids. Which operators a predicate may use depends on the field it names:A data field, one the schema declares to be searched (a vector field, or a string declared with
full_text_search,embedorsparse_embed), rejects comparison operators such as$eqwith a400. Of these, a string whose text is stored and searchable takes the text-match operators: one declared withfull_text_search, or withembedorsparse_embedand the defaultstore_text(the server turns full-text search on for it). Astore_text=Falsestring does not, and neither does a vector field. The operators are$match_phrase(the words as a contiguous, ordered phrase),$match_all(every word, in any order) and$match_any(at least one word).A metadata field, one the schema does not declare or declares only for filtering (an integer, float, boolean, string list, or a string with no search configuration), takes the comparison, set and logical operators (
$eq,$in,$gteand so on). A text-match operator on it is rejected with a400.
The two kinds combine under
$and.include_fields (Sequence[str] | None) – Document fields to include in each document. Omitting it (the default),
[], or["*"]each return every field; a list of names returns just those.search()is the opposite: there, omitting the argument returns only_idand_score. Every field means every field the index stores: a field declared withstore_text: falseis left out, and naming one is rejected by the server with a400.pagination_token (str | None) – Token from a previous filtered fetch response to retrieve the next page. Only valid together with
filter.limit (int | None) – Maximum number of documents per page of a filtered fetch. Omitting it uses the server’s default page size. A fetch by
idsignores it.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only. Must be greater than zero.
- Returns:
FetchDocumentsResponsewithdocuments(document ID mapped to aDocument, reached asdoc.<field>),namespace,usage, andpagination, which carries the next-page token when a filtered fetch has more results and isNoneotherwise.- Raises:
PineconeValueError – If
namespaceis empty, both or neither ofidsandfilterare provided,filteris an empty dict,idsholds more IDs than one request accepts,pagination_tokenis passed withoutfilter, orlimitis outside its accepted range. Also raised iftimeoutis zero or negative.PineconeTypeError – If
limitis not an integer (a bool is not accepted),filteris not a dict (call.to_dict()on a filter-builderCondition), oridsorinclude_fieldsis a barestrrather than a list.
- Return type:
Examples
Fetch specific documents by ID. IDs that do not exist are absent from
response.documentsrather than raising:response = await idx.documents.fetch( namespace="published", ids=["article-101", "article-102"], ) for doc_id, doc in response.documents.items(): print(doc_id, doc.title)
Fetch by filter instead. A filtered fetch is paginated, so read each page’s documents before asking for the next one; the loop below is the whole retrieval, not just the token bookkeeping:
pagination_token = None while True: response = await idx.documents.fetch( namespace="published", filter={"category": {"$eq": "tech"}}, pagination_token=pagination_token, ) for doc_id, doc in response.documents.items(): print(doc_id, doc.title) if response.pagination is None: break pagination_token = response.pagination.next
A filter can use a text-match operator on a schema field, here
title, a string field declared withfull_text_search, instead of a comparison on a metadata field:response = await idx.documents.fetch( namespace="published", filter={"title": {"$match_any": "vectors retrieval"}}, )
See also
search(): when you want the best-matching documents rather than every document that satisfies a filter.fetch(): for indexes where you provide your own vectors.Pagination: the pagination shapes the SDK uses and when each applies.
- async delete(*, namespace, ids=None, filter=None, delete_all=False, timeout=None)[source]¶
Delete documents from a namespace by ID, filter, or delete-all flag.
Exactly one of
ids,filter, ordelete_allmust be provided. Deleting IDs that do not exist does not raise an error.Pinecone applies the delete asynchronously. For a filtered delete,
response.matched_recordsis the point-in-time count of matching documents when the delete was accepted, not a guarantee of the number ultimately deleted.- Parameters:
namespace (str) – Namespace to delete from (required, non-empty).
ids (Sequence[str] | None) – Document IDs to delete. Mutually exclusive with
filteranddelete_all.filter (Mapping[str, Any] | None) – Non-empty metadata filter expression selecting the documents to delete. Text-match operators (
$match_phrase,$match_all,$match_any) are not supported here. Mutually exclusive withidsanddelete_all. Pass a dict; for a filter-builderCondition, passcondition.to_dict().delete_all (bool) – If
True, delete all documents in the namespace. Mutually exclusive withidsandfilter.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only. Must be greater than zero.
- Returns:
DeleteDocumentsResponse.matched_recordsis populated only for filtered deletes (Nonefor by-ID and delete-all paths, and when the count could not be read in time).- Raises:
PineconeValueError – If
namespaceis empty, zero or more than one ofids/filter/delete_allis provided,filteris an empty dict, oridsholds more IDs than one request accepts. Also raised iftimeoutis zero or negative.PineconeTypeError – If
filteris not a dict (call.to_dict()on a filter-builderCondition), oridsis a barestrrather than a list.
- Return type:
Examples
Delete specific documents by ID:
await idx.documents.delete(namespace="published", ids=["article-101"])
Delete every document matching a filter:
response = await idx.documents.delete( namespace="published", filter={"category": {"$eq": "obsolete"}}, ) print(response.matched_records)
Or empty a namespace outright.
delete_allremoves every document in the namespace named; it takes noidsorfilterto narrow it:await idx.documents.delete(namespace="drafts", delete_all=True)
See also
delete_namespace(): to remove the namespace itself, rather than emptying it withdelete_all.delete(): for indexes where you provide your own vectors.
- async update(*, namespace, documents=None, filter=None, set_fields=None, remove_fields=None, timeout=None)[source]¶
Apply partial updates to documents in a namespace.
Documents are selected either per ID with
documents, or in bulk withfilterplusset_fieldsand/orremove_fields. The two shapes are mutually exclusive. Fields that are not mentioned are left unchanged, and an update naming a document that does not exist is accepted as a no-op rather than raising.Pinecone applies the update asynchronously. For a filtered update,
response.matched_recordsis the point-in-time count of matching documents when the update was accepted, not a guarantee of the number ultimately patched.- Parameters:
namespace (str) – Namespace to update in (required, non-empty).
documents (Sequence[Mapping[str, Any] | UpdateDocumentRecord] | None) – Per-document patches. Each element is a dict with an
_idkey or anUpdateDocumentRecord. Any key other than_idand_remove_fieldssets a new value for that field; the names in_remove_fieldsare removed from the document._idvalues must be unique within the request. Mutually exclusive withfilter,set_fields, andremove_fields.filter (Mapping[str, Any] | None) – Non-empty metadata filter expression selecting the documents to patch. Text-match operators (
$match_phrase,$match_all,$match_any) are not supported here. Mutually exclusive withdocuments. Pass a dict; for a filter-builderCondition, passcondition.to_dict().set_fields (Mapping[str, Any] | None) – Fields to set on every document matching
filter, and the values to set them to. Only valid withfilter.remove_fields (Sequence[str] | None) – Names of the fields to remove from every document matching
filter. Only valid withfilter.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only. Must be greater than zero.
- Returns:
UpdateDocumentsResponse.matched_recordsis populated only for filtered updates (Nonefor per-ID updates, and when the count could not be read in time).usage.embed_total_tokenscounts the tokens Pinecone embedded forembedandsparse_embedfields;usageisNonewhen the update embedded no text.- Raises:
PineconeValueError – If
namespaceis empty,documentsis combined with any by-filter field, neitherdocumentsnorfilteris given,set_fieldsorremove_fieldsis passed withoutfilter,filteris an empty dict or carries no patch,documentsis empty or longer than one request accepts, or a patch is malformed; the message names the offending position. Also raised iftimeoutis zero or negative.ApiError – If a field value is
None, which the server rejects; use_remove_fields(per-ID) orremove_fields(by-filter) to remove a field instead.PineconeTypeError – If
filteris not a dict (call.to_dict()on a filter-builderCondition), orremove_fieldsis a barestrrather than a list.
- Return type:
Examples
Patch documents by ID. Each key other than the reserved
_idand_remove_fieldssets that field’s value; fields the patch does not name keep the values they already have, soarticle-101here gets a newtitleand is otherwise untouched:await idx.documents.update( namespace="published", documents=[ {"_id": "article-101", "title": "An introduction to vector search"}, {"_id": "article-102", "_remove_fields": ["draft_notes"]}, ], )
article-102keeps every field it has exceptdraft_notes:_remove_fieldsnames fields to delete rather than setting a field called_remove_fields.Patch every document matching a filter instead, setting one field and removing another across all of them:
response = await idx.documents.update( namespace="published", filter={"category": {"$eq": "news"}}, set_fields={"review_status": "archived"}, remove_fields=["draft_notes"], ) print(response.matched_records)
- list(*, namespace, prefix=None, limit=None, pagination_token=None, timeout=None)[source]¶
List the documents in a namespace, following pagination lazily.
Returns an
AsyncPaginatorthat fetches pages on demand and stops when the server returns nopaginationtoken. Documents come back in sorted order by ID, carrying only their_id.- Parameters:
namespace (str) – Namespace to list from (required, non-empty).
prefix (str | None) – Return only documents whose IDs begin with this prefix, such as
"article-". Must be ASCII.Nonelists every document.limit (int | None) – Maximum number of documents the server returns per page. This tunes the page size, not the total: the paginator follows every page.
None(default) lets the server choose the page size. To stop early, break out of the loop.pagination_token (str | None) – Token from a previous list response to resume from, rather than starting at the first page.
timeout (float | None) – Per-request timeout in seconds, applied to each page request. Overrides the client-level default. Must be greater than zero.
- Returns:
AsyncPaginatoroverListedDocumentRecordobjects. Supportsasync for,to_list(), andpages().- Raises:
PineconeTypeError – If
limitis not an integer (a bool is not accepted).PineconeValueError – If
namespaceis empty,prefixis too long or not ASCII, orlimitis outside its accepted range. Raised by this call, before the paginator is returned. Also raised iftimeoutis zero or negative.
- Return type:
Examples
Iterate every document ID in the namespace, letting the paginator cross page boundaries for you:
async for doc in idx.documents.list(namespace="published", prefix="article-1"): print(doc.id)
Or take the pages themselves, when you want to checkpoint a long walk on the token each page carries:
paginator = idx.documents.list(namespace="published", limit=20) async for page in paginator.pages(): print(len(page.items), page.pagination_token)
See also
fetch(): to read the fields of the documents, not just their IDs.list(): for indexes where you provide your own vectors.Pagination: the pagination shapes the SDK uses and when each applies.