_compression.py 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. from __future__ import annotations
  2. from typing import TYPE_CHECKING
  3. from connectrpc.compression.gzip import GzipCompression
  4. from .compression import Compression
  5. if TYPE_CHECKING:
  6. from collections.abc import Iterable
  7. class IdentityCompression(Compression):
  8. def name(self) -> str:
  9. return "identity"
  10. def compress(self, data: bytes | bytearray | memoryview) -> bytes:
  11. """Return data as-is without compression."""
  12. return data if isinstance(data, bytes) else bytes(data)
  13. def decompress(self, data: bytes | bytearray | memoryview) -> bytes:
  14. """Return data as-is without decompression."""
  15. return data if isinstance(data, bytes) else bytes(data)
  16. _identity = IdentityCompression()
  17. _gzip = GzipCompression()
  18. _default_compressions: dict[str, Compression] = {"gzip": _gzip, "identity": _identity}
  19. def resolve_compressions(
  20. compressions: Iterable[Compression] | None,
  21. ) -> dict[str, Compression]:
  22. if compressions is None:
  23. return _default_compressions
  24. res = {comp.name(): comp for comp in compressions}
  25. # identity is always supported
  26. res["identity"] = _identity
  27. return res
  28. def negotiate_compression(
  29. accept_encoding: str, compressions: dict[str, Compression]
  30. ) -> Compression:
  31. for accept in accept_encoding.split(","):
  32. compression = compressions.get(accept.strip())
  33. if compression:
  34. return compression
  35. return _identity