예제 #1
0
    def _ws_send_recv(self):
        to_server = SimulatorToServer()
        self._on_send(to_server)
        log.pb("to_server: {}".format(MessageToJson(to_server)))

        if (to_server.message_type):
            out_bytes = to_server.SerializeToString()
            try:
                yield self._ws.write_message(out_bytes, binary=True)
            except (StreamClosedError, WebSocketClosedError) as e:
                raise BonsaiServerError(
                    "Websocket connection closed. Code: {}, Reason: {}".format(
                        self._ws.close_code, self._ws.close_reason))

        # read response from server
        in_bytes = yield self._ws.read_message()
        if in_bytes is None:
            raise BonsaiServerError(
                "Websocket connection closed. Code: {}, Reason: {}".format(
                    self._ws.close_code, self._ws.close_reason))

        from_server = ServerToSimulator()
        from_server.ParseFromString(in_bytes)
        log.pb("from_server: {}".format(MessageToJson(from_server)))
        self._on_recv(from_server)
예제 #2
0
 def _handler(self, http_method, url, *args, **kwargs):
     try:
         return func(self, http_method, url, *args, **kwargs)
     except requests.exceptions.ConnectionError:
         message = \
             "{} Request failed. Unable to connect to domain: " \
                 "{}".format(http_method, url)
         raise BonsaiServerError(message)
     except requests.exceptions.Timeout:
         message = "{} Request failed. Request to {} timed out".format(
             http_method, url)
         raise BonsaiServerError(message)
예제 #3
0
    def run(self):
        """ Run loop called from Simulator. Encapsulates one round trip
        to the backend, which might include a simulation loop.
        """
        # Grab a web socket connection if needed
        if self._ws is None:
            message = yield self._connect()
            # If the connection failed, report
            if message is not None:
                raise BonsaiServerError(
                    "Error while connecting to websocket: {}".format(message))

        # If there is a batch of predictions cued up, step through it
        if self._prev_message_type == ServerToSimulator.PREDICTION:
            for step in self._sim_steps:
                self._advance(step)

        # send message to server
        to_server = SimulatorToServer()

        self._on_send(to_server)

        if (to_server.message_type):
            out_bytes = to_server.SerializeToString()
            try:
                yield self._ws.write_message(out_bytes, binary=True)
            except (StreamClosedError, WebSocketClosedError) as e:
                raise BonsaiServerError(
                    "Websocket connection closed. Code: {}, Reason: {}".format(
                        self._ws.close_code, self._ws.close_reason))

        # read response from server
        in_bytes = yield self._ws.read_message()
        if in_bytes is None:
            raise BonsaiServerError(
                "Websocket connection closed. Code: {}, Reason: {}".format(
                    self._ws.close_code, self._ws.close_reason))

        from_server = ServerToSimulator()
        from_server.ParseFromString(in_bytes)
        self._on_recv(from_server)

        if self._prev_message_type == ServerToSimulator.FINISHED:
            yield self._ws.close()
            raise gen.Return(False)

        # You've come this far, celebrate!
        raise gen.Return(True)
예제 #4
0
 def _handle_message(self, message):
     """ Handles error messages returned from initial connection attempt """
     log.network('Handling the following message returned from ws:'
                 ' {}'.format(message))
     if isinstance(message, HTTPError):
         if message.code == 401:
             raise BonsaiServerError(
                 'Error while connecting to websocket: {}. '
                 'Please run \'bonsai configure\' again.'.format(message))
         if message.code == 404:
             raise BonsaiServerError(
                 'Error while connecting to websocket: {}'.format(message))
     if not self._retry_timeout_seconds:
         raise BonsaiServerError(
             'Error while connecting to websocket: {}'.format(message))
     log.network('Error while connecting to websocket: {}'.format(message))
예제 #5
0
    def _try_http_request(self, http_method, url, data):
        """
        param: http_method -> String: Http method for request, I.E. "GET"
        param: url -> String: url to send request
        param: data -> JSON Formatted Dictionary: json data to send with request
        """

        log.api('Sending {} request to {}'.format(http_method, url))
        request_id = str(uuid4())
        try:
            if http_method == 'GET':
                response = self._session.get(
                    url=url, allow_redirects=False,
                    timeout=self._timeout, headers={'RequestId': request_id})

            elif http_method == 'PUT':
                response = self._session.put(
                    url=url, data=data, headers={'RequestId': request_id},
                    allow_redirects=False, timeout=self._timeout)

            elif http_method == 'POST':
                response = self._session.post(
                    url=url, data=data, allow_redirects=False,
                    timeout=self._timeout, headers={'RequestId': request_id})

            elif http_method == 'DELETE':
                response = self._session.delete(
                    url=url, allow_redirects=False,
                    timeout=self._timeout, headers={'RequestId': request_id})
            else:
                raise UsageError('UNSUPPORTED HTTP METHOD')
        except requests.exceptions.ConnectionError:
            message = \
                "Connection Error, {} Request failed. Unable to connect to " \
                "domain: {}\nRequest ID: {}".format(http_method, url, request_id)
            raise BonsaiServerError(message)
        except requests.exceptions.Timeout:
            message = "{} Request failed. Request to {} timed out" \
                "\nRequest ID: {}".format(http_method, url, request_id)
            raise BonsaiServerError(message)

        try:
            response.raise_for_status()
            self._log_response(response, request_id)
        except requests.exceptions.HTTPError as err:
            self._handle_http_error(response, request_id)
        return self._dict(response)
예제 #6
0
 def _handle_http_error(response):
     """
     :param response: The response from the server.
     """
     try:
         message = 'Request failed with error message:\n{}'.format(
             response.json()["error"])
     except ValueError:
         message = 'Request failed.'
     raise BonsaiServerError(message)
예제 #7
0
    def get_next_event(self):
        """ Update the internal event machine and return the next
        event for processing"""
        # Grab a web socket connection if needed
        if self._ws is None:
            message = yield self._connect()
            # If the connection failed, report
            if message is not None:
                raise BonsaiServerError(
                    "Error while connecting to websocket: {}".format(message))

        if self._prev_message_type == ServerToSimulator.PREDICTION:
            if self._prev_step_terminal[0]:
                self._prev_step_terminal[0] = False
                self._prev_step_finish = True
                event = EpisodeFinishEvent()
            else:
                event = self._process_sim_step()
            if event is not None:
                raise gen.Return(event)

        yield self._ws_send_recv()

        pmt = self._prev_message_type
        if pmt == ServerToSimulator.ACKNOWLEDGE_REGISTER:
            if self._sim.predict:
                self._initial_state = self._new_state_message()
                event = EpisodeStartEvent(self._init_properties,
                                          self._initial_state)
                self._prev_step_finish = False
            else:
                event = UnknownEvent()
        if pmt == ServerToSimulator.SET_PROPERTIES or \
           pmt == ServerToSimulator.RESET:
            event = UnknownEvent()
        elif pmt == ServerToSimulator.STOP:
            if self._prev_step_finish:
                event = UnknownEvent()
                self._prev_step_finish = False
            else:
                event = EpisodeFinishEvent()
        elif pmt == ServerToSimulator.START:
            self._initial_state = self._new_state_message()
            event = EpisodeStartEvent(self._init_properties,
                                      self._initial_state)
            self._prev_step_finish = False
        elif pmt == ServerToSimulator.PREDICTION:
            event = self._process_sim_step()
        elif pmt == ServerToSimulator.FINISHED:
            event = FinishedEvent()
        else:
            event = UnknownEvent()

        raise gen.Return(event)
예제 #8
0
 def _handle_message(self, message):
     """ Handles error messages returned from initial connection attempt """
     log.network(
         'Handling the following message returned from ws:'
         ' {}'.format(message))
     if isinstance(message, WSServerHandshakeError):
         if message.code == 401:
             raise BonsaiServerError(
                 'Error while connecting to websocket: 401 - Unauthorized. '
                 'Please run \'bonsai configure\' again.')
         if message.code == 403:
             raise BonsaiServerError(
                 'Error while connecting to websocket: 403 - Forbidden. '
                 'You may be using deprecated authorization methods. '
                 'Please run \'bonsai configure\' again.')
         if message.code == 404:
             raise BonsaiServerError(
                 'Error while connecting to websocket: 404 - Not Found.')
     if not self._retry_timeout_seconds:
         raise BonsaiServerError(
             'Error while connecting to websocket: {}'.format(message))
     log.network('Error while connecting to websocket: {}'.format(message))
예제 #9
0
    def handle_disconnect(self, message=None):
        log.network('Handling disconnect')
        self._thread_stop.set()
        if message:
            self._handle_message(message)

        if self._ws:
            if self._websocket_should_not_reconnect():
                raise BonsaiServerError(
                    'Websocket connection closed. Code: {}, Reason: {}'.format(
                        self._ws.close_code, self._ws.close_reason))
            log.network('ws_close_code: {}, ws_close_reason: {}.'.format(
                self._ws.close_code, self._ws.close_reason))
        self.close()
        log.network('Disconnect handled.')
예제 #10
0
    def _handle_http_error(response, request_id):
        """
        :param response: The response from the server.
        """
        try:
            message = 'Request failed with error code "{}", error message:\n{}'.format(
                response.json()["error"]["code"],
                response.json()["error"]["message"])
        except ValueError:
            message = 'Request failed.'

        message += '\nRequest ID: {}'.format(request_id)

        try:
            message += '\nSpan ID: {}'.format(response.headers['SpanID'])
        except KeyError:
            pass

        raise BonsaiServerError(message)
예제 #11
0
 def _raise(msg):
     raise BonsaiServerError(
         "Received unknown message ({}) from server".format(
             msg.message_type))
예제 #12
0
 def _unsupported(self, to_server):
     descriptor = ServerToSimulator.MessageType.DESCRIPTOR
     raise BonsaiServerError("Unexpected Message during {}: {}".format(
         "prediction" if self._sim.predict else "training",
         descriptor.values_by_number[self._prev_message_type].name))