def _serve_debugger_graph(self, request):
        device_name = request.args.get('device_name')
        if not device_name or device_name == 'null':
            return http_util.Respond(request, str(None), 'text/x-protobuf')

        run_key = interactive_debugger_server_lib.RunKey(
            *json.loads(request.args.get('run_key')))
        graph_def = self._debugger_data_server.get_graph(run_key, device_name)
        logger.debug(
            '_serve_debugger_graph(): device_name = %s, run_key = %s, '
            'type(graph_def) = %s', device_name, run_key, type(graph_def))
        # TODO(cais): Sending text proto may be slow in Python. Investigate whether
        # there are ways to optimize it.
        return http_util.Respond(request, str(graph_def), 'text/x-protobuf')
    def _serve_gated_grpc(self, request):
        mode = request.args.get("mode")
        if mode == "retrieve_all" or mode == "retrieve_device_names":
            # 'retrieve_all': Retrieve all gated-gRPC debug tensors and currently
            #   enabled breakpoints associated with the given run_key.
            # 'retrieve_device_names': Retrieve all device names associated with the
            #   given run key.
            run_key = interactive_debugger_server_lib.RunKey(
                *json.loads(request.args.get("run_key")))
            # debug_graph_defs is a map from device_name to GraphDef.
            debug_graph_defs = self._debugger_data_server.get_graphs(
                run_key, debug=True)
            if mode == "retrieve_device_names":
                return http_util.Respond(
                    request,
                    {
                        "device_names": list(debug_graph_defs.keys()),
                    },
                    "application/json",
                )

            gated = {}
            for device_name in debug_graph_defs:
                gated[
                    device_name] = self._debugger_data_server.get_gated_grpc_tensors(
                        run_key, device_name)

            # Both gated and self._debugger_data_server.breakpoints are lists whose
            # items are (node_name, output_slot, debug_op_name).
            return http_util.Respond(
                request,
                {
                    "gated_grpc_tensors": gated,
                    "breakpoints": self._debugger_data_server.breakpoints,
                    "device_names": list(debug_graph_defs.keys()),
                },
                "application/json",
            )
        elif mode == "breakpoints":
            # Retrieve currently enabled breakpoints.
            return http_util.Respond(
                request,
                self._debugger_data_server.breakpoints,
                "application/json",
            )
        elif mode == "set_state":
            # Set the state of gated-gRPC debug tensors, e.g., disable, enable
            # breakpoint.
            node_name = request.args.get("node_name")
            output_slot = int(request.args.get("output_slot"))
            debug_op = request.args.get("debug_op")
            state = request.args.get("state")
            logger.debug("Setting state of %s:%d:%s to: %s" %
                         (node_name, output_slot, debug_op, state))
            if state == "disable":
                self._debugger_data_server.request_unwatch(
                    node_name, output_slot, debug_op)
            elif state == "watch":
                self._debugger_data_server.request_watch(node_name,
                                                         output_slot,
                                                         debug_op,
                                                         breakpoint=False)
            elif state == "break":
                self._debugger_data_server.request_watch(node_name,
                                                         output_slot,
                                                         debug_op,
                                                         breakpoint=True)
            else:
                return self._error_response(
                    request,
                    "Unrecognized new state for %s:%d:%s: %s" %
                    (node_name, output_slot, debug_op, state),
                )
            return http_util.Respond(
                request,
                {
                    "node_name": node_name,
                    "output_slot": output_slot,
                    "debug_op": debug_op,
                    "state": state,
                },
                "application/json",
            )
        else:
            return self._error_response(
                request,
                "Unrecognized mode for the gated_grpc route: %s" % mode)
    def _serve_gated_grpc(self, request):
        mode = request.args.get('mode')
        if mode == 'retrieve_all' or mode == 'retrieve_device_names':
            # 'retrieve_all': Retrieve all gated-gRPC debug tensors and currently
            #   enabled breakpoints associated with the given run_key.
            # 'retrieve_device_names': Retrieve all device names associated with the
            #   given run key.
            run_key = interactive_debugger_server_lib.RunKey(
                *json.loads(request.args.get('run_key')))
            # debug_graph_defs is a map from device_name to GraphDef.
            debug_graph_defs = self._debugger_data_server.get_graphs(
                run_key, debug=True)
            if mode == 'retrieve_device_names':
                return http_util.Respond(
                    request, {
                        'device_names': list(debug_graph_defs.keys()),
                    }, 'application/json')

            gated = {}
            for device_name in debug_graph_defs:
                gated[
                    device_name] = self._debugger_data_server.get_gated_grpc_tensors(
                        run_key, device_name)

            # Both gated and self._debugger_data_server.breakpoints are lists whose
            # items are (node_name, output_slot, debug_op_name).
            return http_util.Respond(
                request, {
                    'gated_grpc_tensors': gated,
                    'breakpoints': self._debugger_data_server.breakpoints,
                    'device_names': list(debug_graph_defs.keys()),
                }, 'application/json')
        elif mode == 'breakpoints':
            # Retrieve currently enabled breakpoints.
            return http_util.Respond(request,
                                     self._debugger_data_server.breakpoints,
                                     'application/json')
        elif mode == 'set_state':
            # Set the state of gated-gRPC debug tensors, e.g., disable, enable
            # breakpoint.
            node_name = request.args.get('node_name')
            output_slot = int(request.args.get('output_slot'))
            debug_op = request.args.get('debug_op')
            state = request.args.get('state')
            logger.debug('Setting state of %s:%d:%s to: %s' %
                         (node_name, output_slot, debug_op, state))
            if state == 'disable':
                self._debugger_data_server.request_unwatch(
                    node_name, output_slot, debug_op)
            elif state == 'watch':
                self._debugger_data_server.request_watch(node_name,
                                                         output_slot,
                                                         debug_op,
                                                         breakpoint=False)
            elif state == 'break':
                self._debugger_data_server.request_watch(node_name,
                                                         output_slot,
                                                         debug_op,
                                                         breakpoint=True)
            else:
                return self._error_response(
                    request, 'Unrecognized new state for %s:%d:%s: %s' %
                    (node_name, output_slot, debug_op, state))
            return http_util.Respond(
                request, {
                    'node_name': node_name,
                    'output_slot': output_slot,
                    'debug_op': debug_op,
                    'state': state
                }, 'application/json')
        else:
            return self._error_response(
                request,
                'Unrecognized mode for the gated_grpc route: %s' % mode)