Skip to content
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ optional-dependencies.dev = [
"ty==0.0.17",
"types-requests==2.32.4.20260107",
"vulture==2.14",
"vws-python-mock==2026.2.21",
"vws-python-mock==2026.2.22.2",
"vws-test-fixtures==2023.3.5",
"yamlfix==1.19.1",
"zizmor==1.22.0",
Expand Down
4 changes: 1 addition & 3 deletions src/vws/_vws_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
API.
"""

from urllib.parse import urljoin

import requests
from beartype import BeartypeConf, beartype
from vws_auth_tools import authorization_header, rfc_1123_date
Expand Down Expand Up @@ -64,7 +62,7 @@ def target_api_request(
**extra_headers,
}

url = urljoin(base=base_vws_url, url=request_path)
url = base_vws_url.rstrip("/") + request_path

requests_response = requests.request(
method=method,
Expand Down
3 changes: 1 addition & 2 deletions src/vws/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import json
from http import HTTPMethod, HTTPStatus
from typing import Any, BinaryIO
from urllib.parse import urljoin

import requests
from beartype import BeartypeConf, beartype
Expand Down Expand Up @@ -146,7 +145,7 @@ def query(

requests_response = requests.request(
method=method,
url=urljoin(base=self._base_vwq_url, url=request_path),
url=self._base_vwq_url.rstrip("/") + request_path,
headers=headers,
data=content,
timeout=self._request_timeout_seconds,
Expand Down
33 changes: 33 additions & 0 deletions tests/test_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,39 @@ def test_custom_base_url(image: io.BytesIO | BinaryIO) -> None:
match = matches[0]
assert match.target_id == target_id

@staticmethod
def test_custom_base_url_with_path_prefix(
image: io.BytesIO | BinaryIO,
) -> None:
"""
A base VWQ URL with a path prefix is used as-is, without the
prefix being dropped.
"""
base_vwq_url = "http://example.com/prefix"
with MockVWS(base_vwq_url=base_vwq_url) as mock:
database = CloudDatabase()
mock.add_cloud_database(cloud_database=database)
vws_client = VWS(
server_access_key=database.server_access_key,
server_secret_key=database.server_secret_key,
)
target_id = vws_client.add_target(
name="x",
width=1,
image=image,
active_flag=True,
application_metadata=None,
)
vws_client.wait_for_target_processed(target_id=target_id)
cloud_reco_client = CloudRecoService(
client_access_key=database.client_access_key,
client_secret_key=database.client_secret_key,
base_vwq_url=base_vwq_url,
)

matches = cloud_reco_client.query(image=image)
assert len(matches) == 1


class TestMaxNumResults:
"""Tests for the ``max_num_results`` parameter of ``query``."""
Expand Down
18 changes: 18 additions & 0 deletions tests/test_vws.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,24 @@ def test_custom_base_url(image: io.BytesIO | BinaryIO) -> None:
application_metadata=None,
)

@staticmethod
def test_custom_base_url_with_path_prefix() -> None:
"""
A base VWS URL with a path prefix is used as-is, without the
prefix being dropped.
"""
base_vws_url = "http://example.com/prefix"
with MockVWS(base_vws_url=base_vws_url) as mock:
database = CloudDatabase()
mock.add_cloud_database(cloud_database=database)
vws_client = VWS(
server_access_key=database.server_access_key,
server_secret_key=database.server_secret_key,
base_vws_url=base_vws_url,
)

assert not vws_client.list_targets()


class TestListTargets:
"""Tests for listing targets."""
Expand Down