Skip to content

Commit d22b794

Browse files
Reuse shared raw data request helpers in extension list flow
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent f9678d6 commit d22b794

File tree

6 files changed

+129
-37
lines changed

6 files changed

+129
-37
lines changed

hyperbrowser/client/managers/extension_request_utils.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
from typing import Any, IO, List, Type, TypeVar
22

33
from .extension_utils import parse_extension_list_response_data
4-
from .model_request_utils import post_model_request, post_model_request_async
4+
from .model_request_utils import (
5+
get_model_response_data,
6+
get_model_response_data_async,
7+
post_model_request,
8+
post_model_request_async,
9+
)
510
from hyperbrowser.models.extension import ExtensionResponse
611

712
T = TypeVar("T")
@@ -31,10 +36,11 @@ def list_extension_resources(
3136
client: Any,
3237
route_path: str,
3338
) -> List[ExtensionResponse]:
34-
response = client.transport.get(
35-
client._build_url(route_path),
39+
response_data = get_model_response_data(
40+
client=client,
41+
route_path=route_path,
3642
)
37-
return parse_extension_list_response_data(response.data)
43+
return parse_extension_list_response_data(response_data)
3844

3945

4046
async def create_extension_resource_async(
@@ -61,7 +67,8 @@ async def list_extension_resources_async(
6167
client: Any,
6268
route_path: str,
6369
) -> List[ExtensionResponse]:
64-
response = await client.transport.get(
65-
client._build_url(route_path),
70+
response_data = await get_model_response_data_async(
71+
client=client,
72+
route_path=route_path,
6673
)
67-
return parse_extension_list_response_data(response.data)
74+
return parse_extension_list_response_data(response_data)

hyperbrowser/client/managers/model_request_utils.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,21 @@ def get_model_request(
5151
)
5252

5353

54+
def get_model_response_data(
55+
*,
56+
client: Any,
57+
route_path: str,
58+
params: Optional[Dict[str, Any]] = None,
59+
follow_redirects: bool = False,
60+
) -> Any:
61+
response = client.transport.get(
62+
client._build_url(route_path),
63+
params=params,
64+
follow_redirects=follow_redirects,
65+
)
66+
return response.data
67+
68+
5469
def delete_model_request(
5570
*,
5671
client: Any,
@@ -133,6 +148,21 @@ async def get_model_request_async(
133148
)
134149

135150

151+
async def get_model_response_data_async(
152+
*,
153+
client: Any,
154+
route_path: str,
155+
params: Optional[Dict[str, Any]] = None,
156+
follow_redirects: bool = False,
157+
) -> Any:
158+
response = await client.transport.get(
159+
client._build_url(route_path),
160+
params=params,
161+
follow_redirects=follow_redirects,
162+
)
163+
return response.data
164+
165+
136166
async def delete_model_request_async(
137167
*,
138168
client: Any,

tests/test_extension_request_internal_reuse.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ def test_extension_request_utils_reuse_model_request_helpers():
99
module_text = Path(
1010
"hyperbrowser/client/managers/extension_request_utils.py"
1111
).read_text(encoding="utf-8")
12-
assert "model_request_utils import post_model_request, post_model_request_async" in module_text
12+
assert "model_request_utils import (" in module_text
13+
assert "get_model_response_data" in module_text
14+
assert "get_model_response_data_async" in module_text
1315
assert "post_model_request(" in module_text
1416
assert "post_model_request_async(" in module_text
15-
assert "client.transport.post(" not in module_text
17+
assert "client.transport." not in module_text
1618
assert "parse_response_model(" not in module_text

tests/test_extension_request_utils.py

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import asyncio
22
from io import BytesIO
3-
from types import SimpleNamespace
43

54
import hyperbrowser.client.managers.extension_request_utils as extension_request_utils
65

@@ -37,36 +36,31 @@ def _fake_post_model_request(**kwargs):
3736
def test_list_extension_resources_uses_get_and_extension_parser():
3837
captured = {}
3938

40-
class _SyncTransport:
41-
def get(self, url):
42-
captured["url"] = url
43-
return SimpleNamespace(data={"extensions": []})
44-
45-
class _Client:
46-
transport = _SyncTransport()
47-
48-
@staticmethod
49-
def _build_url(path: str) -> str:
50-
return f"https://api.example.test{path}"
39+
def _fake_get_model_response_data(**kwargs):
40+
captured.update(kwargs)
41+
return {"extensions": []}
5142

5243
def _fake_parse_extension_list_response_data(data):
5344
captured["parse_data"] = data
5445
return ["parsed"]
5546

47+
original_get_data = extension_request_utils.get_model_response_data
5648
original_parse = extension_request_utils.parse_extension_list_response_data
49+
extension_request_utils.get_model_response_data = _fake_get_model_response_data
5750
extension_request_utils.parse_extension_list_response_data = (
5851
_fake_parse_extension_list_response_data
5952
)
6053
try:
6154
result = extension_request_utils.list_extension_resources(
62-
client=_Client(),
55+
client=object(),
6356
route_path="/extensions/list",
6457
)
6558
finally:
59+
extension_request_utils.get_model_response_data = original_get_data
6660
extension_request_utils.parse_extension_list_response_data = original_parse
6761

6862
assert result == ["parsed"]
69-
assert captured["url"] == "https://api.example.test/extensions/list"
63+
assert captured["route_path"] == "/extensions/list"
7064
assert captured["parse_data"] == {"extensions": []}
7165

7266

@@ -104,36 +98,33 @@ async def _fake_post_model_request_async(**kwargs):
10498
def test_list_extension_resources_async_uses_get_and_extension_parser():
10599
captured = {}
106100

107-
class _AsyncTransport:
108-
async def get(self, url):
109-
captured["url"] = url
110-
return SimpleNamespace(data={"extensions": []})
111-
112-
class _Client:
113-
transport = _AsyncTransport()
114-
115-
@staticmethod
116-
def _build_url(path: str) -> str:
117-
return f"https://api.example.test{path}"
101+
async def _fake_get_model_response_data_async(**kwargs):
102+
captured.update(kwargs)
103+
return {"extensions": []}
118104

119105
def _fake_parse_extension_list_response_data(data):
120106
captured["parse_data"] = data
121107
return ["parsed"]
122108

109+
original_get_data = extension_request_utils.get_model_response_data_async
123110
original_parse = extension_request_utils.parse_extension_list_response_data
111+
extension_request_utils.get_model_response_data_async = (
112+
_fake_get_model_response_data_async
113+
)
124114
extension_request_utils.parse_extension_list_response_data = (
125115
_fake_parse_extension_list_response_data
126116
)
127117
try:
128118
result = asyncio.run(
129119
extension_request_utils.list_extension_resources_async(
130-
client=_Client(),
120+
client=object(),
131121
route_path="/extensions/list",
132122
)
133123
)
134124
finally:
125+
extension_request_utils.get_model_response_data_async = original_get_data
135126
extension_request_utils.parse_extension_list_response_data = original_parse
136127

137128
assert result == ["parsed"]
138-
assert captured["url"] == "https://api.example.test/extensions/list"
129+
assert captured["route_path"] == "/extensions/list"
139130
assert captured["parse_data"] == {"extensions": []}

tests/test_model_request_internal_reuse.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"parse_response_model(",
2020
),
2121
"hyperbrowser/client/managers/extension_request_utils.py": (
22-
"client.transport.post(",
22+
"client.transport.",
2323
"parse_response_model(",
2424
),
2525
"hyperbrowser/client/managers/job_request_utils.py": (

tests/test_model_request_utils.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,36 @@ def _fake_parse_response_model(data, **kwargs):
128128
assert captured["parse_kwargs"]["operation_name"] == "read resource"
129129

130130

131+
def test_get_model_response_data_gets_payload_without_parsing():
132+
captured = {}
133+
134+
class _SyncTransport:
135+
def get(self, url, params=None, follow_redirects=False):
136+
captured["url"] = url
137+
captured["params"] = params
138+
captured["follow_redirects"] = follow_redirects
139+
return SimpleNamespace(data={"id": "resource-raw"})
140+
141+
class _Client:
142+
transport = _SyncTransport()
143+
144+
@staticmethod
145+
def _build_url(path: str) -> str:
146+
return f"https://api.example.test{path}"
147+
148+
result = model_request_utils.get_model_response_data(
149+
client=_Client(),
150+
route_path="/resource/raw",
151+
params={"page": 1},
152+
follow_redirects=True,
153+
)
154+
155+
assert result == {"id": "resource-raw"}
156+
assert captured["url"] == "https://api.example.test/resource/raw"
157+
assert captured["params"] == {"page": 1}
158+
assert captured["follow_redirects"] is True
159+
160+
131161
def test_delete_model_request_deletes_resource_and_parses_response():
132162
captured = {}
133163

@@ -296,6 +326,38 @@ def _fake_parse_response_model(data, **kwargs):
296326
assert captured["parse_kwargs"]["operation_name"] == "read resource"
297327

298328

329+
def test_get_model_response_data_async_gets_payload_without_parsing():
330+
captured = {}
331+
332+
class _AsyncTransport:
333+
async def get(self, url, params=None, follow_redirects=False):
334+
captured["url"] = url
335+
captured["params"] = params
336+
captured["follow_redirects"] = follow_redirects
337+
return SimpleNamespace(data={"id": "resource-raw-async"})
338+
339+
class _Client:
340+
transport = _AsyncTransport()
341+
342+
@staticmethod
343+
def _build_url(path: str) -> str:
344+
return f"https://api.example.test{path}"
345+
346+
result = asyncio.run(
347+
model_request_utils.get_model_response_data_async(
348+
client=_Client(),
349+
route_path="/resource/raw",
350+
params={"page": 2},
351+
follow_redirects=True,
352+
)
353+
)
354+
355+
assert result == {"id": "resource-raw-async"}
356+
assert captured["url"] == "https://api.example.test/resource/raw"
357+
assert captured["params"] == {"page": 2}
358+
assert captured["follow_redirects"] is True
359+
360+
299361
def test_delete_model_request_async_deletes_resource_and_parses_response():
300362
captured = {}
301363

0 commit comments

Comments
 (0)