Repository: aws/sagemaker-python-sdk

Issue:
OSError: [Errno 21] Is a directory. (On local Mode)
### System Information
- **Framework (e.g. TensorFlow) / Algorithm (e.g. KMeans)**: Tensorflow custom algorithm
- **Framework Version**: 1.4.1
- **Python Version**: 2.7
- **CPU or GPU**: CPU
- **Python SDK Version**: 1.5.0
- **Are you using a custom image**: No

### Describe the problem
I get `OSError: [Errno 21] Is a directory` when training locally on my machine(MacBook Pro). 
```
from sagemaker.tensorflow import TensorFlow

#Bucket location to save your custom code in tar.gz format.
custom_code_upload_location = 's3://sagemaker-<rest of bucket name>/customcode/tensorflow'

#Bucket location where results of model training are saved.
model_artifacts_location = 's3://sagemaker-<rest of bucket name>/artifacts'

role = "arn:aws:iam::****" # commented out

iris_estimator = TensorFlow(entry_point='sagemaker-test.py',
                            role=role,
                            output_path=model_artifacts_location,
                            code_location=custom_code_upload_location,
                            train_instance_count=1,
                            hyperparameters={'dropout_keep_prob': 0.5},
                            train_instance_type='local',
                            training_steps=1000,
                            evaluation_steps=10)

print (iris_estimator)

train_data_location = 's3://sagemaker-<rest of bucket name>'

iris_estimator.fit(train_data_location)

```

the custom algorithm `sagemaker-test.py` is created by following [this tutorial](https://docs.aws.amazon.com/sagemaker/latest/dg/tf-example1.html)

the above code is working in sagemaker notebook instance with `train_instance_type='ml.c4.xlarge'`, I am facing this issue only when running locally. 

### Minimal repro / logs
```
<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
```
Thanks in advance



Discussion:
hi @Shivakishore14, thanks for using SageMaker! `code_location` should point to a tarball, not a directory. Can you try compressing everything in `s3://sagemaker-<rest of bucket name>/customcode/tensorflow` into a tarball, uploading it to S3, and passing the path to that for `code_location` instead?

Resolving patch:
diff --git a/src/sagemaker/local/image.py b/src/sagemaker/local/image.py
--- a/src/sagemaker/local/image.py
+++ b/src/sagemaker/local/image.py
@@ -262,6 +262,9 @@ def _download_folder(self, bucket_name, prefix, target):
         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)


Test patch: