I am uploading a photo to blobstore using plupload. The BlobInfo object has some metadata
content_type: The content type of the blob.
creation: The creation date of the blob, or when it was uploaded.
filename: The file name that the user selected from their machine.
size: The size of the uncompressed blob.
md5_hash: The MD5 hash value of the uploaded blob.
My question is how can I get the other metadata of the photo either from plupload or serverside? Specifically, there is a metadata field of "description" that I need to retrieve.
I would use exif-py as follows:
blob_reader = blobstore.BlobReader(blob_key)
blob_reader_data = StringIO.StringIO(blob_reader.read())
tags = exifread.process_file(blob_reader_data)
the tags object it returns contain the metadata you're looking for.
Related
I'm currently using the Azure Blob Storage SDK for Python. For my project I want to read/load the data from a specific blob without having to download it / store it on disk before accessing.
According to the documentation loading a specfic blob works for my with:
blob_client = BlobClient(blob_service_client.url,
container_name,
blob_name,
credential)
data_stream = blob_client.download_blob()
data = data_stream.readall()
The last readall() command returns me the byte information of the blob content (in my case a image).
With:
with open(loca_path, "wb") as local_file:
data_stream.readinto(my_blob)
it is possible to save the blob content on disk (classic downloading operation)
BUT:
Is it also possible to convert the byte data from data = data_stream.readall() directly into an image?
It already tried image_data = Image.frombytes(mode="RGB", data=data, size=(1080, 1920))
but it returns me an error not enough image data
Here is the sample code for reading the text without downloading the file.
from azure.storage.blob import BlockBlobService, PublicAccess
accountname="xxxx"
accountkey="xxxx"
blob_service_client = BlockBlobService(account_name=accountname,account_key=accountkey)
container_name="test2"
blob_name="a5.txt"
#get the length of the blob file, you can use it if you need a loop in your code to read a blob file.
blob_property = blob_service_client.get_blob_properties(container_name,blob_name)
print("the length of the blob is: " + str(blob_property.properties.content_length) + " bytes")
print("**********")
#get the first 10 bytes data
b1 = blob_service_client.get_blob_to_text(container_name,blob_name,start_range=0,end_range=10)
#you can use the method below to read stream
#blob_service_client.get_blob_to_stream(container_name,blob_name,start_range=0,end_range=10)
print(b1.content)
print("*******")
#get the next range of data
b2=blob_service_client.get_blob_to_text(container_name,blob_name,start_range=10,end_range=50)
print(b2.content)
print("********")
#get the next range of data
b3=blob_service_client.get_blob_to_text(container_name,blob_name,start_range=50,end_range=200)
print(b3.content)
For complete information you can check the document with Python libraries.
Cloud Function will triggered once a file gets uploaded in the storage,
My File Name : PubSubMessage.
Inside Text : Hi, this this the first message
from google.cloud import storage
storage_client = storage.Client()
def hello_gcs(event, context):
file = event
bucket = storage_client.get_bucket(file['bucket'])
blob = bucket.blob(file['name'])
contents = blob.download_as_string()
print('contents: {}'.format(contents))
decodedstring = contents.decode(encoding="utf-8", errors="ignore")
print('decodedstring: \n{}'.format(decodedstring))
print('decodedstring: \n{}'.format(decodedstring))
------WebKitFormBoundaryAWAKqDaYZB3fJBhx
Content-Disposition: form-data; name="file"; filename="PubSubMessage.txt"
Content-Type: text/plain
Hi, this this the first line.
Hi ,this is the second line.
hi this is the space after.
------WebKitFormBoundaryAWAKqDaYZB3fJBhx--
My Requirements.txt file
google-cloud-storage
requests==2.20.0
requests-toolbelt==0.9.1
How do i get the actual string inside the file "Hi, I am the first message....." ?
What is the best possible way to get the text from a file?
TIA
The string you read from Google Storage is a string representation of a multipart form. It contains not only the uploaded file contents but also some metadata. The same kind of request may be used to represent more than one file and/or form fields along with a file.
To access the file contents you want, you can use a library which supports that, such as requests-toolbelt. Check out this SO answer for an example. You'll need the Content-Type header, which includes the boundary, or to manually parse the boundary just from the content, if you absolutely must.
EDIT: from your answer, it seems that the Content-Type header was available in the Storage Metadata in Google Storage, which is a common scenario. For future readers of this answer, the specifics of where to read this header from will depend on your particular case.
Since this library is present in PyPI (the Python Package Index), you can use it even in Cloud Functions by specifying it as a dependency in the requirements.txt file.
Below Code will print the actual text present inside a file.
from requests_toolbelt.multipart import decoder
from google.cloud import storage
storage_client = storage.Client()
def hello_gcs(event, context):
file = event
bucket = storage_client.bucket(file['bucket'])
#print('Bucket Name : {}'.format(file['bucket']))
#print('Object Name : {}'.format(file['name']))
#print('Bucket Object : {}'.format(bucket))
blob = bucket.get_blob(file['name'])
#print('Blob Object : {}'.format(blob))
contentType = blob.content_type
print('Blob ContentType: {}'.format(contentType))
#To download the file as byte object
content = blob.download_as_string()
print('content: {}'.format(content))
for part in decoder.MultipartDecoder(content, contentType).parts:
print(part.text)
I want to get a list of uploaded photos by using: photos = request.files.getlist("photo"). However, if I haven't selected any files in the browser, the photos value is not empty like other fields.
I want to check if no files are submitted by doing:
if not photos:
pass
But there's always an empty FileStorage object even when no files are submitted:
request.files.getlist("photo")
[<FileStorage: '' ('application/octet-stream')>]
Why is it there? How can I check that no files were uploaded if the list is never empty?
request.files is populated with whatever the client submitted. Unfortunately, browsers submit file inputs even when no file is selected, which looks like a file with no name and no data. Neither a name or data is required to have a valid empty file, so it's left up to the app to decide what to do.
FileStorage will be considered False if it has no name. Flask-WTF considers a FileStorage with no name to be empty for validation.
photo = request.files["photo"]
if not photo:
# no photo
photos = request.files["photo"].getlist()
if not photos or not any(f for f in photos):
# no photos
Regarding Empty File Storage Object, means if File field is left empty while submitting form and you are getting a empty file storage object ,and want to filter it.you can apply the below mentioned check.
if not (all(isinstance(item, FileStorage) for item in field.data) and
field.data and all((item.filename != '') for item in field.data)):
return
for no files uploaded, FileStorage objects filename attribute is like field.data.file.filename = '', so that we can filter it based on this condition.
I am using the Dropbox API Explorer - get_thumbnail to get a thumbnail of images stored following the get_thumbnail documentation
The response returns a blob in binary. I am attempting to create a image file to store as an imagefield on my django app's database.
I followed this Quickstart to create the image.
# get_thumbnail request
url = "https://content.dropboxapi.com/2/files/get_thumbnail"
# product_path is a variable storing path from list_folder
new_product_path = "{\"path\":\"/%s\"}" %(product_path)
headers = {
"Authorization": "Bearer <api_token_ommitted>",
"Dropbox-API-Arg": new_product_path
}
r = requests.post(url, headers=headers)
thumbnail = Image.open(BytesIO(r.content))
# album is foreign key for Album model
product = Product.objects.create(album=album, name=converted_name, image=converted_url, thumbnail=thumbnail)
print('Product has been created!')
The results of print(r.content):
b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00C\x00\x06\x04\x05\x06\x05\x04\x06\x06\x05\x06\x07\x07\x06\x08\n\x10\n\n\t\t\n\x14\x0e\x0f\x0c\x10\x17\x14\x18\x18\x17\x14\x16\x16\x1a\x1d%\x1f\x1a\x1b#\x1c\x16\x16 , #&\')*)\x19\x1f-0-(0%()(\xff\xdb\x00C\x01\x07\x07\x07\n\x08\n\x13\n\n\x13(\x1a\x16\x1a((((((((((((((((((((((((((((((((((((((((((((((((((\xff\xc0\x00\x11\x08\x00$\x00#\x03\x01"\x00\x02\x11\x01\x03\x11\x01\xff\xc4\x00\x1f\x00\x00\x01\x05\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\xff\xc4\x00\xb5\x10\x00\x02\x01\x03\x03\x02\x04\x03\x05\x05\x04\x04\x00\x00\x01}\x01\x02\x03\x00\x04\x11\x05\x12!1A\x06\x13Qa\x07"q\x142\x81\x91\xa1\x08#B\xb1\xc1\x15R\xd1\xf0$3br\x82\t\n\x16\x17\x18\x19\x1a%&\'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz\x83\x84\x85\x86\x87\x88\x89\x8a\x92\x93\x94\x95\x96\x97\x98\x99\x9a\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xff\xc4\x00\x1f\x01\x00\x03\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\xff\xc4\x00\xb5\x11\x00\x02\x01\x02\x04\x04\x03\x04\x07\x05\x04\x04\x00\x01\x02w\x00\x01\x02\x03\x11\x04\x05!1\x06\x12AQ\x07aq\x13"2\x81\x08\x14B\x91\xa1\xb1\xc1\t#3R\xf0\x15br\xd1\n\x16$4\xe1%\xf1\x17\x18\x19\x1a&\'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x92\x93\x94\x95\x96\x97\x98\x99\x9a\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xff\xda\x00\x0c\x03\x01\x00\x02\x11\x03\x11\x00?\x00\xfa\x16\x8a\xc3_\x15h\xcd\x1c\x8c\xb7\xa8v\x9cm\xc1\x05\xbe\x80\xf5\xa7\xc3\xe2m\x1eB\xa0\xea6\xf1\x92\xa5\xb1+l \x0e\xb9\'\x8f\xd6\xbc\xa5R\r\xd93\xdcxj\xd1Wp\x7fs6h\xacx|K\xa2L3\x0e\xabg \xeb\xf2\xc9\x9a\xcd\xd6|w\xa3i\x9at\xd7m$\xb3\xac\\\x95\x8a2I\xa6\xe7\x14\xec\xd8G\rZ[A\xfd\xc7UEs\xd6\x9e0\xd1n,\x92\xe5\xaf\x16\x10\xc8\x1fd\xa0\x86\xc7\xb0\xefV-\xfcO\xa2\xcd\x07\x9a\xba\x9d\xa0PpCH\x14\x83\xee\x0f\xf3\xe9B\x9c_Pxj\xd1\xde\x0f\xeef\xcd\x15\x917\x894h#2j\x96x<\xe5d\r\xc7\xe1\x9ab\xf8\xa7B.\xe85{-\xeb\xc1\x1eg"\x9d\xd1>\xc2\xae\xfc\xaf\xeeg\xc2\xd3^\xddN\x00\x9a\xe2g\x00`\x06rq#\xbc\xb8\xe33\xc8p0>c\xd3\xd2\xa0\xa2\xbd\xbeT\xba\x18\xacMT\xef\xcc\xfe\xf3F\xcbX\xbb\xb4\x04C)Q\x90\xdcz\xd5\xa4\xf1>\xa6\xa1\xc7\xda\\\xab\x8c2\x93\xc1\xe75\x89EC\xa5\x07\xbaGB\xcc\xb1)[\x98\xd9\xb9\xf1\r\xf5\xc3\xc7#\xce\xfb\xd3\xa6\x0e1U\xe7\xd6/\'bd\x99\xc9 \x83\xcfPz\xd6u\x14\xd5(-\x90\xdeg\x89\x7fh\xb35\xed\xc4\xbc4\xcf\x8fL\xd4+,\x8ar\xae\xc0\xe7<\x1ae\x15VH\xe6\x9e&\xac\xdf4\xa4\xc2\x8a(\xa6b\x14QE\x00\x14QE\x00\x14QE\x00\x7f\xff\xd9'
I have tried to convert bytes data to image as follows, if your data in bytes format, I think following code will help you
bytes_data = b'\xff\xd8\xff\xe0\x00\x10JFIF\x00'
with open("path/image.png", "wb") as f:
f.write(bytes_data)
Add the new path of image to image field.
For more details refer following
How to generate temporary file in django and then destroy
Temporary file with specific file extension in Python 3
Programmatically saving image to Django ImageField
I've been following the tutorials from google app engine for uploading an image
I've set up a simple HTML page for uploading a file using the "file" input type, and the name of the element is "file"
The form enctype is multipart/form-data and method is 'post'
Following the example, I would store the image data as a blob and store it with my object
myfile = MyFile()
myfile.filedata = db.Blob(self.request.get('file'))
myfile.filename = self.request.get('filename')
myfile.put()
But when I look at what's stored in filedata via datastore viewer, it wasn't binary image data, but instead just
236 bytes, SHA-1 = 63540e4ca6dba45e9ff3553787f7f23d330b7791
When the image I uploaded is definitely larger than 236 bytes.
Should the snippet from above retrieve the entire image and put it in a blob?
It seems like all that's being stored in the blob is the request header.