Reputation: 6450
I am trying to hash the filename and then save into DB. I am using Flask and Python 3.4
This is the code for upload:
@app.route('/', methods=['GET', 'POST'])
def upload_pic():
if request.method == 'POST':
file = request.files['file']
try:
extension = file.filename.rsplit('.', 1)[1].lower()
except IndexError as e:
abort(404)
if file and check_extension(extension):
# Salt and hash the file contents
filename = md5(file.read() + str(round(time.time() * 1000))).hexdigest() + '.' + extension
file.seek(0) # Move cursor back to beginning so we can write to disk
file.save(os.path.join(app.config['UPLOAD_DIR'], filename))
add_pic(filename)
gen_thumbnail(filename)
return redirect(url_for('show_pic', filename=filename))
else: # Bad file extension
abort(404)
else:
return render_template('upload.html')
When i post the form, i get this error traceback.
Traceback (most recent call last):
File "C:\Python34\lib\site-packages\flask\app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Python34\lib\site-packages\flask\app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "C:\Python34\lib\site-packages\flask\app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Python34\lib\site-packages\flask\_compat.py", line 33, in reraise
raise value
File "C:\Python34\lib\site-packages\flask\app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "C:\Python34\lib\site-packages\flask\app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Python34\lib\site-packages\flask\app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Python34\lib\site-packages\flask\_compat.py", line 33, in reraise
raise value
File "C:\Python34\lib\site-packages\flask\app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Python34\lib\site-packages\flask\app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\Ajay\PycharmProjects\codehackr-upload\flaskgur.py", line 70, in upload_pic
filename = md5(file.read() + (round(time.time() * 1000))).hexdigest() + '.' + extension
TypeError: can't concat bytes to int
I dont know whats wrong is happening, please enlighten me.
Thanks.
Upvotes: 3
Views: 23543
Reputation: 13838
Yes, as julienc wrote, the problem was trying to concatenate the result of file.read()
, of type bytes
, with the result of round(time.time() * 1000))
, which was an int
.
BUT DON'T DO WHAT'S SHOWN IN THE OTHER ANSWER! Keep calm and carry on reading...
bytes(n)
– Create bytes
of length n
that is empty (full of zeroes)bytes(12) == b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
This is rarely what you want. Beware!
In the context of this question md5(file.read() + bytes(round(time.time() * 1000)))
hashes the file contents and then around 1.5 trillion empty bytes. Technically it still does what's needed, but ugh, for what a computing cost :-)
bytes([...])
– Create bytes
containing the specified value(s)bytes([12]) == b'\x0c'
bytes([444]) -> ValueError("bytes must be in range(0, 256)")
bytes([0x01, 0xBC]) == b'\x01\xbc'
Each source value must be just between 0 and 255 to fit into a byte.
Of course, could be also written with a tuple, but it's a bit uglier for the case of length 1: bytes((12,))
int.to_bytes(...)
– Create bytes
as a native/binary representation of an integer( 12).to_bytes(8, 'big') == b'\x00\x00\x00\x00\x00\x00\x00\x0c'
(444).to_bytes(8, 'big') == b'\x00\x00\x00\x00\x00\x00\x01\xbc'
This is the answer to the original question, how to convert an integer to a stream etc.
But now you need to think about some low-level things, like number of bytes of the output and the endianness (byte order). See int.to_bytes()
docs for details.
Of course, the extra parentheses are needed only with a literal value, like 12
in my example. They can be omitted when using a variable or other expression, e.g. self._size.to_bytes(8)
.
str.encode(...)
– Create bytes from a stringstr(12).encode() == b'12'
As an alternative to the above, sometimes you don't need or want to think about the low-level considerations and then the same goal can be accomplished by just hashing (or whatever) the simple human textual representation of the value.
encode()
without an explicit encoding argument uses UTF-8, which is a good idea everywhere unless having a good reason to pick something else.
Upvotes: 2
Reputation: 20325
You are trying to concatenate the result of file.read()
with the result of round(time.time() * 1000))
, which is an integer. That's why you get the error:
TypeError: can't concat bytes to int
Try to cast the integer:
file.read() + bytes(round(time.time() * 1000)))
But as @Lev Levitsky noticed, it looks like your code already has the correction: are you sure to run the last version of your code?
Upvotes: 5