Python 尝试使用Boto3从S3下载特定类型的文件-TypeError:预期为字符串或类似字节的对象

Python 尝试使用Boto3从S3下载特定类型的文件-TypeError:预期为字符串或类似字节的对象,python,amazon-s3,boto3,Python,Amazon S3,Boto3,我正试图从S3存储桶中只下载最新的.csv文件,但遇到了一个错误,上面写着“TypeError:预期的字符串或字节类型的对象。” 我目前有一个工作代码,用于识别上次修改的S3对象,对这些对象进行排序,并将它们放入名为latest\u files的列表中 session = boto3.Session() s3_resource = boto3.resource('s3') my_bucket = s3_resource.Bucket('chansbucket') get_last_modifi

我正试图从S3存储桶中只下载最新的.csv文件,但遇到了一个错误,上面写着“TypeError:预期的字符串或字节类型的对象。”

我目前有一个工作代码,用于识别上次修改的S3对象,对这些对象进行排序,并将它们放入名为
latest\u files
的列表中

session = boto3.Session()
s3_resource = boto3.resource('s3')
my_bucket = s3_resource.Bucket('chansbucket')

get_last_modified = lambda obj: int(obj.last_modified.strftime('%s'))

unsorted = []

# filters through the bucket and appends objects to the unsorted list
for file in my_bucket.objects.filter():
    unsorted.append(file)

# sorts last five files in unsorted by last modified time   
    latest_files = [obj.key for obj in sorted(unsorted, key=get_last_modified, reverse=True)][0:5]
现在我想循环浏览
最新的\u文件
,只下载那些以.csv结尾的文件

for file in latest_files:
    if file.endswith('.csv'):
        s3_resource.meta.client.download_file(my_bucket, file, '/Users/mikechan/projects/TT_product_analyses/raw_csv_files/' + file)
这里是我得到错误的地方
TypeError:expected string或bytes-like-object

以下是回溯:

    ---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-27-ca90c5ad9c53> in <module>()
      1 for file in latest_files:
      2     if file.endswith('.csv'):
----> 3         s3_resource.meta.client.download_file(my_bucket, str(file), '/Users/mikechan/projects/TT_product_analyses/raw_csv_files/' + str(file))
      4 
      5 

~/anaconda/lib/python3.6/site-packages/boto3/s3/inject.py in download_file(self, Bucket, Key, Filename, ExtraArgs, Callback, Config)
    170         return transfer.download_file(
    171             bucket=Bucket, key=Key, filename=Filename,
--> 172             extra_args=ExtraArgs, callback=Callback)
    173 
    174 

~/anaconda/lib/python3.6/site-packages/boto3/s3/transfer.py in download_file(self, bucket, key, filename, extra_args, callback)
    305             bucket, key, filename, extra_args, subscribers)
    306         try:
--> 307             future.result()
    308         # This is for backwards compatibility where when retries are
    309         # exceeded we need to throw the same error from boto3 instead of

~/anaconda/lib/python3.6/site-packages/s3transfer/futures.py in result(self)
     71             # however if a KeyboardInterrupt is raised we want want to exit
     72             # out of this and propogate the exception.
---> 73             return self._coordinator.result()
     74         except KeyboardInterrupt as e:
     75             self.cancel()

~/anaconda/lib/python3.6/site-packages/s3transfer/futures.py in result(self)
    231         # final result.
    232         if self._exception:
--> 233             raise self._exception
    234         return self._result
    235 

~/anaconda/lib/python3.6/site-packages/s3transfer/tasks.py in _main(self, transfer_future, **kwargs)
    253             # Call the submit method to start submitting tasks to execute the
    254             # transfer.
--> 255             self._submit(transfer_future=transfer_future, **kwargs)
    256         except BaseException as e:
    257             # If there was an exception raised during the submission of task

~/anaconda/lib/python3.6/site-packages/s3transfer/download.py in _submit(self, client, config, osutil, request_executor, io_executor, transfer_future, bandwidth_limiter)
    351                 Bucket=transfer_future.meta.call_args.bucket,
    352                 Key=transfer_future.meta.call_args.key,
--> 353                 **transfer_future.meta.call_args.extra_args
    354             )
    355             transfer_future.meta.provide_transfer_size(

~/.local/lib/python3.6/site-packages/botocore/client.py in _api_call(self, *args, **kwargs)
    318                     "%s() only accepts keyword arguments." % py_operation_name)
    319             # The "self" in this scope is referring to the BaseClient.
--> 320             return self._make_api_call(operation_name, kwargs)
    321 
    322         _api_call.__name__ = str(py_operation_name)

~/.local/lib/python3.6/site-packages/botocore/client.py in _make_api_call(self, operation_name, api_params)
    594         }
    595         request_dict = self._convert_to_request_dict(
--> 596             api_params, operation_model, context=request_context)
    597 
    598         service_id = self._service_model.service_id.hyphenize()

~/.local/lib/python3.6/site-packages/botocore/client.py in _convert_to_request_dict(self, api_params, operation_model, context)
    628                                  context=None):
    629         api_params = self._emit_api_params(
--> 630             api_params, operation_model, context)
    631         request_dict = self._serializer.serialize_to_request(
    632             api_params, operation_model)

~/.local/lib/python3.6/site-packages/botocore/client.py in _emit_api_params(self, api_params, operation_model, context)
    658                 service_id=service_id,
    659                 operation_name=operation_name),
--> 660             params=api_params, model=operation_model, context=context)
    661         return api_params
    662 

~/.local/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):

~/.local/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):

~/.local/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:

~/.local/lib/python3.6/site-packages/botocore/handlers.py in validate_bucket_name(params, **kwargs)
    216         return
    217     bucket = params['Bucket']
--> 218     if VALID_BUCKET.search(bucket) is None:
    219         error_msg = (
    220             'Invalid bucket name "%s": Bucket name must match '

TypeError: expected string or bytes-like object
---------------------------------------------------------------------------
TypeError回溯(最近一次调用上次)
在()
1对于最新\u文件中的文件:
2如果文件.endswith('.csv'):
---->3 s3_resource.meta.client.下载文件(my_bucket,str(文件),'/Users/mikechan/projects/TT_product_analysis/raw_csv_files/'+str(文件))
4.
5.
下载文件中的~/anaconda/lib/python3.6/site-packages/boto3/s3/inject.py(self、Bucket、Key、Filename、ExtraArgs、Callback、Config)
170 return transfer.download_文件(
171 bucket=bucket,key=key,filename=filename,
-->172额外参数=额外参数,回调=回调)
173
174
下载文件中的~/anaconda/lib/python3.6/site-packages/boto3/s3/transfer.py(self、bucket、key、filename、额外参数、回调)
305存储桶、密钥、文件名、额外参数、订阅者)
306尝试:
-->307.未来结果()
308#这是为了向后兼容,重试时
309超出我们需要从boto3而不是从
~/anaconda/lib/python3.6/site-packages/s3transfer/futures.py输入结果(self)
71#但是,如果引发键盘中断,我们希望退出
72#在这一点上,提出例外。
--->73返回自协调者结果()
74键盘中断除外,如e:
75.自我取消
~/anaconda/lib/python3.6/site-packages/s3transfer/futures.py输入结果(self)
231#最终结果。
232如果为自身,则为例外情况:
-->233自我提升。\u例外情况
234返回自我。\u结果
235
主界面中的~/anaconda/lib/python3.6/site-packages/s3transfer/tasks.py(self,transfer\u future,**kwargs)
253#调用submit方法开始提交任务以执行
254#转移。
-->255自我提交(转移未来=转移未来,**kwargs)
256除BaseException外的e:
257#如果在提交任务期间出现异常
~/anaconda/lib/python3.6/site-packages/s3transfer/download.py in\u submit(self、client、config、osutil、request\u executor、io\u executor、transfer\u future、带宽限制器)
351 Bucket=transfer\u future.meta.call\u args.Bucket,
352 Key=transfer\u future.meta.call\u args.Key,
-->353**transfer\u future.meta.call\u args.extra\u args
354             )
355传输\u future.meta.提供\u传输\u大小(
调用中的~/.local/lib/python3.6/site-packages/botocore/client.py(self,*args,**kwargs)
318“%s()只接受关键字参数。“%py\u操作\u名称)
319#此范围中的“自我”指的是BaseClient。
-->320返回self.\u make\u api\u调用(操作名称,kwargs)
321
322\u api\u调用。\u名称\u=str(py\u操作\u名称)
~/.local/lib/python3.6/site-packages/botocore/client.py in\u make\u api\u调用(self、operation\u name、api\u参数)
594         }
595请求\u dict=self.\u将\u转换为\u请求\u dict(
-->596 api参数,操作模型,上下文=请求上下文)
597
598服务\u id=self.\u服务\u model.service\u id.hyphenize()
~/.local/lib/python3.6/site-packages/botocore/client.py in\u convert\u to\u request\u dict(self、api参数、操作模型、上下文)
628上下文=无):
629 api_参数=self._emit_api_参数(
-->630 api_参数、操作_模型、上下文)
631 request\u dict=self.\u serializer.serialize\u to\u request(
632 api_参数,操作模式)
~/.local/lib/python3.6/site-packages/botocore/client.py in\u emit\u api\u参数(self、api\u参数、操作模型、上下文)
658服务id=服务id,
659操作名称=操作名称),
-->660参数=api参数,模型=操作(模型,上下文=上下文)
661返回api_参数
662
emit中的~/.local/lib/python3.6/site-packages/botocore/hooks.py(self,event_name,**kwargs)
354 def发射(自身,事件名称,**kwargs):
355别名事件名称=自身。别名事件名称(事件名称)
-->356返回self.\u emitter.emit(别名为\u事件\u名称,**kwargs)
357
358 def发射直到响应(自身、事件名称、**kwargs):
emit中的~/.local/lib/python3.6/site-packages/botocore/hooks.py(self,event_name,**kwargs)
226人。
227         """
-->228返回自发出(事件名称,kwargs)
229
230 def发射直到响应(自身、事件名称,**kwargs):
~/.local/lib/python3.6/site-packages/botocore/hooks.py in\u emit(self、event\u name、kwargs、stop\u on\u response)
209对于处理程序中的处理程序\u到\u调用:
210 logger.debug('事件%s:调用处理程序%s',事件名称,处理程序)
-->211响应=处理程序(**kwargs)
212响应。追加((处理程序,响应))
213如果stop_on_响应且响应不是None:
验证桶名称中的~/.local/lib/python3.6/site-packages/botocore/handlers.py(参数,**kwargs)
216返回
217桶=参数
s3_resource.meta.client.download_file(my_bucket, file, '/Users/mikechan/projects/TT_product_analyses/raw_csv_files/' + file)
my_bucket = s3_resource.Bucket('chansbucket')
s3.meta.client.download_file('mybucket', 'hello.txt', '/tmp/hello.txt')