Skip to content

Commit f7e2d19

Browse files
Merge pull request #1145 from adamtheturtle/query-result-obj
Query result obj
2 parents ce0be71 + 1d791a4 commit f7e2d19

File tree

4 files changed

+81
-26
lines changed

4 files changed

+81
-26
lines changed

src/vws/query.py

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,23 @@
22
Tools for interacting with the Vuforia Cloud Recognition Web APIs.
33
"""
44

5+
import datetime
56
import io
6-
from typing import Any, Dict, List
7+
from typing import List, Optional
78
from urllib.parse import urljoin
89

910
import requests
1011
from urllib3.filepost import encode_multipart_formdata
1112
from vws_auth_tools import authorization_header, rfc_1123_date
1213

13-
from ._result_codes import raise_for_result_code
14-
from .exceptions import (
14+
from vws._result_codes import raise_for_result_code
15+
from vws.exceptions import (
1516
ConnectionErrorPossiblyImageTooLarge,
1617
MatchProcessing,
1718
MaxNumResultsOutOfRange,
1819
)
19-
from .include_target_data import CloudRecoIncludeTargetData
20+
from vws.include_target_data import CloudRecoIncludeTargetData
21+
from vws.reports import QueryResult, TargetData
2022

2123

2224
class CloudRecoService:
@@ -46,7 +48,7 @@ def query(
4648
max_num_results: int = 1,
4749
include_target_data:
4850
CloudRecoIncludeTargetData = CloudRecoIncludeTargetData.TOP,
49-
) -> List[Dict[str, Any]]:
51+
) -> List[QueryResult]:
5052
"""
5153
Use the Vuforia Web Query API to make an Image Recognition Query.
5254
@@ -132,4 +134,28 @@ def query(
132134
response=response,
133135
expected_result_code='Success',
134136
)
135-
return list(response.json()['results'])
137+
138+
result = []
139+
result_list = list(response.json()['results'])
140+
for item in result_list:
141+
target_data: Optional[TargetData] = None
142+
if 'target_data' in item:
143+
target_data_dict = item['target_data']
144+
metadata = target_data_dict['application_metadata']
145+
timestamp_string = target_data_dict['target_timestamp']
146+
target_timestamp = datetime.datetime.utcfromtimestamp(
147+
timestamp_string,
148+
)
149+
target_data = TargetData(
150+
name=target_data_dict['name'],
151+
application_metadata=metadata,
152+
target_timestamp=target_timestamp,
153+
)
154+
155+
query_result = QueryResult(
156+
target_id=item['target_id'],
157+
target_data=target_data,
158+
)
159+
160+
result.append(query_result)
161+
return result

src/vws/reports.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import datetime
66
from dataclasses import dataclass
77
from enum import Enum
8+
from typing import Optional
89

910

1011
@dataclass
@@ -77,3 +78,27 @@ class TargetRecord:
7778
width: float
7879
tracking_rating: int
7980
reco_rating: str
81+
82+
83+
@dataclass
84+
class TargetData:
85+
"""
86+
The target data optionally included with a query match.
87+
"""
88+
89+
name: str
90+
application_metadata: Optional[str]
91+
target_timestamp: datetime.datetime
92+
93+
94+
@dataclass
95+
class QueryResult:
96+
"""
97+
One query match result.
98+
99+
See
100+
https://library.vuforia.com/articles/Solution/How-To-Perform-an-Image-Recognition-Query.
101+
"""
102+
103+
target_id: str
104+
target_data: Optional[TargetData]

tests/test_query.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def test_match(
5151
)
5252
vws_client.wait_for_target_processed(target_id=target_id)
5353
[matching_target] = cloud_reco_client.query(image=high_quality_image)
54-
assert matching_target['target_id'] == target_id
54+
assert matching_target.target_id == target_id
5555

5656
def test_too_large(
5757
self,
@@ -101,8 +101,10 @@ def test_custom_base_url(self, high_quality_image: io.BytesIO) -> None:
101101
base_vwq_url=base_vwq_url,
102102
)
103103

104-
[match] = cloud_reco_client.query(image=high_quality_image)
105-
assert match['target_id'] == target_id
104+
matches = cloud_reco_client.query(image=high_quality_image)
105+
assert len(matches) == 1
106+
match = matches[0]
107+
assert match.target_id == target_id
106108

107109

108110
class TestMaxNumResults:
@@ -233,8 +235,8 @@ def test_default(
233235
image=high_quality_image,
234236
max_num_results=2,
235237
)
236-
assert 'target_data' in top_match
237-
assert 'target_data' not in second_match
238+
assert top_match.target_data is not None
239+
assert second_match.target_data is None
238240

239241
def test_top(
240242
self,
@@ -267,8 +269,8 @@ def test_top(
267269
max_num_results=2,
268270
include_target_data=CloudRecoIncludeTargetData.TOP,
269271
)
270-
assert 'target_data' in top_match
271-
assert 'target_data' not in second_match
272+
assert top_match.target_data is not None
273+
assert second_match.target_data is None
272274

273275
def test_none(
274276
self,
@@ -301,8 +303,8 @@ def test_none(
301303
max_num_results=2,
302304
include_target_data=CloudRecoIncludeTargetData.NONE,
303305
)
304-
assert 'target_data' not in top_match
305-
assert 'target_data' not in second_match
306+
assert top_match.target_data is None
307+
assert second_match.target_data is None
306308

307309
def test_all(
308310
self,
@@ -335,5 +337,5 @@ def test_all(
335337
max_num_results=2,
336338
include_target_data=CloudRecoIncludeTargetData.ALL,
337339
)
338-
assert 'target_data' in top_match
339-
assert 'target_data' in second_match
340+
assert top_match.target_data is not None
341+
assert second_match.target_data is not None

tests/test_vws.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ def test_add_target(
6565
matching_targets = cloud_reco_client.query(image=high_quality_image)
6666
if active_flag:
6767
[matching_target] = matching_targets
68-
assert matching_target['target_id'] == target_id
69-
query_target_data = matching_target['target_data']
70-
query_metadata = query_target_data['application_metadata']
68+
assert matching_target.target_id == target_id
69+
assert matching_target.target_data is not None
70+
query_metadata = matching_target.target_data.application_metadata
7171
assert query_metadata == encoded_metadata
7272
else:
7373
assert matching_targets == []
@@ -500,9 +500,10 @@ def test_update_target(
500500
)
501501
vws_client.wait_for_target_processed(target_id=target_id)
502502
[matching_target] = cloud_reco_client.query(image=high_quality_image)
503-
assert matching_target['target_id'] == target_id
504-
query_target_data = matching_target['target_data']
505-
query_metadata = query_target_data['application_metadata']
503+
assert matching_target.target_id == target_id
504+
query_target_data = matching_target.target_data
505+
assert query_target_data is not None
506+
query_metadata = query_target_data.application_metadata
506507
assert query_metadata is None
507508

508509
new_name = uuid.uuid4().hex
@@ -521,9 +522,10 @@ def test_update_target(
521522
[
522523
matching_target,
523524
] = cloud_reco_client.query(image=different_high_quality_image)
524-
assert matching_target['target_id'] == target_id
525-
query_target_data = matching_target['target_data']
526-
query_metadata = query_target_data['application_metadata']
525+
assert matching_target.target_id == target_id
526+
query_target_data = matching_target.target_data
527+
assert query_target_data is not None
528+
query_metadata = query_target_data.application_metadata
527529
assert query_metadata == new_application_metadata
528530

529531
vws_client.update_target(

0 commit comments

Comments
 (0)