class_docstr: Graph drawer that sends/receives graphs to/from Cytoscape using
  CytoscapeRPC.
  
  This graph drawer cooperates with U{Cytoscape<http://www.cytoscape.org>}
  using U{CytoscapeRPC<http://wiki.nbic.nl/index.php/CytoscapeRPC>}.
  You need to install the CytoscapeRPC plugin first and start the
  XML-RPC server on a given port (port 9000 by default) from the
  appropriate Plugins submenu in Cytoscape.
  
  Graph, vertex and edge attributes are transferred to Cytoscape whenever
  possible (i.e. when a suitable mapping exists between a Python type
  and a Cytoscape type). If there is no suitable Cytoscape type for a
  Python type, the drawer will use a string attribute on the Cytoscape
  side and invoke C{str()} on the Python attributes.
  
  If an attribute to be created on the Cytoscape side already exists with
  a different type, an underscore will be appended to the attribute name
  to resolve the type conflict.
  
  You can use the C{network_id} attribute of this class to figure out the
  network ID of the last graph drawn with this drawer.
docstr: Fetches the network with the given name from Cytoscape.
  
  When fetching networks from Cytoscape, the C{canonicalName} attributes
  of vertices and edges are not converted by default. Use the
  C{keep_canonical_names} parameter to retrieve these attributes as well.
  
  @param name: the name of the network in Cytoscape.
  @param directed: whether the network is directed.
  @param keep_canonical_names: whether to keep the C{canonicalName}
      vertex/edge attributes that are added automatically by Cytoscape
  @return: an appropriately constructed igraph L{Graph}.
docstr_tok: ["Fetches","the","network","with","the","given","name","from","Cytoscape",".","When","fetching","networks","from","Cytoscape",",","the","C","{","canonicalName","}","attributes","of","vertices","and","edges","are","not","converted","by","default",".","Use","the","C","{","keep_canonical_names","}","parameter","to","retrieve","these","attributes","as","well",".","@","param","name",":","the","name","of","the","network","in","Cytoscape",".","@","param","directed",":","whether","the","network","is","directed",".","@","param","keep_canonical_names",":","whether","to","keep","the","C","{","canonicalName","}","vertex\/edge","attributes","that","are","added","automatically","by","Cytoscape","@","return",":","an","appropriately","constructed","igraph","L","{","Graph","}","."]
code: def fetch(
      self, name=None, directed=False, keep_canonical_names=False
  ):
      """Fetches the network with the given name from Cytoscape.
  
      When fetching networks from Cytoscape, the C{canonicalName} attributes
      of vertices and edges are not converted by default. Use the
      C{keep_canonical_names} parameter to retrieve these attributes as well.
  
      @param name: the name of the network in Cytoscape.
      @param directed: whether the network is directed.
      @param keep_canonical_names: whether to keep the C{canonicalName}
          vertex/edge attributes that are added automatically by Cytoscape
      @return: an appropriately constructed igraph L{Graph}."""
      from igraph import Graph
  
      cy = self.service
  
      # Check the version number. Anything older than 1.3 is bad.
      version = cy.version()
      if " " in version:
          version = version.split(" ")[0]
      version = tuple(map(int, version.split(".")[:2]))
      if version < (1, 3):
          raise NotImplementedError(
              "CytoscapeGraphDrawer requires Cytoscape-RPC 1.3 or newer"
          )
  
      # Find out the ID of the network we are interested in
      if name is None:
          network_id = cy.getNetworkID()
      else:
          network_id = [
              k for k, v in cy.getNetworkList().items() if v == name
          ]
          if not network_id:
              raise ValueError("no such network: %r" % name)
          elif len(network_id) > 1:
              raise ValueError(
                  "more than one network exists with name: %r" % name
              )
          network_id = network_id[0]
  
      # Fetch the list of all the nodes and edges
      vertices = cy.getNodes(network_id)
      edges = cy.getEdges(network_id)
      n, m = len(vertices), len(edges)
  
      # Fetch the graph attributes
      graph_attrs = cy.getNetworkAttributes(network_id)
  
      # Fetch the vertex attributes
      vertex_attr_names = cy.getNodeAttributeNames()
      vertex_attrs = {}
      for attr_name in vertex_attr_names:
          if attr_name == "canonicalName" and not keep_canonical_names:
              continue
          has_attr = cy.nodesHaveAttribute(attr_name, vertices)
          filtered = [idx for idx, ok in enumerate(has_attr) if ok]
          values = cy.getNodesAttributes(
              attr_name,
              [name for name, ok in zip(vertices, has_attr) if ok],
          )
          attrs = [None] * n
          for idx, value in zip(filtered, values):
              attrs[idx] = value
          vertex_attrs[attr_name] = attrs
  
      # Fetch the edge attributes
      edge_attr_names = cy.getEdgeAttributeNames()
      edge_attrs = {}
      for attr_name in edge_attr_names:
          if attr_name == "canonicalName" and not keep_canonical_names:
              continue
          has_attr = cy.edgesHaveAttribute(attr_name, edges)
          filtered = [idx for idx, ok in enumerate(has_attr) if ok]
          values = cy.getEdgesAttributes(
              attr_name,
              [name for name, ok in zip(edges, has_attr) if ok],
          )
          attrs = [None] * m
          for idx, value in zip(filtered, values):
              attrs[idx] = value
          edge_attrs[attr_name] = attrs
  
      # Create a vertex name index
      vertex_name_index = {v: k for k, v in enumerate(vertices)}
      del vertices
  
      # Remap the edges list to numeric IDs
      edge_list = []
      for edge in edges:
          parts = edge.split()
          edge_list.append(
              (vertex_name_index[parts[0]], vertex_name_index[parts[2]])
          )
      del edges
  
      return Graph(
          n,
          edge_list,
          directed=directed,
          graph_attrs=graph_attrs,
          vertex_attrs=vertex_attrs,
          edge_attrs=edge_attrs,
      )
  
file_path: python-igraph/src/igraph/drawing/graph.py
imports: from warnings import warn
  from igraph.drawing.baseclasses import AbstractGraphDrawer, AbstractXMLRPCDrawer
label_desc: Use image node_id 3 for calling the CytoscapeGraphDrawer obj's underlying member method code with example usage: obj.fetch(name, directed, keep_canonical_names) and returns: Graph