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
🌐
GeeksforGeeks
geeksforgeeks.org › python › convert-from-_io-bytesio-to-a-bytes-like-object-in-python
Convert from '_Io.Bytesio' to a Bytes-Like Object in Python - GeeksforGeeks
July 23, 2025 - Below are the possible approaches to convert from '_Io.Bytesio' To A Bytes-Like Object In Python: ... To convert from _io.BytesIO to a bytes-like object using the read() method, we can use the read() function on the _io.BytesIO object, retrieving ...
Discussions

<class 'bytes'> vs <class '_io.BytesIO'>
These are completely different things. BytesIO is, as the name implies, an input/output object. It doesn't represent the bytes themselves, it represents a stream such as you might read from disk or receive over a network. bytes is the bytes themselves, ie the data that is received via a BytesIO. More on reddit.com
🌐 r/learnpython
4
1
December 1, 2022
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.com
🌐 r/flask
2
2
March 13, 2024
Does BytesIO need to be closed.
From my understanding, probably not, but it can't hurt. The information below is based on this Google Groups chat from 2015, so it could be outdated. StringIO at the very least only use RAM, so at worst not closing them could cause a memory leak, but CPython takes care of it for you. Of course if you use PyPy or some other implementation, things are different. BytesIO is a bit different in that it uses file descriptors, which are in limited supply for each process, but I wouldn't expect you to need too many of these. Personally I'm something of a robustness enthusiast and prefer code that doesn't rely on implementation details over fast code, so I would recommend you to use context managers always, but this is subjective. More on reddit.com
🌐 r/learnpython
8
5
January 18, 2023
Pandas Plot to Bytes (Without Writing to Disk)
From the docs: fname: str or path-like or binary file-like https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.savefig.html So just give it a BytesIO object instead of a str path and you are set. Oh and define the format since it can no longer deduce from the filename extension (png is default but it's better to be explicit). image_data = BytesIO() your_data.savefig(image_data, format='PNG') More on reddit.com
🌐 r/learnpython
2
4
January 12, 2023
🌐
Python
docs.python.org › 3 › library › io.html
io — Core tools for working with streams
Its subclasses, BufferedWriter, BufferedReader, and BufferedRWPair buffer raw binary streams that are writable, readable, and both readable and writable, respectively. BufferedRandom provides a buffered interface to seekable streams. Another BufferedIOBase subclass, BytesIO, is a stream of in-memory bytes.
🌐
Reddit
reddit.com › r/learnpython › vs
r/learnpython on Reddit: <class 'bytes'> vs <class '_io.BytesIO'>
December 1, 2022 -

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

🌐
Medium
medium.com › @abhishekshaw020 › understanding-bytesio-handling-in-memory-files-like-a-pro-e1b767339468
Understanding BytesIO: Handling In-Memory Files Like a Pro | by Abhishek Shaw | Medium
March 31, 2025 - Think of BytesIO as a virtual file that lives in your computer’s memory (RAM) instead of your hard drive. It lets you read and write data just like a normal file, but everything stays in memory—fast, efficient, and no cleanup required! 🚀 · Let’s break it down step by step. ... ✅ Handling file uploads in web apps — Instead of saving uploaded files to disk, you can process them directly in memory.
🌐
DigitalOcean
digitalocean.com › community › tutorials › python-io-bytesio-stringio
Python io.BytesIO and io.StringIO: Memory File Guide | DigitalOcean
August 3, 2022 - There are many ways in which we can use the io module to perform stream and buffer operations in Python. We will demonstrate a lot of examples here to prove the point. Let’s get started. Just like what we do with variables, data can be kept as bytes in an in-memory buffer when we use the io module’s Byte IO operations. Here is a sample program to demonstrate this: import io stream_str = io.BytesIO(b"JournalDev Python: \x00\x01") print(stream_str.getvalue())
🌐
Beautiful Soup
tedboy.github.io › python_stdlib › generated › generated › io.BytesIO.html
io.BytesIO — Python Standard Library
Create a buffered I/O implementation using an in-memory bytes buffer, ready for reading and writing
Find elsewhere
🌐
MangoHost
mangohost.net › mangohost blog › python io bytesio and stringio – in-memory file operations
Python IO BytesIO and StringIO – In-Memory File Operations
August 3, 2025 - In this post, you’ll learn how to leverage BytesIO for binary data and StringIO for text data, understand their performance characteristics, and discover practical applications for server-side development. Both BytesIO and StringIO are part of Python’s io module and implement the same interface as regular file objects.
🌐
GeeksforGeeks
geeksforgeeks.org › python › stringio-and-bytesio-for-managing-data-as-file-object
Stringio And Bytesio For Managing Data As File Object - GeeksforGeeks
July 24, 2025 - StringIO and BytesIO are classes provided by the io module in Python. They allow you to treat strings and bytes respectively as file-like objects. This can be useful when you want to work with in-memory file-like objects without actually writing to or reading from physical files.
🌐
Python.org
discuss.python.org › ideas
Add zero-copy conversion of `bytearray` to `bytes` by providing `__bytes__()` - Page 2 - Ideas - Discussions on Python.org
February 6, 2025 - Currently to be efficient in Python, a “zero copy” / “zero extra memory” pure-python I/O loop needs to: Use a mutable buffer of bytes (bytearray) buf = bytearray(BUFFER_SIZE) Fill it using file.readinto(buf)/os.readint…
🌐
Pynerds
pynerds.com › io-bytesio-in-python
io.BytesIO in Python
Disclaimer: References to any specific company, product or services on this Site are not controlled by GoDaddy.com LLC and do not constitute or imply its association with or endorsement of third party advertisers.
🌐
Real Python
realpython.com › python-bytes
Bytes Objects: Handling Binary Data in Python – Real Python
January 20, 2025 - io.BytesIO: A file-like object for handling binary data streams · The three built-in types listed earlier, along with the array data structure above, are examples of Python’s bytes-like objects designed for efficient sharing of large amounts of binary data. Note: You can use a memoryview to work with both byte...
🌐
GitHub
github.com › python › cpython › blob › main › Modules › _io › bytesio.c
cpython/Modules/_io/bytesio.c at main · python/cpython
_io.BytesIO.seek · pos: Py_ssize_t · whence: int = 0 · / · Change stream position. · Seek to byte offset pos relative to position indicated by whence: 0 Start of stream (the default). pos should be >= 0; 1 Current position - pos may be negative; 2 End of stream - pos usually negative.
Author   python
🌐
Medium
medium.com › @sarthakshah1920 › harnessing-the-power-of-in-memory-buffers-with-bytesio-0ac6d5493178
Harnessing the Power of In-Memory Buffers with BytesIO | by Sarthak Shah | Medium
December 24, 2023 - Whether dealing with images or files, the traditional approach of saving data to disk can introduce various challenges such as slower I/O operations, security concerns, and the need for manual file cleanup. This article explores a more efficient alternative using in-memory buffers, exemplified by the Python BytesIO module.
🌐
Learning Machine
gallon.me › using-the-bytesio-class-in-python.html
Using the BytesIO Class in Python - Learning Machine
February 14, 2025 - The io.BytesIO class in Python is an in-memory stream for binary data. It provides a file-like interface that lets you read and write bytes just like you would with a file, but all the data is...
🌐
Python⇒Speed
pythonspeed.com › articles › bytesio-reduce-memory-usage
The surprising way to save memory with BytesIO
February 27, 2025 - How does this work? BytesIO is using copy-on-write. Internally, it keeps a reference to the new bytes object returned from getvalue(). So long as you don’t write to the BytesIO, any reads can happen off the same memory.
🌐
Substack
dataengineeringcentral.substack.com › p › bytes-for-data-engineers
Bytes for Data Engineers - by Daniel Beach
August 21, 2023 - I see Strings, Ints, Floats, I ... old Byte. Poor little bugger. I don’t know if people think it’s too complicated, in fact, it is less, less to go wrong, less complexity. What’s more computationally expensive than Serialization and Deserialization? Especially in a Data Engineering context. Lots of data moving around, coming from this place and going to that place. Does it really need to be a String all the time? No. Let’s take a look at Bytes, Streams, and Buffers in Python and ...