Skip to content

Commit 0354770

Browse files
Merge pull request #1039 from adamtheturtle/query-2
Add support for `max_num_results`
2 parents d9a1cc7 + 3450e3a commit 0354770

File tree

3 files changed

+88
-1
lines changed

3 files changed

+88
-1
lines changed

src/vws/exceptions.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,28 @@
55
from requests import Response
66

77

8+
class MaxNumResultsOutOfRange(Exception):
9+
"""
10+
Exception raised when the ``max_num_results`` given to the Cloud
11+
Recognition Web API query endpoint is out of range.
12+
"""
13+
14+
def __init__(self, response: Response) -> None:
15+
"""
16+
Args:
17+
response: The response to a request to Vuforia.
18+
"""
19+
super().__init__(response.text)
20+
self._response = response
21+
22+
@property
23+
def response(self) -> Response:
24+
"""
25+
The response returned by Vuforia which included this error.
26+
"""
27+
return self._response
28+
29+
830
class UnknownTarget(Exception):
931
"""
1032
Exception raised when Vuforia returns a response with a result code

src/vws/query.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
from ._authorization import authorization_header, rfc_1123_date
1313
from ._result_codes import raise_for_result_code
14+
from .exceptions import MaxNumResultsOutOfRange
1415

1516

1617
class CloudRecoService:
@@ -34,7 +35,11 @@ def __init__(
3435
self._client_secret_key = client_secret_key.encode()
3536
self._base_vwq_url = base_vwq_url
3637

37-
def query(self, image: io.BytesIO) -> List[Dict[str, Any]]:
38+
def query(
39+
self,
40+
image: io.BytesIO,
41+
max_num_results: int = 1,
42+
) -> List[Dict[str, Any]]:
3843
"""
3944
Use the Vuforia Web Query API to make an Image Recognition Query.
4045
@@ -51,6 +56,7 @@ def query(self, image: io.BytesIO) -> List[Dict[str, Any]]:
5156
image_content = image.getvalue()
5257
body = {
5358
'image': ('image.jpeg', image_content, 'image/jpeg'),
59+
'max_num_results': (None, int(max_num_results), 'text/plain'),
5460
}
5561
date = rfc_1123_date()
5662
request_path = '/v1/query'
@@ -81,6 +87,9 @@ def query(self, image: io.BytesIO) -> List[Dict[str, Any]]:
8187
data=content,
8288
)
8389

90+
if 'Integer out of range' in response.text:
91+
raise MaxNumResultsOutOfRange(response=response)
92+
8493
raise_for_result_code(
8594
response=response,
8695
expected_result_code='Success',

tests/test_query.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
import io
66
import uuid
77

8+
import pytest
89
from mock_vws import MockVWS
910
from mock_vws.database import VuforiaDatabase
1011

1112
from vws import VWS, CloudRecoService
13+
from vws.exceptions import MaxNumResultsOutOfRange
1214

1315

1416
class TestQuery:
@@ -111,3 +113,57 @@ def test_default(
111113
vws_client.wait_for_target_processed(target_id=target_id_2)
112114
matches = cloud_reco_client.query(image=high_quality_image)
113115
assert len(matches) == 1
116+
117+
def test_custom(
118+
self,
119+
vws_client: VWS,
120+
cloud_reco_client: CloudRecoService,
121+
high_quality_image: io.BytesIO,
122+
) -> None:
123+
"""
124+
It is possible to set a custom ``max_num_results``.
125+
"""
126+
target_id = vws_client.add_target(
127+
name=uuid.uuid4().hex,
128+
width=1,
129+
image=high_quality_image,
130+
)
131+
target_id_2 = vws_client.add_target(
132+
name=uuid.uuid4().hex,
133+
width=1,
134+
image=high_quality_image,
135+
)
136+
target_id_3 = vws_client.add_target(
137+
name=uuid.uuid4().hex,
138+
width=1,
139+
image=high_quality_image,
140+
)
141+
vws_client.wait_for_target_processed(target_id=target_id)
142+
vws_client.wait_for_target_processed(target_id=target_id_2)
143+
vws_client.wait_for_target_processed(target_id=target_id_3)
144+
matches = cloud_reco_client.query(
145+
image=high_quality_image,
146+
max_num_results=2,
147+
)
148+
assert len(matches) == 2
149+
150+
def test_too_many(
151+
self,
152+
cloud_reco_client: CloudRecoService,
153+
high_quality_image: io.BytesIO,
154+
) -> None:
155+
"""
156+
A ``MaxNumResultsOutOfRange`` error is raised if the given
157+
``max_num_results`` is out of range.
158+
"""
159+
with pytest.raises(MaxNumResultsOutOfRange) as exc:
160+
cloud_reco_client.query(
161+
image=high_quality_image,
162+
max_num_results=51,
163+
)
164+
165+
expected_value = (
166+
"Integer out of range (51) in form data part 'max_result'. "
167+
'Accepted range is from 1 to 50 (inclusive).'
168+
)
169+
assert str(exc.value) == exc.value.response.text == expected_value

0 commit comments

Comments
 (0)