diff --git a/lazyops/libs/compress/__init__.py b/lazyops/libs/compress/__init__.py new file mode 100644 index 0000000..a2e0086 --- /dev/null +++ b/lazyops/libs/compress/__init__.py @@ -0,0 +1,20 @@ +""" +Compression Utilities +""" + +from typing import Union +from .base import BaseCompress +from .gz import GzipCompress +from .lz import Lz4Compress +from .zb import ZLibCompress +from .ztd import ZStdCompress + +CompressionT = Union[BaseCompress, GzipCompress] + +class Compress: + + gzip = GzipCompress + zstd = ZStdCompress + zlib = ZLibCompress + lz4 = Lz4Compress + \ No newline at end of file diff --git a/lazyops/libs/compress/base.py b/lazyops/libs/compress/base.py new file mode 100644 index 0000000..74a8eb2 --- /dev/null +++ b/lazyops/libs/compress/base.py @@ -0,0 +1,36 @@ +import abc +from typing import Union +from lazyops.utils.pooler import ThreadPoolV2 as ThreadPooler + +class BaseCompress(abc.ABC): + + @abc.abstractclassmethod + def compress(cls, data: Union[str, bytes], **kwargs) -> bytes: + """ + Base Compress + """ + pass + + @abc.abstractclassmethod + def decompress(cls, data: Union[str, bytes], **kwargs) -> bytes: + """ + Base Decompress + """ + pass + + + @abc.abstractclassmethod + async def acompress(cls, data: Union[str, bytes], **kwargs) -> bytes: + """ + Base Compress + """ + return await ThreadPooler.run_async(cls.compress, data, **kwargs) + + @abc.abstractclassmethod + async def adecompress(cls, data: Union[str, bytes], **kwargs) -> bytes: + """ + Base Decompress + """ + return await ThreadPooler.run_async(cls.decompress, data, **kwargs) + + diff --git a/lazyops/libs/compress/gz.py b/lazyops/libs/compress/gz.py new file mode 100644 index 0000000..0579a3a --- /dev/null +++ b/lazyops/libs/compress/gz.py @@ -0,0 +1,26 @@ +""" +GZIP Compress +""" + +import gzip +from .base import BaseCompress +from typing import Union + +class GzipCompress(BaseCompress): + + @classmethod + def compress(cls, data: Union[str, bytes], encoding: str = 'utf-8', **kwargs) -> bytes: + """ + GZip Compress + """ + if isinstance(data, str): data = data.encode(encoding) + return gzip.compress(data) + + @classmethod + def decompress(cls, data: Union[str, bytes], encoding: str = 'utf-8', **kwargs) -> bytes: + """ + GZip Decompress + """ + if isinstance(data, str): data = data.encode(encoding = encoding) + return gzip.decompress(data) + diff --git a/lazyops/libs/compress/lz.py b/lazyops/libs/compress/lz.py new file mode 100644 index 0000000..4af14dd --- /dev/null +++ b/lazyops/libs/compress/lz.py @@ -0,0 +1,47 @@ +""" +LZ4 Compress +""" + +from .base import BaseCompress +from typing import Union + +try: + import lz4.frame + _lz4_available = True +except ImportError: + _lz4_available = False + +def ensure_lz4_available(): + """ + Ensure LZ4 is available + """ + global _lz4_available, lz4 + if _lz4_available is False: + from lazyops.utils.imports import resolve_missing + resolve_missing('lz4', required = True) + import lz4.frame + _lz4_available = True + globals()['lz4'] = lz4 + + +class Lz4Compress(BaseCompress): + + + @classmethod + def compress(cls, data: Union[str, bytes], encoding: str = 'utf-8', **kwargs) -> bytes: + """ + LZ4 Compress + """ + ensure_lz4_available() + if isinstance(data, str): data = data.encode(encoding) + return lz4.frame.compress(data) + + @classmethod + def decompress(cls, data: Union[str, bytes], encoding: str = 'utf-8', **kwargs) -> bytes: + """ + LZ4 Decompress + """ + ensure_lz4_available() + if isinstance(data, str): data = data.encode(encoding = encoding) + return lz4.frame.decompress(data) + diff --git a/lazyops/libs/compress/zb.py b/lazyops/libs/compress/zb.py new file mode 100644 index 0000000..9be9f03 --- /dev/null +++ b/lazyops/libs/compress/zb.py @@ -0,0 +1,26 @@ +""" +ZLib Compress +""" + +import zlib +from .base import BaseCompress +from typing import Union + +class ZLibCompress(BaseCompress): + + @classmethod + def compress(cls, data: Union[str, bytes], encoding: str = 'utf-8', **kwargs) -> bytes: + """ + ZLib Compress + """ + if isinstance(data, str): data = data.encode(encoding) + return zlib.compress(data) + + @classmethod + def decompress(cls, data: Union[str, bytes], encoding: str = 'utf-8', **kwargs) -> bytes: + """ + ZLib Decompress + """ + if isinstance(data, str): data = data.encode(encoding = encoding) + return zlib.decompress(data) + diff --git a/lazyops/libs/compress/ztd.py b/lazyops/libs/compress/ztd.py new file mode 100644 index 0000000..c0df151 --- /dev/null +++ b/lazyops/libs/compress/ztd.py @@ -0,0 +1,49 @@ +""" +ZStd Compress + +Note - ZStd doesn't work as well as it returned some errors when decompressing. +""" + +from .base import BaseCompress +from typing import Union + +try: + import zstd + _zstd_available = True +except ImportError: + _zstd_available = False + +def ensure_zstd_available(): + """ + Ensure Zstd is available + """ + global _zstd_available, zstd + if _zstd_available is False: + from lazyops.utils.imports import resolve_missing + resolve_missing('zstd', required = True) + import zstd + _zstd_available = True + globals()['zstd'] = zstd + + +class ZStdCompress(BaseCompress): + + + @classmethod + def compress(cls, data: Union[str, bytes], encoding: str = 'utf-8', **kwargs) -> bytes: + """ + ZStd Compress + """ + ensure_zstd_available() + if isinstance(data, str): data = data.encode(encoding) + return zstd.compress(data) + + @classmethod + def decompress(cls, data: Union[str, bytes], encoding: str = 'utf-8', **kwargs) -> bytes: + """ + ZStd Decompress + """ + ensure_zstd_available() + if isinstance(data, str): data = data.encode(encoding = encoding) + return zstd.decompress(data) + diff --git a/lazyops/version.py b/lazyops/version.py index 1348742..6d68e80 100644 --- a/lazyops/version.py +++ b/lazyops/version.py @@ -1 +1 @@ -VERSION = '0.2.62rc11' +VERSION = '0.2.62rc12'