autoassembler 0.3.1__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.
Files changed (198) hide show
  1. autoassembler/.fernignore +7 -0
  2. autoassembler/__init__.py +537 -0
  3. autoassembler/_custom/__init__.py +56 -0
  4. autoassembler/_custom/assemblies.py +226 -0
  5. autoassembler/_custom/assemblies_api.py +188 -0
  6. autoassembler/_custom/credentials.py +248 -0
  7. autoassembler/_custom/http.py +42 -0
  8. autoassembler/_custom/operations.py +258 -0
  9. autoassembler/_custom/planning.py +598 -0
  10. autoassembler/_custom/planning_api.py +225 -0
  11. autoassembler/_default_clients.py +32 -0
  12. autoassembler/_version.py +8 -0
  13. autoassembler/alpha/__init__.py +63 -0
  14. autoassembler/alpha/client.py +82 -0
  15. autoassembler/alpha/jobs/__init__.py +39 -0
  16. autoassembler/alpha/jobs/client.py +338 -0
  17. autoassembler/alpha/jobs/raw_client.py +641 -0
  18. autoassembler/alpha/jobs/types/__init__.py +42 -0
  19. autoassembler/alpha/jobs/types/cancel_job_jobs_response.py +12 -0
  20. autoassembler/alpha/jobs/types/list_jobs_jobs_response.py +30 -0
  21. autoassembler/alpha/jobs/types/list_jobs_jobs_response_pagination.py +22 -0
  22. autoassembler/alpha/jobs/types/retry_job_jobs_response.py +16 -0
  23. autoassembler/alpha/planning/__init__.py +49 -0
  24. autoassembler/alpha/planning/client.py +201 -0
  25. autoassembler/alpha/planning/raw_client.py +268 -0
  26. autoassembler/alpha/planning/types/__init__.py +47 -0
  27. autoassembler/alpha/planning/types/apply_ops_planning_request_namespace.py +5 -0
  28. autoassembler/alpha/planning/types/apply_ops_planning_request_ops_item.py +13 -0
  29. autoassembler/alpha/planning/types/apply_ops_planning_request_ops_item_op.py +58 -0
  30. autoassembler/alpha/planning/types/apply_ops_planning_response.py +13 -0
  31. autoassembler/alpha/raw_client.py +13 -0
  32. autoassembler/assemblies/__init__.py +73 -0
  33. autoassembler/assemblies/client.py +1177 -0
  34. autoassembler/assemblies/raw_client.py +1557 -0
  35. autoassembler/assemblies/types/__init__.py +71 -0
  36. autoassembler/assemblies/types/delete_assembly_response.py +12 -0
  37. autoassembler/assemblies/types/download_assembly_cad_request_namespace.py +5 -0
  38. autoassembler/assemblies/types/get_assembly_info_request_namespace.py +5 -0
  39. autoassembler/assemblies/types/get_status_request_namespace.py +5 -0
  40. autoassembler/assemblies/types/get_status_response.py +16 -0
  41. autoassembler/assemblies/types/get_status_response_progress.py +13 -0
  42. autoassembler/assemblies/types/get_status_response_status.py +7 -0
  43. autoassembler/assemblies/types/get_structure_request_namespace.py +5 -0
  44. autoassembler/assemblies/types/list_assembly_versions_request_namespace.py +5 -0
  45. autoassembler/assemblies/types/list_connections_request_namespace.py +5 -0
  46. autoassembler/assemblies/types/process_request_namespace.py +5 -0
  47. autoassembler/assemblies/types/update_assembly_info_request_namespace.py +5 -0
  48. autoassembler/auth/__init__.py +34 -0
  49. autoassembler/auth/client.py +282 -0
  50. autoassembler/auth/raw_client.py +413 -0
  51. autoassembler/auth/types/__init__.py +36 -0
  52. autoassembler/auth/types/create_access_token_request_grant_type.py +7 -0
  53. autoassembler/base_client.py +328 -0
  54. autoassembler/client.py +262 -0
  55. autoassembler/core/__init__.py +127 -0
  56. autoassembler/core/api_error.py +23 -0
  57. autoassembler/core/client_wrapper.py +147 -0
  58. autoassembler/core/datetime_utils.py +70 -0
  59. autoassembler/core/file.py +67 -0
  60. autoassembler/core/force_multipart.py +18 -0
  61. autoassembler/core/http_client.py +965 -0
  62. autoassembler/core/http_response.py +63 -0
  63. autoassembler/core/http_sse/__init__.py +42 -0
  64. autoassembler/core/http_sse/_api.py +455 -0
  65. autoassembler/core/http_sse/_decoders.py +74 -0
  66. autoassembler/core/http_sse/_exceptions.py +7 -0
  67. autoassembler/core/http_sse/_models.py +17 -0
  68. autoassembler/core/jsonable_encoder.py +133 -0
  69. autoassembler/core/logging.py +107 -0
  70. autoassembler/core/parse_error.py +36 -0
  71. autoassembler/core/pydantic_utilities.py +486 -0
  72. autoassembler/core/query_encoder.py +58 -0
  73. autoassembler/core/remove_none_from_dict.py +11 -0
  74. autoassembler/core/request_options.py +40 -0
  75. autoassembler/core/serialization.py +347 -0
  76. autoassembler/environment.py +7 -0
  77. autoassembler/errors/__init__.py +56 -0
  78. autoassembler/errors/bad_request_error.py +10 -0
  79. autoassembler/errors/conflict_error.py +10 -0
  80. autoassembler/errors/forbidden_error.py +11 -0
  81. autoassembler/errors/internal_server_error.py +11 -0
  82. autoassembler/errors/not_found_error.py +11 -0
  83. autoassembler/errors/unauthorized_error.py +10 -0
  84. autoassembler/errors/unprocessable_entity_error.py +11 -0
  85. autoassembler/operation.py +196 -0
  86. autoassembler/operations/__init__.py +4 -0
  87. autoassembler/operations/client.py +209 -0
  88. autoassembler/operations/raw_client.py +343 -0
  89. autoassembler/planning/__init__.py +70 -0
  90. autoassembler/planning/client.py +1174 -0
  91. autoassembler/planning/raw_client.py +1349 -0
  92. autoassembler/planning/types/__init__.py +68 -0
  93. autoassembler/planning/types/adapt_request_namespace.py +5 -0
  94. autoassembler/planning/types/create_mpp_request_body.py +8 -0
  95. autoassembler/planning/types/create_mpp_request_namespace.py +5 -0
  96. autoassembler/planning/types/delete_mpp_request_namespace.py +5 -0
  97. autoassembler/planning/types/delete_mpp_response.py +12 -0
  98. autoassembler/planning/types/evaluate_dfa_request_namespace.py +5 -0
  99. autoassembler/planning/types/get_mpp_request_namespace.py +5 -0
  100. autoassembler/planning/types/get_mpp_response.py +27 -0
  101. autoassembler/planning/types/list_mpps_request_namespace.py +5 -0
  102. autoassembler/planning/types/plan_request_namespace.py +5 -0
  103. autoassembler/planning/types/validate_request_namespace.py +5 -0
  104. autoassembler/py.typed +0 -0
  105. autoassembler/sessions/__init__.py +4 -0
  106. autoassembler/sessions/client.py +102 -0
  107. autoassembler/sessions/raw_client.py +126 -0
  108. autoassembler/types/__init__.py +344 -0
  109. autoassembler/types/access_token_response.py +14 -0
  110. autoassembler/types/active_session.py +25 -0
  111. autoassembler/types/active_session_namespace.py +5 -0
  112. autoassembler/types/adapt_mpp_accepted.py +26 -0
  113. autoassembler/types/assembly.py +30 -0
  114. autoassembler/types/assembly_connection.py +21 -0
  115. autoassembler/types/assembly_connection_relationship.py +5 -0
  116. autoassembler/types/assembly_connections_response.py +13 -0
  117. autoassembler/types/assembly_diff_metadata.py +35 -0
  118. autoassembler/types/assembly_diff_response.py +34 -0
  119. autoassembler/types/assembly_info.py +36 -0
  120. autoassembler/types/assembly_json_response.py +15 -0
  121. autoassembler/types/assembly_process_metadata.py +32 -0
  122. autoassembler/types/assembly_process_response.py +18 -0
  123. autoassembler/types/assembly_search_hit.py +31 -0
  124. autoassembler/types/assembly_version_summary.py +27 -0
  125. autoassembler/types/conflict_error_body.py +19 -0
  126. autoassembler/types/conflict_error_body_error.py +5 -0
  127. autoassembler/types/create_mpp_request.py +13 -0
  128. autoassembler/types/device_authorization_response.py +17 -0
  129. autoassembler/types/diff_accepted.py +42 -0
  130. autoassembler/types/diff_context_node.py +20 -0
  131. autoassembler/types/diff_details.py +73 -0
  132. autoassembler/types/diff_error_response.py +38 -0
  133. autoassembler/types/diff_flags.py +74 -0
  134. autoassembler/types/diff_ml_semantics.py +55 -0
  135. autoassembler/types/diff_node.py +26 -0
  136. autoassembler/types/diff_node_pair_with_parts.py +90 -0
  137. autoassembler/types/diff_node_with_parent.py +15 -0
  138. autoassembler/types/diff_reference_target_nodes.py +25 -0
  139. autoassembler/types/diff_report.py +24 -0
  140. autoassembler/types/diff_rigid_alignment.py +30 -0
  141. autoassembler/types/diff_summary.py +121 -0
  142. autoassembler/types/diff_summary_assembly_labels.py +44 -0
  143. autoassembler/types/diff_summary_geometric_diffs.py +24 -0
  144. autoassembler/types/diff_summary_persistent_edges_congruence.py +24 -0
  145. autoassembler/types/diff_summary_persistent_edges_congruence_pose.py +24 -0
  146. autoassembler/types/diff_summary_persistent_nodes_congruence.py +24 -0
  147. autoassembler/types/diff_summary_persistent_nodes_congruence_pose.py +24 -0
  148. autoassembler/types/diff_summary_total_parts.py +24 -0
  149. autoassembler/types/diff_swap.py +65 -0
  150. autoassembler/types/diff_swap_confidence.py +5 -0
  151. autoassembler/types/diff_swap_group.py +92 -0
  152. autoassembler/types/diff_validation_issue.py +38 -0
  153. autoassembler/types/diff_validation_issue_severity.py +5 -0
  154. autoassembler/types/diff_validation_result.py +35 -0
  155. autoassembler/types/diff_warning.py +79 -0
  156. autoassembler/types/diff_warning_reason.py +18 -0
  157. autoassembler/types/diff_warning_severity.py +5 -0
  158. autoassembler/types/error_response.py +30 -0
  159. autoassembler/types/filter.py +19 -0
  160. autoassembler/types/filter_field.py +7 -0
  161. autoassembler/types/filter_operator.py +5 -0
  162. autoassembler/types/job.py +123 -0
  163. autoassembler/types/job_progress.py +24 -0
  164. autoassembler/types/job_status.py +5 -0
  165. autoassembler/types/list_operations_response.py +25 -0
  166. autoassembler/types/manufacturing_process_plan.py +57 -0
  167. autoassembler/types/mpp_adapt_metadata.py +48 -0
  168. autoassembler/types/mpp_adapt_response.py +22 -0
  169. autoassembler/types/mpp_evaluate_dfa_metadata.py +47 -0
  170. autoassembler/types/mpp_evaluate_dfa_response.py +22 -0
  171. autoassembler/types/mpp_plan_metadata.py +47 -0
  172. autoassembler/types/mpp_plan_response.py +22 -0
  173. autoassembler/types/mpp_summary.py +20 -0
  174. autoassembler/types/mpp_validate_metadata.py +47 -0
  175. autoassembler/types/mpp_validate_response.py +22 -0
  176. autoassembler/types/o_auth_error_response.py +14 -0
  177. autoassembler/types/o_auth_error_response_error.py +18 -0
  178. autoassembler/types/operation.py +27 -0
  179. autoassembler/types/operation_error.py +21 -0
  180. autoassembler/types/operation_metadata.py +148 -0
  181. autoassembler/types/operation_response.py +94 -0
  182. autoassembler/types/process_assembly_accepted.py +14 -0
  183. autoassembler/types/process_assembly_response.py +55 -0
  184. autoassembler/types/process_assembly_skipped.py +14 -0
  185. autoassembler/types/search_assemblies_response.py +14 -0
  186. autoassembler/types/seq_plan_accepted.py +24 -0
  187. autoassembler/types/sever.py +33 -0
  188. autoassembler/types/sever_kind.py +5 -0
  189. autoassembler/types/sever_source.py +5 -0
  190. autoassembler/types/sort.py +8 -0
  191. autoassembler/types/upload_response.py +19 -0
  192. autoassembler/types/user_info.py +19 -0
  193. autoassembler/types/user_info_response.py +23 -0
  194. autoassembler/types/user_info_response_providers.py +14 -0
  195. autoassembler-0.3.1.dist-info/METADATA +209 -0
  196. autoassembler-0.3.1.dist-info/RECORD +198 -0
  197. autoassembler-0.3.1.dist-info/WHEEL +4 -0
  198. autoassembler-0.3.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,42 @@
1
+ """Reading a response the way the generated clients do, for requests sent by hand.
2
+
3
+ Hand-written, protected via `.fernignore`.
4
+ """
5
+
6
+ import typing
7
+ from json.decoder import JSONDecodeError
8
+
9
+ import httpx
10
+ from pydantic import ValidationError
11
+
12
+ from ..core.api_error import ApiError
13
+ from ..core.parse_error import ParsingError
14
+ from ..core.pydantic_utilities import parse_obj_as
15
+ from ..errors.bad_request_error import BadRequestError
16
+ from ..errors.forbidden_error import ForbiddenError
17
+ from ..errors.not_found_error import NotFoundError
18
+
19
+
20
+ def parsed[T](response: httpx.Response, type_: type[T]) -> T:
21
+ """``response`` as a ``type_``, or the error the generated client raises for its status."""
22
+ try:
23
+ body = response.json()
24
+ except JSONDecodeError:
25
+ raise ApiError(
26
+ status_code=response.status_code, headers=dict(response.headers), body=response.text
27
+ ) from None
28
+ headers = dict(response.headers)
29
+ if 200 <= response.status_code < 300:
30
+ try:
31
+ return typing.cast(T, parse_obj_as(type_, body))
32
+ except ValidationError as error:
33
+ raise ParsingError(
34
+ status_code=response.status_code, headers=headers, body=body, cause=error
35
+ ) from error
36
+ if response.status_code == 400:
37
+ raise BadRequestError(headers=headers, body=body)
38
+ if response.status_code == 403:
39
+ raise ForbiddenError(headers=headers, body=body)
40
+ if response.status_code == 404:
41
+ raise NotFoundError(headers=headers, body=body)
42
+ raise ApiError(status_code=response.status_code, headers=headers, body=body)
@@ -0,0 +1,258 @@
1
+ """Custom Operations namespace — hand-written, protected via `.fernignore`.
2
+
3
+ `Operations` subclasses the generated `OperationsClient` and adds `handle`, which wraps an
4
+ operation in an `Operation` that refreshes itself through this client.
5
+
6
+ It also replaces `get_operation` and `list_operations`, the calls that can see operations
7
+ this SDK did not start: the generated unions of operation kinds are closed, so one kind
8
+ added to the server would make them fail. Here a kind this SDK version does not know comes
9
+ back as `UnknownOperationMetadata` / `UnknownOperationResponse` (its ``type`` and raw
10
+ fields); known kinds parse, and are validated, exactly as generated.
11
+ """
12
+
13
+ import typing
14
+
15
+ import pydantic
16
+
17
+ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
18
+ from ..core.jsonable_encoder import encode_path_param
19
+ from ..core.pydantic_utilities import UniversalBaseModel
20
+ from ..core.request_options import RequestOptions
21
+ from ..operation import AsyncOperation, Operation, operation_id
22
+ from ..operations.client import AsyncOperationsClient, OperationsClient
23
+ from ..types.list_operations_response import ListOperationsResponse
24
+ from ..types.operation import Operation as OperationResource
25
+ from ..types.operation_metadata import OperationMetadata
26
+ from ..types.operation_response import OperationResponse
27
+ from .http import parsed
28
+
29
+ _OPERATIONS_PATH = "api/v4/operations"
30
+ _UNKNOWN = "unknown"
31
+
32
+
33
+ class UnknownOperationMetadata(UniversalBaseModel):
34
+ """Metadata of an operation kind this SDK version does not know: from a newer server.
35
+
36
+ ``type`` is ``None`` when the server sent none (operations stored by early server builds).
37
+ """
38
+
39
+ type: str | None = None
40
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(
41
+ extra="allow", frozen=True
42
+ )
43
+
44
+
45
+ class UnknownOperationResponse(UniversalBaseModel):
46
+ """Response of an operation kind this SDK version does not know; ``type`` as in the metadata."""
47
+
48
+ type: str | None = None
49
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(
50
+ extra="allow", frozen=True
51
+ )
52
+
53
+
54
+ def _open(closed: typing.Any, unknown: type) -> typing.Any:
55
+ """``closed``, a generated union discriminated by ``type``, plus ``unknown`` for any other type.
56
+
57
+ Routing on ``type`` keeps a known kind strict: a broken body still fails to parse.
58
+ """
59
+ variants = typing.get_args(typing.get_args(closed)[0])
60
+ known = {typing.get_args(v.model_fields["type"].annotation)[0]: v for v in variants}
61
+
62
+ def tag(value: typing.Any) -> str:
63
+ kind = value.get("type") if isinstance(value, dict) else getattr(value, "type", None)
64
+ return kind if isinstance(kind, str) and kind in known else _UNKNOWN
65
+
66
+ return typing.Annotated[
67
+ typing.Union[ # noqa: UP007 (built from a runtime list)
68
+ tuple(
69
+ [
70
+ *(typing.Annotated[v, pydantic.Tag(t)] for t, v in known.items()),
71
+ typing.Annotated[unknown, pydantic.Tag(_UNKNOWN)],
72
+ ]
73
+ )
74
+ ],
75
+ pydantic.Discriminator(tag),
76
+ ]
77
+
78
+
79
+ class AnyOperation(OperationResource):
80
+ """A server operation of any kind, as `get_operation` and `list_operations` return it.
81
+
82
+ The generated model (`autoassembler.types.Operation`) accepts only the operation kinds in
83
+ this SDK's spec, so reading a kind the server added later fails the whole call. This
84
+ subclass widens its two kind-specific fields: a known ``type`` still parses, strictly, to
85
+ its generated class; any other ``type`` (or none) to `UnknownOperationMetadata` /
86
+ `UnknownOperationResponse`, which keep the raw fields. Everything else is the generated
87
+ model's, so an `AnyOperation` goes wherever one is expected.
88
+
89
+ Type checkers see the plain union; pydantic sees the union routed on ``type`` (`_open`).
90
+ """
91
+
92
+ if typing.TYPE_CHECKING:
93
+ metadata: OperationMetadata | UnknownOperationMetadata # pyright: ignore[reportIncompatibleVariableOverride]
94
+ response: OperationResponse | UnknownOperationResponse | None = None # pyright: ignore[reportIncompatibleVariableOverride]
95
+ else:
96
+ metadata: _open(OperationMetadata, UnknownOperationMetadata)
97
+ response: _open(OperationResponse, UnknownOperationResponse) | None = None
98
+
99
+
100
+ class OperationsPage(ListOperationsResponse):
101
+ """A page of `list_operations`, whose operations may be of kinds this SDK does not know."""
102
+
103
+ operations: list[AnyOperation] # pyright: ignore[reportIncompatibleVariableOverride]
104
+
105
+
106
+ def _list_params(page_size: int | None, page_token: str | None) -> dict[str, typing.Any]:
107
+ return {"pageSize": page_size, "pageToken": page_token}
108
+
109
+
110
+ def response_of[R](type_: type[R]) -> typing.Callable[[OperationResource], R]:
111
+ """A `resolve` returning the finished operation's response, which must be a ``type_``."""
112
+
113
+ def resolve(operation: OperationResource) -> R:
114
+ if not isinstance(operation.response, type_):
115
+ raise TypeError(f"{operation.name} responded with {type(operation.response).__name__}")
116
+ return operation.response
117
+
118
+ return resolve
119
+
120
+
121
+ def async_response_of[R](
122
+ type_: type[R],
123
+ ) -> typing.Callable[[OperationResource], typing.Awaitable[R]]:
124
+ """The async form of `response_of`."""
125
+ resolve = response_of(type_)
126
+
127
+ async def resolve_async(operation: OperationResource) -> R:
128
+ return resolve(operation)
129
+
130
+ return resolve_async
131
+
132
+
133
+ class Operations(OperationsClient):
134
+ """Generated operations client + `handle`, reading kinds this SDK does not know."""
135
+
136
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
137
+ super().__init__(client_wrapper=client_wrapper)
138
+ self._client_wrapper = client_wrapper
139
+
140
+ def get_operation( # pyright: ignore[reportIncompatibleMethodOverride]
141
+ self, id: str, *, request_options: RequestOptions | None = None
142
+ ) -> AnyOperation:
143
+ """The operation ``operations/{id}``, of any kind."""
144
+ response = self._client_wrapper.httpx_client.request(
145
+ f"{_OPERATIONS_PATH}/{encode_path_param(id)}",
146
+ method="GET",
147
+ request_options=request_options,
148
+ )
149
+ return parsed(response, AnyOperation)
150
+
151
+ def list_operations( # pyright: ignore[reportIncompatibleMethodOverride]
152
+ self,
153
+ *,
154
+ page_size: int | None = None,
155
+ page_token: str | None = None,
156
+ request_options: RequestOptions | None = None,
157
+ ) -> OperationsPage:
158
+ """The caller's operations, newest first, of any kind; see the generated call."""
159
+ response = self._client_wrapper.httpx_client.request(
160
+ _OPERATIONS_PATH,
161
+ method="GET",
162
+ params=_list_params(page_size, page_token),
163
+ request_options=request_options,
164
+ )
165
+ return parsed(response, OperationsPage)
166
+
167
+ @typing.overload
168
+ def handle(
169
+ self, operation: OperationResource | str
170
+ ) -> Operation[OperationResponse | UnknownOperationResponse]: ...
171
+ @typing.overload
172
+ def handle[T](
173
+ self,
174
+ operation: OperationResource | str,
175
+ *,
176
+ resolve: typing.Callable[[OperationResource], T],
177
+ ) -> Operation[T]: ...
178
+ def handle(
179
+ self,
180
+ operation: OperationResource | str,
181
+ *,
182
+ resolve: typing.Callable[[OperationResource], typing.Any] | None = None,
183
+ ) -> Operation[typing.Any]:
184
+ """An `Operation` for ``operation``: one an endpoint returned, or the name of one.
185
+
186
+ ``resolve`` maps the finished operation to the result; by default it is the response.
187
+ """
188
+ if isinstance(operation, str):
189
+ operation = self.get_operation(operation_id(operation))
190
+ name = operation.name
191
+ return Operation(
192
+ operation, refresh=lambda: self.get_operation(operation_id(name)), resolve=resolve
193
+ )
194
+
195
+
196
+ class AsyncOperations(AsyncOperationsClient):
197
+ """Async generated operations client + `handle` (mirror of `Operations`)."""
198
+
199
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
200
+ super().__init__(client_wrapper=client_wrapper)
201
+ self._client_wrapper = client_wrapper
202
+
203
+ async def get_operation( # pyright: ignore[reportIncompatibleMethodOverride]
204
+ self, id: str, *, request_options: RequestOptions | None = None
205
+ ) -> AnyOperation:
206
+ """The operation ``operations/{id}``, of any kind."""
207
+ response = await self._client_wrapper.httpx_client.request(
208
+ f"{_OPERATIONS_PATH}/{encode_path_param(id)}",
209
+ method="GET",
210
+ request_options=request_options,
211
+ )
212
+ return parsed(response, AnyOperation)
213
+
214
+ async def list_operations( # pyright: ignore[reportIncompatibleMethodOverride]
215
+ self,
216
+ *,
217
+ page_size: int | None = None,
218
+ page_token: str | None = None,
219
+ request_options: RequestOptions | None = None,
220
+ ) -> OperationsPage:
221
+ """The caller's operations, newest first, of any kind; see `Operations.list_operations`."""
222
+ response = await self._client_wrapper.httpx_client.request(
223
+ _OPERATIONS_PATH,
224
+ method="GET",
225
+ params=_list_params(page_size, page_token),
226
+ request_options=request_options,
227
+ )
228
+ return parsed(response, OperationsPage)
229
+
230
+ @typing.overload
231
+ async def handle(
232
+ self, operation: OperationResource | str
233
+ ) -> AsyncOperation[OperationResponse | UnknownOperationResponse]: ...
234
+ @typing.overload
235
+ async def handle[T](
236
+ self,
237
+ operation: OperationResource | str,
238
+ *,
239
+ resolve: typing.Callable[[OperationResource], typing.Awaitable[T]],
240
+ ) -> AsyncOperation[T]: ...
241
+ async def handle(
242
+ self,
243
+ operation: OperationResource | str,
244
+ *,
245
+ resolve: typing.Callable[[OperationResource], typing.Awaitable[typing.Any]] | None = None,
246
+ ) -> AsyncOperation[typing.Any]:
247
+ """An `AsyncOperation` for ``operation``; see `Operations.handle`.
248
+
249
+ A coroutine, since a name is first fetched.
250
+ """
251
+ if isinstance(operation, str):
252
+ operation = await self.get_operation(operation_id(operation))
253
+ name = operation.name
254
+
255
+ async def refresh() -> OperationResource:
256
+ return await self.get_operation(operation_id(name))
257
+
258
+ return AsyncOperation(operation, refresh=refresh, resolve=resolve)