Skip to content

Commit b397d12

Browse files
Deduplicate /api prefix when base URL already ends with api
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent c189220 commit b397d12

2 files changed

Lines changed: 39 additions & 0 deletions

File tree

hyperbrowser/client/base.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,16 @@ def _build_url(self, path: str) -> str:
7878
if parsed_path.scheme:
7979
raise HyperbrowserError("path must be a relative API path")
8080
normalized_path = f"/{stripped_path.lstrip('/')}"
81+
parsed_base_url = urlparse(self.config.base_url)
82+
base_path = parsed_base_url.path.rstrip("/")
83+
base_has_api_suffix = base_path.endswith("/api")
84+
8185
if normalized_path == "/api" or normalized_path.startswith("/api/"):
86+
if base_has_api_suffix:
87+
deduped_path = normalized_path[len("/api") :]
88+
return f"{self.config.base_url}{deduped_path}"
89+
return f"{self.config.base_url}{normalized_path}"
90+
91+
if base_has_api_suffix:
8292
return f"{self.config.base_url}{normalized_path}"
8393
return f"{self.config.base_url}/api{normalized_path}"

tests/test_url_building.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,35 @@ def test_client_build_url_uses_normalized_base_url():
4242
client.close()
4343

4444

45+
def test_client_build_url_avoids_duplicate_api_when_base_url_already_has_api():
46+
client = Hyperbrowser(
47+
config=ClientConfig(api_key="test-key", base_url="https://example.local/api")
48+
)
49+
try:
50+
assert client._build_url("/session") == "https://example.local/api/session"
51+
assert client._build_url("/api/session") == "https://example.local/api/session"
52+
finally:
53+
client.close()
54+
55+
56+
def test_client_build_url_handles_nested_api_base_paths():
57+
client = Hyperbrowser(
58+
config=ClientConfig(
59+
api_key="test-key", base_url="https://example.local/custom/api"
60+
)
61+
)
62+
try:
63+
assert (
64+
client._build_url("/session") == "https://example.local/custom/api/session"
65+
)
66+
assert (
67+
client._build_url("/api/session")
68+
== "https://example.local/custom/api/session"
69+
)
70+
finally:
71+
client.close()
72+
73+
4574
def test_client_build_url_rejects_empty_or_non_string_paths():
4675
client = Hyperbrowser(config=ClientConfig(api_key="test-key"))
4776
try:

0 commit comments

Comments
 (0)