Skip to content

Commit 6015607

Browse files
authored
Update OpenAPI Models for Namespace (#541)
# Update OpenAPI Models for Namespace ## Summary This PR updates the codebase to align with the latest OpenAPI specification changes for namespace-related models. The API specification has been updated to: - Add `total_count` field to `ListNamespacesResponse` - Replace `total_count` field in `NamespaceDescription` with `indexed_fields` field The wrapper code has been updated to properly parse and populate these new fields when using the gRPC client. ## Changes ### Code Generator Updates - **Updated `codegen/apis` submodule** to latest commit (`bbad89bd51d792534a9ba06a44ed1f2259f7f89f`) - **Updated `pinecone/core/openapi/db_data/model/list_namespaces_response.py`**: - Added `total_count` (int) field to `ListNamespacesResponse` - Field represents the total number of namespaces in the index matching the prefix - **Updated `pinecone/core/openapi/db_data/model/namespace_description.py`**: - Removed `total_count` field (moved to `ListNamespacesResponse`) - Added `indexed_fields` field of type `NamespaceDescriptionIndexedFields` - Field contains a list of all indexed metadata fields in the namespace - **Added new model `pinecone/core/openapi/db_data/model/namespace_description_indexed_fields.py`**: - New model class `NamespaceDescriptionIndexedFields` with `fields` property (list of strings) - Represents the indexed metadata fields for a namespace - **Updated `pinecone/core/openapi/db_data/models/__init__.py`**: - Added export for `NamespaceDescriptionIndexedFields` - **Updated `pinecone/openapi_support/api_version.py`**: - Updated API version SHA to reflect latest specification ### Wrapper Code Updates - **Updated `pinecone/grpc/utils.py`**: - **`parse_list_namespaces_response` function**: - Now extracts `total_count` from gRPC response (`totalCount` in JSON) - Extracts `indexedFields` for each namespace in the list - Creates `NamespaceDescriptionIndexedFields` objects when present - Includes both fields when constructing `ListNamespacesResponse` - **`parse_namespace_description` function**: - Now extracts `indexedFields` from gRPC response (if present) - Creates `NamespaceDescriptionIndexedFields` object with the `fields` array - Includes `indexed_fields` when constructing `NamespaceDescription` - **Added import** for `NamespaceDescriptionIndexedFields` model ## Technical Details ### Field Changes 1. **`ListNamespacesResponse.total_count`** (new): - Type: `int` - Optional: Yes - Description: The total number of namespaces in the index matching the prefix - Source: Extracted from `totalCount` in gRPC JSON response 2. **`NamespaceDescription.indexed_fields`** (new): - Type: `NamespaceDescriptionIndexedFields` - Optional: Yes - Description: A list of all indexed metadata fields in the namespace - Source: Extracted from `indexedFields.fields` in gRPC JSON response 3. **`NamespaceDescription.total_count`** (removed): - This field has been moved to `ListNamespacesResponse` where it is more semantically appropriate ### Backward Compatibility - All new fields are optional, so existing code will continue to work - Existing tests should continue to pass as they only check required fields - The gRPC parsing functions handle missing fields gracefully by setting them to `None` ## Testing - Type checking with mypy passes for updated files - Existing integration tests should continue to work (they only verify required fields) - The parsing functions handle optional fields correctly when they are absent from responses ## Notes - REST API clients will automatically receive these fields when the API returns them (handled by OpenAPI models) - gRPC clients now properly parse and populate these fields from protobuf responses - Both `total_count` and `indexed_fields` are optional fields, so backward compatibility is maintained
1 parent f44ca91 commit 6015607

File tree

7 files changed

+316
-8
lines changed

7 files changed

+316
-8
lines changed

codegen/apis

Submodule apis updated from bbad89b to d5ac931

pinecone/core/openapi/db_data/model/list_namespaces_response.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ def openapi_types(cls):
9696
return {
9797
"namespaces": ([NamespaceDescription],), # noqa: E501
9898
"pagination": (Pagination,), # noqa: E501
99+
"total_count": (int,), # noqa: E501
99100
}
100101

101102
@cached_class_property
@@ -105,6 +106,7 @@ def discriminator(cls):
105106
attribute_map: Dict[str, str] = {
106107
"namespaces": "namespaces", # noqa: E501
107108
"pagination": "pagination", # noqa: E501
109+
"total_count": "total_count", # noqa: E501
108110
}
109111

110112
read_only_vars: Set[str] = set([])
@@ -149,6 +151,7 @@ def _from_openapi_data(cls: Type[T], *args, **kwargs) -> T: # noqa: E501
149151
_visited_composed_classes = (Animal,)
150152
namespaces ([NamespaceDescription]): The list of namespaces belonging to this index. [optional] # noqa: E501
151153
pagination (Pagination): [optional] # noqa: E501
154+
total_count (int): The total number of namespaces in the index matching the prefix [optional] # noqa: E501
152155
"""
153156

154157
_enforce_allowed_values = kwargs.pop("_enforce_allowed_values", False)
@@ -240,6 +243,7 @@ def __init__(self, *args, **kwargs) -> None: # noqa: E501
240243
_visited_composed_classes = (Animal,)
241244
namespaces ([NamespaceDescription]): The list of namespaces belonging to this index. [optional] # noqa: E501
242245
pagination (Pagination): [optional] # noqa: E501
246+
total_count (int): The total number of namespaces in the index matching the prefix [optional] # noqa: E501
243247
"""
244248

245249
_enforce_allowed_values = kwargs.pop("_enforce_allowed_values", True)

pinecone/core/openapi/db_data/model/namespace_description.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,12 @@ def lazy_import():
3131
from pinecone.core.openapi.db_data.model.create_namespace_request_schema import (
3232
CreateNamespaceRequestSchema,
3333
)
34+
from pinecone.core.openapi.db_data.model.namespace_description_indexed_fields import (
35+
NamespaceDescriptionIndexedFields,
36+
)
3437

3538
globals()["CreateNamespaceRequestSchema"] = CreateNamespaceRequestSchema
39+
globals()["NamespaceDescriptionIndexedFields"] = NamespaceDescriptionIndexedFields
3640

3741

3842
from typing import Dict, Literal, Tuple, Set, Any, Type, TypeVar
@@ -97,7 +101,7 @@ def openapi_types(cls):
97101
"name": (str,), # noqa: E501
98102
"record_count": (int,), # noqa: E501
99103
"schema": (CreateNamespaceRequestSchema,), # noqa: E501
100-
"total_count": (int,), # noqa: E501
104+
"indexed_fields": (NamespaceDescriptionIndexedFields,), # noqa: E501
101105
}
102106

103107
@cached_class_property
@@ -108,7 +112,7 @@ def discriminator(cls):
108112
"name": "name", # noqa: E501
109113
"record_count": "record_count", # noqa: E501
110114
"schema": "schema", # noqa: E501
111-
"total_count": "total_count", # noqa: E501
115+
"indexed_fields": "indexed_fields", # noqa: E501
112116
}
113117

114118
read_only_vars: Set[str] = set([])
@@ -154,7 +158,7 @@ def _from_openapi_data(cls: Type[T], *args, **kwargs) -> T: # noqa: E501
154158
name (str): The name of the namespace. [optional] # noqa: E501
155159
record_count (int): The total amount of records within the namespace. [optional] # noqa: E501
156160
schema (CreateNamespaceRequestSchema): [optional] # noqa: E501
157-
total_count (int): The total number of namespaces in the index matching the prefix [optional] # noqa: E501
161+
indexed_fields (NamespaceDescriptionIndexedFields): [optional] # noqa: E501
158162
"""
159163

160164
_enforce_allowed_values = kwargs.pop("_enforce_allowed_values", False)
@@ -247,7 +251,7 @@ def __init__(self, *args, **kwargs) -> None: # noqa: E501
247251
name (str): The name of the namespace. [optional] # noqa: E501
248252
record_count (int): The total amount of records within the namespace. [optional] # noqa: E501
249253
schema (CreateNamespaceRequestSchema): [optional] # noqa: E501
250-
total_count (int): The total number of namespaces in the index matching the prefix [optional] # noqa: E501
254+
indexed_fields (NamespaceDescriptionIndexedFields): [optional] # noqa: E501
251255
"""
252256

253257
_enforce_allowed_values = kwargs.pop("_enforce_allowed_values", True)
Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
"""
2+
Pinecone Data Plane API
3+
4+
Pinecone is a vector database that makes it easy to search and retrieve billions of high-dimensional vectors. # noqa: E501
5+
6+
This file is @generated using OpenAPI.
7+
8+
The version of the OpenAPI document: 2025-10
9+
10+
"""
11+
12+
from pinecone.openapi_support.model_utils import ( # noqa: F401
13+
PineconeApiTypeError,
14+
ModelComposed,
15+
ModelNormal,
16+
ModelSimple,
17+
OpenApiModel,
18+
cached_property,
19+
change_keys_js_to_python,
20+
convert_js_args_to_python_args,
21+
date,
22+
datetime,
23+
file_type,
24+
none_type,
25+
validate_get_composed_info,
26+
)
27+
from pinecone.openapi_support.exceptions import PineconeApiAttributeError
28+
29+
30+
from typing import Dict, Literal, Tuple, Set, Any, Type, TypeVar
31+
from pinecone.openapi_support import PropertyValidationTypedDict, cached_class_property
32+
33+
T = TypeVar("T", bound="NamespaceDescriptionIndexedFields")
34+
35+
36+
class NamespaceDescriptionIndexedFields(ModelNormal):
37+
"""NOTE: This class is @generated using OpenAPI.
38+
39+
Do not edit the class manually.
40+
41+
Attributes:
42+
allowed_values (dict): The key is the tuple path to the attribute
43+
and the for var_name this is (var_name,). The value is a dict
44+
with a capitalized key describing the allowed value and an allowed
45+
value. These dicts store the allowed enum values.
46+
attribute_map (dict): The key is attribute name
47+
and the value is json key in definition.
48+
discriminator_value_class_map (dict): A dict to go from the discriminator
49+
variable value to the discriminator class name.
50+
validations (dict): The key is the tuple path to the attribute
51+
and the for var_name this is (var_name,). The value is a dict
52+
that stores validations for max_length, min_length, max_items,
53+
min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum,
54+
inclusive_minimum, and regex.
55+
additional_properties_type (tuple): A tuple of classes accepted
56+
as additional properties values.
57+
"""
58+
59+
_data_store: Dict[str, Any]
60+
_check_type: bool
61+
62+
allowed_values: Dict[Tuple[str, ...], Dict[str, Any]] = {}
63+
64+
validations: Dict[Tuple[str, ...], PropertyValidationTypedDict] = {}
65+
66+
@cached_class_property
67+
def additional_properties_type(cls):
68+
"""
69+
This must be a method because a model may have properties that are
70+
of type self, this must run after the class is loaded
71+
"""
72+
return (bool, dict, float, int, list, str, none_type) # noqa: E501
73+
74+
_nullable = False
75+
76+
@cached_class_property
77+
def openapi_types(cls):
78+
"""
79+
This must be a method because a model may have properties that are
80+
of type self, this must run after the class is loaded
81+
82+
Returns
83+
openapi_types (dict): The key is attribute name
84+
and the value is attribute type.
85+
"""
86+
return {
87+
"fields": ([str],) # noqa: E501
88+
}
89+
90+
@cached_class_property
91+
def discriminator(cls):
92+
return None
93+
94+
attribute_map: Dict[str, str] = {
95+
"fields": "fields" # noqa: E501
96+
}
97+
98+
read_only_vars: Set[str] = set([])
99+
100+
_composed_schemas: Dict[Literal["allOf", "oneOf", "anyOf"], Any] = {}
101+
102+
@classmethod
103+
@convert_js_args_to_python_args
104+
def _from_openapi_data(cls: Type[T], *args, **kwargs) -> T: # noqa: E501
105+
"""NamespaceDescriptionIndexedFields - a model defined in OpenAPI
106+
107+
Keyword Args:
108+
_check_type (bool): if True, values for parameters in openapi_types
109+
will be type checked and a TypeError will be
110+
raised if the wrong type is input.
111+
Defaults to True
112+
_path_to_item (tuple/list): This is a list of keys or values to
113+
drill down to the model in received_data
114+
when deserializing a response
115+
_spec_property_naming (bool): True if the variable names in the input data
116+
are serialized names, as specified in the OpenAPI document.
117+
False if the variable names in the input data
118+
are pythonic names, e.g. snake case (default)
119+
_configuration (Configuration): the instance to use when
120+
deserializing a file_type parameter.
121+
If passed, type conversion is attempted
122+
If omitted no type conversion is done.
123+
_visited_composed_classes (tuple): This stores a tuple of
124+
classes that we have traveled through so that
125+
if we see that class again we will not use its
126+
discriminator again.
127+
When traveling through a discriminator, the
128+
composed schema that is
129+
is traveled through is added to this set.
130+
For example if Animal has a discriminator
131+
petType and we pass in "Dog", and the class Dog
132+
allOf includes Animal, we move through Animal
133+
once using the discriminator, and pick Dog.
134+
Then in Dog, we will make an instance of the
135+
Animal class but this time we won't travel
136+
through its discriminator because we passed in
137+
_visited_composed_classes = (Animal,)
138+
fields ([str]): [optional] # noqa: E501
139+
"""
140+
141+
_enforce_allowed_values = kwargs.pop("_enforce_allowed_values", False)
142+
_enforce_validations = kwargs.pop("_enforce_validations", False)
143+
_check_type = kwargs.pop("_check_type", True)
144+
_spec_property_naming = kwargs.pop("_spec_property_naming", False)
145+
_path_to_item = kwargs.pop("_path_to_item", ())
146+
_configuration = kwargs.pop("_configuration", None)
147+
_visited_composed_classes = kwargs.pop("_visited_composed_classes", ())
148+
149+
self = super(OpenApiModel, cls).__new__(cls)
150+
151+
if args:
152+
raise PineconeApiTypeError(
153+
"Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments."
154+
% (args, self.__class__.__name__),
155+
path_to_item=_path_to_item,
156+
valid_classes=(self.__class__,),
157+
)
158+
159+
self._data_store = {}
160+
self._enforce_allowed_values = _enforce_allowed_values
161+
self._enforce_validations = _enforce_validations
162+
self._check_type = _check_type
163+
self._spec_property_naming = _spec_property_naming
164+
self._path_to_item = _path_to_item
165+
self._configuration = _configuration
166+
self._visited_composed_classes = _visited_composed_classes + (self.__class__,)
167+
168+
for var_name, var_value in kwargs.items():
169+
if (
170+
var_name not in self.attribute_map
171+
and self._configuration is not None
172+
and self._configuration.discard_unknown_keys
173+
and self.additional_properties_type is None
174+
):
175+
# discard variable.
176+
continue
177+
setattr(self, var_name, var_value)
178+
return self
179+
180+
required_properties = set(
181+
[
182+
"_enforce_allowed_values",
183+
"_enforce_validations",
184+
"_data_store",
185+
"_check_type",
186+
"_spec_property_naming",
187+
"_path_to_item",
188+
"_configuration",
189+
"_visited_composed_classes",
190+
]
191+
)
192+
193+
@convert_js_args_to_python_args
194+
def __init__(self, *args, **kwargs) -> None: # noqa: E501
195+
"""NamespaceDescriptionIndexedFields - a model defined in OpenAPI
196+
197+
Keyword Args:
198+
_check_type (bool): if True, values for parameters in openapi_types
199+
will be type checked and a TypeError will be
200+
raised if the wrong type is input.
201+
Defaults to True
202+
_path_to_item (tuple/list): This is a list of keys or values to
203+
drill down to the model in received_data
204+
when deserializing a response
205+
_spec_property_naming (bool): True if the variable names in the input data
206+
are serialized names, as specified in the OpenAPI document.
207+
False if the variable names in the input data
208+
are pythonic names, e.g. snake case (default)
209+
_configuration (Configuration): the instance to use when
210+
deserializing a file_type parameter.
211+
If passed, type conversion is attempted
212+
If omitted no type conversion is done.
213+
_visited_composed_classes (tuple): This stores a tuple of
214+
classes that we have traveled through so that
215+
if we see that class again we will not use its
216+
discriminator again.
217+
When traveling through a discriminator, the
218+
composed schema that is
219+
is traveled through is added to this set.
220+
For example if Animal has a discriminator
221+
petType and we pass in "Dog", and the class Dog
222+
allOf includes Animal, we move through Animal
223+
once using the discriminator, and pick Dog.
224+
Then in Dog, we will make an instance of the
225+
Animal class but this time we won't travel
226+
through its discriminator because we passed in
227+
_visited_composed_classes = (Animal,)
228+
fields ([str]): [optional] # noqa: E501
229+
"""
230+
231+
_enforce_allowed_values = kwargs.pop("_enforce_allowed_values", True)
232+
_enforce_validations = kwargs.pop("_enforce_validations", True)
233+
_check_type = kwargs.pop("_check_type", True)
234+
_spec_property_naming = kwargs.pop("_spec_property_naming", False)
235+
_path_to_item = kwargs.pop("_path_to_item", ())
236+
_configuration = kwargs.pop("_configuration", None)
237+
_visited_composed_classes = kwargs.pop("_visited_composed_classes", ())
238+
239+
if args:
240+
raise PineconeApiTypeError(
241+
"Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments."
242+
% (args, self.__class__.__name__),
243+
path_to_item=_path_to_item,
244+
valid_classes=(self.__class__,),
245+
)
246+
247+
self._data_store = {}
248+
self._enforce_allowed_values = _enforce_allowed_values
249+
self._enforce_validations = _enforce_validations
250+
self._check_type = _check_type
251+
self._spec_property_naming = _spec_property_naming
252+
self._path_to_item = _path_to_item
253+
self._configuration = _configuration
254+
self._visited_composed_classes = _visited_composed_classes + (self.__class__,)
255+
256+
for var_name, var_value in kwargs.items():
257+
if (
258+
var_name not in self.attribute_map
259+
and self._configuration is not None
260+
and self._configuration.discard_unknown_keys
261+
and self.additional_properties_type is None
262+
):
263+
# discard variable.
264+
continue
265+
setattr(self, var_name, var_value)
266+
if var_name in self.read_only_vars:
267+
raise PineconeApiAttributeError(
268+
f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate "
269+
f"class with read only attributes."
270+
)

pinecone/core/openapi/db_data/models/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
from pinecone.core.openapi.db_data.model.list_namespaces_response import ListNamespacesResponse
3333
from pinecone.core.openapi.db_data.model.list_response import ListResponse
3434
from pinecone.core.openapi.db_data.model.namespace_description import NamespaceDescription
35+
from pinecone.core.openapi.db_data.model.namespace_description_indexed_fields import (
36+
NamespaceDescriptionIndexedFields,
37+
)
3538
from pinecone.core.openapi.db_data.model.namespace_summary import NamespaceSummary
3639
from pinecone.core.openapi.db_data.model.pagination import Pagination
3740
from pinecone.core.openapi.db_data.model.protobuf_any import ProtobufAny

0 commit comments

Comments
 (0)