multipart.py 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. # Copyright (c) Meta Platforms, Inc. and affiliates.
  2. # All rights reserved.
  3. # This source code is licensed under the license found in the
  4. # LICENSE file in the root directory of this source tree.
  5. from typing import Dict, Union
  6. class MultipartResponseBuilder:
  7. message: bytes
  8. def __init__(self, boundary: str) -> None:
  9. self.message = b"--" + boundary.encode("utf-8") + b"\r\n"
  10. @classmethod
  11. def build(
  12. cls, boundary: str, headers: Dict[str, str], body: Union[str, bytes]
  13. ) -> "MultipartResponseBuilder":
  14. builder = cls(boundary=boundary)
  15. for k, v in headers.items():
  16. builder.__append_header(key=k, value=v)
  17. if isinstance(body, bytes):
  18. builder.__append_body(body)
  19. elif isinstance(body, str):
  20. builder.__append_body(body.encode("utf-8"))
  21. else:
  22. raise ValueError(
  23. f"body needs to be of type bytes or str but got {type(body)}"
  24. )
  25. return builder
  26. def get_message(self) -> bytes:
  27. return self.message
  28. def __append_header(self, key: str, value: str) -> "MultipartResponseBuilder":
  29. self.message += key.encode("utf-8") + b": " + value.encode("utf-8") + b"\r\n"
  30. return self
  31. def __close_header(self) -> "MultipartResponseBuilder":
  32. self.message += b"\r\n"
  33. return self
  34. def __append_body(self, body: bytes) -> "MultipartResponseBuilder":
  35. self.__append_header(key="Content-Length", value=str(len(body)))
  36. self.__close_header()
  37. self.message += body
  38. return self