MongoEngine and GridFS - Write files with ImageGridFsProxy - image

I'm playing around with mongoengine(0.8.2) and trying to write some images using the GridFS functionality. This is how I have declared my model:
class Lady(DynamicDocument):
id = ObjectIdField()
name = StringField()
offers = ListField(EmbeddedDocumentField(Offer))
pictures = ListField(ImageField())
So what I want to do is to append the pictures to the pictures field. What I tried is the following:
fileA = open('/home/evermean/Pictures/a.jpg', 'r')
fileB = open('/home/evermean/Pictures/b.jpg', 'r')
upload = [fileA, fileB]
files = []
for f in upload:
mf = ImageGridFsProxy()
mf.put(f, content_type = 'image/jpeg')
files.append(mf)
lady.pictures = files
lady.save()
What I get is the following:
Error
Traceback (most recent call last):
File "/home/evermean/Code/django/pourlamour/core/tests.py", line 38, in test_basic_addition
mf.put(f, content_type = 'image/jpeg')
File "/home/evermean/Code/django/env/pourlamour/local/lib/python2.7/site-packages/mongoengine/fields.py", line 1257, in put
field = self.instance._fields[self.key]
AttributeError: 'NoneType' object has no attribute '_fields'
I tried to figure out what goes wrong and the following line from the fields.py seems to be responsible although I cannot quite see what to do about it.
field = self.instance._fields[self.key]
I also tried to use the GridFSProxy which works ... so why does it fail with ImageGridFsProxy?
Any ideas? Where is my mistake? Thanks for your help.

Related

TypeError: Object of type RowProxy is not JSON serializable - Flask

I am using SQLAlchemy to query the database from my Flask web-application using engine.After I do the SELECT Query and also do use fetchall object after ResultProxy is returned which ultimately returns RowProxy object and then I store in session.
Here is my code:
import os
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from flask import Flask, session
engine = create_engine(os.environ.get('DATABASE_URL'))
db = scoped_session(sessionmaker(bind=engine))
app = Flask(__name__)
app.secret_key = os.environ.get('SECRET_KEY')
#app.route('/')
def index():
session['list'] = db.execute("SELECT title,author,year FROM books WHERE year = 2011 LIMIT 4").fetchall()
print(session['list'])
return "<h1>hello world</h1>"
if __name__ == "__main__":
app.run(debug = True)
Here is the output:
[('Steve Jobs', 'Walter Isaacson', 2011), ('Legend', 'Marie Lu', 2011), ('Hit List', 'Laurell K. Hamilton', 2011), ('Born at Midnight', 'C.C. Hunter', 2011)]
Traceback (most recent call last):
File "C:\Users\avise\AppData\Local\Programs\Python\Python38\Lib\site-packages\flask\app.py", line 2463, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\avise\AppData\Local\Programs\Python\Python38\Lib\site-packages\flask\app.py", line 2449, in wsgi_app
response = self.handle_exception(e)
File "C:\Users\avise\AppData\Local\Programs\Python\Python38\Lib\site-packages\flask\app.py", line 1866, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\avise\AppData\Local\Programs\Python\Python38\Lib\json\encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type RowProxy is not JSON serializable
The session item stores the data as i can see in output.But "hello world" is not rendered.
And if i replace the session variable by ordinary variable say x then it seems to be working.
But i think i need to use sessions so that my application will be used simultaneously by to users to display different things. So, how could i use sessions in this case or is there any other way?
Any help will be appreciated as I am new to Flask and web-development.
From what I understand about the Flask Session object is that it acts as a python dictionary; however values must be JSON serializable. In this case, just like the error suggests, the RowProxy object that is being returned by fetch all is not json serializable.
A solution to this problem would be to instead pass through a result of your query as a dictionary (which is JSON serializable).
It looks like the result of your query is returning a list of tuples so we can do the following:
res = db.execute("SELECT title,author,year FROM books WHERE year = 2011 LIMIT 4").fetchall()
user_books = {}
index = 0
for entry in res:
user_books[index] = {'title':res[index][0],
'author':res[index][1],
'year':res[index][2],
}
index += 1
session['list'] = user_books
A word of caution; however, is that since we are using the title of the book as a key, if there are two books with the same title, information may be overwritten, so consider using a unique id as the key.
Also note that the dictionary construction above would only work for the query you already have - if you added another column to the select statement you would have to edit the code to include the extra column information.

Opening files from filepaths on windows

I try to define a function that will take a file path and turn it into a string.
This is the defenition I came up with:
def get_book(file_path):
'''Takes a file path and returns the entire book as a string.'''
with open(file_path, 'r', 'utf-8') as infile:
content = infile.read()
return content
AnnaKarenina = get_book('../Python/Data/books/AnnaKarenina.txt')
I now get TypeError: an integer is required (got type str)
I also tried using the os.path, different kinds of slashes and other tricks for opening files with windows, but that all returns the error file not found.
Does anyone know what I am doing wrong?
The encoding parameters of open function is a named parameters, so you have to specify it like this :
def get_book(file_path):
'''Takes a file path and returns the entire book as a string.'''
with open(file_path, 'r', encoding='utf-8') as infile:
content = infile.read()
return content
AnnaKarenina = get_book('../Python/Data/books/AnnaKarenina.txt')

Python 3.3 - Getting Header and redirect the results

I would like to create a script that look to a file, read each line (which are url) and fetch the HTTP header for me.
I have a questions :
I try to redirect the result to a text file but, anyhow I try, it is not working.
Can someone help me with my code please ?
import urllib.request
import sys
open('sorti.txt','w')
sorti = open("sorti.txt",'w')
print('Creation de sorti.txt')
text_file = open ("id.txt", "r")
text_file.read().strip('\n')
for lines in text_file:
urllib.request.urlopen('lines').write.sorti()
header = urllib.request.parse_http_list(lines).write.sorti()
sys.stdout(sorti)
text_file.close
sorti.close
Supposing you are looking for something like this
URL1
header_1: value
...
header_n: value
URL2
header_1: value
...
header_n: value
change the code as follows:
text_file = open ("id.txt", "r")
for line in text_file:
sorti.write(line) // writes the current url
obj = urllib.request.urlopen(line)
headers = dict(obj.info()) // gets the headers
for (h,v) in headers.items(): // write all with the specified format
sorti.write("{0}: {1}\n".format(h, v))
sorti.write("\n")
sorti.close
Those write.sorti() will not work.

'File path' use causing program exit in Python 3

I have downloaded a set of html files and saved the file paths which I saved them to in a .txt file. It has each path on a new line. I wanted to look at the first file in the list and then itterate through the whole list, opening the files and extracting data before going on to the next file.
My code works fine with a single path put in directly (for the first file) as:
path = r'C:\path\to\file.html'
and works if I itterate through the text file using:
file_list_fp = r'C:\path\to\file_with_pathlist.txt'
with open(file_list_fp, 'r') as file_list:
for filepath in file_list:
pathend = filepath.find('\n')
path = file[:pathend]
q = open(path, 'r').read()
but it fails when I try getting a single path using either:
with open(file_list_fp, 'r') as file_list:
path_n = file_list.readline()
end = path_n.find('\n')
path_bad1 = path_n[:end]
or:
with open(file_list_fp, 'r') as file_list:
path_bad2 = file_list.readline().split('\n')[0]
With these two my code exits just after that point. I can't figure out why. Any pointers very welcome. (I'm using Python 3.3.1 on windows.)

Jython, ImageInfo

I trying to use ImageInfo and Jython to get information from a image on my harddrive.
I have imported the module fine but keep getting this error:
TypeError: setInput(): expected 2 args; got 1
And this is the code I am trying to use:
filename = "C:\\image.jpg"
img = ImageInfo.setInput(filename)
Could anyone point out what I am doing wrong.
Cheers
Eef
The missing argument Jython complains about is the ImageInfo object itself, which doesn't exist yet. You must construct it first. So:
filename = "C:\\image.jpg"
ii = ImageInfo()
img = ii.setInput(filename)
or
filename = "C:\\image.jpg"
img = ImageInfo().setInput(filename)
may work also.

Resources