How to retrieve file's with grid fs - python

I have inserted image file with gridfs in mongodb with python and I want to retrieve that file with another function. How can I retrieve the file. I am using djanog and python(2.7).Thanks in advance!
def file_grid(request):
datafile = open('jobs.jpg',"r");
thedata = datafile.read()
fs = gridfs.GridFS(db)
stored = fs.put(thedata, filename="testimage")
return HttpResponse("inserted")

fs = gridfs.GridFS(db)
gridout = fs.get_last_version("testimage")
The gridout object is an instance of GridOut for reading files. You could get all the bytes at once with gridout.read(), or iterate over chunks of bytes like:
for chunk in gridout:
do_something_with(chunk)
GridFS chunks are about 256k by default.

Related

Saving a json request as an Image in Flask

I have a flask get request like this
content = {"vname":"","myPhoto":{"fieldname":"myPhoto","originalname":"flower-purple-lical-blosso.jpg","encoding":"7bit","mimetype":"image/jpeg","buffer":{"type":"Buffer","data":[255,216,255,224,0,...]}
My image file is with the key data.
data = content['myphoto']['buffer']['data']
I am unable to save it as a jpeg file.
I am not sure how to decode this object as an image as its currently a list.
If I correctly understood your question, it could be done like this:
#!/usr/bin/env python3
content = {"vname":"","myPhoto":{"fieldname":"myPhoto","originalname":"flower-purple-lical-blosso.jpg","encoding":"7bit","mimetype":"image/jpeg","buffer":{"type":"Buffer","data":[255,216,255,224,0,20]}}}
data = content['myPhoto']['buffer']['data']
str_data = ''.join(chr(d) for d in data) # build string using list comprehension
bytes_data = str_data.encode() # build bytes array from string
with open('output.jpg', 'wb') as f: # open file for writing bytes
f.write(bytes_data) # write bytes array to file
Code of course is not perfect and could be used as starting point.

In Flask, is it possible to make a zip file on the fly and send it to the user? [duplicate]

I have a flask server that grabs binary data for several different files from a database and puts them into a python 'zipfile' object. I want to send the generated zip file with my code using flask's "send_file" method.
I was originally able to send non-zip files successfully by using the BytesIO(bin) as the first argument to send_file, but for some reason I can't do the same thing with my generated zip file. It gives the error:
'ZipFile' does not have the buffer interface.
How do I send this zip file object to the user with Flask?
This is my code:
#app.route("/getcaps",methods=['GET','POST'])
def downloadFiles():
if request.method == 'POST':
mongo = MongoDAO('localhost',27017)
identifier = request.form['CapsuleName']
password = request.form['CapsulePassword']
result = mongo.getCapsuleByIdentifier(identifier,password)
zf = zipfile.ZipFile('capsule.zip','w')
files = result['files']
for individualFile in files:
data = zipfile.ZipInfo(individualFile['fileName'])
data.date_time = time.localtime(time.time())[:6]
data.compress_type = zipfile.ZIP_DEFLATED
zf.writestr(data,individualFile['fileData'])
return send_file(BytesIO(zf), attachment_filename='capsule.zip', as_attachment=True)
return render_template('download.html')
BytesIO() needs to be passed bytes data, but a ZipFile() object is not bytes-data; you actually created a file on your harddisk.
You can create a ZipFile() in memory by using BytesIO() as the base:
memory_file = BytesIO()
with zipfile.ZipFile(memory_file, 'w') as zf:
files = result['files']
for individualFile in files:
data = zipfile.ZipInfo(individualFile['fileName'])
data.date_time = time.localtime(time.time())[:6]
data.compress_type = zipfile.ZIP_DEFLATED
zf.writestr(data, individualFile['fileData'])
memory_file.seek(0)
return send_file(memory_file, attachment_filename='capsule.zip', as_attachment=True)
The with statement ensures that the ZipFile() object is properly closed when you are done adding entries, causing it to write the required trailer to the in-memory file object. The memory_file.seek(0) call is needed to 'rewind' the read-write position of the file object back to the start.

Python flask ajax save decoded base64 image to server temporarily

I am resizing images client side before sending them to my flask app.
The resized image, which is drawn into a canvas to be resized, is sent via a POST request.
In my app the image is decoded via base64:
def resize_image(item):
content = item.split(';')[1]
image_encoded = content.split(',')[1]
body = base64.decodestring(image_encoded.encode('utf-8'))
return body
The imagedata is stored as type String in the body variable. I can save the data to my local machine and it works:
filename = 'some_image.jpg'
with open(filename, 'wb') as f:
print "written"
f.write(body)
What I need is to upload the resized image to AWS3. On one point I need to read() the image contents, but until the image is saved somewhere as a file it is still a String, so it fails:
file_data = request.values['a']
imagedata = resize_image(file_data)
s3 = boto.connect_s3(app.config['MY_AWS_ID'], app.config['MY_AWS_SECRET'], host='s3.eu-central-1.amazonaws.com')
bucket_name = 'my_bucket'
bucket = s3.get_bucket(bucket_name)
k = Key(bucket)
# fails here
file_contents = imagedata.read()
k.key = "my_images/" + "test.png"
k.set_contents_from_string(file_contents)
Unless there is an other solution, I thought I save the image temporarily to my server (Heroku) and upload it and then delete it, how would this work? Deleting afterwards is important here!
set_contents_from_string takes a string as a parameter, you could probably just pass your image string data directly to it for upload to S3
Solution:
Delete this part:
file_contents = imagedata.read()
Use imagedata directly here:
k.set_contents_from_string(imagedata)
If you need to call .read() on your data, but don't need save file on disk use StringIO:
import StringIO
output = StringIO.StringIO()
output.write('decoded image')
output.seek(0)
output.read()
Out[1]: 'decoded image'

Save a pdf file stored in Mongodb GridFS using Python

I had uploaded some PDF, PNG files to a local instance of mongodb. By mistake I deleted these files and I can no longer recover them using the regular recover options. However, they are in my local mongodb database. How can I save them back in their original format on my computer?
I know the following:
import pymongo as pym
import gridfs
def connectToDb():
client = pym.MongoClient('mongodb://localhost:27017/')
db = client.questionbank
collectn = db.questionbank
fs = gridfs.GridFS(db)
return db, collectn, fs
db, collectn, fs = connectToDb()
filelist = list( db.fs.files.find({}, {"_id": 1, "filename": 1}) )
fileid = filelist[0]['_id']
fobj = fs.get(fileid)
## I don't know what to do after this. I think I cannot use read since I don't
## want the string. I want to save the pdf file as a pdf file.
Any help will be greatly appreciated. Thanks in advance.
Okay, I figured this out on my own. It can be done in the following way:
To the above code add the lines:
f = open('tempfigfile.pdf', 'wb')
f.write(fobj.read())
f.close()
This saves the file as tempfigfile.pdf.
This code will save all the files to ur local folder from mongodb gridfs.
i=0
cursor=fs.find()
while(i < cursor.count()):
fi=cursor.next()
with open("C:\\localfolder\\"+fi.filename,"wb") as f:
f.write(fi.read())
f.closed
i=i+1

How to send zip files in the python Flask framework?

I have a flask server that grabs binary data for several different files from a database and puts them into a python 'zipfile' object. I want to send the generated zip file with my code using flask's "send_file" method.
I was originally able to send non-zip files successfully by using the BytesIO(bin) as the first argument to send_file, but for some reason I can't do the same thing with my generated zip file. It gives the error:
'ZipFile' does not have the buffer interface.
How do I send this zip file object to the user with Flask?
This is my code:
#app.route("/getcaps",methods=['GET','POST'])
def downloadFiles():
if request.method == 'POST':
mongo = MongoDAO('localhost',27017)
identifier = request.form['CapsuleName']
password = request.form['CapsulePassword']
result = mongo.getCapsuleByIdentifier(identifier,password)
zf = zipfile.ZipFile('capsule.zip','w')
files = result['files']
for individualFile in files:
data = zipfile.ZipInfo(individualFile['fileName'])
data.date_time = time.localtime(time.time())[:6]
data.compress_type = zipfile.ZIP_DEFLATED
zf.writestr(data,individualFile['fileData'])
return send_file(BytesIO(zf), attachment_filename='capsule.zip', as_attachment=True)
return render_template('download.html')
BytesIO() needs to be passed bytes data, but a ZipFile() object is not bytes-data; you actually created a file on your harddisk.
You can create a ZipFile() in memory by using BytesIO() as the base:
memory_file = BytesIO()
with zipfile.ZipFile(memory_file, 'w') as zf:
files = result['files']
for individualFile in files:
data = zipfile.ZipInfo(individualFile['fileName'])
data.date_time = time.localtime(time.time())[:6]
data.compress_type = zipfile.ZIP_DEFLATED
zf.writestr(data, individualFile['fileData'])
memory_file.seek(0)
return send_file(memory_file, attachment_filename='capsule.zip', as_attachment=True)
The with statement ensures that the ZipFile() object is properly closed when you are done adding entries, causing it to write the required trailer to the in-memory file object. The memory_file.seek(0) call is needed to 'rewind' the read-write position of the file object back to the start.

Categories

Resources