# Buggy code
def _download_folder(self, bucket_name, prefix, target):
    boto_session = self.sagemaker_session.boto_session

    s3 = boto_session.resource("s3")
    bucket = s3.Bucket(bucket_name)

    for obj_sum in bucket.objects.filter(Prefix=prefix):
        obj = s3.Object(obj_sum.bucket_name, obj_sum.key)
        s3_relative_path = obj_sum.key[len(prefix) :].lstrip("/")
        file_path = os.path.join(target, s3_relative_path)

        try:
            os.makedirs(os.path.dirname(file_path))
        except OSError as exc:
            if exc.errno != errno.EEXIST:
                raise
            pass
        obj.download_file(file_path)


# Traceback (OSError)
<sagemaker.tensorflow.estimator.TensorFlow object at 0x107b86610>
INFO:sagemaker:Creating training-job with name: sagemaker-tensorflow-2018-06-21-11-17-58-273
Traceback (most recent call last):
File "test.py", line 28, in <module>
iris_estimator.fit(train_data_location)
File "/Library/Python/2.7/site-packages/sagemaker/tensorflow/estimator.py", line 243, in fit
fit_super()
File "/Library/Python/2.7/site-packages/sagemaker/tensorflow/estimator.py", line 225, in fit_super
super(TensorFlow, self).fit(inputs, wait, logs, job_name)
File "/Library/Python/2.7/site-packages/sagemaker/estimator.py", line 177, in fit
self.latest_training_job = _TrainingJob.start_new(self, inputs)
File "/Library/Python/2.7/site-packages/sagemaker/estimator.py", line 362, in start_new
stop_condition=config['stop_condition'], tags=estimator.tags)
File "/Library/Python/2.7/site-packages/sagemaker/session.py", line 264, in train
self.sagemaker_client.create_training_job(**train_request)
File "/Library/Python/2.7/site-packages/sagemaker/local/local_session.py", line 75, in create_training_job
self.s3_model_artifacts = self.train_container.train(InputDataConfig, HyperParameters)
File "/Library/Python/2.7/site-packages/sagemaker/local/image.py", line 95, in train
volumes = self._prepare_training_volumes(data_dir, input_data_config, hyperparameters)
File "/Library/Python/2.7/site-packages/sagemaker/local/image.py", line 312, in _prepare_training_volumes
self._download_folder(bucket_name, key, channel_dir)
File "/Library/Python/2.7/site-packages/sagemaker/local/image.py", line 275, in _download_folder
obj.download_file(file_path)
File "/Library/Python/2.7/site-packages/boto3/s3/inject.py", line 314, in object_download_file
ExtraArgs=ExtraArgs, Callback=Callback, Config=Config)
File "/Library/Python/2.7/site-packages/boto3/s3/inject.py", line 172, in download_file
extra_args=ExtraArgs, callback=Callback)
File "/Library/Python/2.7/site-packages/boto3/s3/transfer.py", line 307, in download_file
future.result()
File "/Library/Python/2.7/site-packages/s3transfer/futures.py", line 73, in result
return self._coordinator.result()
File "/Library/Python/2.7/site-packages/s3transfer/futures.py", line 233, in result
raise self._exception
OSError: [Errno 21] Is a directory

# Fixed code
def _download_folder(self, bucket_name, prefix, target):
    boto_session = self.sagemaker_session.boto_session

    s3 = boto_session.resource("s3")
    bucket = s3.Bucket(bucket_name)

    for obj_sum in bucket.objects.filter(Prefix=prefix):
        # if obj_sum is a folder object skip it.
        if obj_sum.key != "" and obj_sum.key[-1] == "/":
            continue
        obj = s3.Object(obj_sum.bucket_name, obj_sum.key)
        s3_relative_path = obj_sum.key[len(prefix) :].lstrip("/")
        file_path = os.path.join(target, s3_relative_path)

        try:
            os.makedirs(os.path.dirname(file_path))
        except OSError as exc:
            if exc.errno != errno.EEXIST:
                raise
            pass
        obj.download_file(file_path)