code: def device(self, s1_mode, s2_mode):
      backend = get_backend()
      ip_ext, _, _ = backend.get_listen_addr()
      ip_bind = "0.0.0.0"
      addr_bind = "tcp://{}".format(ip_bind)
  
      s1_type = self._mode_to_type[s1_mode]
      s2_type = self._mode_to_type[s2_mode]
  
      device = zmq.devices.ThreadDevice(
          in_type=s1_type, out_type=s2_type
      )
      _writer_port = device.bind_in_to_random_port(
          addr_bind, min_port=MIN_PORT, max_port=MAX_PORT, max_tries=100
      )
      _reader_port = device.bind_out_to_random_port(
          addr_bind, min_port=MIN_PORT, max_port=MAX_PORT, max_tries=100
      )
      _reader_ext_addr = "tcp://{}:{}".format(ip_ext, _reader_port)
      _writer_ext_addr = "tcp://{}:{}".format(ip_ext, _writer_port)
      return device, _reader_ext_addr, _writer_ext_addr
  
imports: import random
  import logging
  import multiprocessing
  import threading
  from fiber.backend import get_backend
label_desc: Use image node_id 5 for calling the ZMQContext obj's underlying member method code with example usage: obj.device(s1_mode, s2_mode) and returns: device,  _reader_ext_addr,  _writer_ext_addr