text: Title: Refactor: use `Literal` in type hints
  Body: Right now we don't really use `Literal` types anywhere, but we should.
  For example, see the following signature:
  ```python
      @classmethod
      def from_bytes(
          cls: Type[T],
          data: bytes,
          protocol: str = 'protobuf',
          compress: Optional[str] = None,
      ) -> T:
          """Build Document object from binary bytes
  
          :param data: binary bytes
          :param protocol: protocol to use. It can be 'pickle' or 'protobuf'
          :param compress: compress method to use
          :return: a Document object
          """
  ```
  Here, `protocol` can only be `'pickle' or 'protobuf'`, so `Literal['pickle', 'protobuf']` would be the most suitable type hint.
  Changing that will require multiple other changes in order to keep mypy happy, since other code relies on protocol being `str`.
  
  This issue is about adjusting the above, and identifying and fixing other similar instances (if they exists).
  