rboto 0.1.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.
rboto/__init__.py ADDED
@@ -0,0 +1,297 @@
1
+ # Generated by rboto-codegen. DO NOT EDIT.
2
+ from typing import TYPE_CHECKING
3
+
4
+ from ._imports import import_service as _import_service
5
+ from .config import ClientConfig
6
+ from .interceptors import (
7
+ Attempt,
8
+ Interceptor,
9
+ Next,
10
+ OperationContext,
11
+ OperationMetadata,
12
+ OperationRequest,
13
+ OperationResponse,
14
+ operation_context,
15
+ )
16
+ from .logging import LogLevel, LogTraceContext, configure_logging, get_logger
17
+ from .services import (
18
+ api_gateway,
19
+ bedrock,
20
+ bedrock_agent,
21
+ bedrock_agent_runtime,
22
+ bedrock_agentcore,
23
+ bedrock_agentcore_control,
24
+ bedrock_data_automation,
25
+ bedrock_data_automation_runtime,
26
+ bedrock_runtime,
27
+ cloudtrail,
28
+ cloudwatch_logs,
29
+ cognito_identity,
30
+ connecthealth,
31
+ dynamodb,
32
+ eventbridge,
33
+ guardduty,
34
+ kms,
35
+ lambda_,
36
+ lex_runtime_v2,
37
+ pipes,
38
+ polly,
39
+ qbusiness,
40
+ s3,
41
+ sagemaker_runtime_http2,
42
+ scheduler,
43
+ secrets_manager,
44
+ sesv2,
45
+ sfn,
46
+ signin,
47
+ sns,
48
+ sqs,
49
+ ssm,
50
+ sts,
51
+ transcribe_streaming,
52
+ )
53
+ from .session import Session
54
+ from .types import UnknownEnumValue
55
+
56
+ if TYPE_CHECKING:
57
+ from rboto_api_gateway import APIGatewayClient
58
+ from rboto_bedrock import BedrockClient
59
+ from rboto_bedrock_agent import BedrockAgentClient
60
+ from rboto_bedrock_agent_runtime import BedrockAgentRuntimeClient
61
+ from rboto_bedrock_agentcore import BedrockAgentCoreClient
62
+ from rboto_bedrock_agentcore_control import BedrockAgentCoreControlClient
63
+ from rboto_bedrock_data_automation import BedrockDataAutomationClient
64
+ from rboto_bedrock_data_automation_runtime import BedrockDataAutomationRuntimeClient
65
+ from rboto_bedrock_runtime import BedrockRuntimeClient
66
+ from rboto_cloudtrail import CloudTrailClient
67
+ from rboto_cloudwatch_logs import CloudWatchLogsClient
68
+ from rboto_cognito_identity import CognitoIdentityClient
69
+ from rboto_connecthealth import ConnectHealthClient
70
+ from rboto_dynamodb import DynamoDBClient
71
+ from rboto_eventbridge import EventBridgeClient
72
+ from rboto_guardduty import GuardDutyClient
73
+ from rboto_kms import KMSClient
74
+ from rboto_lambda import LambdaClient
75
+ from rboto_lex_runtime_v2 import LexRuntimeV2Client
76
+ from rboto_pipes import EventBridgePipesClient
77
+ from rboto_polly import PollyClient
78
+ from rboto_qbusiness import QBusinessClient
79
+ from rboto_s3 import S3Client
80
+ from rboto_sagemaker_runtime_http2 import SageMakerRuntimeHTTP2Client
81
+ from rboto_scheduler import EventBridgeSchedulerClient
82
+ from rboto_secrets_manager import SecretsManagerClient
83
+ from rboto_sesv2 import SESV2Client
84
+ from rboto_sfn import StepFunctionsClient
85
+ from rboto_signin import SignInClient
86
+ from rboto_sns import SNSClient
87
+ from rboto_sqs import SQSClient
88
+ from rboto_ssm import SSMClient
89
+ from rboto_sts import STSClient
90
+ from rboto_transcribe_streaming import TranscribeStreamingClient
91
+
92
+ __version__ = "0.1.0"
93
+ __all__ = [
94
+ "Attempt",
95
+ "ClientConfig",
96
+ "Interceptor",
97
+ "LogLevel",
98
+ "LogTraceContext",
99
+ "configure_logging",
100
+ "get_logger",
101
+ "OperationContext",
102
+ "Next",
103
+ "OperationMetadata",
104
+ "OperationRequest",
105
+ "OperationResponse",
106
+ "operation_context",
107
+ "Session",
108
+ "UnknownEnumValue",
109
+ "APIGatewayClient",
110
+ "BedrockClient",
111
+ "BedrockAgentClient",
112
+ "BedrockAgentRuntimeClient",
113
+ "BedrockAgentCoreClient",
114
+ "BedrockAgentCoreControlClient",
115
+ "BedrockDataAutomationClient",
116
+ "BedrockDataAutomationRuntimeClient",
117
+ "BedrockRuntimeClient",
118
+ "CloudTrailClient",
119
+ "CloudWatchLogsClient",
120
+ "CognitoIdentityClient",
121
+ "ConnectHealthClient",
122
+ "DynamoDBClient",
123
+ "EventBridgeClient",
124
+ "GuardDutyClient",
125
+ "KMSClient",
126
+ "LambdaClient",
127
+ "LexRuntimeV2Client",
128
+ "EventBridgePipesClient",
129
+ "PollyClient",
130
+ "QBusinessClient",
131
+ "S3Client",
132
+ "SageMakerRuntimeHTTP2Client",
133
+ "EventBridgeSchedulerClient",
134
+ "SecretsManagerClient",
135
+ "SESV2Client",
136
+ "StepFunctionsClient",
137
+ "SignInClient",
138
+ "SNSClient",
139
+ "SQSClient",
140
+ "SSMClient",
141
+ "STSClient",
142
+ "TranscribeStreamingClient",
143
+
144
+ "api_gateway",
145
+ "bedrock",
146
+ "bedrock_agent",
147
+ "bedrock_agent_runtime",
148
+ "bedrock_agentcore",
149
+ "bedrock_agentcore_control",
150
+ "bedrock_data_automation",
151
+ "bedrock_data_automation_runtime",
152
+ "bedrock_runtime",
153
+ "cloudtrail",
154
+ "cloudwatch_logs",
155
+ "cognito_identity",
156
+ "connecthealth",
157
+ "dynamodb",
158
+ "eventbridge",
159
+ "guardduty",
160
+ "kms",
161
+ "lambda_",
162
+ "lex_runtime_v2",
163
+ "pipes",
164
+ "polly",
165
+ "qbusiness",
166
+ "s3",
167
+ "sagemaker_runtime_http2",
168
+ "scheduler",
169
+ "secrets_manager",
170
+ "sesv2",
171
+ "sfn",
172
+ "signin",
173
+ "sns",
174
+ "sqs",
175
+ "ssm",
176
+ "sts",
177
+ "transcribe_streaming",
178
+ ]
179
+
180
+ _CLIENT_MODULES = {
181
+ "APIGatewayClient": (
182
+ "rboto_api_gateway", "api-gateway",
183
+ ),
184
+ "BedrockClient": (
185
+ "rboto_bedrock", "bedrock",
186
+ ),
187
+ "BedrockAgentClient": (
188
+ "rboto_bedrock_agent", "bedrock-agent",
189
+ ),
190
+ "BedrockAgentRuntimeClient": (
191
+ "rboto_bedrock_agent_runtime", "bedrock-agent-runtime",
192
+ ),
193
+ "BedrockAgentCoreClient": (
194
+ "rboto_bedrock_agentcore", "bedrock-agentcore",
195
+ ),
196
+ "BedrockAgentCoreControlClient": (
197
+ "rboto_bedrock_agentcore_control", "bedrock-agentcore-control",
198
+ ),
199
+ "BedrockDataAutomationClient": (
200
+ "rboto_bedrock_data_automation", "bedrock-data-automation",
201
+ ),
202
+ "BedrockDataAutomationRuntimeClient": (
203
+ "rboto_bedrock_data_automation_runtime", "bedrock-data-automation-runtime",
204
+ ),
205
+ "BedrockRuntimeClient": (
206
+ "rboto_bedrock_runtime", "bedrock-runtime",
207
+ ),
208
+ "CloudTrailClient": (
209
+ "rboto_cloudtrail", "cloudtrail",
210
+ ),
211
+ "CloudWatchLogsClient": (
212
+ "rboto_cloudwatch_logs", "cloudwatch-logs",
213
+ ),
214
+ "CognitoIdentityClient": (
215
+ "rboto_cognito_identity", "cognito-identity",
216
+ ),
217
+ "ConnectHealthClient": (
218
+ "rboto_connecthealth", "connecthealth",
219
+ ),
220
+ "DynamoDBClient": (
221
+ "rboto_dynamodb", "dynamodb",
222
+ ),
223
+ "EventBridgeClient": (
224
+ "rboto_eventbridge", "eventbridge",
225
+ ),
226
+ "GuardDutyClient": (
227
+ "rboto_guardduty", "guardduty",
228
+ ),
229
+ "KMSClient": (
230
+ "rboto_kms", "kms",
231
+ ),
232
+ "LambdaClient": (
233
+ "rboto_lambda", "lambda",
234
+ ),
235
+ "LexRuntimeV2Client": (
236
+ "rboto_lex_runtime_v2", "lex-runtime-v2",
237
+ ),
238
+ "EventBridgePipesClient": (
239
+ "rboto_pipes", "pipes",
240
+ ),
241
+ "PollyClient": (
242
+ "rboto_polly", "polly",
243
+ ),
244
+ "QBusinessClient": (
245
+ "rboto_qbusiness", "qbusiness",
246
+ ),
247
+ "S3Client": (
248
+ "rboto_s3", "s3",
249
+ ),
250
+ "SageMakerRuntimeHTTP2Client": (
251
+ "rboto_sagemaker_runtime_http2", "sagemaker-runtime-http2",
252
+ ),
253
+ "EventBridgeSchedulerClient": (
254
+ "rboto_scheduler", "scheduler",
255
+ ),
256
+ "SecretsManagerClient": (
257
+ "rboto_secrets_manager", "secrets-manager",
258
+ ),
259
+ "SESV2Client": (
260
+ "rboto_sesv2", "sesv2",
261
+ ),
262
+ "StepFunctionsClient": (
263
+ "rboto_sfn", "sfn",
264
+ ),
265
+ "SignInClient": (
266
+ "rboto_signin", "signin",
267
+ ),
268
+ "SNSClient": (
269
+ "rboto_sns", "sns",
270
+ ),
271
+ "SQSClient": (
272
+ "rboto_sqs", "sqs",
273
+ ),
274
+ "SSMClient": (
275
+ "rboto_ssm", "ssm",
276
+ ),
277
+ "STSClient": (
278
+ "rboto_sts", "sts",
279
+ ),
280
+ "TranscribeStreamingClient": (
281
+ "rboto_transcribe_streaming", "transcribe-streaming",
282
+ ),
283
+ }
284
+
285
+
286
+ def __getattr__(name: str) -> object:
287
+ target = _CLIENT_MODULES.get(name)
288
+ if target is None:
289
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
290
+ package, extra = target
291
+ client_class = getattr(_import_service(package, extra), name)
292
+ globals()[name] = client_class
293
+ return client_class
294
+
295
+
296
+ def __dir__() -> list[str]:
297
+ return sorted(set(globals()) | _CLIENT_MODULES.keys())
rboto/__init__.pyi ADDED
@@ -0,0 +1,92 @@
1
+ # Generated by rboto-codegen. DO NOT EDIT.
2
+ from rboto_api_gateway import APIGatewayClient as APIGatewayClient
3
+ from rboto_bedrock import BedrockClient as BedrockClient
4
+ from rboto_bedrock_agent import BedrockAgentClient as BedrockAgentClient
5
+ from rboto_bedrock_agent_runtime import BedrockAgentRuntimeClient as BedrockAgentRuntimeClient
6
+ from rboto_bedrock_agentcore import BedrockAgentCoreClient as BedrockAgentCoreClient
7
+ from rboto_bedrock_agentcore_control import (
8
+ BedrockAgentCoreControlClient as BedrockAgentCoreControlClient,
9
+ )
10
+ from rboto_bedrock_data_automation import BedrockDataAutomationClient as BedrockDataAutomationClient
11
+ from rboto_bedrock_data_automation_runtime import (
12
+ BedrockDataAutomationRuntimeClient as BedrockDataAutomationRuntimeClient,
13
+ )
14
+ from rboto_bedrock_runtime import BedrockRuntimeClient as BedrockRuntimeClient
15
+ from rboto_cloudtrail import CloudTrailClient as CloudTrailClient
16
+ from rboto_cloudwatch_logs import CloudWatchLogsClient as CloudWatchLogsClient
17
+ from rboto_cognito_identity import CognitoIdentityClient as CognitoIdentityClient
18
+ from rboto_connecthealth import ConnectHealthClient as ConnectHealthClient
19
+ from rboto_dynamodb import DynamoDBClient as DynamoDBClient
20
+ from rboto_eventbridge import EventBridgeClient as EventBridgeClient
21
+ from rboto_guardduty import GuardDutyClient as GuardDutyClient
22
+ from rboto_kms import KMSClient as KMSClient
23
+ from rboto_lambda import LambdaClient as LambdaClient
24
+ from rboto_lex_runtime_v2 import LexRuntimeV2Client as LexRuntimeV2Client
25
+ from rboto_pipes import EventBridgePipesClient as EventBridgePipesClient
26
+ from rboto_polly import PollyClient as PollyClient
27
+ from rboto_qbusiness import QBusinessClient as QBusinessClient
28
+ from rboto_s3 import S3Client as S3Client
29
+ from rboto_sagemaker_runtime_http2 import SageMakerRuntimeHTTP2Client as SageMakerRuntimeHTTP2Client
30
+ from rboto_scheduler import EventBridgeSchedulerClient as EventBridgeSchedulerClient
31
+ from rboto_secrets_manager import SecretsManagerClient as SecretsManagerClient
32
+ from rboto_sesv2 import SESV2Client as SESV2Client
33
+ from rboto_sfn import StepFunctionsClient as StepFunctionsClient
34
+ from rboto_signin import SignInClient as SignInClient
35
+ from rboto_sns import SNSClient as SNSClient
36
+ from rboto_sqs import SQSClient as SQSClient
37
+ from rboto_ssm import SSMClient as SSMClient
38
+ from rboto_sts import STSClient as STSClient
39
+ from rboto_transcribe_streaming import TranscribeStreamingClient as TranscribeStreamingClient
40
+
41
+ from .config import ClientConfig as ClientConfig
42
+ from .interceptors import Attempt as Attempt
43
+ from .interceptors import Interceptor as Interceptor
44
+ from .interceptors import Next as Next
45
+ from .interceptors import OperationContext as OperationContext
46
+ from .interceptors import OperationMetadata as OperationMetadata
47
+ from .interceptors import OperationRequest as OperationRequest
48
+ from .interceptors import OperationResponse as OperationResponse
49
+ from .interceptors import operation_context as operation_context
50
+ from .logging import LogLevel as LogLevel
51
+ from .logging import LogTraceContext as LogTraceContext
52
+ from .logging import configure_logging as configure_logging
53
+ from .logging import get_logger as get_logger
54
+ from .services import api_gateway as api_gateway
55
+ from .services import bedrock as bedrock
56
+ from .services import bedrock_agent as bedrock_agent
57
+ from .services import bedrock_agent_runtime as bedrock_agent_runtime
58
+ from .services import bedrock_agentcore as bedrock_agentcore
59
+ from .services import bedrock_agentcore_control as bedrock_agentcore_control
60
+ from .services import bedrock_data_automation as bedrock_data_automation
61
+ from .services import bedrock_data_automation_runtime as bedrock_data_automation_runtime
62
+ from .services import bedrock_runtime as bedrock_runtime
63
+ from .services import cloudtrail as cloudtrail
64
+ from .services import cloudwatch_logs as cloudwatch_logs
65
+ from .services import cognito_identity as cognito_identity
66
+ from .services import connecthealth as connecthealth
67
+ from .services import dynamodb as dynamodb
68
+ from .services import eventbridge as eventbridge
69
+ from .services import guardduty as guardduty
70
+ from .services import kms as kms
71
+ from .services import lambda_ as lambda_
72
+ from .services import lex_runtime_v2 as lex_runtime_v2
73
+ from .services import pipes as pipes
74
+ from .services import polly as polly
75
+ from .services import qbusiness as qbusiness
76
+ from .services import s3 as s3
77
+ from .services import sagemaker_runtime_http2 as sagemaker_runtime_http2
78
+ from .services import scheduler as scheduler
79
+ from .services import secrets_manager as secrets_manager
80
+ from .services import sesv2 as sesv2
81
+ from .services import sfn as sfn
82
+ from .services import signin as signin
83
+ from .services import sns as sns
84
+ from .services import sqs as sqs
85
+ from .services import ssm as ssm
86
+ from .services import sts as sts
87
+ from .services import transcribe_streaming as transcribe_streaming
88
+ from .session import Session as Session
89
+ from .types import UnknownEnumValue as UnknownEnumValue
90
+
91
+ __version__: str
92
+ __all__: list[str]
rboto/_imports.py ADDED
@@ -0,0 +1,15 @@
1
+ """Import optional service packages without hiding broken installations."""
2
+
3
+ from importlib import import_module
4
+ from types import ModuleType
5
+
6
+
7
+ def import_service(package: str, extra: str) -> ModuleType:
8
+ try:
9
+ return import_module(package)
10
+ except ModuleNotFoundError as error:
11
+ if error.name != package:
12
+ raise
13
+ raise ImportError(
14
+ f'{extra} support is not installed. Install it with: pip install "rboto[{extra}]"'
15
+ ) from error
rboto/_pagination.py ADDED
@@ -0,0 +1,93 @@
1
+ """Internal iteration shared by generated, typed service paginators."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import AsyncIterator, Awaitable, Callable, Mapping, Sequence, Sized
6
+ from copy import deepcopy
7
+ from dataclasses import dataclass
8
+ from typing import Protocol, TypeVar, cast, runtime_checkable
9
+
10
+ _T = TypeVar("_T")
11
+ Path = tuple[str | int, ...]
12
+
13
+
14
+ @dataclass(frozen=True, slots=True)
15
+ class PaginationSpec:
16
+ input_tokens: tuple[str, ...]
17
+ output_tokens: tuple[tuple[Path, ...], ...]
18
+ more_results: Path | None = None
19
+
20
+
21
+ @runtime_checkable
22
+ class _NativeCursor(Protocol):
23
+ def to_dict(self) -> dict[str, object]: ...
24
+
25
+
26
+ def _snapshot(value: object) -> object:
27
+ # Copy only continuation state. Yielded pages retain their native ownership
28
+ # and can be modified by the consumer without changing the next request.
29
+ if isinstance(value, _NativeCursor):
30
+ return _snapshot(value.to_dict())
31
+ if isinstance(value, Mapping):
32
+ return {key: _snapshot(item) for key, item in cast(Mapping[object, object], value).items()}
33
+ if isinstance(value, (list, tuple)):
34
+ return [_snapshot(item) for item in cast(Sequence[object], value)]
35
+ return deepcopy(value)
36
+
37
+
38
+ def _present(value: object) -> bool:
39
+ return value is not None and not (
40
+ isinstance(value, (str, bytes, Mapping, Sequence)) and len(cast(Sized, value)) == 0
41
+ )
42
+
43
+
44
+ def _read(value: object, path: Path) -> object:
45
+ for part in path:
46
+ if value is None:
47
+ return None
48
+ if isinstance(part, int):
49
+ if not isinstance(value, Sequence) or isinstance(value, (str, bytes)):
50
+ return None
51
+ try:
52
+ value = cast(Sequence[object], value)[part]
53
+ except IndexError:
54
+ return None
55
+ elif isinstance(value, Mapping):
56
+ value = cast(Mapping[str, object], value).get(part)
57
+ else:
58
+ value = getattr(value, part, None)
59
+ return value
60
+
61
+
62
+ def _token(page: object, alternatives: tuple[Path, ...]) -> object:
63
+ for path in alternatives:
64
+ value = _read(page, path)
65
+ if _present(value):
66
+ return value
67
+ return None
68
+
69
+
70
+ async def paginate(
71
+ call: Callable[..., Awaitable[_T]],
72
+ params: dict[str, object],
73
+ spec: PaginationSpec,
74
+ ) -> AsyncIterator[_T]:
75
+ # Generated signatures validate the public arguments. Model-checked token
76
+ # paths are the only arguments this loop updates across requests.
77
+ request = params.copy()
78
+ previous = tuple(_snapshot(request.get(name)) for name in spec.input_tokens)
79
+ while True:
80
+ page = await call(**request)
81
+ following = tuple(_snapshot(_token(page, paths)) for paths in spec.output_tokens)
82
+ has_more = spec.more_results is None or bool(_read(page, spec.more_results))
83
+ finished = not has_more or not any(_present(token) for token in following)
84
+ repeated = following == previous
85
+ yield page
86
+ if finished or repeated:
87
+ return
88
+ for name, token in zip(spec.input_tokens, following, strict=True):
89
+ if _present(token):
90
+ request[name] = token
91
+ else:
92
+ request.pop(name, None)
93
+ previous = tuple(_snapshot(token) for token in following)
rboto/config.py ADDED
@@ -0,0 +1,94 @@
1
+ from dataclasses import dataclass, field
2
+ from math import isfinite
3
+ from typing import Literal
4
+ from urllib.parse import urlsplit
5
+
6
+ from .exceptions import ConfigurationError
7
+
8
+
9
+ def _valid_attempts(value: object) -> bool:
10
+ return isinstance(value, int) and not isinstance(value, bool) and 1 <= value <= 2**32 - 1
11
+
12
+
13
+ @dataclass(frozen=True, slots=True, kw_only=True)
14
+ class ClientConfig:
15
+ """Credential and request settings shared when constructing clients.
16
+
17
+ Timeouts are in seconds. ``max_attempts`` includes the initial request.
18
+ Explicit credentials or a profile can supply the source credentials for
19
+ ``role_arn``. Credential values are excluded from the representation.
20
+ """
21
+
22
+ access_key_id: str | None = field(default=None, repr=False)
23
+ secret_access_key: str | None = field(default=None, repr=False)
24
+ session_token: str | None = field(default=None, repr=False)
25
+ role_arn: str | None = None
26
+ role_session_name: str | None = None
27
+ external_id: str | None = field(default=None, repr=False)
28
+ connect_timeout: float | None = None
29
+ read_timeout: float | None = None
30
+ operation_timeout: float | None = None
31
+ attempt_timeout: float | None = None
32
+ max_attempts: int | None = None
33
+ retry_mode: Literal["standard", "adaptive"] | None = None
34
+ proxy_url: str | None = field(default=None, repr=False)
35
+ no_proxy: str | None = None
36
+ ca_bundle: str | None = None
37
+
38
+ def __post_init__(self) -> None:
39
+ if (self.access_key_id is None) != (self.secret_access_key is None):
40
+ raise ConfigurationError(
41
+ "access_key_id and secret_access_key must be supplied together"
42
+ )
43
+ if self.session_token is not None and self.access_key_id is None:
44
+ raise ConfigurationError("session_token requires explicit credentials")
45
+ if self.role_arn is None and (
46
+ self.role_session_name is not None or self.external_id is not None
47
+ ):
48
+ raise ConfigurationError("role_session_name and external_id require role_arn")
49
+ for name in (
50
+ "access_key_id",
51
+ "secret_access_key",
52
+ "session_token",
53
+ "role_arn",
54
+ "role_session_name",
55
+ "external_id",
56
+ "proxy_url",
57
+ "no_proxy",
58
+ "ca_bundle",
59
+ ):
60
+ value = getattr(self, name)
61
+ if value is not None and (not isinstance(value, str) or not value.strip()):
62
+ raise ConfigurationError(f"{name} must be a nonempty string")
63
+ for name in ("connect_timeout", "read_timeout", "operation_timeout", "attempt_timeout"):
64
+ value = getattr(self, name)
65
+ if value is not None and (
66
+ isinstance(value, bool)
67
+ or not isinstance(value, (int, float))
68
+ or value <= 0
69
+ or value > 2**32 - 1
70
+ or not isfinite(value)
71
+ ):
72
+ raise ConfigurationError(f"{name} must be finite and positive (at most 2**32 - 1)")
73
+ if self.max_attempts is not None and not _valid_attempts(self.max_attempts):
74
+ raise ConfigurationError("max_attempts must be an integer between 1 and 2**32 - 1")
75
+ if self.retry_mode not in (None, "standard", "adaptive"):
76
+ raise ConfigurationError("retry_mode must be 'standard' or 'adaptive'")
77
+ if self.no_proxy is not None and self.proxy_url is None:
78
+ raise ConfigurationError("no_proxy requires proxy_url")
79
+ if self.proxy_url is not None:
80
+ try:
81
+ url = urlsplit(self.proxy_url)
82
+ valid = (
83
+ url.scheme in ("http", "https")
84
+ and bool(url.hostname)
85
+ and url.port != 0
86
+ and url.path in ("", "/")
87
+ and not url.query
88
+ and not url.fragment
89
+ and all(32 < ord(char) < 127 for char in self.proxy_url)
90
+ )
91
+ except ValueError:
92
+ valid = False
93
+ if not valid:
94
+ raise ConfigurationError("proxy_url must be an HTTP(S) URL with a host")
rboto/exceptions.py ADDED
@@ -0,0 +1,73 @@
1
+ from typing import NotRequired, TypedDict
2
+
3
+
4
+ class ErrorDetails(TypedDict):
5
+ Code: str
6
+ Message: str
7
+
8
+
9
+ class ErrorResponse(TypedDict):
10
+ Error: ErrorDetails
11
+ RequestId: NotRequired[str]
12
+
13
+
14
+ class RbotoError(Exception):
15
+ """Base exception for all rboto errors."""
16
+
17
+
18
+ class ClientError(RbotoError):
19
+ """Final error returned by an AWS client operation."""
20
+
21
+ message: str
22
+ error_code: str
23
+ request_id: str | None
24
+ operation_name: str
25
+ response: ErrorResponse
26
+
27
+ def __init__(
28
+ self,
29
+ message: str,
30
+ error_code: str = "UnknownError",
31
+ request_id: str | None = None,
32
+ operation_name: str = "UnknownOperation",
33
+ ) -> None:
34
+ super().__init__(message)
35
+ self.message = message
36
+ self.error_code = error_code
37
+ self.request_id = request_id
38
+ self.operation_name = operation_name
39
+ self.response = {
40
+ "Error": {"Code": error_code, "Message": message},
41
+ }
42
+ if request_id is not None:
43
+ self.response["RequestId"] = request_id
44
+
45
+ def __str__(self) -> str:
46
+ return (
47
+ f"An error occurred ({self.error_code}) when calling "
48
+ f"{self.operation_name}: {self.message}"
49
+ )
50
+
51
+
52
+ class ServiceError(ClientError):
53
+ """Base exception for service-specific AWS errors."""
54
+
55
+
56
+ class ConfigurationError(RbotoError):
57
+ """Invalid rboto configuration."""
58
+
59
+
60
+ class CredentialsError(RbotoError):
61
+ """AWS credentials could not be loaded or refreshed."""
62
+
63
+
64
+ class ConnectionError(ClientError):
65
+ """The request could not reach the service."""
66
+
67
+
68
+ class TimeoutError(ConnectionError):
69
+ """A connection, request attempt, or operation exceeded its timeout."""
70
+
71
+
72
+ class ResponseError(ClientError):
73
+ """The service response could not be decoded."""