I receive a request from the client to download some file from the server. The filename is in Hebrew.
@bottle.get("/download/<folder_name>/<file_name>")
def download(folder_name, file_name):
file_name = file_name.decode('utf-8')
folder_name = folder_name.decode('utf-8')
if os.path.exists(os.path.join(folder_name, file_name)):
return bottle.static_file(file_name, root=folder_name, download=True)
The last line fails :
return bottle.static_file(file_name, root=folder_name, download=True)
I get an exception :
UnicodeEncodeError: 'ascii' codec can't encode characters in position 22-25: ordinal not in range(128)
I have no idea what am i doing wrong here.
Callstack shows the exception derives from python bottle code:
File "C:\Python27\Lib\site-packages\bottle-0.10.9-py2.7.egg\bottle.py", line 1669, in __setitem__
def __setitem__(self, key, value): self.dict[_hkey(key)] = [str(value)]
Please help.
Regard, Omer.
Bottle is trying to set the
Content-Disposition
header on the HTTP response toattachment; filename=...
. This doesn't work for non-ASCII characters, as Bottle handles HTTP headers withstr
internally... but then even if it didn't, there's no cross-browser-compatible way to set aContent-Disposition
with a non-ASCIIfilename
. (Background.)You could set
download='...'
to a safe ASCII-only string to override Bottle's default guess (which is using the local filename, containing Unicode).Alternatively, omit the
download
argument and rely on the browser guessing the filename from the end of the URL. (This is the only widely compatible way to get a Unicode download filename.) Unfortunately then Bottle will omitContent-Disposition
completely, so consider altering the headers on the returned response to include plainContent-Disposition: attachment
without a filename. Or perhaps you don't care, if theContent-Type
is one that will always get downloaded anyway.send_file parameters must be unicode. Here is solution for bottle 0.5.8:
In the last line try encoding the unicode string into binary using
utf-8
codec:From the code you provided, it looks like the
bottle.static_file
method expects a string in binary format, therfore a default conversion usingascii
codec is performed (as seen from the error message). As in your string you use Hebrew characters, which are not part of ascii, the default conversion fails. You need to use codec that supports national alphabets, like theutf-8
.For more information, see Unicode In Python, Completely Demystified