-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to set blob metadata #1185
Comments
Setting the |
I modified the script: #!/usr/bin/env python3
import os
from gcloud import storage
client = storage.Client('dc-app-api')
bucket = client.get_bucket('appsemble-dev')
blob = bucket.blob('kirby.png')
with open(os.path.expanduser('~/Pictures/kirby.png'), 'rb') as img_data:
blob.upload_from_file(img_data)
blob.metadata = {'Color': 'Pink', 'Spam': 'Cheese'}
blob.metadata['Foo'] = 'Bar'
blob.patch() This sets the Also there is no documentation on the |
Thanks for reporting. Looking into it now. |
Ahhh. This is because the blob.metadata['Foo'] = 'Bar' updates the copy, not the dictionary actually stored on the @tseaver WDYT? |
To allow mutation of the |
Right. Custom |
Right, overriding:
|
A custom metadata = {'Holy': 'Grail'}
blob.metadata = metadata
metadata['Ministry'] = 'Silly Walks'
blob.patch() If the setter of |
I think this subclass could work if no setter is defined. An empty metadata object could be set in the |
The fact that the getter returns a copy is not set in stone. We did it to "protect" the integrity of the actual data own by the class, but didn't think through situations like this. We don't need a getter, but do need a setter to track changes on the object. Can't have a setter without a getter, so that's just how it's gotta be. (Also, all properties are stored on a non-public attribute called |
I suppose it could look something like this: class Metadata(dict):
def __init__(self, blob):
self._blob = blob
def __setitem__(self, key, value):
super(self, Metadata).__setitem__(key, value)
self._blob._patch_property('metadata', self)
# XXX Repeat pattern for other modifier functions
class Blob(_PropertyMixin):
...
def __init__(self, ...)
...
self._properties['metadata'] = Metadata(self)
@property
def metadata(self):
return self._properties['metadata'] This marks the metadata as modified if it gets edited and ensures the metadata can't be overridden using a setter. A side effect is that the metadata property is never |
blob.upload_from_file()
blob.metadata = {'luke': 'skywalker'}
blob.patch() worked for me. I was able to upload a file and apply the meta data after the file upload. |
@saxenanurag I'm in the middle of reviewing how we are using the ex- |
👍 What he said 😀 |
Thanks. |
I think this is a duplicate of #754. The use of metadata is a bit ambiguous as metadata refers to both the metadata of an object (such as Cache-Control) and the Anyway, to the issue. Any update? The problem with >>> text = bucket.blob('file.txt')
>>> text.cache_control = 'no-cache'
>>> text.upload_from_string('text')
>>> text.reload()
>>> text.cache_control
>>> text.metageneration
1
>>> text.cache_control = 'no-cache'
>>> text.patch()
>>> text.reload()
>>> text.cache_control
u'no-cache'
>>> text.metageneration
2 |
I've updated a previous patch, hack perhaps, which makes it work. It's not tested extensively. --- a/blob.py
+++ b/blob.py
@@ -494,6 +494,11 @@
# Configure the upload request parameters.
request = Request(upload_url, 'POST', headers)
+
+ if self._properties:
+ headers['content-type'] = 'application/json'
+ request.body = json.dumps(self._properties)
+
upload.configure_request(upload_config, request, url_builder)
# Configure final URL The file >>> text = bucket.blob('file.txt')
>>> text.cache_control = 'no-cache'
>>> text.metadata = {'custom': 'metadata'}
>>> text.upload_from_string('text')
>>> text.reload()
>>> text.cache_control
u'no-cache'
>>> text.metadata
{u'custom': u'metadata'}
>>> text.metageneration
1
>>> text.download_as_string()
'text' |
#3362 passes along all non-ACL blob properties with the (initial or only) upload request. |
You can work around this bug by creating a completely new dictionary, assigning it to blob.metadata, and doing blob.patch():
Your blob will now have the {'mynewproperty':'awesome'} metadata property in its stored metadata list on GCS. |
With patch() the metadata of a file is getting updated properly. But this has two operations,
Is there any option to upload the file along with its metadata? this should be a single step process |
@Prabakaran1410 You don't need to call |
I had some trouble getting this to work because the |
…loudPlatform/python-docs-samples#1185) * Add Snippet for Listing All Subscriptions in a Project * Fixed the failed tests on Kokoro classify_text_tutorial_test.py::test_query_text classify_text_tutorial_test.py::test_query_category
I am trying to set custom metadata on a blob. However, this does not work. I'm using the following script:
When retrieving the blob or inspecing it in the developer console, the metadata is still unset.
The text was updated successfully, but these errors were encountered: