I have stored pdf files uploaded by users in the Datastore, as BlobProperties:
<form action="/" method="post" enctype="multipart/form-data">
<input type="file" name="pdf">
<input type="submit" value="Upload">
</form>
with the following handler:
def post(self):
p = self.request.get('pdf')
if p:
person.pdf = p
I have also tried this version of the last line:
person.pdf = db.Blob(p)
which seems to work the same way. I try to display it thus:
<embed src="{{ person.pdf }}" width="500"
height="375" type="application/pdf">
with this handler:
def get(self,person_id):
person = Person.get_by_id(int(person_id))
self.response.headers['Content-Type']="application/pdf"
template_values = {
'person' : person
}
template = jinja_environment.get_template('person.html')
self.response.out.write(template.render(template_values))
The size of person.pdf indicaties that it does indeed contain the entire pdf content, but in the template, the variable
{{ person.pdf }}
causes the following error:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 10: ordinal not in range(128)
so nothing is displayed. As far as I understand, Blobproperties are stored as strings. What am I missing?
The code tries to convert your string to unicode using ASCII codec. You've uploaded a real pdf, and the content is not ASCII. Also you're likely to break your page if somewhere in the pdf there is a character
"
.Look at encoding the content. Base64 works fairly well, but there are others. At very least you should escape the data there.
I finally solved it by simply doing:
in the display handler. D'oh.
The most basic way that this appears to be wrong is that:
should contain the URL to download the pdf file. However, person.pdf actually contains the file data.
You'll need one handler to serve the html with the URL to the pdf data, and a separate handler to return the pdf data.