pandas keyError "Retries" error while saving DataFrame to s3 in .csv format

Viewed 276

I'm getting a keyError while trying to save my dataframe to s3 in .csv format using .to_csv function of pandas. Versions of packages installed in python environment are listed below:

  • pandas: 1.3.4
  • botocore: 1.23.48
  • fsspec: 2022.1.0
  • s3fs: 2022.1.0

Complete error text is attached below. Let me know if you guys need any other information.

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_1428/656569756.py in <module>
----> 1 _df.iloc[:10].to_csv('s3://***confidential path***/{}/{}.csv'.format(d_i, d_i))

~\anaconda3\lib\site-packages\pandas\core\generic.py in to_csv(self, path_or_buf, sep, na_rep, float_format, columns, header, index, index_label, mode, encoding, compression, quoting, quotechar, line_terminator, chunksize, date_format, doublequote, escapechar, decimal, errors, storage_options)
   3464         )
   3465 
-> 3466         return DataFrameRenderer(formatter).to_csv(
   3467             path_or_buf,
   3468             line_terminator=line_terminator,

~\anaconda3\lib\site-packages\pandas\io\formats\format.py in to_csv(self, path_or_buf, encoding, sep, columns, index_label, mode, compression, quoting, quotechar, line_terminator, chunksize, date_format, doublequote, escapechar, errors, storage_options)
   1103             formatter=self.fmt,
   1104         )
-> 1105         csv_formatter.save()
   1106 
   1107         if created_buffer:

~\anaconda3\lib\site-packages\pandas\io\formats\csvs.py in save(self)
    235         """
    236         # apply compression and byte/text conversion
--> 237         with get_handle(
    238             self.filepath_or_buffer,
    239             self.mode,

~\anaconda3\lib\site-packages\pandas\io\common.py in get_handle(path_or_buf, mode, encoding, compression, memory_map, is_text, errors, storage_options)
    607 
    608     # open URLs
--> 609     ioargs = _get_filepath_or_buffer(
    610         path_or_buf,
    611         encoding=encoding,

~\anaconda3\lib\site-packages\pandas\io\common.py in _get_filepath_or_buffer(filepath_or_buffer, encoding, compression, mode, storage_options)
    356 
    357         try:
--> 358             file_obj = fsspec.open(
    359                 filepath_or_buffer, mode=fsspec_mode, **(storage_options or {})
    360             ).open()

~\anaconda3\lib\site-packages\fsspec\core.py in open(urlpath, mode, compression, encoding, errors, protocol, newline, **kwargs)
    454     ``OpenFile`` object.
    455     """
--> 456     return open_files(
    457         urlpath=[urlpath],
    458         mode=mode,

~\anaconda3\lib\site-packages\fsspec\core.py in open_files(urlpath, mode, compression, encoding, errors, name_function, num, protocol, newline, auto_mkdir, expand, **kwargs)
    297     if "r" not in mode and auto_mkdir:
    298         parents = {fs._parent(path) for path in paths}
--> 299         [fs.makedirs(parent, exist_ok=True) for parent in parents]
    300     return OpenFiles(
    301         [

~\anaconda3\lib\site-packages\fsspec\core.py in <listcomp>(.0)
    297     if "r" not in mode and auto_mkdir:
    298         parents = {fs._parent(path) for path in paths}
--> 299         [fs.makedirs(parent, exist_ok=True) for parent in parents]
    300     return OpenFiles(
    301         [

~\anaconda3\lib\site-packages\fsspec\asyn.py in wrapper(*args, **kwargs)
     89     def wrapper(*args, **kwargs):
     90         self = obj or args[0]
---> 91         return sync(self.loop, func, *args, **kwargs)
     92 
     93     return wrapper

~\anaconda3\lib\site-packages\fsspec\asyn.py in sync(loop, func, timeout, *args, **kwargs)
     69         raise FSTimeoutError from return_result
     70     elif isinstance(return_result, BaseException):
---> 71         raise return_result
     72     else:
     73         return return_result

~\anaconda3\lib\site-packages\fsspec\asyn.py in _runner(event, coro, result, timeout)
     23         coro = asyncio.wait_for(coro, timeout=timeout)
     24     try:
---> 25         result[0] = await coro
     26     except Exception as ex:
     27         result[0] = ex

~\anaconda3\lib\site-packages\s3fs\core.py in _makedirs(self, path, exist_ok)
    744     async def _makedirs(self, path, exist_ok=False):
    745         try:
--> 746             await self._mkdir(path, create_parents=True)
    747         except FileExistsError:
    748             if exist_ok:

~\anaconda3\lib\site-packages\s3fs\core.py in _mkdir(self, path, acl, create_parents, **kwargs)
    729                         "LocationConstraint": region_name
    730                     }
--> 731                 await self._call_s3("create_bucket", **params)
    732                 self.invalidate_cache("")
    733                 self.invalidate_cache(bucket)

~\anaconda3\lib\site-packages\s3fs\core.py in _call_s3(self, method, *akwarglist, **kwargs)
    279                 err = e
    280         err = translate_boto_error(err)
--> 281         raise err
    282 
    283     call_s3 = sync_wrapper(_call_s3)

~\anaconda3\lib\site-packages\s3fs\core.py in _call_s3(self, method, *akwarglist, **kwargs)
    259         for i in range(self.retries):
    260             try:
--> 261                 out = await method(**additional_kwargs)
    262                 return out
    263             except S3_RETRYABLE_ERRORS as e:

~\anaconda3\lib\site-packages\aiobotocore\client.py in _make_api_call(self, operation_name, api_params)
    171             http, parsed_response = event_response
    172         else:
--> 173             http, parsed_response = await self._make_request(
    174                 operation_model, request_dict, request_context)
    175 

~\anaconda3\lib\site-packages\aiobotocore\client.py in _make_request(self, operation_model, request_dict, request_context)
    191     async def _make_request(self, operation_model, request_dict, request_context):
    192         try:
--> 193             return await self._endpoint.make_request(operation_model, request_dict)
    194         except Exception as e:
    195             await self.meta.events.emit(

~\anaconda3\lib\site-packages\aiobotocore\endpoint.py in _send_request(self, request_dict, operation_model)
     79         success_response, exception = await self._get_response(
     80             request, operation_model, context)
---> 81         while await self._needs_retry(attempts, operation_model,
     82                                       request_dict, success_response,
     83                                       exception):

~\anaconda3\lib\site-packages\aiobotocore\endpoint.py in _needs_retry(self, attempts, operation_model, request_dict, response, caught_exception)
    211             service_id,
    212             operation_model.name)
--> 213         responses = await self._event_emitter.emit(
    214             event_name, response=response, endpoint=self,
    215             operation=operation_model, attempts=attempts,

~\anaconda3\lib\site-packages\aiobotocore\hooks.py in _emit(self, event_name, kwargs, stop_on_response)
     27                 response = await handler(**kwargs)
     28             else:
---> 29                 response = handler(**kwargs)
     30 
     31             responses.append((handler, response))

~\anaconda3\lib\site-packages\botocore\retryhandler.py in __call__(self, attempts, response, caught_exception, **kwargs)
    187         }
    188         if isinstance(self._checker, MaxAttemptsDecorator):
--> 189             retries_context = kwargs['request_dict']['context']['retries']
    190             checker_kwargs.update({'retries_context': retries_context})
    191 

KeyError: 'retries'
1 Answers

Context: I am running python code on AWS Sagemaker reading in data from S3 using pandas. Had the same issue as yourself.

It appears the KeyError is being raised due to an internal issue in the library aibotocore. This is an open issue as of now: Github

A potential work around is to pin the versions of the libraries as suggested on the thread. The exact set that worked for me was:

pip install pandas==1.2.5 --use-deprecated=legacy-resolver
pip install fsspec==2022.1.0 --use-deprecated=legacy-resolver
pip install s3fs==2022.1.0 --use-deprecated=legacy-resolver
pip install aiobotocore==2.1.0 --use-deprecated=legacy-resolver
pip install awscli==1.22.24 --use-deprecated=legacy-resolver
pip install boto3==1.20.24 --use-deprecated=legacy-resolver

Hope it works for you!

Related