|
8 | 8 | import socket |
9 | 9 | from contextlib import contextmanager |
10 | 10 | from errno import ESPIPE |
11 | | -from typing import Any, BinaryIO, Dict, Iterator, List, Optional, Set, Tuple, Union, cast |
| 11 | +from typing import Any, BinaryIO, Dict, Iterator, List, Optional, Tuple, Union, cast |
12 | 12 |
|
13 | 13 | import boto3 |
14 | 14 | from botocore.exceptions import ReadTimeoutError |
| 15 | +from botocore.loaders import Loader |
| 16 | +from botocore.model import ServiceModel |
15 | 17 |
|
16 | 18 | from awswrangler import _utils, exceptions |
17 | 19 | from awswrangler._config import apply_configs |
|
24 | 26 | _MIN_WRITE_BLOCK: int = 5_242_880 # 5 MB (5 * 2**20) |
25 | 27 | _MIN_PARALLEL_READ_BLOCK: int = 5_242_880 # 5 MB (5 * 2**20) |
26 | 28 |
|
27 | | -BOTOCORE_ACCEPTED_KWARGS: Dict[str, Set[str]] = { |
28 | | - "get_object": { |
29 | | - "SSECustomerAlgorithm", |
30 | | - "SSECustomerKey", |
31 | | - "RequestPayer", |
32 | | - "ExpectedBucketOwner", |
33 | | - "VersionId", |
34 | | - }, |
35 | | - "copy_object": { |
36 | | - "ACL", |
37 | | - "Metadata", |
38 | | - "ServerSideEncryption", |
39 | | - "StorageClass", |
40 | | - "SSECustomerAlgorithm", |
41 | | - "SSECustomerKey", |
42 | | - "SSEKMSKeyId", |
43 | | - "SSEKMSEncryptionContext", |
44 | | - "Tagging", |
45 | | - "RequestPayer", |
46 | | - "ExpectedBucketOwner", |
47 | | - "CopySource", |
48 | | - }, |
49 | | - "create_multipart_upload": { |
50 | | - "ACL", |
51 | | - "Metadata", |
52 | | - "ServerSideEncryption", |
53 | | - "StorageClass", |
54 | | - "SSECustomerAlgorithm", |
55 | | - "SSECustomerKey", |
56 | | - "SSEKMSKeyId", |
57 | | - "SSEKMSEncryptionContext", |
58 | | - "Tagging", |
59 | | - "RequestPayer", |
60 | | - "ExpectedBucketOwner", |
61 | | - }, |
62 | | - "upload_part": { |
63 | | - "SSECustomerAlgorithm", |
64 | | - "SSECustomerKey", |
65 | | - "RequestPayer", |
66 | | - "ExpectedBucketOwner", |
67 | | - }, |
68 | | - "complete_multipart_upload": { |
69 | | - "RequestPayer", |
70 | | - "ExpectedBucketOwner", |
71 | | - }, |
72 | | - "put_object": { |
73 | | - "ACL", |
74 | | - "Metadata", |
75 | | - "ServerSideEncryption", |
76 | | - "StorageClass", |
77 | | - "SSECustomerAlgorithm", |
78 | | - "SSECustomerKey", |
79 | | - "SSEKMSKeyId", |
80 | | - "SSEKMSEncryptionContext", |
81 | | - "Tagging", |
82 | | - "RequestPayer", |
83 | | - "ExpectedBucketOwner", |
84 | | - }, |
85 | | - "list_objects_v2": { |
86 | | - "RequestPayer", |
87 | | - "ExpectedBucketOwner", |
88 | | - }, |
89 | | - "delete_objects": { |
90 | | - "RequestPayer", |
91 | | - "ExpectedBucketOwner", |
92 | | - "Objects", |
93 | | - }, |
94 | | - "head_object": { |
95 | | - "RequestPayer", |
96 | | - "ExpectedBucketOwner", |
97 | | - "VersionId", |
98 | | - }, |
99 | | -} |
| 29 | +_BOTOCORE_LOADER = Loader() |
| 30 | +_S3_JSON_MODEL = _BOTOCORE_LOADER.load_service_model(service_name="s3", type_name="service-2") |
| 31 | +_S3_SERVICE_MODEL = ServiceModel(_S3_JSON_MODEL, service_name="s3") |
| 32 | + |
| 33 | + |
| 34 | +def _snake_to_camel_case(s: str) -> str: |
| 35 | + return "".join(c.title() for c in s.split("_")) |
100 | 36 |
|
101 | 37 |
|
102 | 38 | def get_botocore_valid_kwargs(function_name: str, s3_additional_kwargs: Dict[str, Any]) -> Dict[str, Any]: |
103 | 39 | """Filter and keep only the valid botocore key arguments.""" |
104 | | - return {k: v for k, v in s3_additional_kwargs.items() if k in BOTOCORE_ACCEPTED_KWARGS[function_name]} |
| 40 | + s3_operation_model = _S3_SERVICE_MODEL.operation_model(_snake_to_camel_case(function_name)) |
| 41 | + allowed_kwargs = s3_operation_model.input_shape.members.keys() # pylint: disable=E1101 |
| 42 | + return {k: v for k, v in s3_additional_kwargs.items() if k in allowed_kwargs} |
105 | 43 |
|
106 | 44 |
|
107 | 45 | def _fetch_range( |
|
0 commit comments