code: def save(self, draft: bool = False, clone: bool = False) -> "Report":
      if not self.modified:
          termwarn("Report has not been modified")
  
      # create project if not exists
      projects = self._api.projects(self.entity)
      is_new_project = True
      for p in projects:
          if p.name == self.project:
              is_new_project = False
              break
  
      if is_new_project:
          self._api.create_project(self.project, self.entity)
  
      # All panel grids must have at least one runset
      for pg in self.panel_grids:
          if not pg.runsets:
              pg.runsets = PanelGrid._default_runsets()
  
      # Check runsets with `None` for project and replace with the report's project.
      # We have to do this here because RunSets don't know about their report until they're added to it.
      for rs in self.runsets:
          rs.entity = coalesce(rs.entity, self._api.default_entity)
          rs.project = coalesce(rs.project, self.project)
  
      r = self._api.client.execute(
          UPSERT_VIEW,
          variable_values={
              "id": None if clone or not self.id else self.id,
              "name": generate_name()
              if clone or not self.name
              else self.name,
              "entityName": self.entity,
              "projectName": self.project,
              "description": self.description,
              "displayName": self.title,
              "type": "runs/draft" if draft else "runs",
              "spec": json.dumps(self.spec),
          },
      )
  
      viewspec = r["upsertView"]["view"]
      viewspec["spec"] = json.loads(viewspec["spec"])
      if clone:
          return Report.from_json(viewspec)
      else:
          self._viewspec["id"] = viewspec["id"]
          self._viewspec["name"] = viewspec["name"]
          return self
  
imports: import base64
  import inspect
  import json
  import re
  import urllib
  from copy import deepcopy
  from typing import List
  from ...None import __version__
  from ...None import termlog, termwarn
  from ...sdk.lib import ipython
  from ..public import Api
  from ..public import RetryingClient
  from ._blocks import P, PanelGrid, UnknownBlock, WeaveBlock, block_mapping, weave_blocks
  from .mutations import UPSERT_VIEW, VIEW_REPORT
  from .runset import Runset
  from .util import Attr, Base, Block, coalesce, generate_name, nested_get, nested_set
  from .validators import OneOf, TypeValidator
label_desc: Use image node_id 17 for calling the Report obj's underlying member method code with example usage: obj.save(draft, clone) and returns: Report, self