code: def get_penalty_model(specification, database=None):
      
      # only handles index-labelled nodes
      if not _is_index_labelled(specification.graph):
          relabel_applied = True
          mapping, inverse_mapping = _graph_canonicalization(specification.graph)
          specification = specification.relabel_variables(mapping, inplace=False)
      else:
          relabel_applied = False
  
      # connect to the database. Note that once the connection is made it cannot be
      # broken up between several processes.
      if database is None:
          conn = cache_connect()
      else:
          conn = cache_connect(database)
  
      # get the penalty_model
      with conn as cur:
          try:
              widget = next(iter_penalty_model_from_specification(cur, specification))
          except StopIteration:
              widget = None
  
      # close the connection
      conn.close()
  
      if widget is None:
          raise pm.MissingPenaltyModel("no penalty model with the given specification found in cache")
  
      if relabel_applied:
          # relabel the widget in-place
          widget.relabel_variables(inverse_mapping, inplace=True)
  
      return widget
docs: Factory function for penaltymodel_cache.
  
      Args:
          specification (penaltymodel.Specification): The specification
              for the desired penalty model.
          database (str, optional): The path to the desired sqlite database
              file. If None, will use the default.
  
      Returns:
          :class:`penaltymodel.PenaltyModel`: Penalty model with the given specification.
  
      Raises:
          :class:`penaltymodel.MissingPenaltyModel`: If the penalty model is not in the
              cache.
  
      Parameters:
          priority (int): 100