Skip to content

Commit

Permalink
move param validation to endpoint resolution and write tests
Browse files Browse the repository at this point in the history
  • Loading branch information
davidlm committed Sep 18, 2023
1 parent 07161f7 commit 09b0cf1
Show file tree
Hide file tree
Showing 9 changed files with 311 additions and 61 deletions.
24 changes: 1 addition & 23 deletions botocore/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -649,9 +649,7 @@ def _build_endpoint_resolver(
if self._is_s3_service(service_name_raw) and s3_config_raw:
client_context = s3_config_raw
elif client_config is not None:
client_context = self._compute_client_context(
service_model.client_context_parameters, client_config
)
client_context = client_config.client_context_params or {}
else:
client_context = {}
sig_version = (
Expand Down Expand Up @@ -769,23 +767,3 @@ def _compute_user_agent_appid_config(self, config_kwargs):
f'maximum length of {USERAGENT_APPID_MAXLEN} characters.'
)
config_kwargs['user_agent_appid'] = user_agent_appid

def _compute_client_context(self, client_context_params, client_config):
client_context = {}
context_values = client_config.client_context_params
if context_values is not None:
for param in client_context_params:
param_name = param.name
if param_name in context_values:
value = self._validate_client_context_param_value(
param, context_values[param_name]
)
client_context[param_name] = value
return client_context

def _validate_client_context_param_value(self, param, value):
if param.type == 'boolean':
value = ensure_boolean(value)
elif param.type == 'string' and not isinstance(value, str):
value = str(value)
return value
5 changes: 0 additions & 5 deletions botocore/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,13 +210,8 @@ class Config:
:type request_min_compression_size_bytes: int
:param request_min_compression_bytes: The minimum size in bytes that a
request body should be to trigger compression. All requests with
<<<<<<< HEAD
streaming input that don't contain the ``requiresLength`` trait will be
compressed regardless of this setting.
=======
streaming input that don't contain the `requiresLength` trait will
be compressed regardless of this setting.
>>>>>>> 2b9b84927 (add support for client context params and add to docs)
Defaults to None.
Expand Down
22 changes: 17 additions & 5 deletions botocore/regions.py
Original file line number Diff line number Diff line change
Expand Up @@ -593,9 +593,21 @@ def _resolve_param_as_dynamic_context_param(

def _resolve_param_as_client_context_param(self, param_name):
client_ctx_params = self._get_client_context_params()
if param_name in client_ctx_params:
client_ctx_varname = client_ctx_params[param_name]
return self._client_context.get(client_ctx_varname)
ctx_param = client_ctx_params.get(param_name)
param_value = self._client_context.get(xform_name(param_name))
if ctx_param is not None and param_value is not None:
return self._resolve_client_context_param_value(
param_value, ctx_param
)

def _resolve_client_context_param_value(self, param_value, ctx_param):
if ctx_param.type == 'boolean':
return ensure_boolean(param_value)

if ctx_param.type == 'string' and not isinstance(param_value, str):
return str(param_value)

return param_value

def _resolve_param_as_builtin(self, builtin_name, builtins):
if builtin_name not in EndpointResolverBuiltins.__members__.values():
Expand All @@ -620,9 +632,9 @@ def _get_dynamic_context_params(self, operation_model):

@instance_cache
def _get_client_context_params(self):
"""Mapping of param names to client configuration variable"""
"""Mapping of param names to param objects"""
return {
param.name: xform_name(param.name)
param.name: param
for param in self._service_model.client_context_parameters
}

Expand Down
11 changes: 11 additions & 0 deletions tests/functional/docs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,17 @@ def get_docstring_for_method(self, service_name, method_name):
method_contents = self.get_method_document_block(method_name, contents)
return method_contents

def get_client_context_params_block(self, contents):
contents = contents.decode('utf-8')
start_param_document = '===\nClient Context Parameters\n==='
start_index = contents.find(start_param_document)
self.assertNotEqual(
start_index, -1, 'Context param section is not found in contents'
)
# context params are at the end of the service client file
contents = contents[start_index:]
return contents.encode('utf-8')

def assert_is_documented_as_autopopulated_param(
self, service_name, method_name, param_name, doc_string=None
):
Expand Down
17 changes: 17 additions & 0 deletions tests/functional/docs/test_s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,20 @@ def test_copy_source_param_docs_also_modified(self):
self.assert_contains_line(
"You can also provide this value as a dictionary", param_docs
)

def test_client_context_params_omitted(self):
contents = ServiceDocumenter(
's3', self._session, self.root_services_path
).document_service()
context_params_content = self.get_client_context_params_block(contents)
'Accelerate', 'ForcePathStyle'
self.assert_not_contains_line(
'* ``accelerate`` (boolean) - '
'Enables this client to use S3 Transfer Acceleration endpoints.',
context_params_content,
)
self.assert_not_contains_line(
'* ``force_path_style`` (boolean) - '
'Forces this client to use path-style addressing for buckets.',
context_params_content,
)
Loading

0 comments on commit 09b0cf1

Please sign in to comment.