Repository: googleapis/google-cloud-python

Issue:
Account for existing objects in bucket when using storage.bucket.Bucket.upload_file
From TODO:

``` python
    # TODO: What do we do about overwriting data?
```

See [`storage.bucket.Bucket.upload_file`](https://github.com/GoogleCloudPlatform/gcloud-python/blob/1f2aaf3606802f4f02eeb30e22e1082ef7f4594e/gcloud/storage/bucket.py#L201) for relevant code and #146 for some context.

`git blame` output

```
b7f1b774 (JJ Geewax   2014-01-29 18:02:29 -0500 201)     # TODO: What do we do about overwriting data?
```

Account for existing objects in bucket when using storage.bucket.Bucket.upload_file
From TODO:

``` python
    # TODO: What do we do about overwriting data?
```

See [`storage.bucket.Bucket.upload_file`](https://github.com/GoogleCloudPlatform/gcloud-python/blob/1f2aaf3606802f4f02eeb30e22e1082ef7f4594e/gcloud/storage/bucket.py#L201) for relevant code and #146 for some context.

`git blame` output

```
b7f1b774 (JJ Geewax   2014-01-29 18:02:29 -0500 201)     # TODO: What do we do about overwriting data?
```



Discussion:
It's possible there is an API feature to only write if doesn't exist (though race conditions may make this a PITA). May also be worth requesting from API eng team?

Once support for the `lifecycle` field of the bucket resource lands (see #314), this issue will resolve:  buckets with no `lifecycle` defined will overwrite without checking for existing objects, while those with `lifecycle` policies will obey them (generations, etc.).

See the [lifecycle spec](https://cloud.google.com/storage/docs/lifecycle) for notes on configuring the bucket's `lifecycle` policy.

The lifecycle rules for number of versions will only be effective if [object versioning](https://cloud.google.com/storage/docs/object-versioning) is enabled on the bucket.  Currently, we can enable this via:

```
self.patch_metadata({'versioning': {'enabled': True})
```

#314 proposes adding more direct support for the `versioning` and `lifecycle` fields (along with others).

It's possible there is an API feature to only write if doesn't exist (though race conditions may make this a PITA). May also be worth requesting from API eng team?

Once support for the `lifecycle` field of the bucket resource lands (see #314), this issue will resolve:  buckets with no `lifecycle` defined will overwrite without checking for existing objects, while those with `lifecycle` policies will obey them (generations, etc.).

See the [lifecycle spec](https://cloud.google.com/storage/docs/lifecycle) for notes on configuring the bucket's `lifecycle` policy.

The lifecycle rules for number of versions will only be effective if [object versioning](https://cloud.google.com/storage/docs/object-versioning) is enabled on the bucket.  Currently, we can enable this via:

```
self.patch_metadata({'versioning': {'enabled': True})
```

#314 proposes adding more direct support for the `versioning` and `lifecycle` fields (along with others).


Resolving patch:
diff --git a/gcloud/storage/key.py b/gcloud/storage/key.py
--- a/gcloud/storage/key.py
+++ b/gcloud/storage/key.py
@@ -214,6 +214,18 @@ def upload_from_file(self, file_obj, rewind=False, size=None,
                          content_type=None):
         """Upload the contents of this key from a file-like object.
 
+        .. note::
+
+           The effect of uploading to an existing key depends on the
+           "versioning" and "lifecycle" policies defined on the key's
+           bucket.  In the absence of those policies, upload will
+           overwrite any existing contents.
+
+           See the `object versioning
+           <https://cloud.google.com/storage/docs/object-versioning>`_ and
+           `lifecycle <https://cloud.google.com/storage/docs/lifecycle>`_
+           API documents for details.
+
         :type file_obj: file
         :param file_obj: A file handle open for reading.
 
@@ -276,6 +288,18 @@ def upload_from_file(self, file_obj, rewind=False, size=None,
     def upload_from_filename(self, filename):
         """Upload this key's contents from the content of f named file.
 
+        .. note::
+
+           The effect of uploading to an existing key depends on the
+           "versioning" and "lifecycle" policies defined on the key's
+           bucket.  In the absence of those policies, upload will
+           overwrite any existing contents.
+
+           See the `object versioning
+           <https://cloud.google.com/storage/docs/object-versioning>`_ and
+           `lifecycle <https://cloud.google.com/storage/docs/lifecycle>`_
+           API documents for details.
+
         :type filename: string
         :param filename: The path to the file.
         """
@@ -290,6 +314,18 @@ def upload_from_filename(self, filename):
     def upload_from_string(self, data, content_type='text/plain'):
         """Upload contents of this key from the provided string.
 
+        .. note::
+
+           The effect of uploading to an existing key depends on the
+           "versioning" and "lifecycle" policies defined on the key's
+           bucket.  In the absence of those policies, upload will
+           overwrite any existing contents.
+
+           See the `object versioning
+           <https://cloud.google.com/storage/docs/object-versioning>`_ and
+           `lifecycle <https://cloud.google.com/storage/docs/lifecycle>`_
+           API documents for details.
+
         :type data: string
         :param data: The data to store in this key.
 


Test patch: