How to declare a Mongo Binary Object in Flask - mongodb

I'm building a flask application where I will be serving small images. These images are stored in MongoDB as BinaryData. In a helper function, I can store the data with these lines of python:
a = {"file_name": f, "payload": Binary(article.read())}
ARTICLES.insert(a)
I'm trying to build a class that contains the image. However, I cannot find the correct field declaration
class BinaryFile(mongo.Document):
created_at = mongo.DateTimeField(default=datetime.datetime.now, required=True)
file_name = mongo.StringField(max_length=255, required=True)
payload = mongo.Binary()
producing this error:
AttributeError: 'MongoEngine' object has no attribute 'Binary'
Can anyone suggest the correct way to declare this value or am I completely off base? This page does not provide a way to declare a field as Binary: http://api.mongodb.org/python/current/api/bson/index.html
Thanks!

Gabe helped get me on the right path.
First, I had to decide whether to use standard Binary format or move to GridFS, I chose to stick with regular Binary.
What I didn't understand was that the DateTimeField and StringField were being provided by MongoEngine. Gabe's comment got me going that way and I found the MongoEngine fields docs: http://docs.mongoengine.org/apireference.html#fields
I called that and got the error here: mongoengine.fields.ImproperlyConfigured: PIL library was not found which was fixed by doing
pip install Pillow
So now I have
import datetime
from app import mongo
from flask import url_for
from bson.binary import Binary
class BinaryFile(mongo.Document):
created_at = mongo.DateTimeField(default=datetime.datetime.now, required=True)
file_name = mongo.StringField(max_length=255, required=True)
payload = mongo.ImageField(required=False)
and I'm on to the next error! See you soon!

Related

Fetching data from mongo-tracker in ' Rasa' and storing it in mongoDB at runtime like sender_id,timestamp

Could you please tell me how are you fetching specific details from the tracker store. Elaborating my doubt below:
in my run_app.py (socketIO class) i have used mongotracker like this-
db = MongoTrackerStore(domain=“d.yml”,host=‘host ip’, db=‘xyz’, username=“x”,password=“x”,collection=“x”,event_broker=None)
agent = Agent.load(‘models/dialogue’, interpreter=‘models/current/nlu’,action_endpoint = action_endpoint,tracker_store=db)
now i want to fetch some data like db.sender_id or db.event. the reason of doing it is to store it column wise on my mongodb.Please help me solving this problem.
This information should already be stored in your mongodb, so there should be no extra need for you to store it.
Maybe see the documentation for this https://rasa.com/docs/core/tracker_stores/ and make sure your endpoints.yml file includes the correct information:
tracker_store:
store_type: mongod
url: <url to your mongo instance, e.g. mongodb://localhost:27017>
db: <name of the db within your mongo instance, e.g. rasa>
username: <username used for authentication>
password: <password used for authentication>
auth_source: <database name associated with the user’s credentials>
For information on how to fetch specific details from your mongodb maybe have a look at the mongodb docs https://docs.mongodb.com/manual/reference/method/db.collection.find/.
look at this Example
I am using Pymongo to connect monogoDB. try to understand my code
from typing import Any, Text, Dict, List
from pymongo.database import Database
from pymongo import MongoClient
from rasa_sdk import Action, Tracker
from rasa_sdk.executor import CollectingDispatcher
import pymongo
# url="http://localhost:3000/api"
client = pymongo.MongoClient("localhost", 27017)
db=client.sample
class mercdesCarAction(Action):
def name(self):
return "mercdesCarAction"
def run(self,dispatcher,tracker,domain):
res = db.datas.find({'action':'mercdesCarAction'})
for i in res:
dispatcher.utter_button_message(i['text'],i['buttons'])
return []

Having problems extending Quill

I'm hitting some problems extending Quill.
I want to modify the List and ListItem classes in Quill, so I tried to copy formats/list.js into my code base as a starting point. I then import my local copy and register it with Quill like so...
import { List, ListItem } from './quill/list';
Quill.register({
'formats/list': List,
'formats/list/item': ListItem
}, true);
However, when I attempt to create a list in the editor the code crashes in the List class with the following error:
ParchmentError {message: "[Parchment] Unable to create list-item blot", name: "ParchmentError"}
This happens on this line... https://github.com/quilljs/quill/blob/develop/formats/list.js#L99
I assume it relates to the imports I was forced to change, but I can't figure out what's wrong. I've not made any other changes to list.js. The original file has the following:-
import Block from '../blots/block';
import Container from '../blots/container';
Which I changed to this:-
import Quill from 'quill';
let Block = Quill.import('blots/block');
let Container = Quill.import('blots/container');
Is the way I am importing wrong? What is causing the error?
Figured it out (well a colleague did).
I needed to import Parchment like so :-
let Parchment = Quill.import('parchment');
instead of import Parchment from 'parchment';
This is because you'll end up with a different static Parchment class to the one used internally to Quill, so asking Quill for it's instance ensures you are both working with the same one (ie, the one where the blots were registered).
I came across that problem a couple hours ago.
In Quill's source code, List is a default export while ListItem is a named export.
So your import should look like this:
import List, { ListItem } from './quill/list';
Be sure to export them appropriately on your custom list.js file.
Good luck!

Python w/QT Creator form - Possible to grab multiple values?

I'm surprised to not find a previous question about this, but I did give an honest try before posting.
I've created a ui with Qt Creator which contains quite a few QtWidgets of type QLineEdit, QTextEdit, and QCheckbox. I've used pyuic5 to convert to a .py file for use in a small python app. I've successfully got the form connected and working, but this is my first time using python with forms.
I'm searching to see if there is a built-in function or object that would allow me to pull the ObjectNames and Values of all widgets contained within the GUI form and store them in a dictionary with associated keys:values, because I need to send off the information for post-processing.
I guess something like this would work manually:
...
dict = []
dict['checkboxName1'] = self.checkboxName1.isChecked()
dict['checkboxName2'] = self.checkboxName2.isChecked()
dict['checkboxName3'] = self.checkboxName3.isChecked()
dict['checkboxName4'] = self.checkboxName4.isChecked()
dict['lineEditName1'] = self.lineEditName1.text()
... and on and on
But is there a way to grab all the objects and loop through them, even if each different type (i.e. checkboxes, lineedits, etc) needs to be done separately?
I hope I've explained that clearly.
Thank you.
Finally got it working. Couldn't find a python specific example anywhere, so through trial and error this worked perfectly. I'm including the entire working code of a .py file that can generate a list of all QCheckBox objectNames on a properly referenced form.
I named my form main_form.ui from within Qt Creator. I then converted it into a .py file with pyuic5
pyuic5 main_form.ui -o main_form.py
This is the contents of a sandbox.py file:
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
import main_form
# the name of my Qt Creator .ui form converted to main_form.py with pyuic5
# pyuic5 original_form_name_in_creator.ui -o main_form.py
class MainApp(QtWidgets.QMainWindow, main_form.Ui_MainWindow):
def __init__(self):
super(self.__class__, self).__init__()
self.setupUi(self)
# Push button object on main_form named btn_test
self.btn_test.clicked.connect(self.runTest)
def runTest(self):
# I believe this creates a List of all QCheckBox objects on entire UI page
c = self.findChildren(QtWidgets.QCheckBox)
# This is just to show how to access objectName property as an example
for box in c:
print(box.objectName())
def main():
app = QtWidgets.QApplication(sys.argv) # A new instance of QApplication
form = MainApp() # We set the form to be our ExampleApp (design)
form.show() # Show the form
app.exec_() # and execute the app
if __name__ == '__main__': # if we're running file directly and not importing it
main() # run the main function
See QObject::findChildren()
In C++ the template argument would allow one to specify which type of widget to retrieve, e.g. to just retrieve the QLineEdit objects, but I don't know if or how that is mapped into Python.
Might need to retrieve all types and then switch handling while iterating over the resulting list.

Obsolete/erroneous code in convolutional_mlp.py at DeepLearningTutorials?

This code contains the following tidbit:
from theano.tensor.nnet import conv2d
...
# convolve input feature maps with filters
conv_out = conv2d(
input=input,
filters=self.W,
filter_shape=filter_shape,
input_shape=image_shape
)
which raises an exception due to 'input_shape' not being found, despite being mentioned in the documentation where it says that:
"image_shape ... – Deprecated alias for input_shape"
Looking at conv.py both locally and in the source I found:
def conv2d(input, filters, image_shape=None, filter_shape=None,
border_mode='valid', subsample=(1, 1), **kargs):
Needless to say, there is no trace of input_shape.
If one modifies the code above as follows
# convolve input feature maps with filters
conv_out = conv2d(
input=input,
filters=self.W,
filter_shape=filter_shape,
image_shape=image_shape
)
, the exception disappears and the code runs fine.
What am I missing? If image_shape is deprecated, how come it works while input_shape does not?
Is the theano version at the repository obsolete?
PS: I would have liked to ask directly the folks at http://deeplearning.net, but I could not find how.
Are you sure you have the latest version installed?
conv.py contains the deprecated implementation of conv2d. The new implementation can be found in __init__.py
Make sure you are using the import statement
from theano.tensor.nnet import conv2d
and not
from theano.tensor.nnet.conv import conv2d
since the second one is going to import the deprecated implementation

saving picture to mongodb

am trying yo do this using tornado and pil and mongodb.
avat = self.request.files['avatar'][0]["body"]
nomfich = self.request.files['avatar'][0]["filename"]
try:
image = Image.open(StringIO.StringIO(buf=avat))
size = image.size
type = image.format
avatar = r"/profile-images/{0}/{1}".format(pseudo, nomfich)
except IOError:
self.redirect("/erreur-im")
and the database code:
user={
"pseudo": pseudo,
"password":password,
"email":email,
"tel":tel,
"commune":commune,
"statut":statut,
"nom":nom,
"prenom":prenom,
"daten":daten,
"sexe":sexe,
"avatar":avatar
}
self.db.essog.insert(user)
and it worked ok, the "avatar" is saved, but there in no image, it saves only a name!
my problem is:
to understand how database deals with pictures, must i make image.save(path, format), but the path, is it a path of a normal system path (windows, or linux)?
the profile is simple, and i've limited the picture upload to 500ko, and the document in mongodb is 16mb, so the document will handle the entire profile, but must i use gridFS even for small document when it contains picture?
the key problem is in path of the picture saving, am stuck, and it's the first time i deal with database, so am sorry for that question.
You don't necessarily need GridFS for storing files in MongoDB, but it surely makes it a nicer experience, because it handles the splitting and saving of the binary data, while making the metadata also available. You can then store an ID in your User document to the avatar picture.
That aside, you could also store binary data directly in your documents, though in your code you are not saving the data. You simply are opening it with PIL.Image, but then doing nothing with it.
Assuming you are using pymongo for your driver, I think what you can do is just wrap the binary data in a Binary container, and then store it. This is untested by me, but I assume it should work:
from pymongo.binary import Binary
binary_avatar = Binary(avat)
user={
...
"avatar":avatar,
"avatar_file": binary_avatar
...
}
Now that being said... just make it easier on yourself and use GridFS. That is what it is meant for.
If you were to use GridFS, it might look like this:
from gridfs import GridFS
avat_ctype = self.request.files['avatar'][0]["content_type"]
fs = GridFS(db)
avatar_id = fs.put(avat, content_type=avat_ctype, filename=nomfich)
user={
...
"avatar_name":avatar,
"avatar_id": avatar_id
...
}
This is the code to insert and retrieve image in mongodb without using gridfs.
def insert_image(request):
with open(request.GET["image_name"], "rb") as image_file:
encoded_string = base64.b64encode(image_file.read())
print encoded_string
abc=db.database_name.insert({"image":encoded_string})
return HttpResponse("inserted")
def retrieve_image(request):
data = db.database_name.find()
data1 = json.loads(dumps(data))
img = data1[0]
img1 = img['image']
decode=img1.decode()
img_tag = '<img alt="sample" src="data:image/png;base64,{0}">'.format(decode)
return HttpResponse(img_tag)
there is an error in :
from pymongo.binary import Binary
the correct syntax is:
from bson.binary import Binary
thk you all for your endless support
Luca
You need to save binary data using the Binary() datatype of pymongo.
http://api.mongodb.org/python/2.0/api/bson/binary.html#module-bson.binary