feat: add optional libtw2 huffman backend
Prefer libtw2 over TeeAI huffman but do not install it by default. Thanks to @heinrich5991 for porting his rust code to python.
This commit is contained in:
parent
ec507c0dcc
commit
d9c5f0d066
23
README.md
23
README.md
|
@ -125,6 +125,29 @@ packet.messages.append(msg)
|
|||
packet.pack() # => b'\x02~\x06H\x1f\x93\xd7\x00\x00\x80\x01option\x00test\x00\x00\x00'
|
||||
```
|
||||
|
||||
## Zero dependencies by default
|
||||
|
||||
Running ``pip install twnet_parser`` will not install any additional packages.
|
||||
|
||||
But there is an optional dependency for huffman compression.
|
||||
By default twnet_parser is using the huffman compression code from the [TeeAI](https://github.com/edg-l/TeeAI)
|
||||
project which is written in pure python.
|
||||
If you have [libtw2-huffman](https://pypi.org/project/libtw2-huffman/) installed it will use that one instead.
|
||||
Because it is faster since it is written in rust and has better error handling.
|
||||
But since it is so much overhead it is not installed by default to keep twnet_parser light weight.
|
||||
|
||||
|
||||
You can install it by running ``pip install libtw2-huffman``
|
||||
or by running ``pip install -r requirements/optional.txt``
|
||||
|
||||
|
||||
You can also check which huffman backend is currently active with these lines of code
|
||||
|
||||
```python
|
||||
import twnet_parser.huffman
|
||||
print(twnet_parser.huffman.backend_name()) # => rust-libtw2 or python-TeeAI
|
||||
```
|
||||
|
||||
## development setup
|
||||
|
||||
```bash
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
-r prod.txt
|
||||
-r optional.txt
|
||||
astroid==2.15.0
|
||||
attrs==22.2.0
|
||||
bleach==6.0.0
|
||||
|
|
1
requirements/optional.txt
Normal file
1
requirements/optional.txt
Normal file
|
@ -0,0 +1 @@
|
|||
libtw2-huffman==0.2.0
|
24
twnet_parser/huffman.py
Normal file
24
twnet_parser/huffman.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
from twnet_parser.external.huffman import huffman
|
||||
|
||||
HAS_LIBTW2 = False
|
||||
|
||||
try:
|
||||
import libtw2_huffman # type: ignore
|
||||
HAS_LIBTW2 = True
|
||||
except ImportError:
|
||||
HAS_LIBTW2 = False
|
||||
|
||||
def backend_name() -> str:
|
||||
if HAS_LIBTW2:
|
||||
return 'rust-libtw2'
|
||||
return 'python-TeeAI'
|
||||
|
||||
def compress(data: bytes) -> bytes:
|
||||
if HAS_LIBTW2:
|
||||
return libtw2_huffman.compress(data)
|
||||
return huffman.decompress(bytearray(data))
|
||||
|
||||
def decompress(data: bytes) -> bytes:
|
||||
if HAS_LIBTW2:
|
||||
return libtw2_huffman.decompress(data)
|
||||
return huffman.decompress(bytearray(data))
|
|
@ -15,7 +15,7 @@ from twnet_parser.msg_matcher.control6 import match_control6
|
|||
from twnet_parser.msg_matcher.connless6 import match_connless6
|
||||
from twnet_parser.constants import NET_MAX_SEQUENCE, NET_PACKETVERSION
|
||||
|
||||
from twnet_parser.external.huffman import huffman
|
||||
import twnet_parser.huffman
|
||||
|
||||
# TODO: what is a nice pythonic way of storing those?
|
||||
# also does some version:: namespace thing make sense?
|
||||
|
@ -419,7 +419,7 @@ class PacketParser():
|
|||
return pck
|
||||
if pck.header.flags.compression:
|
||||
payload = bytearray(pck.payload_raw)
|
||||
pck.payload_decompressed = huffman.decompress(payload)
|
||||
pck.payload_decompressed = twnet_parser.huffman.decompress(payload)
|
||||
pck.messages = cast(
|
||||
list[Union[CtrlMessage, NetMessage, ConnlessMessage]],
|
||||
self.get_messages(pck.payload_decompressed))
|
||||
|
@ -448,7 +448,7 @@ class PacketParser():
|
|||
return pck
|
||||
if pck.header.flags.compression:
|
||||
payload = bytearray(pck.payload_raw)
|
||||
pck.payload_decompressed = huffman.decompress(payload)
|
||||
pck.payload_decompressed = twnet_parser.huffman.decompress(payload)
|
||||
pck.messages = cast(
|
||||
list[Union[CtrlMessage, NetMessage, ConnlessMessage]],
|
||||
self.get_messages(pck.payload_decompressed))
|
||||
|
|
Loading…
Reference in a new issue