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.
@@ -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
+ )