class_docstr: Low-level API client for interacting with dstack server. Implements all API endpoints
  
  Attributes:
      users: operations with users
      projects: operations with projects
      backends: operations with backends
      runs: operations with runs
      logs: operations with logs
      gateways: operations with gateways
class_docstr_tok: ["Low-level","API","client","for","interacting","with","dstack","server",".","Implements","all","API","endpoints","Attributes",":","users",":","operations","with","users","projects",":","operations","with","projects","backends",":","operations","with","backends","runs",":","operations","with","runs","logs",":","operations","with","logs","gateways",":","operations","with","gateways"]
code: def _request(
      self,
      path: str,
      body: Optional[str] = None,
      raise_for_status: bool = True,
      **kwargs,
  ) -> requests.Response:
      path = path.lstrip("/")
      if body is not None:
          kwargs.setdefault("headers", {})[
              "Content-Type"
          ] = "application/json"
          kwargs["data"] = body
  
      logger.debug("POST /%s", path)
      for _ in range(_MAX_RETRIES):
          try:
              resp = self._s.post(f"{self._base_url}/{path}", **kwargs)
              break
          except requests.exceptions.ConnectionError as e:
              logger.debug("Could not connect to server: %s", e)
              time.sleep(_RETRY_INTERVAL)
      else:
          raise ClientError(
              f"Failed to connect to dstack server {self._base_url}"
          )
  
      if raise_for_status:
          if resp.status_code == 500:
              raise ClientError("Unexpected dstack server error")
          if resp.status_code == 400:  # raise ServerClientError
              detail: List[Dict] = resp.json()["detail"]
              if (
                  len(detail) == 1
                  and detail[0]["code"] in _server_client_errors
              ):
                  kwargs = detail[0]
                  code = kwargs.pop("code")
                  raise _server_client_errors[code](**kwargs)
          resp.raise_for_status()
      return resp
  
imports: import os
  import time
  from typing import Dict, List, Optional, Type
  import requests
  from dstack import version
  from dstack._internal.core.errors import ClientError, ServerClientError
  from dstack._internal.utils.logging import get_logger
  from dstack.api.server._backends import BackendsAPIClient
  from dstack.api.server._gateways import GatewaysAPIClient
  from dstack.api.server._logs import LogsAPIClient
  from dstack.api.server._projects import ProjectsAPIClient
  from dstack.api.server._repos import ReposAPIClient
  from dstack.api.server._runs import RunsAPIClient
  from dstack.api.server._secrets import SecretsAPIClient
  from dstack.api.server._users import UsersAPIClient
label_desc: Use image node_id 10 for calling the APIClient obj's underlying member method code with example usage: obj._request(path, body, raise_for_status) and returns: resp