Skip to content

Commit 6116a10

Browse files
Centralize shared polling retry defaults
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent 5fba692 commit 6116a10

10 files changed

+87
-28
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ This runs lint, format checks, compile checks, tests, and package build.
115115
- `tests/test_plain_list_helper_usage.py` (shared plain-list normalization helper usage enforcement),
116116
- `tests/test_plain_type_guard_usage.py` (`str`/`int` guardrail enforcement via plain-type checks),
117117
- `tests/test_plain_type_identity_usage.py` (direct `type(... ) is str|int` guardrail enforcement via shared helpers),
118+
- `tests/test_polling_defaults_usage.py` (shared polling-default constant usage enforcement across polling helper modules),
118119
- `tests/test_polling_loop_usage.py` (`while True` polling-loop centralization in `hyperbrowser/client/polling.py`),
119120
- `tests/test_pyproject_architecture_marker.py` (pytest marker registration enforcement),
120121
- `tests/test_readme_examples_listing.py` (README example-listing consistency enforcement),

hyperbrowser/client/managers/job_fetch_utils.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
from typing import Any, Awaitable, Callable, Optional, TypeVar
22

3-
from hyperbrowser.models.consts import POLLING_ATTEMPTS
4-
53
from ..polling import (
64
build_fetch_operation_name,
75
collect_paginated_results,
86
collect_paginated_results_async,
97
retry_operation,
108
retry_operation_async,
119
)
10+
from .polling_defaults import (
11+
DEFAULT_POLLING_RETRY_ATTEMPTS,
12+
DEFAULT_POLLING_RETRY_DELAY_SECONDS,
13+
)
1214

1315
T = TypeVar("T")
1416
R = TypeVar("R")
@@ -22,8 +24,8 @@ def retry_operation_with_defaults(
2224
return retry_operation(
2325
operation_name=operation_name,
2426
operation=operation,
25-
max_attempts=POLLING_ATTEMPTS,
26-
retry_delay_seconds=0.5,
27+
max_attempts=DEFAULT_POLLING_RETRY_ATTEMPTS,
28+
retry_delay_seconds=DEFAULT_POLLING_RETRY_DELAY_SECONDS,
2729
)
2830

2931

@@ -35,8 +37,8 @@ async def retry_operation_with_defaults_async(
3537
return await retry_operation_async(
3638
operation_name=operation_name,
3739
operation=operation,
38-
max_attempts=POLLING_ATTEMPTS,
39-
retry_delay_seconds=0.5,
40+
max_attempts=DEFAULT_POLLING_RETRY_ATTEMPTS,
41+
retry_delay_seconds=DEFAULT_POLLING_RETRY_DELAY_SECONDS,
4042
)
4143

4244

@@ -86,8 +88,8 @@ def collect_paginated_results_with_defaults(
8688
get_total_page_batches=get_total_page_batches,
8789
on_page_success=on_page_success,
8890
max_wait_seconds=max_wait_seconds,
89-
max_attempts=POLLING_ATTEMPTS,
90-
retry_delay_seconds=0.5,
91+
max_attempts=DEFAULT_POLLING_RETRY_ATTEMPTS,
92+
retry_delay_seconds=DEFAULT_POLLING_RETRY_DELAY_SECONDS,
9193
)
9294

9395

@@ -107,6 +109,6 @@ async def collect_paginated_results_with_defaults_async(
107109
get_total_page_batches=get_total_page_batches,
108110
on_page_success=on_page_success,
109111
max_wait_seconds=max_wait_seconds,
110-
max_attempts=POLLING_ATTEMPTS,
111-
retry_delay_seconds=0.5,
112+
max_attempts=DEFAULT_POLLING_RETRY_ATTEMPTS,
113+
retry_delay_seconds=DEFAULT_POLLING_RETRY_DELAY_SECONDS,
112114
)

hyperbrowser/client/managers/job_wait_utils.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
from typing import Awaitable, Callable, Optional, TypeVar
22

3-
from hyperbrowser.models.consts import POLLING_ATTEMPTS
4-
53
from ..polling import wait_for_job_result, wait_for_job_result_async
4+
from .polling_defaults import (
5+
DEFAULT_POLLING_RETRY_ATTEMPTS,
6+
DEFAULT_POLLING_RETRY_DELAY_SECONDS,
7+
)
68

79
T = TypeVar("T")
810

@@ -25,8 +27,8 @@ def wait_for_job_result_with_defaults(
2527
poll_interval_seconds=poll_interval_seconds,
2628
max_wait_seconds=max_wait_seconds,
2729
max_status_failures=max_status_failures,
28-
fetch_max_attempts=POLLING_ATTEMPTS,
29-
fetch_retry_delay_seconds=0.5,
30+
fetch_max_attempts=DEFAULT_POLLING_RETRY_ATTEMPTS,
31+
fetch_retry_delay_seconds=DEFAULT_POLLING_RETRY_DELAY_SECONDS,
3032
)
3133

3234

@@ -48,6 +50,6 @@ async def wait_for_job_result_with_defaults_async(
4850
poll_interval_seconds=poll_interval_seconds,
4951
max_wait_seconds=max_wait_seconds,
5052
max_status_failures=max_status_failures,
51-
fetch_max_attempts=POLLING_ATTEMPTS,
52-
fetch_retry_delay_seconds=0.5,
53+
fetch_max_attempts=DEFAULT_POLLING_RETRY_ATTEMPTS,
54+
fetch_retry_delay_seconds=DEFAULT_POLLING_RETRY_DELAY_SECONDS,
5355
)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from hyperbrowser.models.consts import POLLING_ATTEMPTS
2+
3+
DEFAULT_POLLING_RETRY_ATTEMPTS = POLLING_ATTEMPTS
4+
DEFAULT_POLLING_RETRY_DELAY_SECONDS = 0.5

tests/test_architecture_marker_usage.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"tests/test_page_params_helper_usage.py",
2727
"tests/test_plain_type_guard_usage.py",
2828
"tests/test_plain_type_identity_usage.py",
29+
"tests/test_polling_defaults_usage.py",
2930
"tests/test_plain_list_helper_usage.py",
3031
"tests/test_optional_serialization_helper_usage.py",
3132
"tests/test_type_utils_usage.py",

tests/test_core_type_helper_usage.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"hyperbrowser/client/managers/job_start_payload_utils.py",
4040
"hyperbrowser/client/managers/page_params_utils.py",
4141
"hyperbrowser/client/managers/job_wait_utils.py",
42+
"hyperbrowser/client/managers/polling_defaults.py",
4243
"hyperbrowser/client/managers/session_upload_utils.py",
4344
"hyperbrowser/client/managers/session_profile_update_utils.py",
4445
"hyperbrowser/client/managers/web_pagination_utils.py",

tests/test_job_fetch_utils.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
from types import SimpleNamespace
33

44
import hyperbrowser.client.managers.job_fetch_utils as job_fetch_utils
5+
from hyperbrowser.client.managers.polling_defaults import (
6+
DEFAULT_POLLING_RETRY_ATTEMPTS,
7+
DEFAULT_POLLING_RETRY_DELAY_SECONDS,
8+
)
59

610

711
def test_retry_operation_with_defaults_forwards_arguments() -> None:
@@ -24,8 +28,8 @@ def _fake_retry_operation(**kwargs):
2428

2529
assert result == {"ok": True}
2630
assert captured_kwargs["operation_name"] == "fetch job"
27-
assert captured_kwargs["max_attempts"] == job_fetch_utils.POLLING_ATTEMPTS
28-
assert captured_kwargs["retry_delay_seconds"] == 0.5
31+
assert captured_kwargs["max_attempts"] == DEFAULT_POLLING_RETRY_ATTEMPTS
32+
assert captured_kwargs["retry_delay_seconds"] == DEFAULT_POLLING_RETRY_DELAY_SECONDS
2933

3034

3135
def test_retry_operation_with_defaults_async_forwards_arguments() -> None:
@@ -50,8 +54,8 @@ async def _fake_retry_operation_async(**kwargs):
5054

5155
assert result == {"ok": True}
5256
assert captured_kwargs["operation_name"] == "fetch job"
53-
assert captured_kwargs["max_attempts"] == job_fetch_utils.POLLING_ATTEMPTS
54-
assert captured_kwargs["retry_delay_seconds"] == 0.5
57+
assert captured_kwargs["max_attempts"] == DEFAULT_POLLING_RETRY_ATTEMPTS
58+
assert captured_kwargs["retry_delay_seconds"] == DEFAULT_POLLING_RETRY_DELAY_SECONDS
5559

5660

5761
def test_collect_paginated_results_with_defaults_forwards_arguments() -> None:
@@ -79,8 +83,8 @@ def _fake_collect_paginated_results(**kwargs):
7983
assert result is None
8084
assert captured_kwargs["operation_name"] == "batch job"
8185
assert captured_kwargs["max_wait_seconds"] == 25.0
82-
assert captured_kwargs["max_attempts"] == job_fetch_utils.POLLING_ATTEMPTS
83-
assert captured_kwargs["retry_delay_seconds"] == 0.5
86+
assert captured_kwargs["max_attempts"] == DEFAULT_POLLING_RETRY_ATTEMPTS
87+
assert captured_kwargs["retry_delay_seconds"] == DEFAULT_POLLING_RETRY_DELAY_SECONDS
8488

8589

8690
def test_collect_paginated_results_with_defaults_async_forwards_arguments() -> None:
@@ -110,8 +114,8 @@ async def _fake_collect_paginated_results_async(**kwargs):
110114
assert result is None
111115
assert captured_kwargs["operation_name"] == "batch job"
112116
assert captured_kwargs["max_wait_seconds"] == 25.0
113-
assert captured_kwargs["max_attempts"] == job_fetch_utils.POLLING_ATTEMPTS
114-
assert captured_kwargs["retry_delay_seconds"] == 0.5
117+
assert captured_kwargs["max_attempts"] == DEFAULT_POLLING_RETRY_ATTEMPTS
118+
assert captured_kwargs["retry_delay_seconds"] == DEFAULT_POLLING_RETRY_DELAY_SECONDS
115119

116120

117121
def test_fetch_job_result_with_defaults_uses_fetch_operation_name() -> None:

tests/test_job_wait_utils.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import asyncio
22

33
import hyperbrowser.client.managers.job_wait_utils as job_wait_utils
4+
from hyperbrowser.client.managers.polling_defaults import (
5+
DEFAULT_POLLING_RETRY_ATTEMPTS,
6+
DEFAULT_POLLING_RETRY_DELAY_SECONDS,
7+
)
48

59

610
def test_wait_for_job_result_with_defaults_forwards_arguments():
@@ -31,8 +35,11 @@ def _fake_wait_for_job_result(**kwargs):
3135
assert captured_kwargs["poll_interval_seconds"] == 1.5
3236
assert captured_kwargs["max_wait_seconds"] == 25.0
3337
assert captured_kwargs["max_status_failures"] == 4
34-
assert captured_kwargs["fetch_max_attempts"] == job_wait_utils.POLLING_ATTEMPTS
35-
assert captured_kwargs["fetch_retry_delay_seconds"] == 0.5
38+
assert captured_kwargs["fetch_max_attempts"] == DEFAULT_POLLING_RETRY_ATTEMPTS
39+
assert (
40+
captured_kwargs["fetch_retry_delay_seconds"]
41+
== DEFAULT_POLLING_RETRY_DELAY_SECONDS
42+
)
3643

3744

3845
def test_wait_for_job_result_with_defaults_async_forwards_arguments():
@@ -65,5 +72,8 @@ async def _fake_wait_for_job_result_async(**kwargs):
6572
assert captured_kwargs["poll_interval_seconds"] == 1.5
6673
assert captured_kwargs["max_wait_seconds"] == 25.0
6774
assert captured_kwargs["max_status_failures"] == 4
68-
assert captured_kwargs["fetch_max_attempts"] == job_wait_utils.POLLING_ATTEMPTS
69-
assert captured_kwargs["fetch_retry_delay_seconds"] == 0.5
75+
assert captured_kwargs["fetch_max_attempts"] == DEFAULT_POLLING_RETRY_ATTEMPTS
76+
assert (
77+
captured_kwargs["fetch_retry_delay_seconds"]
78+
== DEFAULT_POLLING_RETRY_DELAY_SECONDS
79+
)

tests/test_polling_defaults.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from hyperbrowser.client.managers.polling_defaults import (
2+
DEFAULT_POLLING_RETRY_ATTEMPTS,
3+
DEFAULT_POLLING_RETRY_DELAY_SECONDS,
4+
)
5+
from hyperbrowser.models.consts import POLLING_ATTEMPTS
6+
7+
8+
def test_polling_defaults_use_sdk_polling_attempts_constant():
9+
assert DEFAULT_POLLING_RETRY_ATTEMPTS == POLLING_ATTEMPTS
10+
11+
12+
def test_polling_defaults_retry_delay_constant_is_expected_value():
13+
assert DEFAULT_POLLING_RETRY_DELAY_SECONDS == 0.5
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from pathlib import Path
2+
3+
import pytest
4+
5+
pytestmark = pytest.mark.architecture
6+
7+
8+
MODULES = (
9+
"hyperbrowser/client/managers/job_fetch_utils.py",
10+
"hyperbrowser/client/managers/job_wait_utils.py",
11+
)
12+
13+
14+
def test_polling_default_helpers_use_shared_constants_module():
15+
for module_path in MODULES:
16+
module_text = Path(module_path).read_text(encoding="utf-8")
17+
assert "from .polling_defaults import (" in module_text
18+
assert "DEFAULT_POLLING_RETRY_ATTEMPTS" in module_text
19+
assert "DEFAULT_POLLING_RETRY_DELAY_SECONDS" in module_text
20+
assert "POLLING_ATTEMPTS" not in module_text
21+
assert "retry_delay_seconds=0.5" not in module_text

0 commit comments

Comments
 (0)