'How to access file metadata, for files in google cloud storage, from a python google cloud function
I'm trying to access the custom metadata on a file in Google cloud storage from within a Cloud Function, but it always returns "None".
The file definitely has custom metadata on it - the custom metadata can be seen from the GCS browser.
I can access the custom metadata successfully if I run my code in a cloud shell environment.
But if I run the same code in a cloud function, then the returned blob.metadata is always "None".
What am I doing wrong? What do I have to do differently in a Cloud Function compared to a Cloud Shell.
from google.cloud import storage
client = storage.Client()
bucket = client.bucket(<my bucket name>)
blob = bucket.get_blob(<my filename>)
metadata = blob.metadata
Note also that blob.download_as_string() gets me the file contents correctly - it's just the custom metadata I can't get.
Solution 1:[1]
blob.metadata only returns Storage object's custom metadata (a dict). None means that there is no custom metadata. See the docs of metadata :
Retrieve arbitrary/application specific metadata for the object.
The documentation of Object resource (API) specify that metadata is :
User-provided metadata, in key/value pairs.
Note that custom metadata is different from fixed-key metadata, that you can also edit with Edit metadata button in Google Cloud Console. Fixed-key metadata contains :
- Content-Type
- Content-Encoding
- Content-Disposition
- Content-Language
- Cache-Control
This particular kind of metadata can be accessed via blob.content_type, blob.content_encoding, ... (check a complete example).
To add custom metadata, just click Add item button on the same window (Edit metadata) or use gsutil (see Editing object metadata docs) :
gsutil setmeta -h "x-goog-meta-examplekey:examplevalue" gs://<your-bucket>
Solution 2:[2]
In fact blob.metadata will not show the user metadata, you have to add blob.patch() and metadata will appear in blob.metadata variable
from google.cloud import storage
client = storage.Client()
bucket = client.bucket(<my bucket name>)
blob = bucket.get_blob(<my filename>)
blob.patch()
metadata = blob.metadata
To save user metadata, you can set blob.metadata and then call blob.patch to add or modify metadata, or blob.update to erase user metadata for this blob
Solution 3:[3]
Use blob.get_metadata, NOT blob.metadata
From the docs, blob.metadata does not make an HTTP request.
Solution 4:[4]
I ran into the same problem. But in my case, I have a trigger to run a cloud function whenever an object is created in a bucket. I needed to get the metadata as well using the code that you used, but it returns None as well.
I then changed the trigger to google.storage.object.metadataUpdate, so my Cloud Function would trigger whenever I set or update the metadata of an object. By doing that, I could get the metadata using the same code.
Solution 5:[5]
blob.reload() can be used to refresh metadata from upstream.
blob = storage.Blob("name", bucket=bucket)
blob.reload()
metadata: dict = blob.metadata
Reload properties from Cloud Storage.
https://googleapis.dev/python/storage/2.2.1/blobs.html#google.cloud.storage.blob.Blob.reload
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | Sabito 錆兎 stands with Ukraine |
| Solution 4 | jdb |
| Solution 5 | klden |
