diff --git a/codegen/apis b/codegen/apis index 7e21ca9a..827d26f4 160000 --- a/codegen/apis +++ b/codegen/apis @@ -1 +1 @@ -Subproject commit 7e21ca9adb6a530ce11909d6209d69551f86e9bd +Subproject commit 827d26f4825902994a099595d49779d16fea3a0a diff --git a/codegen/buf.yaml b/codegen/buf.yaml index a979e0a5..988170bd 100644 --- a/codegen/buf.yaml +++ b/codegen/buf.yaml @@ -9,4 +9,4 @@ breaking: deps: - buf.build/googleapis/googleapis modules: - - path: apis/_build/2025-01 + - path: apis/_build/2025-04 diff --git a/docs/grpc.rst b/docs/grpc.rst index 2ced748d..1980e9c7 100644 --- a/docs/grpc.rst +++ b/docs/grpc.rst @@ -80,3 +80,14 @@ Vectors .. automethod:: pinecone.grpc::GRPCIndex.list .. automethod:: pinecone.grpc::GRPCIndex.list_paginated + +Namespaces +---------- + +.. automethod:: pinecone.grpc::GRPCIndex.list_namespaces + +.. automethod:: pinecone.grpc::GRPCIndex.list_namespaces_paginated + +.. automethod:: pinecone.grpc::GRPCIndex.describe_namespace + +.. automethod:: pinecone.grpc::GRPCIndex.delete_namespace diff --git a/pinecone/core/grpc/protos/db_data_2025_01_pb2.py b/pinecone/core/grpc/protos/db_data_2025_04_pb2.py similarity index 72% rename from pinecone/core/grpc/protos/db_data_2025_01_pb2.py rename to pinecone/core/grpc/protos/db_data_2025_04_pb2.py index ab0491f8..caf7aa59 100644 --- a/pinecone/core/grpc/protos/db_data_2025_01_pb2.py +++ b/pinecone/core/grpc/protos/db_data_2025_04_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # NO CHECKED-IN PROTOBUF GENCODE -# source: db_data_2025-01.proto +# source: db_data_2025-04.proto # Protobuf Python Version: 5.29.0 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor @@ -15,7 +15,7 @@ 29, 0, '', - 'db_data_2025-01.proto' + 'db_data_2025-04.proto' ) # @@protoc_insertion_point(imports) @@ -27,11 +27,11 @@ from google.api import field_behavior_pb2 as google_dot_api_dot_field__behavior__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x64\x62_data_2025-01.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1cgoogle/api/annotations.proto\x1a\x1fgoogle/api/field_behavior.proto\"J\n\x0cSparseValues\x12\x1d\n\x07indices\x18\x01 \x03(\rB\x03\xe0\x41\x02R\x07indices\x12\x1b\n\x06values\x18\x02 \x03(\x02\x42\x03\xe0\x41\x02R\x06values\"\x9e\x01\n\x06Vector\x12\x13\n\x02id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\x02id\x12\x16\n\x06values\x18\x02 \x03(\x02R\x06values\x12\x32\n\rsparse_values\x18\x04 \x01(\x0b\x32\r.SparseValuesR\x0csparseValues\x12\x33\n\x08metadata\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructR\x08metadata\"\xba\x01\n\x0cScoredVector\x12\x13\n\x02id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\x02id\x12\x14\n\x05score\x18\x02 \x01(\x02R\x05score\x12\x16\n\x06values\x18\x03 \x03(\x02R\x06values\x12\x32\n\rsparse_values\x18\x05 \x01(\x0b\x32\r.SparseValuesR\x0csparseValues\x12\x33\n\x08metadata\x18\x04 \x01(\x0b\x32\x17.google.protobuf.StructR\x08metadata\"\xa1\x01\n\x0cRequestUnion\x12(\n\x06upsert\x18\x01 \x01(\x0b\x32\x0e.UpsertRequestH\x00R\x06upsert\x12(\n\x06\x64\x65lete\x18\x02 \x01(\x0b\x32\x0e.DeleteRequestH\x00R\x06\x64\x65lete\x12(\n\x06update\x18\x03 \x01(\x0b\x32\x0e.UpdateRequestH\x00R\x06updateB\x13\n\x11RequestUnionInner\"U\n\rUpsertRequest\x12&\n\x07vectors\x18\x01 \x03(\x0b\x32\x07.VectorB\x03\xe0\x41\x02R\x07vectors\x12\x1c\n\tnamespace\x18\x02 \x01(\tR\tnamespace\"7\n\x0eUpsertResponse\x12%\n\x0eupserted_count\x18\x01 \x01(\rR\rupsertedCount\"\x8f\x01\n\rDeleteRequest\x12\x10\n\x03ids\x18\x01 \x03(\tR\x03ids\x12\x1d\n\ndelete_all\x18\x02 \x01(\x08R\tdeleteAll\x12\x1c\n\tnamespace\x18\x03 \x01(\tR\tnamespace\x12/\n\x06\x66ilter\x18\x04 \x01(\x0b\x32\x17.google.protobuf.StructR\x06\x66ilter\"\x10\n\x0e\x44\x65leteResponse\"C\n\x0c\x46\x65tchRequest\x12\x15\n\x03ids\x18\x01 \x03(\tB\x03\xe0\x41\x02R\x03ids\x12\x1c\n\tnamespace\x18\x02 \x01(\tR\tnamespace\"\xd6\x01\n\rFetchResponse\x12\x35\n\x07vectors\x18\x01 \x03(\x0b\x32\x1b.FetchResponse.VectorsEntryR\x07vectors\x12\x1c\n\tnamespace\x18\x02 \x01(\tR\tnamespace\x12!\n\x05usage\x18\x03 \x01(\x0b\x32\x06.UsageH\x00R\x05usage\x88\x01\x01\x1a\x43\n\x0cVectorsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x1d\n\x05value\x18\x02 \x01(\x0b\x32\x07.VectorR\x05value:\x02\x38\x01\x42\x08\n\x06_usage\"\xbd\x01\n\x0bListRequest\x12\x1b\n\x06prefix\x18\x01 \x01(\tH\x00R\x06prefix\x88\x01\x01\x12\x19\n\x05limit\x18\x02 \x01(\rH\x01R\x05limit\x88\x01\x01\x12.\n\x10pagination_token\x18\x03 \x01(\tH\x02R\x0fpaginationToken\x88\x01\x01\x12\x1c\n\tnamespace\x18\x04 \x01(\tR\tnamespaceB\t\n\x07_prefixB\x08\n\x06_limitB\x13\n\x11_pagination_token\" \n\nPagination\x12\x12\n\x04next\x18\x01 \x01(\tR\x04next\"\x1a\n\x08ListItem\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\"\xbf\x01\n\x0cListResponse\x12#\n\x07vectors\x18\x01 \x03(\x0b\x32\t.ListItemR\x07vectors\x12\x30\n\npagination\x18\x02 \x01(\x0b\x32\x0b.PaginationH\x00R\npagination\x88\x01\x01\x12\x1c\n\tnamespace\x18\x03 \x01(\tR\tnamespace\x12!\n\x05usage\x18\x04 \x01(\x0b\x32\x06.UsageH\x01R\x05usage\x88\x01\x01\x42\r\n\x0b_paginationB\x08\n\x06_usage\"\xbd\x01\n\x0bQueryVector\x12\x16\n\x06values\x18\x01 \x03(\x02R\x06values\x12\x32\n\rsparse_values\x18\x05 \x01(\x0b\x32\r.SparseValuesR\x0csparseValues\x12\x13\n\x05top_k\x18\x02 \x01(\rR\x04topK\x12\x1c\n\tnamespace\x18\x03 \x01(\tR\tnamespace\x12/\n\x06\x66ilter\x18\x04 \x01(\x0b\x32\x17.google.protobuf.StructR\x06\x66ilter\"\xd1\x02\n\x0cQueryRequest\x12\x1c\n\tnamespace\x18\x01 \x01(\tR\tnamespace\x12\x18\n\x05top_k\x18\x02 \x01(\rB\x03\xe0\x41\x02R\x04topK\x12/\n\x06\x66ilter\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructR\x06\x66ilter\x12%\n\x0einclude_values\x18\x04 \x01(\x08R\rincludeValues\x12)\n\x10include_metadata\x18\x05 \x01(\x08R\x0fincludeMetadata\x12*\n\x07queries\x18\x06 \x03(\x0b\x32\x0c.QueryVectorB\x02\x18\x01R\x07queries\x12\x16\n\x06vector\x18\x07 \x03(\x02R\x06vector\x12\x32\n\rsparse_vector\x18\t \x01(\x0b\x32\r.SparseValuesR\x0csparseVector\x12\x0e\n\x02id\x18\x08 \x01(\tR\x02id\"[\n\x12SingleQueryResults\x12\'\n\x07matches\x18\x01 \x03(\x0b\x32\r.ScoredVectorR\x07matches\x12\x1c\n\tnamespace\x18\x02 \x01(\tR\tnamespace\"\xb6\x01\n\rQueryResponse\x12\x31\n\x07results\x18\x01 \x03(\x0b\x32\x13.SingleQueryResultsB\x02\x18\x01R\x07results\x12\'\n\x07matches\x18\x02 \x03(\x0b\x32\r.ScoredVectorR\x07matches\x12\x1c\n\tnamespace\x18\x03 \x01(\tR\tnamespace\x12!\n\x05usage\x18\x04 \x01(\x0b\x32\x06.UsageH\x00R\x05usage\x88\x01\x01\x42\x08\n\x06_usage\":\n\x05Usage\x12\"\n\nread_units\x18\x01 \x01(\rH\x00R\treadUnits\x88\x01\x01\x42\r\n\x0b_read_units\"\xca\x01\n\rUpdateRequest\x12\x13\n\x02id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\x02id\x12\x16\n\x06values\x18\x02 \x03(\x02R\x06values\x12\x32\n\rsparse_values\x18\x05 \x01(\x0b\x32\r.SparseValuesR\x0csparseValues\x12:\n\x0cset_metadata\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructR\x0bsetMetadata\x12\x1c\n\tnamespace\x18\x04 \x01(\tR\tnamespace\"\x10\n\x0eUpdateResponse\"L\n\x19\x44\x65scribeIndexStatsRequest\x12/\n\x06\x66ilter\x18\x01 \x01(\x0b\x32\x17.google.protobuf.StructR\x06\x66ilter\"5\n\x10NamespaceSummary\x12!\n\x0cvector_count\x18\x01 \x01(\rR\x0bvectorCount\"\x9f\x03\n\x1a\x44\x65scribeIndexStatsResponse\x12K\n\nnamespaces\x18\x01 \x03(\x0b\x32+.DescribeIndexStatsResponse.NamespacesEntryR\nnamespaces\x12!\n\tdimension\x18\x02 \x01(\rH\x00R\tdimension\x88\x01\x01\x12%\n\x0eindex_fullness\x18\x03 \x01(\x02R\rindexFullness\x12,\n\x12total_vector_count\x18\x04 \x01(\rR\x10totalVectorCount\x12\x1b\n\x06metric\x18\x05 \x01(\tH\x01R\x06metric\x88\x01\x01\x12$\n\x0bvector_type\x18\x06 \x01(\tH\x02R\nvectorType\x88\x01\x01\x1aP\n\x0fNamespacesEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\'\n\x05value\x18\x02 \x01(\x0b\x32\x11.NamespaceSummaryR\x05value:\x02\x38\x01\x42\x0c\n\n_dimensionB\t\n\x07_metricB\x0e\n\x0c_vector_type2\xb9\x04\n\rVectorService\x12\x45\n\x06Upsert\x12\x0e.UpsertRequest\x1a\x0f.UpsertResponse\"\x1a\x82\xd3\xe4\x93\x02\x14\"\x0f/vectors/upsert:\x01*\x12X\n\x06\x44\x65lete\x12\x0e.DeleteRequest\x1a\x0f.DeleteResponse\"-\x82\xd3\xe4\x93\x02\'\"\x0f/vectors/delete:\x01*Z\x11*\x0f/vectors/delete\x12>\n\x05\x46\x65tch\x12\r.FetchRequest\x1a\x0e.FetchResponse\"\x16\x82\xd3\xe4\x93\x02\x10\x12\x0e/vectors/fetch\x12:\n\x04List\x12\x0c.ListRequest\x1a\r.ListResponse\"\x15\x82\xd3\xe4\x93\x02\x0f\x12\r/vectors/list\x12\x39\n\x05Query\x12\r.QueryRequest\x1a\x0e.QueryResponse\"\x11\x82\xd3\xe4\x93\x02\x0b\"\x06/query:\x01*\x12\x45\n\x06Update\x12\x0e.UpdateRequest\x1a\x0f.UpdateResponse\"\x1a\x82\xd3\xe4\x93\x02\x14\"\x0f/vectors/update:\x01*\x12\x88\x01\n\x12\x44\x65scribeIndexStats\x12\x1a.DescribeIndexStatsRequest\x1a\x1b.DescribeIndexStatsResponse\"9\x82\xd3\xe4\x93\x02\x33\"\x15/describe_index_stats:\x01*Z\x17\x12\x15/describe_index_statsBS\n\x11io.pinecone.protoP\x01Z\n\x05\x46\x65tch\x12\r.FetchRequest\x1a\x0e.FetchResponse\"\x16\x82\xd3\xe4\x93\x02\x10\x12\x0e/vectors/fetch\x12:\n\x04List\x12\x0c.ListRequest\x1a\r.ListResponse\"\x15\x82\xd3\xe4\x93\x02\x0f\x12\r/vectors/list\x12\x39\n\x05Query\x12\r.QueryRequest\x1a\x0e.QueryResponse\"\x11\x82\xd3\xe4\x93\x02\x0b\"\x06/query:\x01*\x12\x45\n\x06Update\x12\x0e.UpdateRequest\x1a\x0f.UpdateResponse\"\x1a\x82\xd3\xe4\x93\x02\x14\"\x0f/vectors/update:\x01*\x12\x88\x01\n\x12\x44\x65scribeIndexStats\x12\x1a.DescribeIndexStatsRequest\x1a\x1b.DescribeIndexStatsResponse\"9\x82\xd3\xe4\x93\x02\x33\"\x15/describe_index_stats:\x01*Z\x17\x12\x15/describe_index_stats\x12V\n\x0eListNamespaces\x12\x16.ListNamespacesRequest\x1a\x17.ListNamespacesResponse\"\x13\x82\xd3\xe4\x93\x02\r\x12\x0b/namespaces\x12\x66\n\x11\x44\x65scribeNamespace\x12\x19.DescribeNamespaceRequest\x1a\x15.NamespaceDescription\"\x1f\x82\xd3\xe4\x93\x02\x19\x12\x17/namespaces/{namespace}\x12\\\n\x0f\x44\x65leteNamespace\x12\x17.DeleteNamespaceRequest\x1a\x0f.DeleteResponse\"\x1f\x82\xd3\xe4\x93\x02\x19*\x17/namespaces/{namespace}BS\n\x11io.pinecone.protoP\x01Z None: ... +class ListNamespacesRequest(_message.Message): + __slots__ = ("pagination_token", "limit") + PAGINATION_TOKEN_FIELD_NUMBER: _ClassVar[int] + LIMIT_FIELD_NUMBER: _ClassVar[int] + pagination_token: str + limit: int + def __init__(self, pagination_token: _Optional[str] = ..., limit: _Optional[int] = ...) -> None: ... + +class ListNamespacesResponse(_message.Message): + __slots__ = ("namespaces", "pagination") + NAMESPACES_FIELD_NUMBER: _ClassVar[int] + PAGINATION_FIELD_NUMBER: _ClassVar[int] + namespaces: _containers.RepeatedCompositeFieldContainer[NamespaceDescription] + pagination: Pagination + def __init__(self, namespaces: _Optional[_Iterable[_Union[NamespaceDescription, _Mapping]]] = ..., pagination: _Optional[_Union[Pagination, _Mapping]] = ...) -> None: ... + +class DescribeNamespaceRequest(_message.Message): + __slots__ = ("namespace",) + NAMESPACE_FIELD_NUMBER: _ClassVar[int] + namespace: str + def __init__(self, namespace: _Optional[str] = ...) -> None: ... + +class NamespaceDescription(_message.Message): + __slots__ = ("name", "record_count") + NAME_FIELD_NUMBER: _ClassVar[int] + RECORD_COUNT_FIELD_NUMBER: _ClassVar[int] + name: str + record_count: int + def __init__(self, name: _Optional[str] = ..., record_count: _Optional[int] = ...) -> None: ... + +class DeleteNamespaceRequest(_message.Message): + __slots__ = ("namespace",) + NAMESPACE_FIELD_NUMBER: _ClassVar[int] + namespace: str + def __init__(self, namespace: _Optional[str] = ...) -> None: ... + class DescribeIndexStatsResponse(_message.Message): __slots__ = ("namespaces", "dimension", "index_fullness", "total_vector_count", "metric", "vector_type") class NamespacesEntry(_message.Message): diff --git a/pinecone/core/grpc/protos/db_data_2025_01_pb2_grpc.py b/pinecone/core/grpc/protos/db_data_2025_04_pb2_grpc.py similarity index 53% rename from pinecone/core/grpc/protos/db_data_2025_01_pb2_grpc.py rename to pinecone/core/grpc/protos/db_data_2025_04_pb2_grpc.py index 4c80e120..d733efcf 100644 --- a/pinecone/core/grpc/protos/db_data_2025_01_pb2_grpc.py +++ b/pinecone/core/grpc/protos/db_data_2025_04_pb2_grpc.py @@ -2,7 +2,7 @@ """Client and server classes corresponding to protobuf-defined services.""" import grpc -import pinecone.core.grpc.protos.db_data_2025_01_pb2 as db__data__2025__01__pb2 +import pinecone.core.grpc.protos.db_data_2025_04_pb2 as db__data__2025__04__pb2 class VectorServiceStub(object): @@ -10,7 +10,7 @@ class VectorServiceStub(object): This service could also be called a `gRPC` service or a `REST`-like api. """ - def __init__(self, channel) -> None: + def __init__(self, channel): """Constructor. Args: @@ -18,38 +18,53 @@ def __init__(self, channel) -> None: """ self.Upsert = channel.unary_unary( '/VectorService/Upsert', - request_serializer=db__data__2025__01__pb2.UpsertRequest.SerializeToString, - response_deserializer=db__data__2025__01__pb2.UpsertResponse.FromString, + request_serializer=db__data__2025__04__pb2.UpsertRequest.SerializeToString, + response_deserializer=db__data__2025__04__pb2.UpsertResponse.FromString, ) self.Delete = channel.unary_unary( '/VectorService/Delete', - request_serializer=db__data__2025__01__pb2.DeleteRequest.SerializeToString, - response_deserializer=db__data__2025__01__pb2.DeleteResponse.FromString, + request_serializer=db__data__2025__04__pb2.DeleteRequest.SerializeToString, + response_deserializer=db__data__2025__04__pb2.DeleteResponse.FromString, ) self.Fetch = channel.unary_unary( '/VectorService/Fetch', - request_serializer=db__data__2025__01__pb2.FetchRequest.SerializeToString, - response_deserializer=db__data__2025__01__pb2.FetchResponse.FromString, + request_serializer=db__data__2025__04__pb2.FetchRequest.SerializeToString, + response_deserializer=db__data__2025__04__pb2.FetchResponse.FromString, ) self.List = channel.unary_unary( '/VectorService/List', - request_serializer=db__data__2025__01__pb2.ListRequest.SerializeToString, - response_deserializer=db__data__2025__01__pb2.ListResponse.FromString, + request_serializer=db__data__2025__04__pb2.ListRequest.SerializeToString, + response_deserializer=db__data__2025__04__pb2.ListResponse.FromString, ) self.Query = channel.unary_unary( '/VectorService/Query', - request_serializer=db__data__2025__01__pb2.QueryRequest.SerializeToString, - response_deserializer=db__data__2025__01__pb2.QueryResponse.FromString, + request_serializer=db__data__2025__04__pb2.QueryRequest.SerializeToString, + response_deserializer=db__data__2025__04__pb2.QueryResponse.FromString, ) self.Update = channel.unary_unary( '/VectorService/Update', - request_serializer=db__data__2025__01__pb2.UpdateRequest.SerializeToString, - response_deserializer=db__data__2025__01__pb2.UpdateResponse.FromString, + request_serializer=db__data__2025__04__pb2.UpdateRequest.SerializeToString, + response_deserializer=db__data__2025__04__pb2.UpdateResponse.FromString, ) self.DescribeIndexStats = channel.unary_unary( '/VectorService/DescribeIndexStats', - request_serializer=db__data__2025__01__pb2.DescribeIndexStatsRequest.SerializeToString, - response_deserializer=db__data__2025__01__pb2.DescribeIndexStatsResponse.FromString, + request_serializer=db__data__2025__04__pb2.DescribeIndexStatsRequest.SerializeToString, + response_deserializer=db__data__2025__04__pb2.DescribeIndexStatsResponse.FromString, + ) + self.ListNamespaces = channel.unary_unary( + '/VectorService/ListNamespaces', + request_serializer=db__data__2025__04__pb2.ListNamespacesRequest.SerializeToString, + response_deserializer=db__data__2025__04__pb2.ListNamespacesResponse.FromString, + ) + self.DescribeNamespace = channel.unary_unary( + '/VectorService/DescribeNamespace', + request_serializer=db__data__2025__04__pb2.DescribeNamespaceRequest.SerializeToString, + response_deserializer=db__data__2025__04__pb2.NamespaceDescription.FromString, + ) + self.DeleteNamespace = channel.unary_unary( + '/VectorService/DeleteNamespace', + request_serializer=db__data__2025__04__pb2.DeleteNamespaceRequest.SerializeToString, + response_deserializer=db__data__2025__04__pb2.DeleteResponse.FromString, ) @@ -61,9 +76,9 @@ class VectorServiceServicer(object): def Upsert(self, request, context): """Upsert vectors - Writes vectors into a namespace. If a new value is upserted for an existing vector ID, it will overwrite the previous value. + Upsert vectors into a namespace. If a new value is upserted for an existing vector ID, it will overwrite the previous value. - For guidance and examples, see [Upsert data](https://docs.pinecone.io/guides/data/upsert-data). + For guidance, examples, and limits, see [Upsert data](https://docs.pinecone.io/guides/index-data/upsert-data). """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') @@ -74,7 +89,7 @@ def Delete(self, request, context): Delete vectors by id from a single namespace. - For guidance and examples, see [Delete data](https://docs.pinecone.io/guides/data/delete-data). + For guidance and examples, see [Delete data](https://docs.pinecone.io/guides/manage-data/delete-data). """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') @@ -83,9 +98,9 @@ def Delete(self, request, context): def Fetch(self, request, context): """Fetch vectors - Look up and returns vectors by ID from a single namespace. The returned vectors include the vector data and/or metadata. + Look up and return vectors by ID from a single namespace. The returned vectors include the vector data and/or metadata. - For guidance and examples, see [Fetch data](https://docs.pinecone.io/guides/data/fetch-data). + For guidance and examples, see [Fetch data](https://docs.pinecone.io/guides/manage-data/fetch-data). """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') @@ -98,20 +113,20 @@ def List(self, request, context): This returns up to 100 IDs at a time by default in sorted order (bitwise/"C" collation). If the `limit` parameter is set, `list` returns up to that number of IDs instead. Whenever there are additional IDs to return, the response also includes a `pagination_token` that you can use to get the next batch of IDs. When the response does not include a `pagination_token`, there are no more IDs to return. - For guidance and examples, see [List record IDs](https://docs.pinecone.io/guides/data/list-record-ids). + For guidance and examples, see [List record IDs](https://docs.pinecone.io/guides/manage-data/list-record-ids). - **Note:** This is supported only for serverless indexes. + **Note:** `list` is supported only for serverless indexes. """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') def Query(self, request, context): - """Query vectors + """Search with a vector - Searches a namespace, using a query vector. It retrieves the ids of the most similar items in a namespace, along with their similarity scores. + Search a namespace with a query vector or record ID and return the IDs of the most similar records, along with their similarity scores. - For guidance and examples, see [Query data](https://docs.pinecone.io/guides/data/query-data). + For guidance, examples, and limits, see [Search](https://docs.pinecone.io/guides/search/search-overview). """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') @@ -122,7 +137,7 @@ def Update(self, request, context): Update a vector in a namespace. If a value is included, it will overwrite the previous value. If a `set_metadata` is included, the values of the fields specified in it will be added or overwrite the previous value. - For guidance and examples, see [Update data](https://docs.pinecone.io/guides/data/update-data). + For guidance and examples, see [Update data](https://docs.pinecone.io/guides/manage-data/update-data). """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') @@ -139,43 +154,87 @@ def DescribeIndexStats(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def ListNamespaces(self, request, context): + """List namespaces + + Get a list of all [namespaces](https://docs.pinecone.io/guides/index-data/indexing-overview#namespaces) in a serverless index. + + Up to 100 namespaces are returned at a time by default, in sorted order (bitwise ā€œCā€ collation). If the `limit` parameter is set, up to that number of namespaces are returned instead. Whenever there are additional namespaces to return, the response also includes a `pagination_token` that you can use to get the next batch of namespaces. When the response does not include a `pagination_token`, there are no more namespaces to return. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def DescribeNamespace(self, request, context): + """Describe a namespace + + Describe a [namespace](https://docs.pinecone.io/guides/index-data/indexing-overview#namespaces) in a serverless index, including the total number of vectors in the namespace. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def DeleteNamespace(self, request, context): + """Delete a namespace + + Delete a namespace from an index. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def add_VectorServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'Upsert': grpc.unary_unary_rpc_method_handler( servicer.Upsert, - request_deserializer=db__data__2025__01__pb2.UpsertRequest.FromString, - response_serializer=db__data__2025__01__pb2.UpsertResponse.SerializeToString, + request_deserializer=db__data__2025__04__pb2.UpsertRequest.FromString, + response_serializer=db__data__2025__04__pb2.UpsertResponse.SerializeToString, ), 'Delete': grpc.unary_unary_rpc_method_handler( servicer.Delete, - request_deserializer=db__data__2025__01__pb2.DeleteRequest.FromString, - response_serializer=db__data__2025__01__pb2.DeleteResponse.SerializeToString, + request_deserializer=db__data__2025__04__pb2.DeleteRequest.FromString, + response_serializer=db__data__2025__04__pb2.DeleteResponse.SerializeToString, ), 'Fetch': grpc.unary_unary_rpc_method_handler( servicer.Fetch, - request_deserializer=db__data__2025__01__pb2.FetchRequest.FromString, - response_serializer=db__data__2025__01__pb2.FetchResponse.SerializeToString, + request_deserializer=db__data__2025__04__pb2.FetchRequest.FromString, + response_serializer=db__data__2025__04__pb2.FetchResponse.SerializeToString, ), 'List': grpc.unary_unary_rpc_method_handler( servicer.List, - request_deserializer=db__data__2025__01__pb2.ListRequest.FromString, - response_serializer=db__data__2025__01__pb2.ListResponse.SerializeToString, + request_deserializer=db__data__2025__04__pb2.ListRequest.FromString, + response_serializer=db__data__2025__04__pb2.ListResponse.SerializeToString, ), 'Query': grpc.unary_unary_rpc_method_handler( servicer.Query, - request_deserializer=db__data__2025__01__pb2.QueryRequest.FromString, - response_serializer=db__data__2025__01__pb2.QueryResponse.SerializeToString, + request_deserializer=db__data__2025__04__pb2.QueryRequest.FromString, + response_serializer=db__data__2025__04__pb2.QueryResponse.SerializeToString, ), 'Update': grpc.unary_unary_rpc_method_handler( servicer.Update, - request_deserializer=db__data__2025__01__pb2.UpdateRequest.FromString, - response_serializer=db__data__2025__01__pb2.UpdateResponse.SerializeToString, + request_deserializer=db__data__2025__04__pb2.UpdateRequest.FromString, + response_serializer=db__data__2025__04__pb2.UpdateResponse.SerializeToString, ), 'DescribeIndexStats': grpc.unary_unary_rpc_method_handler( servicer.DescribeIndexStats, - request_deserializer=db__data__2025__01__pb2.DescribeIndexStatsRequest.FromString, - response_serializer=db__data__2025__01__pb2.DescribeIndexStatsResponse.SerializeToString, + request_deserializer=db__data__2025__04__pb2.DescribeIndexStatsRequest.FromString, + response_serializer=db__data__2025__04__pb2.DescribeIndexStatsResponse.SerializeToString, + ), + 'ListNamespaces': grpc.unary_unary_rpc_method_handler( + servicer.ListNamespaces, + request_deserializer=db__data__2025__04__pb2.ListNamespacesRequest.FromString, + response_serializer=db__data__2025__04__pb2.ListNamespacesResponse.SerializeToString, + ), + 'DescribeNamespace': grpc.unary_unary_rpc_method_handler( + servicer.DescribeNamespace, + request_deserializer=db__data__2025__04__pb2.DescribeNamespaceRequest.FromString, + response_serializer=db__data__2025__04__pb2.NamespaceDescription.SerializeToString, + ), + 'DeleteNamespace': grpc.unary_unary_rpc_method_handler( + servicer.DeleteNamespace, + request_deserializer=db__data__2025__04__pb2.DeleteNamespaceRequest.FromString, + response_serializer=db__data__2025__04__pb2.DeleteResponse.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( @@ -201,8 +260,8 @@ def Upsert(request, timeout=None, metadata=None): return grpc.experimental.unary_unary(request, target, '/VectorService/Upsert', - db__data__2025__01__pb2.UpsertRequest.SerializeToString, - db__data__2025__01__pb2.UpsertResponse.FromString, + db__data__2025__04__pb2.UpsertRequest.SerializeToString, + db__data__2025__04__pb2.UpsertResponse.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @@ -218,8 +277,8 @@ def Delete(request, timeout=None, metadata=None): return grpc.experimental.unary_unary(request, target, '/VectorService/Delete', - db__data__2025__01__pb2.DeleteRequest.SerializeToString, - db__data__2025__01__pb2.DeleteResponse.FromString, + db__data__2025__04__pb2.DeleteRequest.SerializeToString, + db__data__2025__04__pb2.DeleteResponse.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @@ -235,8 +294,8 @@ def Fetch(request, timeout=None, metadata=None): return grpc.experimental.unary_unary(request, target, '/VectorService/Fetch', - db__data__2025__01__pb2.FetchRequest.SerializeToString, - db__data__2025__01__pb2.FetchResponse.FromString, + db__data__2025__04__pb2.FetchRequest.SerializeToString, + db__data__2025__04__pb2.FetchResponse.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @@ -252,8 +311,8 @@ def List(request, timeout=None, metadata=None): return grpc.experimental.unary_unary(request, target, '/VectorService/List', - db__data__2025__01__pb2.ListRequest.SerializeToString, - db__data__2025__01__pb2.ListResponse.FromString, + db__data__2025__04__pb2.ListRequest.SerializeToString, + db__data__2025__04__pb2.ListResponse.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @@ -269,8 +328,8 @@ def Query(request, timeout=None, metadata=None): return grpc.experimental.unary_unary(request, target, '/VectorService/Query', - db__data__2025__01__pb2.QueryRequest.SerializeToString, - db__data__2025__01__pb2.QueryResponse.FromString, + db__data__2025__04__pb2.QueryRequest.SerializeToString, + db__data__2025__04__pb2.QueryResponse.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @@ -286,8 +345,8 @@ def Update(request, timeout=None, metadata=None): return grpc.experimental.unary_unary(request, target, '/VectorService/Update', - db__data__2025__01__pb2.UpdateRequest.SerializeToString, - db__data__2025__01__pb2.UpdateResponse.FromString, + db__data__2025__04__pb2.UpdateRequest.SerializeToString, + db__data__2025__04__pb2.UpdateResponse.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @@ -303,7 +362,58 @@ def DescribeIndexStats(request, timeout=None, metadata=None): return grpc.experimental.unary_unary(request, target, '/VectorService/DescribeIndexStats', - db__data__2025__01__pb2.DescribeIndexStatsRequest.SerializeToString, - db__data__2025__01__pb2.DescribeIndexStatsResponse.FromString, + db__data__2025__04__pb2.DescribeIndexStatsRequest.SerializeToString, + db__data__2025__04__pb2.DescribeIndexStatsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def ListNamespaces(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/VectorService/ListNamespaces', + db__data__2025__04__pb2.ListNamespacesRequest.SerializeToString, + db__data__2025__04__pb2.ListNamespacesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def DescribeNamespace(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/VectorService/DescribeNamespace', + db__data__2025__04__pb2.DescribeNamespaceRequest.SerializeToString, + db__data__2025__04__pb2.NamespaceDescription.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def DeleteNamespace(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/VectorService/DeleteNamespace', + db__data__2025__04__pb2.DeleteNamespaceRequest.SerializeToString, + db__data__2025__04__pb2.DeleteResponse.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/pinecone/grpc/__init__.py b/pinecone/grpc/__init__.py index 307b2a20..92c10d0f 100644 --- a/pinecone/grpc/__init__.py +++ b/pinecone/grpc/__init__.py @@ -51,12 +51,14 @@ from pinecone.db_data.dataclasses import Vector, SparseValues -from pinecone.core.grpc.protos.db_data_2025_01_pb2 import ( +from pinecone.core.grpc.protos.db_data_2025_04_pb2 import ( Vector as GRPCVector, SparseValues as GRPCSparseValues, DeleteResponse as GRPCDeleteResponse, ) +from pinecone.core.openapi.db_data.models import ListNamespacesResponse + __all__ = [ "GRPCIndex", "PineconeGRPC", @@ -67,4 +69,5 @@ "Vector", "SparseValues", "PineconeGrpcFuture", + "ListNamespacesResponse", ] diff --git a/pinecone/grpc/grpc_runner.py b/pinecone/grpc/grpc_runner.py index 253a6b33..cc2e35d5 100644 --- a/pinecone/grpc/grpc_runner.py +++ b/pinecone/grpc/grpc_runner.py @@ -10,6 +10,7 @@ from pinecone.exceptions.exceptions import PineconeException from grpc import CallCredentials, Compression from google.protobuf.message import Message +from pinecone.openapi_support.api_version import API_VERSION class GrpcRunner: @@ -21,6 +22,7 @@ def __init__(self, index_name: str, config: Config, grpc_config: GRPCClientConfi "api-key": config.api_key, "service-name": index_name, "client-version": CLIENT_VERSION, + "x-pinecone-api-version": API_VERSION, } if self.grpc_client_config.additional_metadata: self.fixed_metadata.update(self.grpc_client_config.additional_metadata) diff --git a/pinecone/grpc/index_grpc.py b/pinecone/grpc/index_grpc.py index dae3db37..83fce126 100644 --- a/pinecone/grpc/index_grpc.py +++ b/pinecone/grpc/index_grpc.py @@ -4,6 +4,7 @@ from google.protobuf import json_format from pinecone.utils.tqdm import tqdm +from pinecone.utils import require_kwargs from concurrent.futures import as_completed, Future @@ -15,6 +16,8 @@ parse_upsert_response, parse_update_response, parse_delete_response, + parse_namespace_description, + parse_list_namespaces_response, ) from .vector_factory_grpc import VectorFactoryGRPC from .sparse_values_factory import SparseValuesFactory @@ -23,9 +26,11 @@ FetchResponse, QueryResponse, IndexDescription as DescribeIndexStatsResponse, + NamespaceDescription, + ListNamespacesResponse, ) from pinecone.db_control.models.list_response import ListResponse as SimpleListResponse, Pagination -from pinecone.core.grpc.protos.db_data_2025_01_pb2 import ( +from pinecone.core.grpc.protos.db_data_2025_04_pb2 import ( Vector as GRPCVector, QueryVector as GRPCQueryVector, UpsertRequest, @@ -39,10 +44,13 @@ DeleteResponse, UpdateResponse, SparseValues as GRPCSparseValues, + DescribeNamespaceRequest, + DeleteNamespaceRequest, + ListNamespacesRequest, ) from pinecone import Vector, SparseValues from pinecone.db_data.query_results_aggregator import QueryNamespacesResults, QueryResultsAggregator -from pinecone.core.grpc.protos.db_data_2025_01_pb2_grpc import VectorServiceStub +from pinecone.core.grpc.protos.db_data_2025_04_pb2_grpc import VectorServiceStub from .base import GRPCIndexBase from .future import PineconeGrpcFuture from ..db_data.types import ( @@ -54,7 +62,7 @@ ) -__all__ = ["GRPCIndex", "GRPCVector", "GRPCQueryVector", "GRPCSparseValues"] +__all__ = ["GRPCIndex", "GRPCVector", "GRPCQueryVector", "GRPCSparseValues", "NamespaceDescription", "ListNamespacesResponse"] _logger = logging.getLogger(__name__) """ :meta private: """ @@ -681,6 +689,142 @@ def describe_index_stats( json_response = json_format.MessageToDict(response) return parse_stats_response(json_response) + @require_kwargs + def describe_namespace( + self, namespace: str, **kwargs + ) -> NamespaceDescription: + """ + The describe_namespace operation returns information about a specific namespace, + including the total number of vectors in the namespace. + + Examples: + + .. code-block:: python + + >>> index.describe_namespace(namespace='my_namespace') + + Args: + namespace (str): The namespace to describe. + + Returns: NamespaceDescription object which contains information about the namespace. + """ + timeout = kwargs.pop("timeout", None) + request = DescribeNamespaceRequest(namespace=namespace) + response = self.runner.run(self.stub.DescribeNamespace, request, timeout=timeout) + return parse_namespace_description(response) + + @require_kwargs + def delete_namespace( + self, namespace: str, **kwargs + ) -> Dict[str, Any]: + """ + The delete_namespace operation deletes a namespace from an index. + This operation is irreversible and will permanently delete all data in the namespace. + + Examples: + + .. code-block:: python + + >>> index.delete_namespace(namespace='my_namespace') + + Args: + namespace (str): The namespace to delete. + + Returns: Empty dictionary indicating successful deletion. + """ + timeout = kwargs.pop("timeout", None) + request = DeleteNamespaceRequest(namespace=namespace) + response = self.runner.run(self.stub.DeleteNamespace, request, timeout=timeout) + return parse_delete_response(response) + + @require_kwargs + def list_namespaces_paginated( + self, + limit: Optional[int] = None, + pagination_token: Optional[str] = None, + **kwargs, + ) -> ListNamespacesResponse: + """ + The list_namespaces_paginated operation returns a list of all namespaces in a serverless index. + It returns namespaces in a paginated form, with a pagination token to fetch the next page of results. + + Examples: + + .. code-block:: python + + >>> results = index.list_namespaces_paginated(limit=10) + >>> [ns.name for ns in results.namespaces] + ['namespace1', 'namespace2', 'namespace3'] + >>> results.pagination.next + eyJza2lwX3Bhc3QiOiI5OTMiLCJwcmVmaXgiOiI5OSJ9 + >>> next_results = index.list_namespaces_paginated(limit=10, pagination_token=results.pagination.next) + + Args: + limit (Optional[int]): The maximum number of namespaces to return. If unspecified, the server will use a default value. [optional] + pagination_token (Optional[str]): A token needed to fetch the next page of results. This token is returned + in the response if additional results are available. [optional] + + Returns: ListNamespacesResponse object which contains the list of namespaces and pagination information. + """ + args_dict = self._parse_non_empty_args( + [ + ("limit", limit), + ("pagination_token", pagination_token), + ] + ) + timeout = kwargs.pop("timeout", None) + request = ListNamespacesRequest(**args_dict, **kwargs) + response = self.runner.run(self.stub.ListNamespaces, request, timeout=timeout) + return parse_list_namespaces_response(response) + + @require_kwargs + def list_namespaces(self, limit: Optional[int] = None, **kwargs): + """ + The list_namespaces operation accepts all of the same arguments as list_namespaces_paginated, and returns a generator that yields + each namespace. It automatically handles pagination tokens on your behalf. + + Args: + limit (Optional[int]): The maximum number of namespaces to fetch in each network call. If unspecified, the server will use a default value. [optional] + + Returns: + Returns a generator that yields each namespace. It automatically handles pagination tokens on your behalf so you can + easily iterate over all results. The ``list_namespaces`` method accepts all of the same arguments as list_namespaces_paginated + + Examples: + + .. code-block:: python + + >>> for namespace in index.list_namespaces(): + >>> print(namespace.name) + namespace1 + namespace2 + namespace3 + + You can convert the generator into a list by wrapping the generator in a call to the built-in ``list`` function: + + .. code-block:: python + + namespaces = list(index.list_namespaces()) + + You should be cautious with this approach because it will fetch all namespaces at once, which could be a large number + of network calls and a lot of memory to hold the results. + """ + done = False + while not done: + try: + results = self.list_namespaces_paginated(limit=limit, **kwargs) + except Exception as e: + raise e + + if results.namespaces and len(results.namespaces) > 0: + for namespace in results.namespaces: + yield namespace + + if results.pagination and results.pagination.next: + kwargs.update({"pagination_token": results.pagination.next}) + else: + done = True + @staticmethod def _parse_non_empty_args(args: List[Tuple[str, Any]]) -> Dict[str, Any]: return {arg_name: val for arg_name, val in args if val is not None} diff --git a/pinecone/grpc/sparse_values_factory.py b/pinecone/grpc/sparse_values_factory.py index 5bb14685..06aa8e67 100644 --- a/pinecone/grpc/sparse_values_factory.py +++ b/pinecone/grpc/sparse_values_factory.py @@ -6,7 +6,7 @@ from ..db_data import SparseValuesTypeError, SparseValuesMissingKeysError from ..db_data.types import SparseVectorTypedDict -from pinecone.core.grpc.protos.db_data_2025_01_pb2 import SparseValues as GRPCSparseValues +from pinecone.core.grpc.protos.db_data_2025_04_pb2 import SparseValues as GRPCSparseValues from pinecone.core.openapi.db_data.models import SparseValues as OpenApiSparseValues from pinecone import SparseValues diff --git a/pinecone/grpc/utils.py b/pinecone/grpc/utils.py index 92f2ce15..1be98f5b 100644 --- a/pinecone/grpc/utils.py +++ b/pinecone/grpc/utils.py @@ -13,6 +13,9 @@ IndexDescription as DescribeIndexStatsResponse, UpsertResponse, NamespaceSummary, + NamespaceDescription, + ListNamespacesResponse, + Pagination, ) from pinecone.db_data.dataclasses import FetchResponse @@ -126,3 +129,37 @@ def parse_stats_response(response: dict): total_vector_count=total_vector_count, _check_type=False, ) + + +def parse_namespace_description(response: Message) -> NamespaceDescription: + json_response = json_format.MessageToDict(response) + return NamespaceDescription( + name=json_response.get("name", ""), + record_count=json_response.get("recordCount", 0), + _check_type=False, + ) + + +def parse_list_namespaces_response(response: Message) -> ListNamespacesResponse: + json_response = json_format.MessageToDict(response) + + namespaces = [] + for ns in json_response.get("namespaces", []): + namespaces.append(NamespaceDescription( + name=ns.get("name", ""), + record_count=ns.get("recordCount", 0), + _check_type=False, + )) + + pagination = None + if "pagination" in json_response and json_response["pagination"]: + pagination = Pagination( + next=json_response["pagination"].get("next", ""), + _check_type=False, + ) + + return ListNamespacesResponse( + namespaces=namespaces, + pagination=pagination, + _check_type=False, + ) diff --git a/pinecone/grpc/vector_factory_grpc.py b/pinecone/grpc/vector_factory_grpc.py index 22efd269..3af3add8 100644 --- a/pinecone/grpc/vector_factory_grpc.py +++ b/pinecone/grpc/vector_factory_grpc.py @@ -17,7 +17,7 @@ from ..db_data.types import VectorTuple, VectorTypedDict from .sparse_values_factory import SparseValuesFactory -from pinecone.core.grpc.protos.db_data_2025_01_pb2 import ( +from pinecone.core.grpc.protos.db_data_2025_04_pb2 import ( Vector as GRPCVector, SparseValues as GRPCSparseValues, ) diff --git a/tests/integration/data/test_namespace.py b/tests/integration/data/test_namespace.py index 459bfdfd..6c2099ee 100644 --- a/tests/integration/data/test_namespace.py +++ b/tests/integration/data/test_namespace.py @@ -1,9 +1,6 @@ -import os import time import logging -import pytest - from pinecone import NamespaceDescription logger = logging.getLogger(__name__) @@ -43,9 +40,6 @@ def delete_all_namespaces(index): except Exception as e: logger.error(f"Error in delete_all_namespaces: {e}") -@pytest.mark.skipif( - os.getenv("USE_GRPC") == "true", reason="Disable until grpc namespaces support is added" -) class TestNamespaceOperations: def test_describe_namespace(self, idx): """Test describing a namespace""" diff --git a/tests/integration/data_grpc_futures/stub_backend.py b/tests/integration/data_grpc_futures/stub_backend.py index d8983db9..85f400ea 100644 --- a/tests/integration/data_grpc_futures/stub_backend.py +++ b/tests/integration/data_grpc_futures/stub_backend.py @@ -2,8 +2,8 @@ import grpc import logging from concurrent import futures -import pinecone.core.grpc.protos.db_data_2025_01_pb2 as pb2 -import pinecone.core.grpc.protos.db_data_2025_01_pb2_grpc as pb2_grpc +import pinecone.core.grpc.protos.db_data_2025_04_pb2 as pb2 +import pinecone.core.grpc.protos.db_data_2025_04_pb2_grpc as pb2_grpc logger = logging.getLogger(__name__) diff --git a/tests/unit_grpc/test_grpc_index_describe_index_stats.py b/tests/unit_grpc/test_grpc_index_describe_index_stats.py index 0599badb..554fbd40 100644 --- a/tests/unit_grpc/test_grpc_index_describe_index_stats.py +++ b/tests/unit_grpc/test_grpc_index_describe_index_stats.py @@ -1,6 +1,6 @@ from pinecone import Config from pinecone.grpc import GRPCIndex -from pinecone.core.grpc.protos.db_data_2025_01_pb2 import DescribeIndexStatsRequest +from pinecone.core.grpc.protos.db_data_2025_04_pb2 import DescribeIndexStatsRequest from pinecone.grpc.utils import dict_to_proto_struct diff --git a/tests/unit_grpc/test_grpc_index_fetch.py b/tests/unit_grpc/test_grpc_index_fetch.py index ca5c9e7d..97291fe0 100644 --- a/tests/unit_grpc/test_grpc_index_fetch.py +++ b/tests/unit_grpc/test_grpc_index_fetch.py @@ -1,6 +1,6 @@ from pinecone import Config from pinecone.grpc import GRPCIndex -from pinecone.core.grpc.protos.db_data_2025_01_pb2 import FetchRequest +from pinecone.core.grpc.protos.db_data_2025_04_pb2 import FetchRequest class TestGrpcIndexFetch: diff --git a/tests/unit_grpc/test_grpc_index_namespace.py b/tests/unit_grpc/test_grpc_index_namespace.py new file mode 100644 index 00000000..d44dd4e8 --- /dev/null +++ b/tests/unit_grpc/test_grpc_index_namespace.py @@ -0,0 +1,78 @@ +from pinecone import Config +from pinecone.grpc import GRPCIndex +from pinecone.core.grpc.protos.db_data_2025_04_pb2 import ( + DescribeNamespaceRequest, + DeleteNamespaceRequest, + ListNamespacesRequest, +) + + +class TestGrpcIndexNamespace: + def setup_method(self): + self.config = Config(api_key="test-api-key", host="foo.pinecone.io") + self.index = GRPCIndex( + config=self.config, index_name="example-name", _endpoint_override="test-endpoint" + ) + + def test_describe_namespace(self, mocker): + mocker.patch.object(self.index.runner, "run", autospec=True) + self.index.describe_namespace(namespace="test_namespace") + self.index.runner.run.assert_called_once_with( + self.index.stub.DescribeNamespace, + DescribeNamespaceRequest(namespace="test_namespace"), + timeout=None + ) + + def test_describe_namespace_with_timeout(self, mocker): + mocker.patch.object(self.index.runner, "run", autospec=True) + self.index.describe_namespace(namespace="test_namespace", timeout=30) + self.index.runner.run.assert_called_once_with( + self.index.stub.DescribeNamespace, + DescribeNamespaceRequest(namespace="test_namespace"), + timeout=30 + ) + + def test_delete_namespace(self, mocker): + mocker.patch.object(self.index.runner, "run", autospec=True) + self.index.delete_namespace(namespace="test_namespace") + self.index.runner.run.assert_called_once_with( + self.index.stub.DeleteNamespace, + DeleteNamespaceRequest(namespace="test_namespace"), + timeout=None + ) + + def test_delete_namespace_with_timeout(self, mocker): + mocker.patch.object(self.index.runner, "run", autospec=True) + self.index.delete_namespace(namespace="test_namespace", timeout=30) + self.index.runner.run.assert_called_once_with( + self.index.stub.DeleteNamespace, + DeleteNamespaceRequest(namespace="test_namespace"), + timeout=30 + ) + + def test_list_namespaces_paginated(self, mocker): + mocker.patch.object(self.index.runner, "run", autospec=True) + self.index.list_namespaces_paginated(limit=10, pagination_token="token123") + self.index.runner.run.assert_called_once_with( + self.index.stub.ListNamespaces, + ListNamespacesRequest(limit=10, pagination_token="token123"), + timeout=None + ) + + def test_list_namespaces_paginated_with_timeout(self, mocker): + mocker.patch.object(self.index.runner, "run", autospec=True) + self.index.list_namespaces_paginated(limit=10, timeout=30) + self.index.runner.run.assert_called_once_with( + self.index.stub.ListNamespaces, + ListNamespacesRequest(limit=10), + timeout=30 + ) + + def test_list_namespaces_paginated_no_args(self, mocker): + mocker.patch.object(self.index.runner, "run", autospec=True) + self.index.list_namespaces_paginated() + self.index.runner.run.assert_called_once_with( + self.index.stub.ListNamespaces, + ListNamespacesRequest(), + timeout=None + ) \ No newline at end of file diff --git a/tests/unit_grpc/test_grpc_index_query.py b/tests/unit_grpc/test_grpc_index_query.py index 2dbc846b..d237aa98 100644 --- a/tests/unit_grpc/test_grpc_index_query.py +++ b/tests/unit_grpc/test_grpc_index_query.py @@ -2,7 +2,7 @@ from pinecone import Config from pinecone.grpc import GRPCIndex -from pinecone.core.grpc.protos.db_data_2025_01_pb2 import QueryRequest +from pinecone.core.grpc.protos.db_data_2025_04_pb2 import QueryRequest from pinecone.grpc.utils import dict_to_proto_struct diff --git a/tests/unit_grpc/test_grpc_index_update.py b/tests/unit_grpc/test_grpc_index_update.py index f9abd958..207cd09e 100644 --- a/tests/unit_grpc/test_grpc_index_update.py +++ b/tests/unit_grpc/test_grpc_index_update.py @@ -1,6 +1,6 @@ from pinecone import Config from pinecone.grpc import GRPCIndex -from pinecone.core.grpc.protos.db_data_2025_01_pb2 import UpdateRequest +from pinecone.core.grpc.protos.db_data_2025_04_pb2 import UpdateRequest from pinecone.grpc.utils import dict_to_proto_struct diff --git a/tests/unit_grpc/test_grpc_index_upsert.py b/tests/unit_grpc/test_grpc_index_upsert.py index 987053f7..1a65da1c 100644 --- a/tests/unit_grpc/test_grpc_index_upsert.py +++ b/tests/unit_grpc/test_grpc_index_upsert.py @@ -6,7 +6,7 @@ from pinecone import Config from pinecone.grpc import GRPCIndex -from pinecone.core.grpc.protos.db_data_2025_01_pb2 import ( +from pinecone.core.grpc.protos.db_data_2025_04_pb2 import ( Vector, UpsertRequest, UpsertResponse,