capo-lambda-web 0.2.0__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.
- capo_lambda_web/__init__.py +71 -0
- capo_lambda_web/_async.py +25 -0
- capo_lambda_web/_auth/_identity.py +16 -0
- capo_lambda_web/_auth/_providers.py +886 -0
- capo_lambda_web/_auth/_signers.py +121 -0
- capo_lambda_web/_auth/_sigv4.py +579 -0
- capo_lambda_web/_auth/_zapros_handler.py +80 -0
- capo_lambda_web/_body.py +221 -0
- capo_lambda_web/_iter.py +113 -0
- capo_lambda_web/_operations/lambda_web/create_web_function.py +184 -0
- capo_lambda_web/_operations/lambda_web/create_web_function_endpoint.py +194 -0
- capo_lambda_web/_operations/lambda_web/create_web_function_revision.py +188 -0
- capo_lambda_web/_operations/lambda_web/delete_resource_policy.py +147 -0
- capo_lambda_web/_operations/lambda_web/delete_web_function.py +145 -0
- capo_lambda_web/_operations/lambda_web/delete_web_function_endpoint.py +149 -0
- capo_lambda_web/_operations/lambda_web/delete_web_function_revision.py +149 -0
- capo_lambda_web/_operations/lambda_web/get_resource_policy.py +165 -0
- capo_lambda_web/_operations/lambda_web/get_web_account_settings.py +155 -0
- capo_lambda_web/_operations/lambda_web/get_web_function.py +171 -0
- capo_lambda_web/_operations/lambda_web/get_web_function_endpoint.py +180 -0
- capo_lambda_web/_operations/lambda_web/get_web_function_revision.py +174 -0
- capo_lambda_web/_operations/lambda_web/list_tags.py +164 -0
- capo_lambda_web/_operations/lambda_web/list_web_function_endpoints.py +176 -0
- capo_lambda_web/_operations/lambda_web/list_web_function_revisions.py +176 -0
- capo_lambda_web/_operations/lambda_web/list_web_functions.py +168 -0
- capo_lambda_web/_operations/lambda_web/put_resource_policy.py +179 -0
- capo_lambda_web/_operations/lambda_web/tag_resource.py +155 -0
- capo_lambda_web/_operations/lambda_web/untag_resource.py +148 -0
- capo_lambda_web/_operations/lambda_web/update_web_function_endpoint.py +196 -0
- capo_lambda_web/_pagination.py +21 -0
- capo_lambda_web/_protocol/__init__.py +1 -0
- capo_lambda_web/_protocol/errors.py +93 -0
- capo_lambda_web/_protocol/eventstream.py +240 -0
- capo_lambda_web/_protocol/serialize.py +47 -0
- capo_lambda_web/_protocol/xml.py +33 -0
- capo_lambda_web/_resources/lambda_web/web_function.py +477 -0
- capo_lambda_web/_rule_engine/__init__.py +0 -0
- capo_lambda_web/_rule_engine/_aws_partition.py +160 -0
- capo_lambda_web/_rule_engine/_endpoint_rule_set.py +135 -0
- capo_lambda_web/_rule_engine/_endpoint_runtime.py +389 -0
- capo_lambda_web/_services/_aws_config.py +160 -0
- capo_lambda_web/_services/_pipeline.py +264 -0
- capo_lambda_web/_services/async_lambda_web.py +1394 -0
- capo_lambda_web/_services/lambda_web.py +1374 -0
- capo_lambda_web/errors/__init__.py +36 -0
- capo_lambda_web/errors/_base.py +94 -0
- capo_lambda_web/errors/access_denied_exception.py +48 -0
- capo_lambda_web/errors/conflict_exception.py +58 -0
- capo_lambda_web/errors/internal_server_exception.py +47 -0
- capo_lambda_web/errors/resource_not_found_exception.py +60 -0
- capo_lambda_web/errors/service_quota_exceeded_exception.py +74 -0
- capo_lambda_web/errors/throttling_exception.py +60 -0
- capo_lambda_web/errors/validation_exception.py +46 -0
- capo_lambda_web/py.typed +0 -0
- capo_lambda_web/types/_prelude/blob.py +12 -0
- capo_lambda_web/types/_prelude/timestamp.py +17 -0
- capo_lambda_web/types/account_quotas.py +47 -0
- capo_lambda_web/types/account_usage.py +26 -0
- capo_lambda_web/types/application_log_level.py +22 -0
- capo_lambda_web/types/auth_type.py +18 -0
- capo_lambda_web/types/auto_deployment_mode.py +18 -0
- capo_lambda_web/types/build_config.py +55 -0
- capo_lambda_web/types/code_config.py +37 -0
- capo_lambda_web/types/create_web_function_endpoint_request.py +164 -0
- capo_lambda_web/types/create_web_function_endpoint_response.py +291 -0
- capo_lambda_web/types/create_web_function_request.py +72 -0
- capo_lambda_web/types/create_web_function_response.py +144 -0
- capo_lambda_web/types/create_web_function_revision_request.py +76 -0
- capo_lambda_web/types/create_web_function_revision_response.py +157 -0
- capo_lambda_web/types/date_time.py +20 -0
- capo_lambda_web/types/delete_resource_policy_request.py +29 -0
- capo_lambda_web/types/delete_web_function_endpoint_request.py +27 -0
- capo_lambda_web/types/delete_web_function_request.py +24 -0
- capo_lambda_web/types/delete_web_function_revision_request.py +27 -0
- capo_lambda_web/types/description.py +5 -0
- capo_lambda_web/types/domain_name.py +5 -0
- capo_lambda_web/types/endpoint_arn.py +5 -0
- capo_lambda_web/types/endpoint_config.py +134 -0
- capo_lambda_web/types/endpoint_name.py +5 -0
- capo_lambda_web/types/endpoint_state.py +20 -0
- capo_lambda_web/types/endpoint_type.py +19 -0
- capo_lambda_web/types/endpoint_update_status.py +19 -0
- capo_lambda_web/types/environment_variables.py +22 -0
- capo_lambda_web/types/filter.py +46 -0
- capo_lambda_web/types/filter_list.py +29 -0
- capo_lambda_web/types/filter_value_list.py +14 -0
- capo_lambda_web/types/function_arn.py +5 -0
- capo_lambda_web/types/function_endpoint_summary.py +249 -0
- capo_lambda_web/types/function_endpoint_summary_list.py +33 -0
- capo_lambda_web/types/function_name.py +5 -0
- capo_lambda_web/types/function_revision_summary.py +83 -0
- capo_lambda_web/types/function_revision_summary_list.py +33 -0
- capo_lambda_web/types/function_state.py +20 -0
- capo_lambda_web/types/function_summary.py +91 -0
- capo_lambda_web/types/function_summary_list.py +31 -0
- capo_lambda_web/types/get_resource_policy_request.py +24 -0
- capo_lambda_web/types/get_resource_policy_response.py +39 -0
- capo_lambda_web/types/get_web_account_settings_request.py +18 -0
- capo_lambda_web/types/get_web_account_settings_response.py +59 -0
- capo_lambda_web/types/get_web_function_endpoint_request.py +27 -0
- capo_lambda_web/types/get_web_function_endpoint_response.py +285 -0
- capo_lambda_web/types/get_web_function_request.py +24 -0
- capo_lambda_web/types/get_web_function_response.py +91 -0
- capo_lambda_web/types/get_web_function_revision_request.py +27 -0
- capo_lambda_web/types/get_web_function_revision_response.py +155 -0
- capo_lambda_web/types/kms_key_arn.py +5 -0
- capo_lambda_web/types/list_tags_request.py +24 -0
- capo_lambda_web/types/list_tags_response.py +32 -0
- capo_lambda_web/types/list_web_function_endpoints_request.py +54 -0
- capo_lambda_web/types/list_web_function_endpoints_response.py +52 -0
- capo_lambda_web/types/list_web_function_revisions_request.py +54 -0
- capo_lambda_web/types/list_web_function_revisions_response.py +52 -0
- capo_lambda_web/types/list_web_functions_request.py +51 -0
- capo_lambda_web/types/list_web_functions_response.py +46 -0
- capo_lambda_web/types/logging_config.py +67 -0
- capo_lambda_web/types/max_results.py +5 -0
- capo_lambda_web/types/next_token.py +5 -0
- capo_lambda_web/types/policy_revision_id.py +5 -0
- capo_lambda_web/types/put_resource_policy_request.py +43 -0
- capo_lambda_web/types/put_resource_policy_response.py +39 -0
- capo_lambda_web/types/region.py +5 -0
- capo_lambda_web/types/region_list.py +17 -0
- capo_lambda_web/types/regional_endpoint.py +140 -0
- capo_lambda_web/types/regional_endpoints.py +33 -0
- capo_lambda_web/types/resource_arn.py +5 -0
- capo_lambda_web/types/resource_policy.py +5 -0
- capo_lambda_web/types/revision_arn.py +5 -0
- capo_lambda_web/types/revision_config.py +69 -0
- capo_lambda_web/types/revision_error.py +40 -0
- capo_lambda_web/types/revision_errors.py +29 -0
- capo_lambda_web/types/revision_id.py +5 -0
- capo_lambda_web/types/revision_state.py +19 -0
- capo_lambda_web/types/revision_weight.py +38 -0
- capo_lambda_web/types/revision_weight_list.py +31 -0
- capo_lambda_web/types/role_arn.py +5 -0
- capo_lambda_web/types/runtime_config.py +26 -0
- capo_lambda_web/types/s3_object.py +39 -0
- capo_lambda_web/types/scaling_config.py +23 -0
- capo_lambda_web/types/service_config.py +87 -0
- capo_lambda_web/types/system_log_level.py +19 -0
- capo_lambda_web/types/tag_key.py +5 -0
- capo_lambda_web/types/tag_key_list.py +17 -0
- capo_lambda_web/types/tag_resource_request.py +38 -0
- capo_lambda_web/types/tags.py +25 -0
- capo_lambda_web/types/telemetry_config.py +36 -0
- capo_lambda_web/types/throttle_config.py +23 -0
- capo_lambda_web/types/untag_resource_request.py +27 -0
- capo_lambda_web/types/update_web_function_endpoint_request.py +121 -0
- capo_lambda_web/types/update_web_function_endpoint_response.py +291 -0
- capo_lambda_web-0.2.0.dist-info/METADATA +104 -0
- capo_lambda_web-0.2.0.dist-info/RECORD +154 -0
- capo_lambda_web-0.2.0.dist-info/WHEEL +5 -0
- capo_lambda_web-0.2.0.dist-info/licenses/LICENSE +21 -0
- capo_lambda_web-0.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import random
|
|
4
|
+
import time
|
|
5
|
+
from collections.abc import AsyncIterator, Iterator, Sequence
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from typing import TYPE_CHECKING, Awaitable, Callable, Generic, TypeVar, cast
|
|
8
|
+
|
|
9
|
+
from typing_extensions import Never
|
|
10
|
+
from zapros import (
|
|
11
|
+
AsyncClient,
|
|
12
|
+
Client,
|
|
13
|
+
ConnectionError,
|
|
14
|
+
ConnectTimeoutError,
|
|
15
|
+
PoolTimeoutError,
|
|
16
|
+
Response,
|
|
17
|
+
SSLError,
|
|
18
|
+
TimeoutError,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
from capo_lambda_web._async import anysleep
|
|
22
|
+
from capo_lambda_web._body import Body
|
|
23
|
+
from capo_lambda_web._iter import StaticAnyIterator
|
|
24
|
+
from capo_lambda_web.errors import ServiceError
|
|
25
|
+
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from capo_lambda_web._auth._identity import Credentials
|
|
28
|
+
from capo_lambda_web._auth._providers import IdentityProvider
|
|
29
|
+
|
|
30
|
+
TInput = TypeVar("TInput")
|
|
31
|
+
TOutput = TypeVar("TOutput")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass
|
|
35
|
+
class OperationOptions:
|
|
36
|
+
client: Client
|
|
37
|
+
use_dual_stack: bool | None = None
|
|
38
|
+
use_fips: bool | None = None
|
|
39
|
+
region: str | None = None
|
|
40
|
+
endpoint: str | None = None
|
|
41
|
+
retry_max_attempts: int | None = None
|
|
42
|
+
credentials_provider: IdentityProvider[Credentials] | None = None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass
|
|
46
|
+
class AsyncOperationOptions:
|
|
47
|
+
client: AsyncClient
|
|
48
|
+
use_dual_stack: bool | None = None
|
|
49
|
+
use_fips: bool | None = None
|
|
50
|
+
region: str | None = None
|
|
51
|
+
endpoint: str | None = None
|
|
52
|
+
retry_max_attempts: int | None = None
|
|
53
|
+
credentials_provider: IdentityProvider[Credentials] | None = None
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@dataclass
|
|
57
|
+
class OperationRequest(Generic[TInput]):
|
|
58
|
+
input: TInput
|
|
59
|
+
options: OperationOptions
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass
|
|
63
|
+
class AsyncOperationRequest(Generic[TInput]):
|
|
64
|
+
input: TInput
|
|
65
|
+
options: AsyncOperationOptions
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@dataclass
|
|
69
|
+
class OperationResponse(Generic[TOutput]):
|
|
70
|
+
output: TOutput
|
|
71
|
+
response: Response
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@dataclass
|
|
75
|
+
class AsyncOperationResponse(Generic[TOutput]):
|
|
76
|
+
output: TOutput
|
|
77
|
+
response: Response
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
NextFn = Callable[
|
|
81
|
+
[OperationRequest[TInput]],
|
|
82
|
+
OperationResponse[TOutput],
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
AsyncNextFn = Callable[
|
|
86
|
+
[AsyncOperationRequest[TInput]],
|
|
87
|
+
Awaitable[AsyncOperationResponse[TOutput]],
|
|
88
|
+
]
|
|
89
|
+
|
|
90
|
+
Interceptor = Callable[
|
|
91
|
+
[OperationRequest[TInput], NextFn[TInput, TOutput]],
|
|
92
|
+
OperationResponse[TOutput],
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
AsyncInterceptor = Callable[
|
|
96
|
+
[AsyncOperationRequest[TInput], AsyncNextFn[TInput, TOutput]],
|
|
97
|
+
Awaitable[AsyncOperationResponse[TOutput]],
|
|
98
|
+
]
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def execute_pipeline(
|
|
102
|
+
request: OperationRequest[TInput],
|
|
103
|
+
handler: NextFn[TInput, TOutput],
|
|
104
|
+
interceptors: Sequence[Interceptor[TInput, TOutput]],
|
|
105
|
+
) -> OperationResponse[TOutput]:
|
|
106
|
+
def make_chain(index: int) -> NextFn[TInput, TOutput]:
|
|
107
|
+
if index < len(interceptors):
|
|
108
|
+
interceptor = interceptors[index]
|
|
109
|
+
|
|
110
|
+
def next_fn(req: OperationRequest[TInput]) -> OperationResponse[TOutput]:
|
|
111
|
+
return interceptor(req, make_chain(index + 1))
|
|
112
|
+
|
|
113
|
+
return next_fn
|
|
114
|
+
return handler
|
|
115
|
+
|
|
116
|
+
return make_chain(0)(request)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
async def aexecute_pipeline(
|
|
120
|
+
request: AsyncOperationRequest[TInput],
|
|
121
|
+
handler: AsyncNextFn[TInput, TOutput],
|
|
122
|
+
interceptors: Sequence[AsyncInterceptor[TInput, TOutput]],
|
|
123
|
+
) -> AsyncOperationResponse[TOutput]:
|
|
124
|
+
def make_chain(index: int) -> AsyncNextFn[TInput, TOutput]:
|
|
125
|
+
if index < len(interceptors):
|
|
126
|
+
interceptor = interceptors[index]
|
|
127
|
+
|
|
128
|
+
async def next_fn(
|
|
129
|
+
req: AsyncOperationRequest[TInput],
|
|
130
|
+
) -> AsyncOperationResponse[TOutput]:
|
|
131
|
+
return await interceptor(req, make_chain(index + 1))
|
|
132
|
+
|
|
133
|
+
return next_fn
|
|
134
|
+
return handler
|
|
135
|
+
|
|
136
|
+
return await make_chain(0)(request)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def raise_error(response: Response, handle_error: Callable[[Response], Never]) -> Never:
|
|
140
|
+
try:
|
|
141
|
+
handle_error(response)
|
|
142
|
+
except ServiceError as exc:
|
|
143
|
+
# The response itself can say a retry is safe, even when the error is
|
|
144
|
+
# not marked @retryable: a 429, a transient 5xx or a Retry-After header.
|
|
145
|
+
if response.status == 429:
|
|
146
|
+
exc.is_throttling_error = True
|
|
147
|
+
if (
|
|
148
|
+
response.status in (429, 500, 502, 503, 504)
|
|
149
|
+
or "retry-after" in response.headers
|
|
150
|
+
):
|
|
151
|
+
exc.is_retryable = True
|
|
152
|
+
raise
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def _is_retryable(exc: Exception) -> bool:
|
|
156
|
+
if isinstance(exc, ServiceError):
|
|
157
|
+
return exc.is_retryable
|
|
158
|
+
if isinstance(exc, SSLError):
|
|
159
|
+
return False
|
|
160
|
+
if isinstance(exc, (ConnectionError, TimeoutError)):
|
|
161
|
+
return True
|
|
162
|
+
return False
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def _is_pre_transmission(exc: Exception) -> bool:
|
|
166
|
+
# True when the request body was certainly not written before the error,
|
|
167
|
+
# so the same stream can be reused as-is. A bare ConnectionError is
|
|
168
|
+
# ambiguous ("cannot be established or is lost"), so it does not qualify.
|
|
169
|
+
return isinstance(exc, (ConnectTimeoutError, PoolTimeoutError))
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def _prepare_retry(inp: object) -> bool:
|
|
173
|
+
if not isinstance(inp, dict):
|
|
174
|
+
return True
|
|
175
|
+
for value in inp.values():
|
|
176
|
+
if isinstance(value, Body):
|
|
177
|
+
value = cast(Body[Iterator[bytes]], value)
|
|
178
|
+
if value.rebuild() is None:
|
|
179
|
+
return False
|
|
180
|
+
elif isinstance(value, StaticAnyIterator):
|
|
181
|
+
continue
|
|
182
|
+
elif isinstance(value, (Iterator, AsyncIterator)):
|
|
183
|
+
return False
|
|
184
|
+
return True
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
async def _aprepare_retry(inp: object) -> bool:
|
|
188
|
+
if not isinstance(inp, dict):
|
|
189
|
+
return True
|
|
190
|
+
for value in inp.values():
|
|
191
|
+
if isinstance(value, Body):
|
|
192
|
+
value = cast(Body[AsyncIterator[bytes]], value)
|
|
193
|
+
if await value.arebuild() is None:
|
|
194
|
+
return False
|
|
195
|
+
elif isinstance(value, StaticAnyIterator):
|
|
196
|
+
continue
|
|
197
|
+
elif isinstance(value, (Iterator, AsyncIterator)):
|
|
198
|
+
return False
|
|
199
|
+
return True
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def _retry_delay(attempt: int, is_throttling: bool) -> float:
|
|
203
|
+
base = 1.0 if is_throttling else 0.5
|
|
204
|
+
delay = base * (2.0 ** min(attempt - 1, 10))
|
|
205
|
+
delay = min(20.0, delay)
|
|
206
|
+
return random.uniform(0.0, delay)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def retry() -> Interceptor[TInput, TOutput]:
|
|
210
|
+
def interceptor(
|
|
211
|
+
request: OperationRequest[TInput], next: NextFn[TInput, TOutput]
|
|
212
|
+
) -> OperationResponse[TOutput]:
|
|
213
|
+
max_attempts = request.options.retry_max_attempts or 3
|
|
214
|
+
last_exc: Exception | None = None
|
|
215
|
+
for attempt in range(1, max_attempts + 1):
|
|
216
|
+
try:
|
|
217
|
+
return next(request)
|
|
218
|
+
except Exception as exc:
|
|
219
|
+
if not _is_retryable(exc):
|
|
220
|
+
raise
|
|
221
|
+
last_exc = exc
|
|
222
|
+
if attempt < max_attempts:
|
|
223
|
+
if not _is_pre_transmission(exc) and not _prepare_retry(
|
|
224
|
+
request.input
|
|
225
|
+
):
|
|
226
|
+
raise
|
|
227
|
+
is_throttling = (
|
|
228
|
+
isinstance(exc, ServiceError) and exc.is_throttling_error
|
|
229
|
+
)
|
|
230
|
+
time.sleep(_retry_delay(attempt, is_throttling))
|
|
231
|
+
|
|
232
|
+
assert last_exc
|
|
233
|
+
raise last_exc
|
|
234
|
+
|
|
235
|
+
return interceptor
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def aretry() -> AsyncInterceptor[TInput, TOutput]:
|
|
239
|
+
async def interceptor(
|
|
240
|
+
request: AsyncOperationRequest[TInput], next: AsyncNextFn[TInput, TOutput]
|
|
241
|
+
) -> AsyncOperationResponse[TOutput]:
|
|
242
|
+
max_attempts = request.options.retry_max_attempts or 3
|
|
243
|
+
last_exc: Exception | None = None
|
|
244
|
+
for attempt in range(1, max_attempts + 1):
|
|
245
|
+
try:
|
|
246
|
+
return await next(request)
|
|
247
|
+
except Exception as exc:
|
|
248
|
+
if not _is_retryable(exc):
|
|
249
|
+
raise
|
|
250
|
+
last_exc = exc
|
|
251
|
+
if attempt < max_attempts:
|
|
252
|
+
if not _is_pre_transmission(exc) and not await _aprepare_retry(
|
|
253
|
+
request.input
|
|
254
|
+
):
|
|
255
|
+
raise
|
|
256
|
+
is_throttling = (
|
|
257
|
+
isinstance(exc, ServiceError) and exc.is_throttling_error
|
|
258
|
+
)
|
|
259
|
+
await anysleep(_retry_delay(attempt, is_throttling))
|
|
260
|
+
|
|
261
|
+
assert last_exc
|
|
262
|
+
raise last_exc
|
|
263
|
+
|
|
264
|
+
return interceptor
|