Repository: mosecorg/mosec (language: python)

Issue:
[BUG]NameError: name 'plasma' is not defined
**Describe the bug**
NameError: name 'plasma' is not defined

**To Reproduce**
Steps to reproduce the behavior:
```
import base64
import json
import os

import cv2
import numpy as np
import yaml
from mosec import Worker, Server
from mosec.errors import ValidationError

from inference import Inference


def _get_model():
    if os.path.exists('config.yaml'):
        config = open('config.yaml', mode='r', encoding='utf-8')
        config = yaml.load(config, Loader=yaml.FullLoader)

        model = Inference(
            det_model_path=config['det_model_path'],
            rec_model_path=config['rec_model_path'],
            device=config['device'],
            dict_path=config['dict_path'],
            rec_std=0.5, rec_mean=0.5, threshold=0.7,
            angle_classes=config['angle_classes'],
            angle_classify_model_path=config['angle_model_path'],
            object_classes=None,
            object_classify_model_path=None
        )
        return model, config
    else:
        raise FileNotFoundError('must have a config.yaml file!')


class OCRInference(Worker):
    def __init__(self):
        super(OCRInference, self).__init__()
        self.model, self.config = _get_model()

    def forward(self, req: dict):
        try:
            image = req["image"]
            save_name = req['saveName']
            im = np.frombuffer(base64.b64decode(image), np.uint8)
            im = cv2.imdecode(im, 1)
            result = self.model.infer(img=im,
                                      img_save_name=save_name,
                                      cut_image_save_path=self.config['cut_image_save_path'],
                                      need_angle=self.config['need_angle'],
                                      need_object=self.config['need_object'])
            return json.dumps({'status': 1, 'result': result})

        except KeyError as err:
            raise ValidationError(f"cannot find key {err}")
        except Exception as err:
            raise ValidationError(f"cannot decode as image data: {err}")


if __name__ == "__main__":
    server = Server()

    server.append_worker(OCRInference, num=2, max_batch_size=16)
    server.run()

```

**Desktop (please complete the following information):**
 - OS: [e.g. Ubuntu 20.04]
 - Library Version: [e.g. 0.1.0]
 - Rust Version: [e.g. 1.55.0]
 - Python Version: [e.g. 3.8.5]

**Additional context**
Add any other context about the problem here.



Discussion / hints:
 ok we must install `pyarrow`
Thanks for your feedback.

`plasma` is required in the shared memory feature. This shouldn't be imported when the feature is not enabled. We will fix it.

Fix patch:
diff --git a/Cargo.lock b/Cargo.lock
index 3756fa13..b766e654 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -355,7 +355,7 @@ dependencies = [
 
 [[package]]
 name = "mosec"
-version = "0.3.0"
+version = "0.3.1"
 dependencies = [
  "async-channel",
  "bytes",
diff --git a/Cargo.toml b/Cargo.toml
index 354214c4..70b854ca 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "mosec"
-version = "0.3.0"
+version = "0.3.1"
 authors = ["Keming <kemingy94@gmail.com>", "Zichen <lkevinzc@gmail.com>"]
 edition = "2021"
 license = "Apache-2.0"
diff --git a/mosec/_version.py b/mosec/_version.py
index 493f7415..260c070a 100644
--- a/mosec/_version.py
+++ b/mosec/_version.py
@@ -1,1 +1,1 @@
-__version__ = "0.3.0"
+__version__ = "0.3.1"
diff --git a/mosec/coordinator.py b/mosec/coordinator.py
index 031edb0e..1c6d1acc 100644
--- a/mosec/coordinator.py
+++ b/mosec/coordinator.py
@@ -10,7 +10,7 @@
 from typing import Any, Callable, List, Optional, Tuple, Type
 
 from .errors import DecodingError, ValidationError
-from .plugins.ipc_wrapper import IPCWrapper
+from .ipc import IPCWrapper
 from .protocol import Protocol
 from .worker import Worker
 
diff --git a/mosec/ipc.py b/mosec/ipc.py
new file mode 100644
index 00000000..f75ec1f5
--- /dev/null
+++ b/mosec/ipc.py
@@ -0,0 +1,31 @@
+import abc
+from typing import List
+
+
+class IPCWrapper(abc.ABC):
+    """
+    This public class defines the mosec IPC wrapper plugin interface.
+    The wrapper has to at least implement `put` and `get` method.
+    """
+
+    @abc.abstractmethod
+    def put(self, data: List[bytes]) -> List[bytes]:
+        """Put bytes to somewhere to get ids, which are sent via protocol.
+
+        Args:
+            data (List[bytes]): List of bytes data.
+
+        Returns:
+            List[bytes]: List of bytes ID.
+        """
+
+    @abc.abstractmethod
+    def get(self, ids: List[bytes]) -> List[bytes]:
+        """Get bytes from somewhere by ids, which are received via protocol.
+
+        Args:
+            ids (List[bytes]): List of bytes ID.
+
+        Returns:
+            List[bytes]: List of bytes data.
+        """
diff --git a/mosec/plugins/__init__.py b/mosec/plugins/__init__.py
index 628bae1a..1bff8e98 100644
--- a/mosec/plugins/__init__.py
+++ b/mosec/plugins/__init__.py
@@ -1,3 +1,3 @@
-from .ipc_wrapper import IPCWrapper, PlasmaShmWrapper
+from .plasma_shm import PlasmaShmWrapper
 
-__all__ = ["IPCWrapper", "PlasmaShmWrapper"]
+__all__ = ["PlasmaShmWrapper"]
diff --git a/mosec/plugins/ipc_wrapper.py b/mosec/plugins/plasma_shm.py
similarity index 64%
rename from mosec/plugins/ipc_wrapper.py
rename to mosec/plugins/plasma_shm.py
index d5d02a9b..45df1977 100644
--- a/mosec/plugins/ipc_wrapper.py
+++ b/mosec/plugins/plasma_shm.py
@@ -1,4 +1,3 @@
-import abc
 from typing import List
 
 try:
@@ -9,34 +8,7 @@
     plugins, because users may not enable them.
     """
 
-
-class IPCWrapper(abc.ABC):
-    """
-    This public class defines the mosec IPC wrapper plugin interface.
-    The wrapper has to at least implement `put` and `get` method.
-    """
-
-    @abc.abstractmethod
-    def put(self, data: List[bytes]) -> List[bytes]:
-        """Put bytes to somewhere to get ids, which are sent via protocol.
-
-        Args:
-            data (List[bytes]): List of bytes data.
-
-        Returns:
-            List[bytes]: List of bytes ID.
-        """
-
-    @abc.abstractmethod
-    def get(self, ids: List[bytes]) -> List[bytes]:
-        """Get bytes from somewhere by ids, which are received via protocol.
-
-        Args:
-            ids (List[bytes]): List of bytes ID.
-
-        Returns:
-            List[bytes]: List of bytes data.
-        """
+from ..ipc import IPCWrapper
 
 
 class PlasmaShmWrapper(IPCWrapper):
diff --git a/mosec/server.py b/mosec/server.py
index af02177f..700df543 100644
--- a/mosec/server.py
+++ b/mosec/server.py
@@ -17,7 +17,7 @@
 
 from .args import ArgParser
 from .coordinator import STAGE_EGRESS, STAGE_INGRESS, Coordinator
-from .plugins import IPCWrapper
+from .ipc import IPCWrapper
 from .worker import Worker
 
 logger = logging.getLogger(__name__)
diff --git a/setup.py b/setup.py
index 118790df..a9337dbb 100644
--- a/setup.py
+++ b/setup.py
@@ -107,7 +107,6 @@ def build_extension(self, ext: Extension):
             "msgpack>=1.0.2",
             "pre-commit>=2.15.0",
             "httpx>=0.19.0",
-            "pyarrow>=6.0.1",
         ],
         "doc": [
             "mkdocstrings>=0.16.0",


Test patch:
diff --git a/tests/test_service.py b/tests/test_service.py
index 576e0949..b2fa2e9b 100644
--- a/tests/test_service.py
+++ b/tests/test_service.py
@@ -44,10 +44,12 @@ def square_service():
 @pytest.fixture(scope="session")
 def square_service_shm():
     port = "8091"
+    subprocess.call(["pip", "install", "pyarrow"])
     service = start_service("square_service_shm", port)
     time.sleep(2)  # wait for service to start
     assert not service.poll(), service.stdout.read().decode("utf-8")
     yield port
+    subprocess.call(["pip", "uninstall", "pyarrow", "-y"])
     service.terminate()