class_docstr: A client for the Project API.
code: def _request_reply(self, method, params):
      if self.is_shutdown:  # pylint: disable=using-constant-test
          raise ConnectionShutdownError("connection already closed")
  
      request = {
          "jsonrpc": "2.0",
          "method": method,
          "params": params,
          "id": self.next_request_id,
      }
      self.next_request_id += 1
  
      request_str = json.dumps(request)
      self.write_file.write(request_str)
      _LOG.debug("send -> %s", request_str)
      self.write_file.write("\n")
      if self.testonly_did_write_request:
          self.testonly_did_write_request()  # Allow test to assert on server processing.
      reply_line = self.read_file.readline()
      _LOG.debug("recv <- %s", reply_line)
      if not reply_line:
          self.shutdown()
          raise ConnectionShutdownError(
              "got EOF reading reply from API server"
          )
  
      reply = json.loads(reply_line)
  
      if reply.get("jsonrpc") != "2.0":
          raise MalformedReplyError(
              f"Server reply should include 'jsonrpc': '2.0'; "
              f"saw jsonrpc={reply.get('jsonrpc')!r}"
          )
  
      if reply["id"] != request["id"]:
          raise MismatchedIdError(
              f"Reply id ({reply['id']}) does not equal request id ({request['id']}"
          )
  
      if "error" in reply:
          raise server.JSONRPCError.from_json(
              f"calling method {method}", reply["error"]
          )
  
      if "result" not in reply:
          raise MalformedReplyError(
              f"Expected 'result' key in server reply, got {reply!r}"
          )
  
      return reply["result"]
  
imports: import base64
  import io
  import json
  import logging
  import platform
  import os
  import pathlib
  import subprocess
  import sys
  import typing
  from .None import server
label_desc: Use image node_id 4 for calling the ProjectAPIClient obj's underlying member method code with example usage: obj._request_reply(method, params) and returns: reply