It seems you are confused io.BytesIO. Let's look at some examples of using BytesIO.
>>> from io import BytesIO
>>> inp_b = BytesIO(b'Hello World', )
>>> inp_b
<_io.BytesIO object at 0x7ff2a71ecb30>
>>> inp.read() # read the bytes stream for first time
b'Hello World'
>>> inp.read() # now it is positioned at the end so doesn't give anything.
b''
>>> inp.seek(0) # position it back to begin
>>> BytesIO.read(inp) # This is same as above and prints bytes stream
b'Hello World'
>>> inp.seek(0)
>>> inp.read(4) # Just read upto four bytes of stream.
>>> b'Hell'
This should give you an idea of how read on BytesIO works. I think what you need to do is this.
return send_file(
BytesIO(image.data),
mimetype='image/jpg',
as_attachment=True,
attachment_filename='f.jpg'
)
Answer from Srikanth Chekuri on Stack Overflow<class 'bytes'> vs <class '_io.BytesIO'>
Flask-Wtforms Filefield to bytesio to s3
I don't use wtforms, but i've done it by generating a pre-signed URL on the flask backend. Then you just upload using javascript and your presigned URL.
More on reddit.comDoes BytesIO need to be closed.
Pandas Plot to Bytes (Without Writing to Disk)
It's a file-like object. Read them:
>>> b = io.BytesIO(b'hello')
>>> b.read()
b'hello'
If the data coming in from body is too large to read into memory, you'll want to refactor your code and use zlib.decompressobj instead of zlib.decompress.
In case you write into the object first, make sure to reset the stream before reading:
>>> b = io.BytesIO()
>>> image = PIL.Image.open(path_to_image)
>>> image.save(b, format='PNG')
>>> b.seek(0)
>>> b.read()
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x06\xcf\x00\x00\x03W\x08\x02\x00'
or directly get the data with getvalue
>>> b.getvalue()
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x06\xcf\x00\x00\x03W\x08\x02\x00'
Hello all,
I'm trying to wrap my head around the practical differences between:
<class 'bytes'> and <class '_io.BytesIO'>.
I read through the documentation:
https://docs.python.org/3/library/io.html?highlight=bytesio#binary-i-o
Binary I/O (also called buffered I/O) expects bytes-like objects and produces bytes objects. No encoding, decoding, or newline translation is performed. This category of streams can be used for all kinds of non-text data, and also when manual control over the handling of text data is desired.
It provides some examples:
The easiest way to create a binary stream is with open() with 'b' in the mode string:
and
f = io.BytesIO(b"some initial binary data: \x00\x01")
So I read all this, but so what? Why would you use the io.BytesIO data type over a standard bytes data type?
EDIT: Let me provide some additional context that I just discovered after reading the documentation on lxml.
https://lxml.de/parsing.html#parsing-html
I'm using the requests object and parsing the results with lxml. Here is the example code:
from io import BytesIO
from lxml import etree
#* etree - https://lxml.de/parsing.html
#? etree stands for element tree
import requests
#? Need to know concepts
#? What are bytes
#? HTTP status codes
#? HTTP methods (GET. POST, PUT, DELETE)
#? bytes - https://docs.python.org/3/library/stdtypes.html?highlight=bytes#bytes-objects
url = 'http://localhost'
#! The URL https://nostarch.com/ doesn't seem to work
resp = requests.get(url=url)
html_bytes = resp.content
parser = etree.HTMLParser()
content = etree.parse(BytesIO(html_bytes), parser=parser)
print(type(html_bytes))
print(type(BytesIO(html_bytes)))
for link in content.findall('//a'):
print(f"{link.get('href')} -> {link.text}")Kind regards