From b2289716cc455e5b25345418be826b0306111e11 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Thu, 10 Sep 2026 23:32:45 +0100 Subject: [PATCH 1/2] Type JSON response bodies without Any --- src/mock_vws/_mock_common.py | 4 ++-- src/mock_vws/_query_tools.py | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/mock_vws/_mock_common.py b/src/mock_vws/_mock_common.py index c331cdf9a..c91e44570 100644 --- a/src/mock_vws/_mock_common.py +++ b/src/mock_vws/_mock_common.py @@ -7,7 +7,7 @@ from collections.abc import Callable, Iterable, Mapping from dataclasses import dataclass from functools import partial -from typing import Any, Final, override +from typing import Final, override from beartype import beartype @@ -174,7 +174,7 @@ def http_date() -> str: @beartype -def json_dump(*, body: dict[str, Any]) -> str: # pyrefly: ignore [explicit-any] +def json_dump(*, body: Mapping[str, object]) -> str: """ Returns: JSON dump of data in the same way that Vuforia dumps data. diff --git a/src/mock_vws/_query_tools.py b/src/mock_vws/_query_tools.py index aa1176651..23260e091 100644 --- a/src/mock_vws/_query_tools.py +++ b/src/mock_vws/_query_tools.py @@ -2,7 +2,6 @@ import base64 import uuid -from typing import Any from beartype import beartype @@ -12,6 +11,7 @@ from mock_vws._mock_common import json_dump from mock_vws._query_validators import ValidatedQuery from mock_vws.image_matchers import ImageMatcher +from mock_vws.model_target import JSONValue @beartype @@ -61,7 +61,7 @@ def get_query_match_response_text( if match.tracking_rating > minimum_rating ] - results: list[dict[str, Any]] = [] # pyrefly: ignore [explicit-any] + results: list[dict[str, JSONValue]] = [] for target in matches: target_timestamp = target.last_modified_date.timestamp() if target.application_metadata is None: @@ -70,12 +70,13 @@ def get_query_match_response_text( application_metadata = base64.b64encode( s=decode_base64(encoded_data=target.application_metadata), ).decode(encoding="ascii") - target_data = { + target_data: dict[str, JSONValue] = { "target_timestamp": int(target_timestamp), "name": target.name, "application_metadata": application_metadata, } + result: dict[str, JSONValue] if include_target_data == "all" or ( include_target_data == "top" and not bool(results) ): From 9e443032c95dec94e447fcc3ac8b1e6c9aca6815 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Fri, 11 Sep 2026 00:00:59 +0100 Subject: [PATCH 2/2] Type JSON response bodies recursively --- src/mock_vws/_flask_server/vws.py | 25 +++++++++++-------- src/mock_vws/_mock_common.py | 3 ++- src/mock_vws/_query_tools.py | 17 +++++-------- .../mock_web_services_api.py | 19 +++++++------- 4 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/mock_vws/_flask_server/vws.py b/src/mock_vws/_flask_server/vws.py index 7d001df7b..8db7d6ead 100644 --- a/src/mock_vws/_flask_server/vws.py +++ b/src/mock_vws/_flask_server/vws.py @@ -32,7 +32,11 @@ ) from mock_vws._database_matchers import get_database_matching_server_keys from mock_vws._matching import matching_targets -from mock_vws._mock_common import RequestData, json_dump, sorted_targets +from mock_vws._mock_common import ( + RequestData, + json_dump, + sorted_targets, +) from mock_vws._model_target_web_api import ( create_model_target_dataset, delete_model_target_dataset, @@ -77,6 +81,7 @@ StructuralSimilarityMatcher, ) from mock_vws.model_target import ( + JSONValue, ModelTargetDataset, ModelTargetDatasetType, OAuth2ClientCredential, @@ -855,7 +860,7 @@ def get_target(target_id: str) -> Response: width = target.width tracking_rating = target.tracking_rating reco_rating = target.reco_rating - target_record = { + target_record: dict[str, JSONValue] = { "target_id": target.target_id, "active_flag": target.active_flag, "name": target.name, @@ -875,7 +880,7 @@ def get_target(target_id: str) -> Response: "x-aws-region": "us-east-2, us-west-2", "x-content-type-options": "nosniff", } - body = { + body: dict[str, JSONValue] = { "result_code": ResultCodes.SUCCESS.value, "transaction_id": uuid.uuid4().hex, "target_record": target_record, @@ -922,7 +927,7 @@ def delete_target(target_id: str) -> Response: timeout=30, ) - body = { + body: dict[str, JSONValue] = { "transaction_id": uuid.uuid4().hex, "result_code": ResultCodes.SUCCESS.value, } @@ -1030,7 +1035,7 @@ def database_summary() -> Response: databases=databases, ) - body = { + body: dict[str, JSONValue] = { "result_code": ResultCodes.SUCCESS.value, "transaction_id": uuid.uuid4().hex, "name": database.database_name, @@ -1093,7 +1098,7 @@ def target_summary(target_id: str) -> Response: total_recos = target.total_recos current_month_recos = target.current_month_recos previous_month_recos = target.previous_month_recos - body = { + body: dict[str, JSONValue] = { "status": target.status, "transaction_id": uuid.uuid4().hex, "result_code": ResultCodes.SUCCESS.value, @@ -1157,7 +1162,7 @@ def get_duplicates(target_id: str) -> Response: and other.active_flag } - similar_targets = [ + similar_targets: list[JSONValue] = [ other.target_id for other in matching_targets( matcher=image_match_checker, @@ -1166,7 +1171,7 @@ def get_duplicates(target_id: str) -> Response: ) ] - body = { + body: dict[str, JSONValue] = { "transaction_id": uuid.uuid4().hex, "result_code": ResultCodes.SUCCESS.value, "similar_targets": similar_targets, @@ -1206,12 +1211,12 @@ def target_list() -> Response: request_path=request.path, databases=databases, ) - results = [ + results: list[JSONValue] = [ target.target_id for target in sorted_targets(targets=database.not_deleted_targets) ] - body = { + body: dict[str, JSONValue] = { "transaction_id": uuid.uuid4().hex, "result_code": ResultCodes.SUCCESS.value, "results": results, diff --git a/src/mock_vws/_mock_common.py b/src/mock_vws/_mock_common.py index c91e44570..fcf497b35 100644 --- a/src/mock_vws/_mock_common.py +++ b/src/mock_vws/_mock_common.py @@ -12,6 +12,7 @@ from beartype import beartype from mock_vws._constants import ResultCodes +from mock_vws.model_target import JSONValue from mock_vws.target import ImageTarget # A database ID as it appears in the path of a reco counts report request. @@ -174,7 +175,7 @@ def http_date() -> str: @beartype -def json_dump(*, body: Mapping[str, object]) -> str: +def json_dump(*, body: Mapping[str, JSONValue]) -> str: """ Returns: JSON dump of data in the same way that Vuforia dumps data. diff --git a/src/mock_vws/_query_tools.py b/src/mock_vws/_query_tools.py index 23260e091..3a08d34ad 100644 --- a/src/mock_vws/_query_tools.py +++ b/src/mock_vws/_query_tools.py @@ -61,7 +61,7 @@ def get_query_match_response_text( if match.tracking_rating > minimum_rating ] - results: list[dict[str, JSONValue]] = [] + results: list[JSONValue] = [] for target in matches: target_timestamp = target.last_modified_date.timestamp() if target.application_metadata is None: @@ -76,23 +76,18 @@ def get_query_match_response_text( "application_metadata": application_metadata, } - result: dict[str, JSONValue] + result: dict[str, JSONValue] = { + "target_id": target.target_id, + } if include_target_data == "all" or ( include_target_data == "top" and not bool(results) ): - result = { - "target_id": target.target_id, - "target_data": target_data, - } - else: - result = { - "target_id": target.target_id, - } + result["target_data"] = target_data results.append(result) results = results[: int(max_num_results)] - body = { + body: dict[str, JSONValue] = { "result_code": ResultCodes.SUCCESS.value, "results": results, "query_id": uuid.uuid4().hex, diff --git a/src/mock_vws/_requests_mock_server/mock_web_services_api.py b/src/mock_vws/_requests_mock_server/mock_web_services_api.py index 03369b5f1..51fb12811 100644 --- a/src/mock_vws/_requests_mock_server/mock_web_services_api.py +++ b/src/mock_vws/_requests_mock_server/mock_web_services_api.py @@ -61,6 +61,7 @@ from mock_vws.database import VuMarkDatabase from mock_vws.image_matchers import ImageMatcher from mock_vws.model_target import ( + JSONValue, ModelTargetDatasetType, ModelTargetFailureResponse, ModelTargetGenerationFailure, @@ -598,7 +599,7 @@ def add_target(self, request: RequestData) -> _ResponseType: usegmt=True, ) status_code = HTTPStatus.CREATED - body = { + body: dict[str, JSONValue] = { "transaction_id": uuid.uuid4().hex, "result_code": ResultCodes.TARGET_CREATED.value, "target_id": new_target.target_id, @@ -784,7 +785,7 @@ def database_summary(self, request: RequestData) -> _ResponseType: localtime=False, usegmt=True, ) - body = { + body: dict[str, JSONValue] = { "result_code": ResultCodes.SUCCESS.value, "transaction_id": uuid.uuid4().hex, "name": database.database_name, @@ -839,11 +840,11 @@ def target_list(self, request: RequestData) -> _ResponseType: usegmt=True, ) - response_results = [ + response_results: list[JSONValue] = [ target.target_id for target in sorted_targets(targets=database.not_deleted_targets) ] - body = { + body: dict[str, JSONValue] = { "transaction_id": uuid.uuid4().hex, "result_code": ResultCodes.SUCCESS.value, "results": response_results, @@ -889,7 +890,7 @@ def get_target(self, request: RequestData) -> _ResponseType: width = target.width tracking_rating = target.tracking_rating reco_rating = target.reco_rating - target_record = { + target_record: dict[str, JSONValue] = { "target_id": target.target_id, "active_flag": target.active_flag, "name": target.name, @@ -903,7 +904,7 @@ def get_target(self, request: RequestData) -> _ResponseType: usegmt=True, ) - body = { + body: dict[str, JSONValue] = { "result_code": ResultCodes.SUCCESS.value, "transaction_id": uuid.uuid4().hex, "target_record": target_record, @@ -956,7 +957,7 @@ def get_duplicates(self, request: RequestData) -> _ResponseType: and other.active_flag } - similar_targets = [ + similar_targets: list[JSONValue] = [ other.target_id for other in matching_targets( matcher=self._duplicate_match_checker, @@ -970,7 +971,7 @@ def get_duplicates(self, request: RequestData) -> _ResponseType: localtime=False, usegmt=True, ) - body = { + body: dict[str, JSONValue] = { "transaction_id": uuid.uuid4().hex, "result_code": ResultCodes.SUCCESS.value, "similar_targets": similar_targets, @@ -1132,7 +1133,7 @@ def target_summary(self, request: RequestData) -> _ResponseType: total_recos = target.total_recos current_month_recos = target.current_month_recos previous_month_recos = target.previous_month_recos - body = { + body: dict[str, JSONValue] = { "status": target.status, "transaction_id": uuid.uuid4().hex, "result_code": ResultCodes.SUCCESS.value,