vws-python 2026.8.14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vws/__init__.py +21 -0
- vws/_async_vws_request.py +77 -0
- vws/_image_utils.py +18 -0
- vws/_model_targets.py +323 -0
- vws/_reco_counts.py +80 -0
- vws/_vws_request.py +76 -0
- vws/async_model_target_service.py +381 -0
- vws/async_query.py +224 -0
- vws/async_vumark_service.py +155 -0
- vws/async_vws.py +752 -0
- vws/exceptions/__init__.py +1 -0
- vws/exceptions/base_exceptions.py +74 -0
- vws/exceptions/cloud_reco_exceptions.py +44 -0
- vws/exceptions/custom_exceptions.py +107 -0
- vws/exceptions/model_target_exceptions.py +210 -0
- vws/exceptions/vws_exceptions.py +256 -0
- vws/include_target_data.py +18 -0
- vws/model_target_datasets.py +152 -0
- vws/model_target_service.py +366 -0
- vws/py.typed +0 -0
- vws/query.py +194 -0
- vws/reports.py +391 -0
- vws/response.py +19 -0
- vws/transports.py +315 -0
- vws/vumark_accept.py +18 -0
- vws/vumark_service.py +138 -0
- vws/vws.py +719 -0
- vws_python-2026.8.14.dist-info/METADATA +152 -0
- vws_python-2026.8.14.dist-info/RECORD +32 -0
- vws_python-2026.8.14.dist-info/WHEEL +5 -0
- vws_python-2026.8.14.dist-info/licenses/LICENSE +21 -0
- vws_python-2026.8.14.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""Async interface to the Vuforia VuMark Generation Web API."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from http import HTTPMethod, HTTPStatus
|
|
5
|
+
from typing import Self
|
|
6
|
+
|
|
7
|
+
from beartype import BeartypeConf, beartype
|
|
8
|
+
|
|
9
|
+
from vws._async_vws_request import async_target_api_request
|
|
10
|
+
from vws.exceptions.base_exceptions import VWSError
|
|
11
|
+
from vws.exceptions.custom_exceptions import ServerError
|
|
12
|
+
from vws.exceptions.vws_exceptions import TooManyRequestsError
|
|
13
|
+
from vws.transports import AsyncHTTPXTransport, AsyncTransport
|
|
14
|
+
from vws.vumark_accept import VuMarkAccept # noqa: TC001
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@beartype(conf=BeartypeConf(is_pep484_tower=True))
|
|
18
|
+
class AsyncVuMarkService:
|
|
19
|
+
"""An async interface to the Vuforia VuMark Generation Web
|
|
20
|
+
API.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
*,
|
|
26
|
+
server_access_key: str,
|
|
27
|
+
server_secret_key: str,
|
|
28
|
+
base_vws_url: str = "https://vws.vuforia.com",
|
|
29
|
+
request_timeout_seconds: float | tuple[float, float] = 30.0,
|
|
30
|
+
transport: AsyncTransport | None = None,
|
|
31
|
+
) -> None:
|
|
32
|
+
"""
|
|
33
|
+
Args:
|
|
34
|
+
server_access_key: A VWS server access key.
|
|
35
|
+
server_secret_key: A VWS server secret key.
|
|
36
|
+
base_vws_url: The base URL for the VWS API.
|
|
37
|
+
request_timeout_seconds: The timeout for each
|
|
38
|
+
HTTP request. This can be a float to set both
|
|
39
|
+
the connect and read timeouts, or a
|
|
40
|
+
(connect, read) tuple.
|
|
41
|
+
transport: The async HTTP transport to use for
|
|
42
|
+
requests. Defaults to
|
|
43
|
+
``AsyncHTTPXTransport()``.
|
|
44
|
+
"""
|
|
45
|
+
self._server_access_key = server_access_key
|
|
46
|
+
self._server_secret_key = server_secret_key
|
|
47
|
+
self._base_vws_url = base_vws_url
|
|
48
|
+
self._request_timeout_seconds = request_timeout_seconds
|
|
49
|
+
self._transport = (
|
|
50
|
+
transport if transport is not None else AsyncHTTPXTransport()
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
async def aclose(self) -> None:
|
|
54
|
+
"""Close the underlying transport if it supports closing."""
|
|
55
|
+
await self._transport.aclose()
|
|
56
|
+
|
|
57
|
+
async def __aenter__(self) -> Self:
|
|
58
|
+
"""Enter the async context manager."""
|
|
59
|
+
return self
|
|
60
|
+
|
|
61
|
+
async def __aexit__(self, *_args: object) -> None:
|
|
62
|
+
"""Exit the async context manager and close the transport."""
|
|
63
|
+
await self.aclose()
|
|
64
|
+
|
|
65
|
+
async def generate_vumark_instance(
|
|
66
|
+
self,
|
|
67
|
+
*,
|
|
68
|
+
target_id: str,
|
|
69
|
+
instance_id: str,
|
|
70
|
+
accept: VuMarkAccept,
|
|
71
|
+
) -> bytes:
|
|
72
|
+
"""Generate a VuMark instance image.
|
|
73
|
+
|
|
74
|
+
See
|
|
75
|
+
https://developer.vuforia.com/library/vuforia-engine/web-api/vumark-generation-web-api/
|
|
76
|
+
for parameter details.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
target_id: The ID of the VuMark target.
|
|
80
|
+
instance_id: The instance ID to encode in the
|
|
81
|
+
VuMark.
|
|
82
|
+
accept: The image format to return.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
The VuMark instance image bytes.
|
|
86
|
+
|
|
87
|
+
Raises:
|
|
88
|
+
~vws.exceptions.vws_exceptions.AuthenticationFailureError: The
|
|
89
|
+
secret key is not correct.
|
|
90
|
+
~vws.exceptions.vws_exceptions.AuthorizationFailedError: There was
|
|
91
|
+
a general authentication problem.
|
|
92
|
+
~vws.exceptions.vws_exceptions.FailError: There was an error with
|
|
93
|
+
the request. For example, the given access key does not match a
|
|
94
|
+
known database.
|
|
95
|
+
~vws.exceptions.vws_exceptions.InvalidAcceptHeaderError: The
|
|
96
|
+
Accept header value is not supported.
|
|
97
|
+
~vws.exceptions.vws_exceptions.InvalidInstanceIdError: The
|
|
98
|
+
instance ID is invalid. For example, it may be empty.
|
|
99
|
+
~vws.exceptions.vws_exceptions.InvalidTargetTypeError: The target
|
|
100
|
+
is not a VuMark template target.
|
|
101
|
+
~vws.exceptions.vws_exceptions.LicenseCheckFailedError: The
|
|
102
|
+
license state and/or type does not allow this request.
|
|
103
|
+
~vws.exceptions.vws_exceptions.QuotaExceededError: No more
|
|
104
|
+
instances can be created for the associated license.
|
|
105
|
+
~vws.exceptions.vws_exceptions.RequestTimeTooSkewedError: There is
|
|
106
|
+
an error with the time sent to Vuforia.
|
|
107
|
+
~vws.exceptions.vws_exceptions.TargetStatusNotSuccessError: The
|
|
108
|
+
target is not in the success state.
|
|
109
|
+
~vws.exceptions.vws_exceptions.UnknownTargetError: The given target
|
|
110
|
+
ID does not match a target in the database.
|
|
111
|
+
~vws.exceptions.custom_exceptions.ServerError: There is an error
|
|
112
|
+
with Vuforia's servers.
|
|
113
|
+
~vws.exceptions.vws_exceptions.TooManyRequestsError: Vuforia is
|
|
114
|
+
rate limiting access.
|
|
115
|
+
"""
|
|
116
|
+
request_path = f"/targets/{target_id}/instances"
|
|
117
|
+
content_type = "application/json"
|
|
118
|
+
request_data = json.dumps(
|
|
119
|
+
obj={"instance_id": instance_id},
|
|
120
|
+
).encode(encoding="utf-8")
|
|
121
|
+
|
|
122
|
+
response = await async_target_api_request(
|
|
123
|
+
content_type=content_type,
|
|
124
|
+
server_access_key=self._server_access_key,
|
|
125
|
+
server_secret_key=self._server_secret_key,
|
|
126
|
+
method=HTTPMethod.POST,
|
|
127
|
+
data=request_data,
|
|
128
|
+
request_path=request_path,
|
|
129
|
+
base_vws_url=self._base_vws_url,
|
|
130
|
+
request_timeout_seconds=(self._request_timeout_seconds),
|
|
131
|
+
extra_headers={"Accept": accept},
|
|
132
|
+
transport=self._transport,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
if (
|
|
136
|
+
response.status_code == HTTPStatus.TOO_MANY_REQUESTS
|
|
137
|
+
): # pragma: no cover
|
|
138
|
+
# The Vuforia API returns a 429 response with no
|
|
139
|
+
# JSON body.
|
|
140
|
+
raise TooManyRequestsError(response=response)
|
|
141
|
+
|
|
142
|
+
if (
|
|
143
|
+
response.status_code >= HTTPStatus.INTERNAL_SERVER_ERROR
|
|
144
|
+
): # pragma: no cover
|
|
145
|
+
raise ServerError(response=response)
|
|
146
|
+
|
|
147
|
+
if response.status_code == HTTPStatus.OK:
|
|
148
|
+
return response.content
|
|
149
|
+
|
|
150
|
+
result_code = json.loads(s=response.text)["result_code"]
|
|
151
|
+
|
|
152
|
+
raise VWSError.from_result_code(
|
|
153
|
+
result_code=result_code,
|
|
154
|
+
response=response,
|
|
155
|
+
)
|