Skip to content

Commit e3d8d82

Browse files
committed
Enhance serverless index configuration with read capacity and metadata schema options. Added support for OnDemand and Dedicated read capacity modes, along with the ability to specify filterable metadata fields in the index schema. Updated related models and request factory to handle new configurations. Added integration tests for various index creation scenarios.
1 parent ce18ffa commit e3d8d82

File tree

14 files changed

+736
-17
lines changed

14 files changed

+736
-17
lines changed

.cursor/rules/docstrings.mdc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
alwaysApply: true
3+
---
4+
- All methods should have docstrings formatted as RST. When changing a method, review the docstring to make sure it is up-to-date.
5+
- Verify markdown docs in the docs/ directory are up to date
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
alwaysApply: true
3+
---
4+
- When implementing new features, always add integration tests covering the new functionality.
5+
- Test edge cases as well as happy path

.cursor/rules/sync-vs-async.mdc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
alwaysApply: true
3+
---
4+
All user-facing functionality needs to be implemented in both Pinecone and PineconeAsyncio classes

PR_DESCRIPTION.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# Add Admin API Update Endpoints and Organization Resource
2+
3+
## Summary
4+
5+
This PR implements new update endpoints for the Admin API and adds a new `OrganizationResource` class to expose organization management functionality. The changes include:
6+
7+
1. **API Key Updates**: Added `update()` method to `ApiKeyResource` to support updating API key names and roles
8+
2. **Organization Resource**: Created a new `OrganizationResource` class with full CRUD operations (list, fetch, get, describe, update)
9+
3. **Integration**: Exposed `OrganizationResource` in the `Admin` class via `organization` and `organizations` properties
10+
4. **Testing**: Added comprehensive integration tests for all new functionality
11+
12+
## Changes
13+
14+
### 1. API Key Resource Updates
15+
16+
**File**: `pinecone/admin/resources/api_key.py`
17+
18+
- Added `update()` method to `ApiKeyResource` class
19+
- Supports updating API key `name` and `roles`
20+
- Includes RST-formatted docstrings with examples
21+
- Follows existing patterns from other resource classes
22+
23+
**Example Usage**:
24+
```python
25+
from pinecone import Admin
26+
27+
admin = Admin()
28+
29+
# Update API key name
30+
api_key = admin.api_key.update(
31+
api_key_id='my-api-key-id',
32+
name='updated-api-key-name'
33+
)
34+
35+
# Update API key roles
36+
api_key = admin.api_key.update(
37+
api_key_id='my-api-key-id',
38+
roles=['ProjectViewer']
39+
)
40+
```
41+
42+
### 2. Organization Resource
43+
44+
**File**: `pinecone/admin/resources/organization.py` (new file)
45+
46+
Created a new `OrganizationResource` class with the following methods:
47+
48+
- `list()`: List all organizations associated with the account
49+
- `fetch(organization_id)`: Fetch an organization by ID
50+
- `get(organization_id)`: Alias for `fetch()`
51+
- `describe(organization_id)`: Alias for `fetch()`
52+
- `update(organization_id, name)`: Update an organization's name
53+
54+
All methods include RST-formatted docstrings with usage examples.
55+
56+
**Example Usage**:
57+
```python
58+
from pinecone import Admin
59+
60+
admin = Admin()
61+
62+
# List all organizations
63+
organizations = admin.organization.list()
64+
for org in organizations.data:
65+
print(org.name)
66+
67+
# Fetch an organization
68+
org = admin.organization.get(organization_id="my-org-id")
69+
70+
# Update an organization
71+
org = admin.organization.update(
72+
organization_id="my-org-id",
73+
name="updated-name"
74+
)
75+
```
76+
77+
### 3. Admin Class Integration
78+
79+
**File**: `pinecone/admin/admin.py`
80+
81+
- Added `_organization` instance variable for lazy initialization
82+
- Added `organization` property to access `OrganizationResource`
83+
- Added `organizations` property as an alias for `organization`
84+
- Includes comprehensive docstrings with examples
85+
86+
**File**: `pinecone/admin/resources/__init__.py`
87+
88+
- Exported `OrganizationResource` in `__all__`
89+
90+
### 4. Integration Tests
91+
92+
**File**: `tests/integration/admin/test_api_key.py`
93+
94+
- Added `test_update_api_key()` test covering:
95+
- Updating API key name only
96+
- Updating API key roles only
97+
- Updating both name and roles
98+
- Verifying changes persist after fetch
99+
- Proper cleanup of created resources
100+
101+
**File**: `tests/integration/admin/test_organization.py` (new file)
102+
103+
Added comprehensive integration tests:
104+
105+
- `test_update_organization()`: Tests updating organization name with proper cleanup (reverts name changes)
106+
- `test_list_organizations()`: Tests listing organizations, verifies response structure, field types, and dictionary/get-style access
107+
- `test_fetch_organization()`: Tests fetching an organization by ID, verifies all fields match list results
108+
- `test_fetch_aliases()`: Tests that `fetch()`, `get()`, and `describe()` return identical results
109+
110+
All tests include proper error handling and cleanup to avoid resource waste.
111+
112+
## Testing
113+
114+
All new integration tests have been run and pass:
115+
116+
```bash
117+
poetry run pytest tests/integration/admin/test_api_key.py::TestAdminApiKey::test_update_api_key -v
118+
poetry run pytest tests/integration/admin/test_organization.py -v
119+
```
120+
121+
## Implementation Details
122+
123+
- All methods follow existing patterns from `ProjectResource` and `ApiKeyResource`
124+
- Uses `@require_kwargs` decorator for parameter validation
125+
- Uses `parse_non_empty_args()` utility to build request objects
126+
- All docstrings follow RST format with examples
127+
- Error handling follows existing patterns
128+
- Tests verify both attribute access and dictionary-style access for compatibility
129+
130+
## Backward Compatibility
131+
132+
✅ All changes are backward compatible. No existing functionality is modified or removed.
133+
134+
## Related
135+
136+
- Implements update endpoints found in `pinecone/core/openapi/admin/` (generated OpenAPI code)
137+
- Follows workspace rules for RST docstrings and integration testing
138+

codegen/apis

Submodule apis updated from 827d26f to bbad89b

docs/db_control/serverless-indexes.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,107 @@ pc.create_index(
126126
)
127127
```
128128

129+
## Read Capacity Configuration
130+
131+
You can configure the read capacity mode for your serverless index. By default, indexes are created with `OnDemand` mode. You can also specify `Dedicated` mode with dedicated read nodes.
132+
133+
### OnDemand Read Capacity
134+
135+
OnDemand mode automatically scales read capacity based on demand. This is the default mode.
136+
137+
```python
138+
from pinecone import (
139+
Pinecone,
140+
ServerlessSpec,
141+
CloudProvider,
142+
AwsRegion,
143+
Metric
144+
)
145+
146+
pc = Pinecone(api_key='<<PINECONE_API_KEY>>')
147+
148+
pc.create_index(
149+
name='my-index',
150+
dimension=1536,
151+
metric=Metric.COSINE,
152+
spec=ServerlessSpec(
153+
cloud=CloudProvider.AWS,
154+
region=AwsRegion.US_WEST_2,
155+
read_capacity={"mode": "OnDemand"}
156+
)
157+
)
158+
```
159+
160+
### Dedicated Read Capacity
161+
162+
Dedicated mode allocates dedicated read nodes for your workload. You must specify `node_type`, `scaling`, and scaling configuration.
163+
164+
```python
165+
from pinecone import (
166+
Pinecone,
167+
ServerlessSpec,
168+
CloudProvider,
169+
GcpRegion,
170+
Metric
171+
)
172+
173+
pc = Pinecone(api_key='<<PINECONE_API_KEY>>')
174+
175+
pc.create_index(
176+
name='my-index',
177+
dimension=1536,
178+
metric=Metric.COSINE,
179+
spec=ServerlessSpec(
180+
cloud=CloudProvider.GCP,
181+
region=GcpRegion.US_CENTRAL1,
182+
read_capacity={
183+
"mode": "Dedicated",
184+
"dedicated": {
185+
"node_type": "t1",
186+
"scaling": "Manual",
187+
"manual": {
188+
"shards": 2,
189+
"replicas": 2
190+
}
191+
}
192+
}
193+
)
194+
)
195+
```
196+
197+
## Metadata Schema Configuration
198+
199+
You can configure which metadata fields are filterable by specifying a metadata schema. By default, all metadata fields are indexed. However, large amounts of metadata can cause slower index building as well as slower query execution, particularly when data is not cached in a query executor's memory and local SSD and must be fetched from object storage.
200+
201+
To prevent performance issues due to excessive metadata, you can limit metadata indexing to the fields that you plan to use for query filtering. When you specify a metadata schema, only fields marked as `filterable: true` are indexed and can be used in filters.
202+
203+
```python
204+
from pinecone import (
205+
Pinecone,
206+
ServerlessSpec,
207+
CloudProvider,
208+
AwsRegion,
209+
Metric
210+
)
211+
212+
pc = Pinecone(api_key='<<PINECONE_API_KEY>>')
213+
214+
pc.create_index(
215+
name='my-index',
216+
dimension=1536,
217+
metric=Metric.COSINE,
218+
spec=ServerlessSpec(
219+
cloud=CloudProvider.AWS,
220+
region=AwsRegion.US_WEST_2,
221+
schema={
222+
"genre": {"filterable": True},
223+
"year": {"filterable": True},
224+
"description": {"filterable": True}
225+
}
226+
)
227+
)
228+
```
229+
129230
## Configuring, listing, describing, and deleting
130231

131232
See [shared index actions](shared-index-actions.md) to learn about how to manage the lifecycle of your index after it is created.

pinecone/db_control/models/backup_model.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,40 @@
11
import json
2+
from typing import Optional, TYPE_CHECKING
23
from pinecone.core.openapi.db_control.model.backup_model import BackupModel as OpenAPIBackupModel
34
from pinecone.utils.repr_overrides import custom_serializer
45

6+
if TYPE_CHECKING:
7+
from pinecone.core.openapi.db_control.model.backup_model_schema import BackupModelSchema
8+
59

610
class BackupModel:
11+
"""Represents a Pinecone backup configuration and status.
12+
13+
The BackupModel describes the configuration and status of a Pinecone backup,
14+
including metadata about the source index, backup location, and schema
15+
configuration.
16+
"""
17+
718
def __init__(self, backup: OpenAPIBackupModel):
819
self._backup = backup
920

21+
@property
22+
def schema(self) -> Optional["BackupModelSchema"]:
23+
"""Schema for the behavior of Pinecone's internal metadata index.
24+
25+
This property defines which metadata fields are indexed and filterable
26+
in the backup. By default, all metadata is indexed. When ``schema`` is
27+
present, only fields which are present in the ``fields`` object with
28+
``filterable: true`` are indexed.
29+
30+
The schema is a map of metadata field names to their configuration,
31+
where each field configuration specifies whether the field is filterable.
32+
33+
:type: BackupModelSchema, optional
34+
:returns: The metadata schema configuration, or None if not set.
35+
"""
36+
return getattr(self._backup, "schema", None)
37+
1038
def __getattr__(self, attr):
1139
return getattr(self._backup, attr)
1240

0 commit comments

Comments
 (0)