Give raw string bytes in socket message instead of string
Is your feature request related to a problem?
For very high performance websocket clients it is sometimes not desirable to automatically convert bytes to string, even if the server sends as string. It's unnecessary overhead when using high performance json parsing like orjson which can handle bytes faster.
Describe the solution you'd like
A flag that allows me to opt in to receiving bytes of string instead of actual python string.
Describe alternatives you've considered
Switch to synchronous websocket client (already supports this).
Related component
Client
Additional context
No response
Code of Conduct
- [x] I agree to follow the aio-libs Code of Conduct
Look at how aioshelly implements this. Let me know if you were thinking something else
@bdraco sorry I can't trace through that library at the moment to understand the approach.
I was thinking in session.ws_connect have a flag (not sure what to call it, maybe str_bytes=True) and if so either give the string bytes directly with WSMsgType.TEXT (or maybe more sensible to use WSMsgType.BINARY)
Look at how aioshelly implements this. Let me know if you were thinking something else
Isn't that just relying on orjson working with str? As far as I can see, decoding to str is not optional currently: https://github.com/aio-libs/aiohttp/blob/056d9297b2cb96c83466a3eaac3055acd9432229/aiohttp/_websocket/reader_py.py#L272-L274
https://github.com/home-assistant-libs/aioshelly/pull/713/files
But I just realized you care about the incoming not the outgoing
I was thinking in
session.ws_connecthave a flag (not sure what to call it, maybestr_bytes=True) and if so either give the string bytes directly withWSMsgType.TEXT(or maybe more sensible to useWSMsgType.BINARY)
You'd probably still want WSMsgType.TEXT since it has different semantic meaning than WSMsgType.BINARY.
It gets a bit messy because WSMessageText than can be str | bytes. Maybe we end up with WSMessageEncodedText but not sure how to handle that in 3.x.
I can see why you want it though as other libraries and yes, aioshelly have the same issue with the needless decode overhead that orjson will do for you.
It gets a bit messy because
WSMessageTextthan can bestr | bytes. Maybe we end up withWSMessageEncodedTextbut not sure how to handle that in 3.x.
Not sure how to handle that in any version. We should know whether it's str or bytes, so we probably need 2 types and need to figure out a way for the typing information to know which of the 2 message types we should be receiving.
I suspect that'll be fairly complex to figure out.
e.g. ClientWebSocketResponse may need to become Generic depending on the parameter, so that .receive() can have 2 different unions for the return type. Same for web side.
Managed to work it out. The actual change is about 7 lines.. and than another 100+ lines of typing :(
Without Unpack we have to write everything for ws_connect out for both
and we need Self as well to properly type it.
I gave up on the typing and closed https://github.com/aio-libs/aiohttp/pull/11764. It doesn't seem like we should add hundreds of lines of typing just to support this change
Another option would be to add the option to receive and a new api to receive_text_bytes
alternate approach which doesn't try to make it a Generic because that ballooned into something awful
https://github.com/aio-libs/aiohttp/pull/11765
@bdraco you are awesome for looking at this
does that #11765 seem like it will make it in eventually?
TBH, I'm not sure if we want to go with https://github.com/aio-libs/aiohttp/pull/11764 or https://github.com/aio-libs/aiohttp/pull/11765.
11764 got very large and is likely to be another 300 lines larger to fully finish it. Its about to get very busy for me as I wrap up the end of year items. I'm hoping to have some time during the end of year holiday to finish it up.
@projects2080 can you give https://github.com/aio-libs/aiohttp/pull/11764 a try?
hi @bdraco on holiday atm, will try it soon, thank you