将 boto 客户端参数作为变量传递

passing boto client parameters as variables

我有下面的 boto3 脚本。我将访问密钥和秘密密钥传递给它。然后它启动列表中的每个爬虫。如果我将访问密钥和秘密密钥作为变量传递给它,它会抛出以下错误。如果我实际上在 boto3.client 中输入访问密钥和秘密密钥,它就可以工作。有谁知道问题可能是什么以及如何解决?

代码:

### Works ####
glue_assumed_client = boto3.client(
                    'glue',
                    region_name='us-west-2',
                    aws_access_key_id='xxxx',
                                       aws_secret_access_key= 'xxx/yyyy'
                                       )

crwlr_lst=['v2metrc_disp','v2metrc_invent']
for i in crwlr_lst:


    response = glue_assumed_client.start_crawler(Name = i)



### Fails ###
access_key='xxxx',
access_secret= 'xxx/yyyy'
glue_assumed_client = boto3.client(
                    'glue',
                    region_name='us-west-2',
                    aws_access_key_id=access_key,
                                       aws_secret_access_key= access_secret
                                       )

crwlr_lst=['v2metrc_disp','v2metrc_invent']
for i in crwlr_lst:


    response = glue_assumed_client.start_crawler(Name = i)



error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-23-d720f9fd9d98> in <module>
     15 
     16 
---> 17     response = glue_assumed_client.start_crawler(Name = i)

/anaconda3/envs/py36/lib/python3.6/site-packages/botocore/client.py in _api_call(self, *args, **kwargs)
    355                     "%s() only accepts keyword arguments." % py_operation_name)
    356             # The "self" in this scope is referring to the BaseClient.
--> 357             return self._make_api_call(operation_name, kwargs)
    358 
    359         _api_call.__name__ = str(py_operation_name)

/anaconda3/envs/py36/lib/python3.6/site-packages/botocore/client.py in _make_api_call(self, operation_name, api_params)
    646         else:
    647             http, parsed_response = self._make_request(
--> 648                 operation_model, request_dict, request_context)
    649 
    650         self.meta.events.emit(

/anaconda3/envs/py36/lib/python3.6/site-packages/botocore/client.py in _make_request(self, operation_model, request_dict, request_context)
    665     def _make_request(self, operation_model, request_dict, request_context):
    666         try:
--> 667             return self._endpoint.make_request(operation_model, request_dict)
    668         except Exception as e:
    669             self.meta.events.emit(

/anaconda3/envs/py36/lib/python3.6/site-packages/botocore/endpoint.py in make_request(self, operation_model, request_dict)
    100         logger.debug("Making request for %s with params: %s",
    101                      operation_model, request_dict)
--> 102         return self._send_request(request_dict, operation_model)
    103 
    104     def create_request(self, params, operation_model=None):

/anaconda3/envs/py36/lib/python3.6/site-packages/botocore/endpoint.py in _send_request(self, request_dict, operation_model)
    130     def _send_request(self, request_dict, operation_model):
    131         attempts = 1
--> 132         request = self.create_request(request_dict, operation_model)
    133         context = request_dict['context']
    134         success_response, exception = self._get_response(

/anaconda3/envs/py36/lib/python3.6/site-packages/botocore/endpoint.py in create_request(self, params, operation_model)
    114                 op_name=operation_model.name)
    115             self._event_emitter.emit(event_name, request=request,
--> 116                                      operation_name=operation_model.name)
    117         prepared_request = self.prepare_request(request)
    118         return prepared_request

/anaconda3/envs/py36/lib/python3.6/site-packages/botocore/hooks.py in emit(self, event_name, **kwargs)
    354     def emit(self, event_name, **kwargs):
    355         aliased_event_name = self._alias_event_name(event_name)
--> 356         return self._emitter.emit(aliased_event_name, **kwargs)
    357 
    358     def emit_until_response(self, event_name, **kwargs):

/anaconda3/envs/py36/lib/python3.6/site-packages/botocore/hooks.py in emit(self, event_name, **kwargs)
    226                  handlers.
    227         """
--> 228         return self._emit(event_name, kwargs)
    229 
    230     def emit_until_response(self, event_name, **kwargs):

/anaconda3/envs/py36/lib/python3.6/site-packages/botocore/hooks.py in _emit(self, event_name, kwargs, stop_on_response)
    209         for handler in handlers_to_call:
    210             logger.debug('Event %s: calling handler %s', event_name, handler)
--> 211             response = handler(**kwargs)
    212             responses.append((handler, response))
    213             if stop_on_response and response is not None:

/anaconda3/envs/py36/lib/python3.6/site-packages/botocore/signers.py in handler(self, operation_name, request, **kwargs)
     88         # this method is invoked to sign the request.
     89         # Don't call this method directly.
---> 90         return self.sign(operation_name, request)
     91 
     92     def sign(self, operation_name, request, region_name=None,

/anaconda3/envs/py36/lib/python3.6/site-packages/botocore/signers.py in sign(self, operation_name, request, region_name, signing_type, expires_in, signing_name)
    155                     raise e
    156 
--> 157             auth.add_auth(request)
    158 
    159     def _choose_signer(self, operation_name, signing_type, context):

/anaconda3/envs/py36/lib/python3.6/site-packages/botocore/auth.py in add_auth(self, request)
    369         logger.debug('Signature:\n%s', signature)
    370 
--> 371         self._inject_signature_to_request(request, signature)
    372 
    373     def _inject_signature_to_request(self, request, signature):

/anaconda3/envs/py36/lib/python3.6/site-packages/botocore/auth.py in _inject_signature_to_request(self, request, signature)
    372 
    373     def _inject_signature_to_request(self, request, signature):
--> 374         l = ['AWS4-HMAC-SHA256 Credential=%s' % self.scope(request)]
    375         headers_to_sign = self.headers_to_sign(request)
    376         l.append('SignedHeaders=%s' % self.signed_headers(headers_to_sign))

/anaconda3/envs/py36/lib/python3.6/site-packages/botocore/auth.py in scope(self, request)
    322         scope.append(self._service_name)
    323         scope.append('aws4_request')
--> 324         return '/'.join(scope)
    325 
    326     def credential_scope(self, request):

TypeError: sequence item 0: expected str instance, tuple found

问题出在变量声明后的逗号上:

### Fails ###
access_key='xxxx',
#                ^ this is the problem

你需要删除它所以它是这样的:

### Fails ###
access_key='xxxx'
#                ^ no comma here

有了逗号,你就把 access_key 变成了一个元组,而它应该只是一个字符串。