Skip to content

Commit d028808

Browse files
committed
refactor(reserved tag key): Iterator pattern conversion, read method removed and service class renamed
1 parent fc4ab31 commit d028808

6 files changed

Lines changed: 27 additions & 90 deletions

File tree

examples/reserved_tag_key.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,7 @@ def main():
5353
try:
5454
# 1. List existing reserved tag keys
5555
print("\n1. Listing reserved tag keys...")
56-
reserved_tag_keys = client.reserved_tag_key.list(TFE_ORG)
57-
print(f"✅ Found {len(reserved_tag_keys.items)} reserved tag keys:")
58-
for rtk in reserved_tag_keys.items:
56+
for rtk in client.reserved_tag_key.list(TFE_ORG):
5957
print(
6058
f" - ID: {rtk.id}, Key: {rtk.key}, Disable Overrides: {rtk.disable_overrides}"
6159
)
@@ -87,18 +85,16 @@ def main():
8785

8886
# 5. Verify deletion by listing again
8987
print("\n5. Verifying deletion...")
90-
reserved_tag_keys_after = client.reserved_tag_key.list(TFE_ORG)
91-
print(
92-
f"✅ Reserved tag keys after deletion: {len(reserved_tag_keys_after.items)}"
93-
)
88+
reserved_tag_keys_after = list(client.reserved_tag_key.list(TFE_ORG))
89+
print(f"Reserved tag keys after deletion: {len(reserved_tag_keys_after)}")
9490

9591
# 6. Demonstrate pagination with options
9692
print("\n6. Demonstrating pagination options...")
97-
list_options = ReservedTagKeyListOptions(page_size=5, page_number=1)
98-
paginated_rtks = client.reserved_tag_key.list(TFE_ORG, list_options)
99-
print(f"✅ Page 1 with page size 5: {len(paginated_rtks.items)} keys")
100-
print(f" Total pages: {paginated_rtks.total_pages}")
101-
print(f" Total count: {paginated_rtks.total_count}")
93+
list_options = ReservedTagKeyListOptions(page_size=5)
94+
for rtk in client.reserved_tag_key.list(TFE_ORG, list_options):
95+
print(
96+
f" - ID: {rtk.id}, Key: {rtk.key}, Disable Overrides: {rtk.disable_overrides}"
97+
)
10298

10399
print("\n🎉 Reserved Tag Keys API example completed successfully!")
104100

src/pytfe/client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from .resources.query_run import QueryRuns
2222
from .resources.registry_module import RegistryModules
2323
from .resources.registry_provider import RegistryProviders
24-
from .resources.reserved_tag_key import ReservedTagKey
24+
from .resources.reserved_tag_key import ReservedTagKeys
2525
from .resources.run import Runs
2626
from .resources.run_event import RunEvents
2727
from .resources.run_task import RunTasks
@@ -91,7 +91,7 @@ def __init__(self, config: TFEConfig | None = None):
9191
self.ssh_keys = SSHKeys(self._transport)
9292

9393
# Reserved Tag Key
94-
self.reserved_tag_key = ReservedTagKey(self._transport)
94+
self.reserved_tag_key = ReservedTagKeys(self._transport)
9595

9696
def close(self) -> None:
9797
try:

src/pytfe/models/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@
206206
from .reserved_tag_key import (
207207
ReservedTagKey,
208208
ReservedTagKeyCreateOptions,
209-
ReservedTagKeyList,
210209
ReservedTagKeyListOptions,
211210
ReservedTagKeyUpdateOptions,
212211
)
@@ -358,7 +357,6 @@
358357
# Reserved tag keys
359358
"ReservedTagKey",
360359
"ReservedTagKeyCreateOptions",
361-
"ReservedTagKeyList",
362360
"ReservedTagKeyListOptions",
363361
"ReservedTagKeyUpdateOptions",
364362
# Agent & pools

src/pytfe/models/reserved_tag_key.py

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -65,24 +65,6 @@ class ReservedTagKeyListOptions(BaseModel):
6565

6666
model_config = ConfigDict(populate_by_name=True)
6767

68-
page_number: int | None = Field(
69-
None, alias="page[number]", description="Page number to retrieve", ge=1
70-
)
7168
page_size: int | None = Field(
7269
None, alias="page[size]", description="Number of items per page", ge=1, le=100
7370
)
74-
75-
76-
class ReservedTagKeyList(BaseModel):
77-
"""Represents a paginated list of reserved tag keys."""
78-
79-
model_config = ConfigDict(populate_by_name=True)
80-
81-
items: list[ReservedTagKey] = Field(
82-
default_factory=list, description="List of reserved tag keys"
83-
)
84-
current_page: int | None = Field(None, description="Current page number")
85-
total_pages: int | None = Field(None, description="Total number of pages")
86-
prev_page: str | None = Field(None, description="URL of the previous page")
87-
next_page: str | None = Field(None, description="URL of the next page")
88-
total_count: int | None = Field(None, description="Total number of items")
Lines changed: 12 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,42 @@
11
from __future__ import annotations
22

3+
from collections.abc import Iterator
34
from typing import Any
45

56
from ..errors import (
67
InvalidOrgError,
78
ValidationError,
89
)
910
from ..models.reserved_tag_key import (
10-
ReservedTagKey as ReservedTagKeyModel,
11-
)
12-
from ..models.reserved_tag_key import (
11+
ReservedTagKey,
1312
ReservedTagKeyCreateOptions,
14-
ReservedTagKeyList,
1513
ReservedTagKeyListOptions,
1614
ReservedTagKeyUpdateOptions,
1715
)
1816
from ..utils import valid_string_id
1917
from ._base import _Service
2018

2119

22-
class ReservedTagKey(_Service):
20+
class ReservedTagKeys(_Service):
2321
"""Reserved Tag Key API for Terraform Enterprise."""
2422

2523
def list(
2624
self, organization: str, options: ReservedTagKeyListOptions | None = None
27-
) -> ReservedTagKeyList:
25+
) -> Iterator[ReservedTagKey]:
2826
"""List reserved tag keys for the given organization."""
2927
if not valid_string_id(organization):
3028
raise InvalidOrgError()
3129

3230
params = (
3331
options.model_dump(by_alias=True, exclude_none=True) if options else None
3432
)
35-
36-
r = self.t.request(
37-
"GET",
38-
f"/api/v2/organizations/{organization}/reserved-tag-keys",
39-
params=params,
40-
)
41-
42-
jd = r.json()
43-
items = []
44-
meta = jd.get("meta", {})
45-
pagination = meta.get("pagination", {})
46-
47-
for d in jd.get("data", []):
48-
items.append(self._parse_reserved_tag_key(d))
49-
50-
return ReservedTagKeyList(
51-
items=items,
52-
current_page=pagination.get("current-page"),
53-
total_pages=pagination.get("total-pages"),
54-
prev_page=pagination.get("prev-page"),
55-
next_page=pagination.get("next-page"),
56-
total_count=pagination.get("total-count"),
57-
)
33+
path = f"/api/v2/organizations/{organization}/reserved-tag-keys"
34+
for item in self._list(path, params=params):
35+
yield self._parse_reserved_tag_key(item)
5836

5937
def create(
6038
self, organization: str, options: ReservedTagKeyCreateOptions
61-
) -> ReservedTagKeyModel:
39+
) -> ReservedTagKey:
6240
"""Create a new reserved tag key for the given organization."""
6341
if not valid_string_id(organization):
6442
raise InvalidOrgError()
@@ -82,20 +60,9 @@ def create(
8260

8361
return self._parse_reserved_tag_key(data)
8462

85-
def read(self, reserved_tag_key_id: str) -> ReservedTagKeyModel:
86-
"""Read a reserved tag key by its ID."""
87-
if not valid_string_id(reserved_tag_key_id):
88-
raise ValidationError("Invalid reserved tag key ID")
89-
90-
# Note: Based on the API docs, there's no explicit GET endpoint for individual reserved tag keys
91-
# This method would need to be implemented if such an endpoint exists
92-
raise NotImplementedError(
93-
"Individual reserved tag key read is not supported by the API"
94-
)
95-
9663
def update(
9764
self, reserved_tag_key_id: str, options: ReservedTagKeyUpdateOptions
98-
) -> ReservedTagKeyModel:
65+
) -> ReservedTagKey:
9966
"""Update a reserved tag key."""
10067
if not valid_string_id(reserved_tag_key_id):
10168
raise ValidationError("Invalid reserved tag key ID")
@@ -125,10 +92,10 @@ def delete(self, reserved_tag_key_id: str) -> None:
12592
raise ValidationError("Invalid reserved tag key ID")
12693

12794
self.t.request("DELETE", f"/api/v2/reserved-tag-keys/{reserved_tag_key_id}")
128-
# DELETE returns 204 No Content on success
95+
return None
12996

130-
def _parse_reserved_tag_key(self, data: dict[str, Any]) -> ReservedTagKeyModel:
97+
def _parse_reserved_tag_key(self, data: dict[str, Any]) -> ReservedTagKey:
13198
"""Parse reserved tag key data from API response."""
13299
attrs = data.get("attributes", {})
133100
attrs["id"] = data.get("id")
134-
return ReservedTagKeyModel.model_validate(attrs)
101+
return ReservedTagKey.model_validate(attrs)

tests/units/test_reserved_tag_key.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
ReservedTagKeyListOptions,
1515
ReservedTagKeyUpdateOptions,
1616
)
17-
from pytfe.resources.reserved_tag_key import ReservedTagKey
17+
from pytfe.resources.reserved_tag_key import ReservedTagKeys
1818

1919

2020
class TestReservedTagKeyParsing:
@@ -24,7 +24,7 @@ class TestReservedTagKeyParsing:
2424
def reserved_tag_key_service(self):
2525
"""Create a ReservedTagKey service for testing parsing."""
2626
mock_transport = Mock(spec=HTTPTransport)
27-
return ReservedTagKey(mock_transport)
27+
return ReservedTagKeys(mock_transport)
2828

2929
def test_parse_reserved_tag_key_minimal(self, reserved_tag_key_service):
3030
"""Test _parse_reserved_tag_key with minimal data."""
@@ -68,12 +68,12 @@ class TestReservedTagKey:
6868
def reserved_tag_key_service(self):
6969
"""Create a ReservedTagKey service for testing."""
7070
mock_transport = Mock(spec=HTTPTransport)
71-
return ReservedTagKey(mock_transport)
71+
return ReservedTagKeys(mock_transport)
7272

7373
def test_list_reserved_tag_keys_invalid_org(self, reserved_tag_key_service):
7474
"""Test listing reserved tag keys with invalid organization."""
7575
with pytest.raises(InvalidOrgError):
76-
reserved_tag_key_service.list("")
76+
list(reserved_tag_key_service.list(""))
7777

7878
def test_create_reserved_tag_key_invalid_org(self, reserved_tag_key_service):
7979
"""Test creating reserved tag key with invalid organization."""
@@ -83,11 +83,6 @@ def test_create_reserved_tag_key_invalid_org(self, reserved_tag_key_service):
8383
with pytest.raises(InvalidOrgError):
8484
reserved_tag_key_service.create("", options)
8585

86-
def test_read_reserved_tag_key_not_implemented(self, reserved_tag_key_service):
87-
"""Test reading reserved tag key raises NotImplementedError."""
88-
with pytest.raises(NotImplementedError):
89-
reserved_tag_key_service.read("rtk-123")
90-
9186
def test_update_reserved_tag_key_invalid_id(self, reserved_tag_key_service):
9287
"""Test updating reserved tag key with invalid ID."""
9388
options = ReservedTagKeyUpdateOptions(key="updated-key")
@@ -115,6 +110,5 @@ def test_reserved_tag_key_update_options_model(self):
115110

116111
def test_reserved_tag_key_list_options_model(self):
117112
"""Test ReservedTagKeyListOptions model validation."""
118-
options = ReservedTagKeyListOptions(page_number=2, page_size=50)
119-
assert options.page_number == 2
113+
options = ReservedTagKeyListOptions(page_size=50)
120114
assert options.page_size == 50

0 commit comments

Comments
 (0)