Skip to content

Commit d3017fb

Browse files
committed
fix(admin): enforce 80-character max length on ApiKeys.create name
## Purpose The backend rejects names longer than 80 characters with a confusing HTTP 400 error. The SDK accepted any length, giving users no early feedback when they exceeded the limit. ## Solution Added `require_max_length` helper to `pinecone/_internal/validation.py` following the same pattern as existing `require_non_empty` and `require_positive` utilities. Called it in `ApiKeys.create()` after the existing `require_non_empty` check. Added `test_api_key_create_name_too_long` to both the unit test suite (`tests/unit/admin/test_admin_api_keys.py`) and integration tests (`tests/integration/test_admin.py`). Validation fires before any network call, so the integration test requires no credentials.
1 parent d137f72 commit d3017fb

4 files changed

Lines changed: 38 additions & 2 deletions

File tree

‎pinecone/_internal/validation.py‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ def require_in_range(name: str, value: int, min_val: int, max_val: int) -> None:
3838
raise ValidationError(f"{name} must be between {min_val} and {max_val}, got {value}")
3939

4040

41+
def require_max_length(name: str, value: str, max_length: int) -> None:
42+
"""Raise ValidationError if value exceeds max_length characters."""
43+
if len(value) > max_length:
44+
raise ValidationError(f"{name} is too long (max {max_length} characters)")
45+
46+
4147
def require_one_of(name: str, value: str, allowed: Sequence[str]) -> None:
4248
"""Raise ValidationError if *value* is not in the *allowed* set."""
4349
if value not in allowed:

‎pinecone/admin/api_keys.py‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from typing import TYPE_CHECKING, Any
88

99
from pinecone._internal.adapters.admin_adapter import AdminAdapter
10-
from pinecone._internal.validation import require_non_empty
10+
from pinecone._internal.validation import require_max_length, require_non_empty
1111
from pinecone.errors.exceptions import ValidationError
1212
from pinecone.models.admin.api_key import APIKeyList, APIKeyModel, APIKeyRole, APIKeyWithSecret
1313

@@ -107,7 +107,7 @@ def create(
107107
108108
Raises:
109109
:exc:`~pinecone.errors.exceptions.PineconeValueError`:
110-
If *project_id* or *name* is empty.
110+
If *project_id* or *name* is empty, or if *name* exceeds 80 characters.
111111
:exc:`ApiError`: If the API returns an error response.
112112
113113
Examples:
@@ -128,6 +128,7 @@ def create(
128128
"""
129129
require_non_empty("project_id", project_id)
130130
require_non_empty("name", name)
131+
require_max_length("name", name, 80)
131132
body: dict[str, Any] = {"name": name}
132133
if description is not None:
133134
body["description"] = description

‎tests/integration/test_admin.py‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,30 @@ def test_project_lifecycle_create_describe_update_delete(admin: Admin) -> None:
298298
admin.projects.describe(project_id=created.id)
299299

300300

301+
# ---------------------------------------------------------------------------
302+
# api_keys — validation (no credentials required)
303+
# ---------------------------------------------------------------------------
304+
305+
306+
@pytest.mark.integration
307+
def test_api_key_create_name_too_long() -> None:
308+
"""ApiKeys.create() raises PineconeValueError when name exceeds 80 characters.
309+
310+
Validation fires before any network call; no service-account credentials needed.
311+
"""
312+
from pinecone._internal.config import PineconeConfig
313+
from pinecone._internal.constants import ADMIN_API_VERSION
314+
from pinecone._internal.http_client import HTTPClient
315+
from pinecone.admin.api_keys import ApiKeys
316+
317+
config = PineconeConfig(api_key="test-key", host="https://api.pinecone.io")
318+
http = HTTPClient(config, ADMIN_API_VERSION)
319+
api_keys = ApiKeys(http=http)
320+
321+
with pytest.raises(PineconeValueError, match="name"):
322+
api_keys.create(project_id="proj-abc123", name="x" * 81)
323+
324+
301325
# ---------------------------------------------------------------------------
302326
# api_keys — name-nullability
303327
# ---------------------------------------------------------------------------

‎tests/unit/admin/test_admin_api_keys.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,11 @@ def test_create_requires_project_id(api_keys: ApiKeys) -> None:
307307
api_keys.create(project_id="", name="mykey")
308308

309309

310+
def test_api_key_create_name_too_long(api_keys: ApiKeys) -> None:
311+
with pytest.raises(ValidationError, match="name"):
312+
api_keys.create(project_id="p1", name="x" * 81)
313+
314+
310315
def test_describe_requires_api_key_id(api_keys: ApiKeys) -> None:
311316
with pytest.raises(ValidationError, match="api_key_id"):
312317
api_keys.describe(api_key_id="")

0 commit comments

Comments
 (0)