Skip to content

Commit 3745eba

Browse files
Centralize profile manager request and metadata handling
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent 00988eb commit 3745eba

14 files changed

+672
-52
lines changed

CONTRIBUTING.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ This runs lint, format checks, compile checks, tests, and package build.
126126
- `tests/test_plain_type_identity_usage.py` (direct `type(... ) is str|int` guardrail enforcement via shared helpers),
127127
- `tests/test_polling_defaults_usage.py` (shared polling-default constant usage enforcement across polling helper modules),
128128
- `tests/test_polling_loop_usage.py` (`while True` polling-loop centralization in `hyperbrowser/client/polling.py`),
129+
- `tests/test_profile_operation_metadata_usage.py` (profile manager operation-metadata usage enforcement),
130+
- `tests/test_profile_request_helper_usage.py` (profile manager request-helper usage enforcement),
131+
- `tests/test_profile_route_constants_usage.py` (profile manager route-constant usage enforcement),
129132
- `tests/test_pyproject_architecture_marker.py` (pytest marker registration enforcement),
130133
- `tests/test_readme_examples_listing.py` (README example-listing consistency enforcement),
131134
- `tests/test_schema_injection_helper_usage.py` (shared schema injection helper usage enforcement in payload builders),

hyperbrowser/client/managers/async_manager/profile.py

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,25 @@
88
ProfileResponse,
99
)
1010
from hyperbrowser.models.session import BasicResponse
11+
from ..profile_operation_metadata import PROFILE_OPERATION_METADATA
12+
from ..profile_request_utils import (
13+
create_profile_resource_async,
14+
delete_profile_resource_async,
15+
get_profile_resource_async,
16+
list_profile_resources_async,
17+
)
18+
from ..profile_route_constants import PROFILE_ROUTE_PREFIX, PROFILES_ROUTE_PATH
1119
from ..serialization_utils import (
1220
serialize_model_dump_or_default,
1321
serialize_optional_model_dump_to_dict,
1422
)
15-
from ..response_utils import parse_response_model
1623

1724

1825
class ProfileManager:
26+
_OPERATION_METADATA = PROFILE_OPERATION_METADATA
27+
_ROUTE_PREFIX = PROFILE_ROUTE_PREFIX
28+
_LIST_ROUTE_PATH = PROFILES_ROUTE_PATH
29+
1930
def __init__(self, client):
2031
self._client = client
2132

@@ -26,34 +37,30 @@ async def create(
2637
params,
2738
error_message="Failed to serialize profile create params",
2839
)
29-
response = await self._client.transport.post(
30-
self._client._build_url("/profile"),
31-
data=payload,
32-
)
33-
return parse_response_model(
34-
response.data,
40+
return await create_profile_resource_async(
41+
client=self._client,
42+
route_prefix=self._ROUTE_PREFIX,
43+
payload=payload,
3544
model=CreateProfileResponse,
36-
operation_name="create profile",
45+
operation_name=self._OPERATION_METADATA.create_operation_name,
3746
)
3847

3948
async def get(self, id: str) -> ProfileResponse:
40-
response = await self._client.transport.get(
41-
self._client._build_url(f"/profile/{id}"),
42-
)
43-
return parse_response_model(
44-
response.data,
49+
return await get_profile_resource_async(
50+
client=self._client,
51+
route_prefix=self._ROUTE_PREFIX,
52+
profile_id=id,
4553
model=ProfileResponse,
46-
operation_name="get profile",
54+
operation_name=self._OPERATION_METADATA.get_operation_name,
4755
)
4856

4957
async def delete(self, id: str) -> BasicResponse:
50-
response = await self._client.transport.delete(
51-
self._client._build_url(f"/profile/{id}"),
52-
)
53-
return parse_response_model(
54-
response.data,
58+
return await delete_profile_resource_async(
59+
client=self._client,
60+
route_prefix=self._ROUTE_PREFIX,
61+
profile_id=id,
5562
model=BasicResponse,
56-
operation_name="delete profile",
63+
operation_name=self._OPERATION_METADATA.delete_operation_name,
5764
)
5865

5966
async def list(
@@ -64,12 +71,10 @@ async def list(
6471
default_factory=ProfileListParams,
6572
error_message="Failed to serialize profile list params",
6673
)
67-
response = await self._client.transport.get(
68-
self._client._build_url("/profiles"),
74+
return await list_profile_resources_async(
75+
client=self._client,
76+
list_route_path=self._LIST_ROUTE_PATH,
6977
params=query_params,
70-
)
71-
return parse_response_model(
72-
response.data,
7378
model=ProfileListResponse,
74-
operation_name="list profiles",
79+
operation_name=self._OPERATION_METADATA.list_operation_name,
7580
)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from dataclasses import dataclass
2+
3+
4+
@dataclass(frozen=True)
5+
class ProfileOperationMetadata:
6+
create_operation_name: str
7+
get_operation_name: str
8+
delete_operation_name: str
9+
list_operation_name: str
10+
11+
12+
PROFILE_OPERATION_METADATA = ProfileOperationMetadata(
13+
create_operation_name="create profile",
14+
get_operation_name="get profile",
15+
delete_operation_name="delete profile",
16+
list_operation_name="list profiles",
17+
)
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
from typing import Any, Dict, Optional, Type, TypeVar
2+
3+
from .response_utils import parse_response_model
4+
5+
T = TypeVar("T")
6+
7+
8+
def create_profile_resource(
9+
*,
10+
client: Any,
11+
route_prefix: str,
12+
payload: Dict[str, Any],
13+
model: Type[T],
14+
operation_name: str,
15+
) -> T:
16+
response = client.transport.post(
17+
client._build_url(route_prefix),
18+
data=payload,
19+
)
20+
return parse_response_model(
21+
response.data,
22+
model=model,
23+
operation_name=operation_name,
24+
)
25+
26+
27+
def get_profile_resource(
28+
*,
29+
client: Any,
30+
route_prefix: str,
31+
profile_id: str,
32+
model: Type[T],
33+
operation_name: str,
34+
) -> T:
35+
response = client.transport.get(
36+
client._build_url(f"{route_prefix}/{profile_id}"),
37+
)
38+
return parse_response_model(
39+
response.data,
40+
model=model,
41+
operation_name=operation_name,
42+
)
43+
44+
45+
def delete_profile_resource(
46+
*,
47+
client: Any,
48+
route_prefix: str,
49+
profile_id: str,
50+
model: Type[T],
51+
operation_name: str,
52+
) -> T:
53+
response = client.transport.delete(
54+
client._build_url(f"{route_prefix}/{profile_id}"),
55+
)
56+
return parse_response_model(
57+
response.data,
58+
model=model,
59+
operation_name=operation_name,
60+
)
61+
62+
63+
def list_profile_resources(
64+
*,
65+
client: Any,
66+
list_route_path: str,
67+
params: Optional[Dict[str, Any]],
68+
model: Type[T],
69+
operation_name: str,
70+
) -> T:
71+
response = client.transport.get(
72+
client._build_url(list_route_path),
73+
params=params,
74+
)
75+
return parse_response_model(
76+
response.data,
77+
model=model,
78+
operation_name=operation_name,
79+
)
80+
81+
82+
async def create_profile_resource_async(
83+
*,
84+
client: Any,
85+
route_prefix: str,
86+
payload: Dict[str, Any],
87+
model: Type[T],
88+
operation_name: str,
89+
) -> T:
90+
response = await client.transport.post(
91+
client._build_url(route_prefix),
92+
data=payload,
93+
)
94+
return parse_response_model(
95+
response.data,
96+
model=model,
97+
operation_name=operation_name,
98+
)
99+
100+
101+
async def get_profile_resource_async(
102+
*,
103+
client: Any,
104+
route_prefix: str,
105+
profile_id: str,
106+
model: Type[T],
107+
operation_name: str,
108+
) -> T:
109+
response = await client.transport.get(
110+
client._build_url(f"{route_prefix}/{profile_id}"),
111+
)
112+
return parse_response_model(
113+
response.data,
114+
model=model,
115+
operation_name=operation_name,
116+
)
117+
118+
119+
async def delete_profile_resource_async(
120+
*,
121+
client: Any,
122+
route_prefix: str,
123+
profile_id: str,
124+
model: Type[T],
125+
operation_name: str,
126+
) -> T:
127+
response = await client.transport.delete(
128+
client._build_url(f"{route_prefix}/{profile_id}"),
129+
)
130+
return parse_response_model(
131+
response.data,
132+
model=model,
133+
operation_name=operation_name,
134+
)
135+
136+
137+
async def list_profile_resources_async(
138+
*,
139+
client: Any,
140+
list_route_path: str,
141+
params: Optional[Dict[str, Any]],
142+
model: Type[T],
143+
operation_name: str,
144+
) -> T:
145+
response = await client.transport.get(
146+
client._build_url(list_route_path),
147+
params=params,
148+
)
149+
return parse_response_model(
150+
response.data,
151+
model=model,
152+
operation_name=operation_name,
153+
)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
PROFILE_ROUTE_PREFIX = "/profile"
2+
PROFILES_ROUTE_PATH = "/profiles"

hyperbrowser/client/managers/sync_manager/profile.py

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,25 @@
88
ProfileResponse,
99
)
1010
from hyperbrowser.models.session import BasicResponse
11+
from ..profile_operation_metadata import PROFILE_OPERATION_METADATA
12+
from ..profile_request_utils import (
13+
create_profile_resource,
14+
delete_profile_resource,
15+
get_profile_resource,
16+
list_profile_resources,
17+
)
18+
from ..profile_route_constants import PROFILE_ROUTE_PREFIX, PROFILES_ROUTE_PATH
1119
from ..serialization_utils import (
1220
serialize_model_dump_or_default,
1321
serialize_optional_model_dump_to_dict,
1422
)
15-
from ..response_utils import parse_response_model
1623

1724

1825
class ProfileManager:
26+
_OPERATION_METADATA = PROFILE_OPERATION_METADATA
27+
_ROUTE_PREFIX = PROFILE_ROUTE_PREFIX
28+
_LIST_ROUTE_PATH = PROFILES_ROUTE_PATH
29+
1930
def __init__(self, client):
2031
self._client = client
2132

@@ -26,34 +37,30 @@ def create(
2637
params,
2738
error_message="Failed to serialize profile create params",
2839
)
29-
response = self._client.transport.post(
30-
self._client._build_url("/profile"),
31-
data=payload,
32-
)
33-
return parse_response_model(
34-
response.data,
40+
return create_profile_resource(
41+
client=self._client,
42+
route_prefix=self._ROUTE_PREFIX,
43+
payload=payload,
3544
model=CreateProfileResponse,
36-
operation_name="create profile",
45+
operation_name=self._OPERATION_METADATA.create_operation_name,
3746
)
3847

3948
def get(self, id: str) -> ProfileResponse:
40-
response = self._client.transport.get(
41-
self._client._build_url(f"/profile/{id}"),
42-
)
43-
return parse_response_model(
44-
response.data,
49+
return get_profile_resource(
50+
client=self._client,
51+
route_prefix=self._ROUTE_PREFIX,
52+
profile_id=id,
4553
model=ProfileResponse,
46-
operation_name="get profile",
54+
operation_name=self._OPERATION_METADATA.get_operation_name,
4755
)
4856

4957
def delete(self, id: str) -> BasicResponse:
50-
response = self._client.transport.delete(
51-
self._client._build_url(f"/profile/{id}"),
52-
)
53-
return parse_response_model(
54-
response.data,
58+
return delete_profile_resource(
59+
client=self._client,
60+
route_prefix=self._ROUTE_PREFIX,
61+
profile_id=id,
5562
model=BasicResponse,
56-
operation_name="delete profile",
63+
operation_name=self._OPERATION_METADATA.delete_operation_name,
5764
)
5865

5966
def list(self, params: Optional[ProfileListParams] = None) -> ProfileListResponse:
@@ -62,12 +69,10 @@ def list(self, params: Optional[ProfileListParams] = None) -> ProfileListRespons
6269
default_factory=ProfileListParams,
6370
error_message="Failed to serialize profile list params",
6471
)
65-
response = self._client.transport.get(
66-
self._client._build_url("/profiles"),
72+
return list_profile_resources(
73+
client=self._client,
74+
list_route_path=self._LIST_ROUTE_PATH,
6775
params=query_params,
68-
)
69-
return parse_response_model(
70-
response.data,
7176
model=ProfileListResponse,
72-
operation_name="list profiles",
77+
operation_name=self._OPERATION_METADATA.list_operation_name,
7378
)

tests/test_architecture_marker_usage.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
"tests/test_polling_defaults_usage.py",
3535
"tests/test_plain_list_helper_usage.py",
3636
"tests/test_optional_serialization_helper_usage.py",
37+
"tests/test_profile_operation_metadata_usage.py",
38+
"tests/test_profile_request_helper_usage.py",
39+
"tests/test_profile_route_constants_usage.py",
3740
"tests/test_type_utils_usage.py",
3841
"tests/test_polling_loop_usage.py",
3942
"tests/test_core_type_helper_usage.py",

tests/test_core_type_helper_usage.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
"hyperbrowser/client/managers/page_params_utils.py",
5050
"hyperbrowser/client/managers/job_wait_utils.py",
5151
"hyperbrowser/client/managers/polling_defaults.py",
52+
"hyperbrowser/client/managers/profile_operation_metadata.py",
53+
"hyperbrowser/client/managers/profile_request_utils.py",
54+
"hyperbrowser/client/managers/profile_route_constants.py",
5255
"hyperbrowser/client/managers/session_upload_utils.py",
5356
"hyperbrowser/client/managers/session_profile_update_utils.py",
5457
"hyperbrowser/client/managers/web_operation_metadata.py",

0 commit comments

Comments
 (0)