google-cloud-python: Unable to set blob metadata
I am trying to set custom metadata on a blob. However, this does not work. I’m using the following script:
#!/usr/bin/env python3
import os
from gcloud import storage
client = storage.Client('super secret id')
bucket = client.get_bucket('super secret bucket')
blob = bucket.blob('kirby.png')
blob.metadata = dict(Color='Pink')
with open(os.path.expanduser('~/Pictures/kirby.png'), 'rb') as img_data:
blob.upload_from_file(img_data)
When retrieving the blob or inspecing it in the developer console, the metadata is still unset.
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Comments: 22 (11 by maintainers)
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
metadataproperty, meant for custom metadata.Anyway, to the issue. Any update? The problem with
patchis that the object is online briefly with wrong metadata, or less briefly in case of a connection failure between two requests. And, it increasesmetageneration.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.
I had some trouble getting this to work because the
metadatawas alwaysNone(even though I manually added values via the Storage UI). Later I realized I was usingbucket.blob("name")rather thanbucket.get_blob("name")so the metadata hadn’t been loaded. Might help someone else.I’ve updated a previous patch, hack perhaps, which makes it work. It’s not tested extensively.
The file
google/cloud/storage/blob.pyis located in your Pythonsite-packagesdirectory.worked for me. I was able to upload a file and apply the meta data after the file upload.
@Prabakaran1410 You don’t need to call
patchon the blob after upload: since PR #3362, all properties assigned to the blob before upload are passed through.@saxenanurag I’m in the middle of reviewing how we are using the ex-
apitoolscode (now ingcloud.streaming), and can see how we should be able to send the patched metadata along with the upload request.Setting the
metadatalocally does not cause the instance to make the API call to patch it on the server, and we don’t send metadata along with theupload_from_file()call. You need to add a call toblob.patch()to persist the changes toblob.metadata.